diff --git a/extras/openslides_gui/__init__.py b/extras/openslides_gui/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/extras/openslides_gui/__main__.py b/extras/openslides_gui/__main__.py
deleted file mode 100644
index 14932bed3..000000000
--- a/extras/openslides_gui/__main__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .gui import main
-
-if __name__ == "__main__":
- main()
diff --git a/extras/openslides_gui/data/openslides-logo_wide.png b/extras/openslides_gui/data/openslides-logo_wide.png
deleted file mode 100644
index d46f12df8..000000000
Binary files a/extras/openslides_gui/data/openslides-logo_wide.png and /dev/null differ
diff --git a/extras/openslides_gui/data/openslides.ico b/extras/openslides_gui/data/openslides.ico
deleted file mode 100644
index 0f562a295..000000000
Binary files a/extras/openslides_gui/data/openslides.ico and /dev/null differ
diff --git a/extras/openslides_gui/gui.py b/extras/openslides_gui/gui.py
deleted file mode 100644
index 33ac3855d..000000000
--- a/extras/openslides_gui/gui.py
+++ /dev/null
@@ -1,756 +0,0 @@
-from __future__ import unicode_literals
-
-import Queue
-import datetime
-import errno
-import gettext
-import itertools
-import json
-import locale
-import os
-import subprocess
-import sys
-import threading
-
-import wx
-
-import openslides
-
-from openslides.utils.main import (
- detect_openslides_type,
- filesystem2unicode,
- unicode2filesystem,
- get_default_user_data_path,
- get_port,
- PortableDirNotWritable,
-)
-
-
-# NOTE: djangos translation module can't be used here since it requires
-# a defined settings module
-_translations = gettext.NullTranslations()
-_ = lambda text: _translations.ugettext(text)
-ungettext = lambda msg1, msg2, n: _translations.ungettext(msg1, msg2, n)
-
-
-def get_data_path(*args):
- path = filesystem2unicode(__file__)
- return os.path.join(os.path.dirname(path), "data", *args)
-
-
-class RunCmdEvent(wx.PyCommandEvent):
- def __init__(self, evt_type, evt_id):
- super(RunCmdEvent, self).__init__(evt_type, evt_id)
-
- self.running = False
- self.exitcode = None
-
-EVT_RUN_CMD_ID = wx.NewEventType()
-EVT_RUN_CMD = wx.PyEventBinder(EVT_RUN_CMD_ID, 1)
-
-
-class RunCommandControl(wx.Panel):
- UPDATE_INTERVAL = 500
-
- def __init__(self, parent):
- super(RunCommandControl, self).__init__(parent)
-
- self.child_process = None
- self.output_queue = Queue.Queue()
- self.output_read_thread = None
- self.canceled = False
- self.output_mutex = threading.RLock()
-
- vbox = wx.BoxSizer(wx.VERTICAL)
-
- self.te_output = wx.TextCtrl(
- self, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL)
- vbox.Add(self.te_output, 1, wx.EXPAND)
-
- self.update_timer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self.on_update_timer, self.update_timer)
-
- self.SetSizerAndFit(vbox)
-
- def _read_output(self):
- while True:
- # NOTE: don't use iterator interface since it uses an
- # internal buffer and we don't see output in a timely fashion
- line = self.child_process.stdout.readline()
- if not line:
- break
- self.output_queue.put(line)
-
- def is_alive(self):
- if self.child_process is None:
- return False
- return self.child_process.poll() is None
-
- def run_command(self, *args):
- if self.is_alive():
- raise ValueError("already running a command")
-
- cmd = [sys.executable, "-u", "-m", "openslides"]
- cmd.extend(args)
-
- # XXX: subprocess on windows only handles byte strings
- # with python3 this will hopefully no longer be the case
- cmd = [unicode2filesystem(x) for x in cmd]
-
- creationflags = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0)
- self.child_process = subprocess.Popen(
- cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT, creationflags=creationflags)
- self.child_process.stdin.close()
- self.output_read_thread = threading.Thread(target=self._read_output)
- self.output_read_thread.start()
-
- self.update_timer.Start(self.UPDATE_INTERVAL)
-
- evt = RunCmdEvent(EVT_RUN_CMD_ID, self.GetId())
- evt.running = True
- self.GetEventHandler().ProcessEvent(evt)
-
- def cancel_command(self):
- if not self.is_alive():
- return
-
- # TODO: try sigint first, then get more aggressive if user insists
- self.child_process.kill()
- self.canceled = True
-
- def on_update_timer(self, evt):
- is_alive = self.is_alive()
- if not is_alive:
- # join thread to make sure everything was read
- self.output_read_thread.join()
- self.output_read_thread = None
-
- for line_no in itertools.count():
- try:
- data = self.output_queue.get(block=False)
- except Queue.Empty:
- break
- else:
- # XXX: check whether django uses utf-8 or locale for
- # it's cli output
- text = data.decode("utf-8", errors="replace")
- with self.output_mutex:
- self.te_output.AppendText(text)
-
- # avoid waiting too long here if child is still alive
- if is_alive and line_no > 10:
- break
-
- if not is_alive:
- exitcode = self.child_process.returncode
- self.update_timer.Stop()
- self.child_process = None
-
- evt = RunCmdEvent(EVT_RUN_CMD_ID, self.GetId())
- evt.running = False
- evt.exitcode = exitcode
- self.GetEventHandler().ProcessEvent(evt)
-
- def append_message(self, text, newline="\n"):
- with self.output_mutex:
- self.te_output.AppendText(text + newline)
-
-
-class SettingsDialog(wx.Dialog):
- def __init__(self, parent):
- super(SettingsDialog, self).__init__(parent, wx.ID_ANY, _("Settings"))
-
- grid = wx.GridBagSizer(5, 5)
- row = 0
-
- lb_host = wx.StaticText(self, label=_("&Host:"))
- grid.Add(lb_host, pos=(row, 0))
- self.tc_host = wx.TextCtrl(self)
- grid.Add(self.tc_host, pos=(row, 1), flag=wx.EXPAND)
-
- row += 1
-
- lb_port = wx.StaticText(self, label=_("&Port:"))
- grid.Add(lb_port, pos=(row, 0))
- self.tc_port = wx.TextCtrl(self)
- grid.Add(self.tc_port, pos=(row, 1), flag=wx.EXPAND)
-
- row += 1
-
- sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL)
- if not sizer is None:
- grid.Add((0, 0), pos=(row, 0), span=(1, 2))
- row += 1
- grid.Add(sizer, pos=(row, 0), span=(1, 2))
-
- box = wx.BoxSizer(wx.VERTICAL)
- box.Add(
- grid, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL,
- border=5, proportion=1)
-
- self.SetSizerAndFit(box)
-
- @property
- def host(self):
- return self.tc_host.GetValue()
-
- @host.setter
- def host(self, host):
- self.tc_host.SetValue(host)
-
- @property
- def port(self):
- return self.tc_port.GetValue()
-
- @port.setter
- def port(self, port):
- self.tc_port.SetValue(port)
-
-
-class BackupSettingsDialog(wx.Dialog):
- # NOTE: keep order in sync with _update_interval_choices()
- _INTERVAL_UNITS = ["second", "minute", "hour"]
-
- def __init__(self, parent):
- super(BackupSettingsDialog, self).__init__(
- parent, wx.ID_ANY, _("Database backup"))
-
- self._interval_units = {}
-
- grid = wx.GridBagSizer(5, 5)
- row = 0
-
- self.cb_backup = wx.CheckBox(
- self, label=_("&Regularly backup database"))
- self.cb_backup.SetValue(True)
- self.cb_backup.Bind(wx.EVT_CHECKBOX, self.on_backup_checked)
- grid.Add(self.cb_backup, pos=(row, 0), span=(1, 3))
- row += 1
-
- lb_dest = wx.StaticText(self, label=_("&Destination:"))
- grid.Add(lb_dest, pos=(row, 0))
- style = wx.FLP_SAVE | wx.FLP_USE_TEXTCTRL
- self.fp_dest = wx.FilePickerCtrl(self, style=style)
- grid.Add(self.fp_dest, pos=(row, 1), span=(1, 2), flag=wx.EXPAND)
- row += 1
-
- lb_interval = wx.StaticText(self, label=_("&Every"))
- grid.Add(lb_interval, pos=(row, 0))
- self.sb_interval = wx.SpinCtrl(self, min=1, initial=1)
- self.sb_interval.Bind(wx.EVT_SPINCTRL, self.on_interval_changed)
- grid.Add(self.sb_interval, pos=(row, 1))
- self.ch_interval_unit = wx.Choice(self)
- grid.Add(self.ch_interval_unit, pos=(row, 2))
- row += 1
-
- grid.AddGrowableCol(1)
-
- sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL)
- if not sizer is None:
- grid.Add((0, 0), pos=(row, 0), span=(1, 3))
- row += 1
- grid.Add(sizer, pos=(row, 0), span=(1, 3))
-
- box = wx.BoxSizer(wx.VERTICAL)
- box.Add(
- grid, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL,
- border=5, proportion=1)
-
- self.SetSizerAndFit(box)
- self._update_interval_choices()
- self._update_backup_enabled()
-
- @property
- def backupdb_enabled(self):
- return self.cb_backup.GetValue()
-
- @backupdb_enabled.setter
- def backupdb_enabled(self, enabled):
- self.cb_backup.SetValue(enabled)
- self._update_backup_enabled()
-
- @property
- def backupdb_destination(self):
- return self.fp_dest.GetPath()
-
- @backupdb_destination.setter
- def backupdb_destination(self, path):
- self.fp_dest.SetPath(path)
-
- @property
- def interval(self):
- return self.sb_interval.GetValue()
-
- @interval.setter
- def interval(self, value):
- self.sb_interval.SetValue(value)
- self._update_interval_choices()
-
- @property
- def interval_unit(self):
- return self._INTERVAL_UNITS[self.ch_interval_unit.GetSelection()]
-
- @interval_unit.setter
- def interval_unit(self, unit):
- try:
- idx = self._INTERVAL_UNITS.index(unit)
- except IndexError:
- raise ValueError("Unknown unit {0}".format(unit))
-
- self.ch_interval_unit.SetSelection(idx)
-
- def _update_interval_choices(self):
- count = self.sb_interval.GetValue()
- choices = [
- ungettext("second", "seconds", count),
- ungettext("minute", "minutes", count),
- ungettext("hour", "hours", count),
- ]
-
- current = self.ch_interval_unit.GetSelection()
- if current == wx.NOT_FOUND:
- current = 2 # default to hour
-
- self.ch_interval_unit.Clear()
- self.ch_interval_unit.AppendItems(choices)
- self.ch_interval_unit.SetSelection(current)
-
- def _update_backup_enabled(self):
- checked = self.cb_backup.IsChecked()
- self.fp_dest.Enable(checked)
- self.sb_interval.Enable(checked)
- self.ch_interval_unit.Enable(checked)
-
- def on_backup_checked(self, evt):
- self._update_backup_enabled()
-
- def on_interval_changed(self, evt):
- self._update_interval_choices()
-
- # TODO: validate settings on close (e.g. non-empty path if backup is
- # enabled)
-
-
-class MainWindow(wx.Frame):
- def __init__(self, parent=None):
- super(MainWindow, self).__init__(parent, title="OpenSlides")
- icons = wx.IconBundleFromFile(
- get_data_path("openslides.ico"),
- wx.BITMAP_TYPE_ICO)
- self.SetIcons(icons)
-
- self.server_running = False
-
- self.gui_settings_path = None
- self.gui_initialized = False
-
- self.backupdb_enabled = False
- self.backupdb_destination = ""
- self.backupdb_interval = 15
- self.backupdb_interval_unit = "minute"
- self.last_backup = None
-
- self.backup_timer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self.on_backup_timer, self.backup_timer)
-
- spacing = 5
-
- panel = wx.Panel(self)
- grid = wx.GridBagSizer(spacing, spacing)
-
- # logo & about button
- logo_box = wx.BoxSizer(wx.HORIZONTAL)
- grid.Add(logo_box, pos=(0, 0), flag=wx.EXPAND)
- row = 0
-
- fp = get_data_path("openslides-logo_wide.png")
- with open(fp, "rb") as f:
- logo_wide_bmp = wx.ImageFromStream(f).ConvertToBitmap()
-
- logo_wide = wx.StaticBitmap(panel, wx.ID_ANY, logo_wide_bmp)
- logo_box.AddSpacer(2 * spacing)
- logo_box.Add(logo_wide)
- logo_box.AddStretchSpacer()
-
- version_str = _("Version {0}").format(openslides.get_version())
- lb_version = wx.StaticText(panel, label=version_str)
- font = lb_version.GetFont()
- font.SetPointSize(8)
- lb_version.SetFont(font)
- logo_box.Add(lb_version, flag=wx.ALIGN_CENTER_VERTICAL)
-
- self.bt_about = wx.Button(panel, label=_("&About..."))
- self.bt_about.Bind(wx.EVT_BUTTON, self.on_about_clicked)
- grid.Add(self.bt_about, pos=(row, 1), flag=wx.ALIGN_CENTER_VERTICAL)
- row += 1
-
- grid.Add((0, spacing), pos=(row, 0), span=(1, 2))
- row += 1
-
- # server settings
- server_settings = wx.StaticBox(panel, wx.ID_ANY, _("Server Settings"))
- server_box = wx.StaticBoxSizer(server_settings, wx.VERTICAL)
- grid.Add(server_box, pos=(row, 0), flag=wx.EXPAND)
-
- self._host = None
- self._port = None
- hbox = wx.BoxSizer(wx.HORIZONTAL)
- server_box.Add(hbox, flag=wx.EXPAND)
- self.lb_host = wx.StaticText(panel)
- hbox.Add(self.lb_host, flag=wx.ALIGN_CENTER_VERTICAL)
- hbox.AddStretchSpacer()
- self.lb_port = wx.StaticText(panel)
- hbox.Add(self.lb_port, flag=wx.ALIGN_CENTER_VERTICAL)
- hbox.AddStretchSpacer()
- self.bt_settings = wx.Button(panel, label=_("S&ettings..."))
- self.bt_settings.Bind(wx.EVT_BUTTON, self.on_settings_clicked)
- hbox.Add(self.bt_settings)
-
- server_box.AddSpacer(spacing)
- self.cb_start_browser = wx.CheckBox(
- panel, label=_("Automatically open &browser"))
- self.cb_start_browser.SetValue(True)
- server_box.Add(self.cb_start_browser)
- server_box.AddStretchSpacer()
-
- server_box.AddSpacer(spacing)
- self.bt_server = wx.Button(panel, label=_("&Start server"))
- self.bt_server.Bind(wx.EVT_BUTTON, self.on_start_server_clicked)
- server_box.Add(self.bt_server, flag=wx.EXPAND)
-
- self.host = "0.0.0.0"
- self.port = unicode(get_port(self.host, 80))
-
- # "action" buttons
- action_vbox = wx.BoxSizer(wx.VERTICAL)
- action_vbox.AddSpacer(3 * spacing)
- grid.Add(action_vbox, pos=(row, 1))
- self.bt_backup = wx.Button(panel, label=_("&Backup database..."))
- self.bt_backup.Bind(wx.EVT_BUTTON, self.on_backup_clicked)
- action_vbox.Add(self.bt_backup)
- action_vbox.AddSpacer(spacing)
- self.bt_sync_db = wx.Button(panel, label=_("S&ync database"))
- self.bt_sync_db.Bind(wx.EVT_BUTTON, self.on_syncdb_clicked)
- action_vbox.Add(self.bt_sync_db)
- action_vbox.AddSpacer(spacing)
- self.bt_reset_admin = wx.Button(panel, label=_("&Reset admin"))
- self.bt_reset_admin.Bind(wx.EVT_BUTTON, self.on_reset_admin_clicked)
- action_vbox.Add(self.bt_reset_admin)
- row += 1
-
- # command output
- self.cmd_run_ctrl = RunCommandControl(panel)
- self.cmd_run_ctrl.Bind(EVT_RUN_CMD, self.on_run_cmd_changed)
- grid.Add(
- self.cmd_run_ctrl,
- pos=(row, 0), span=(1, 2),
- flag=wx.EXPAND)
-
- grid.AddGrowableCol(0)
- grid.AddGrowableRow(3)
-
- box = wx.BoxSizer(wx.VERTICAL)
- box.Add(
- grid, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL,
- border=spacing, proportion=1)
- panel.SetSizerAndFit(box)
- self.Fit()
- self.SetMinSize(self.ClientToWindowSize(box.GetMinSize()))
- self.SetInitialSize(wx.Size(500, 400))
-
- self.Bind(wx.EVT_CLOSE, self.on_close)
-
- def initialize_gui(self):
- if self.gui_initialized:
- return True
-
- # Set path for gui settings to default user data according to the
- # OpenSlides type. This does not depend on any argument the user might
- # type in.
- openslides_type = detect_openslides_type()
- try:
- default_user_data_path = get_default_user_data_path(openslides_type)
- except PortableDirNotWritable:
- wx.MessageBox(
- _("The portable directory is not writable. Please copy the "
- "openslides portable to a writeable location and start it "
- "again from there"),
- _("Error: Portable directory not writable"),
- wx.OK | wx.ICON_ERROR)
- return False
-
- self.gui_settings_path = os.path.join(
- default_user_data_path, 'openslides', 'gui_settings.json')
- self.load_gui_settings()
- self.apply_backup_settings()
-
- self.gui_initialized = True
- return True
-
- @property
- def backup_interval_seconds(self):
- if self.backupdb_interval_unit == "second":
- factor = 1
- elif self.backupdb_interval_unit == "minute":
- factor = 60
- elif self.backupdb_interval_unit == "hour":
- factor = 3600
-
- return self.backupdb_interval * factor
-
- @property
- def host(self):
- return self._host
-
- @host.setter
- def host(self, host):
- self._host = host
- self.lb_host.SetLabel(_("Host: {0}").format(host))
-
- @property
- def port(self):
- return self._port
-
- @port.setter
- def port(self, port):
- self._port = port
- self.lb_port.SetLabel(_("Port: {0}").format(port))
-
- def load_gui_settings(self):
- if self.gui_settings_path is None:
- return
-
- try:
- f = open(self.gui_settings_path, "rb")
- except IOError as e:
- if e.errno == errno.ENOENT:
- return
- raise
-
- with f:
- settings = json.load(f)
-
- def setattr_unless_none(attr, value):
- if not value is None:
- setattr(self, attr, value)
-
- backup_settings = settings.get("database_backup", {})
- setattr_unless_none("backupdb_enabled", backup_settings.get("enabled"))
- setattr_unless_none(
- "backupdb_destination", backup_settings.get("destination"))
- setattr_unless_none(
- "backupdb_interval", backup_settings.get("interval"))
- setattr_unless_none(
- "backupdb_interval_unit", backup_settings.get("interval_unit"))
- last_backup = backup_settings.get("last_backup")
- if not last_backup is None:
- self.last_backup = datetime.datetime.strptime(
- last_backup, "%Y-%m-%d %H:%M:%S")
- server_settings = settings.get("server_settings", {})
- setattr_unless_none("host", server_settings.get("host"))
- setattr_unless_none("port", server_settings.get("port"))
-
- def save_gui_settings(self):
- if self.last_backup is None:
- last_backup = None
- else:
- last_backup = self.last_backup.strftime("%Y-%m-%d %H:%M:%S")
- settings = {
- "database_backup": {
- "enabled": self.backupdb_enabled,
- "destination": self.backupdb_destination,
- "internal": self.backupdb_interval,
- "interval_unit": self.backupdb_interval_unit,
- "last_backup": last_backup
- },
- "server_settings": {
- "host": self.host,
- "port": self.port,
- },
- }
-
- dp = os.path.dirname(self.gui_settings_path)
- if not os.path.exists(dp):
- os.makedirs(dp)
- with open(self.gui_settings_path, "wb") as f:
- json.dump(settings, f, ensure_ascii=False, indent=4)
-
- def apply_backup_settings(self):
- if self.backupdb_enabled and self.server_running:
- now = datetime.datetime.utcnow()
- delta = datetime.timedelta(seconds=self.backup_interval_seconds)
- ref = self.last_backup
- if ref is None:
- ref = now
- ref += delta
-
- d = ref - now
- seconds = d.days * 86400 + d.seconds
- if seconds < 1:
- seconds = 30 # avoid backup immediatly after start
- self.backup_timer.Start(seconds * 1000, True)
- else:
- self.backup_timer.Stop()
-
- def do_backup(self):
- cmd = [
- sys.executable, "-u", "-m", "openslides", "backupdb",
- self.backupdb_destination,
- ]
- p = subprocess.Popen(
- cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- p.stdin.close()
- output = p.stdout.read().strip()
- exitcode = p.wait()
- if output:
- self.cmd_run_ctrl.append_message(output)
-
- time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- if exitcode == 0:
- self.cmd_run_ctrl.append_message(
- _("{0}: Database backup successful.").format(time))
- else:
- self.cmd_run_ctrl.append_message(
- _("{0}: Database backup failed!").format(time))
-
- self.last_backup = datetime.datetime.utcnow()
-
- def on_syncdb_clicked(self, evt):
- self.cmd_run_ctrl.append_message(_("Syncing database..."))
- self.cmd_run_ctrl.run_command("syncdb")
-
- def on_reset_admin_clicked(self, evt):
- self.cmd_run_ctrl.append_message(_("Resetting admin user..."))
- self.cmd_run_ctrl.run_command("createsuperuser")
-
- def on_about_clicked(self, evt):
- info = wx.AboutDialogInfo()
- info.SetName("OpenSlides")
- info.SetVersion(openslides.get_version())
- info.SetDescription(_(
- "OpenSlides is a free web based presentation and "
- "assembly system.\n"
- "OpenSlides is free software; licensed under the MIT license."
- ).replace(u" ", u"\u00a0"))
- info.SetCopyright(_(u"\u00a9 2011-2015 by OpenSlides team"))
- info.SetWebSite(("http://www.openslides.org/", "www.openslides.org"))
-
- # XXX: at least on wxgtk this has no effect
- info.SetIcon(self.GetIcon())
- wx.AboutBox(info)
-
- def on_start_server_clicked(self, evt):
- if self.server_running:
- self.cmd_run_ctrl.cancel_command()
- return
-
- if self._host == "0.0.0.0":
- args = ["--port", self._port]
- else:
- args = ["--address", self._host, "--port", self._port]
-
- if not self.cb_start_browser.GetValue():
- args.append("--no-browser")
-
- self.server_running = True
- self.cmd_run_ctrl.run_command("start", *args)
-
- # initiate backup_timer if backup is enabled
- self.apply_backup_settings()
-
- self.bt_server.SetLabel(_("&Stop server"))
-
- def on_settings_clicked(self, evt):
- dlg = SettingsDialog(self)
- dlg.host = self._host
- dlg.port = self._port
-
- if dlg.ShowModal() == wx.ID_OK:
- self.host = dlg.host
- self.port = dlg.port
-
- def on_backup_clicked(self, evt):
- dlg = BackupSettingsDialog(self)
- dlg.backupdb_enabled = self.backupdb_enabled
- dlg.backupdb_destination = self.backupdb_destination
- dlg.interval = self.backupdb_interval
- dlg.interval_unit = self.backupdb_interval_unit
- if dlg.ShowModal() == wx.ID_OK:
- self.backupdb_enabled = dlg.backupdb_enabled
- self.backupdb_destination = dlg.backupdb_destination
- self.backupdb_interval = dlg.interval
- self.backupdb_interval_unit = dlg.interval_unit
- self.apply_backup_settings()
-
- def on_run_cmd_changed(self, evt):
- show_completion_msg = not evt.running
- if self.server_running and not evt.running:
- self.bt_server.SetLabel(_("&Start server"))
- self.server_running = False
-
- self.backup_timer.Stop()
- if self.backupdb_enabled:
- self.do_backup()
-
- # no operation completed msg when stopping server
- show_completion_msg = False
-
- self.bt_settings.Enable(not evt.running)
- self.bt_backup.Enable(not evt.running)
- self.bt_sync_db.Enable(not evt.running)
- self.bt_reset_admin.Enable(not evt.running)
- self.bt_server.Enable(self.server_running or not evt.running)
-
- if show_completion_msg:
- if evt.exitcode == 0:
- text = _("Operation successfully completed.")
- else:
- text = _("Operation failed (exit code = {0})").format(
- evt.exitcode)
- self.cmd_run_ctrl.append_message(text)
-
- def on_backup_timer(self, evt):
- if not self.backupdb_enabled:
- return
-
- self.do_backup()
- self.backup_timer.Start(1000 * self.backup_interval_seconds, True)
-
- def on_close(self, ev):
- self.cmd_run_ctrl.cancel_command()
- self.save_gui_settings()
- self.Destroy()
-
-class OpenslidesApp(wx.App):
- def __init__(self):
- super(OpenslidesApp, self).__init__(False)
-
- def OnInit(self):
- window = MainWindow()
- self.SetTopWindow(window)
-
- if not window.initialize_gui():
- self.Exit()
- return False
-
- window.Show()
- return True
-
-def main():
- locale.setlocale(locale.LC_ALL, "")
- lang = locale.getdefaultlocale()[0]
- if lang:
- global _translations
- localedir = filesystem2unicode(openslides.__file__)
- localedir = os.path.dirname(localedir)
- localedir = os.path.join(localedir, "locale")
- _translations = gettext.translation(
- "django", localedir, [lang], fallback=True)
-
- app = OpenslidesApp()
- app.MainLoop()
-
-if __name__ == "__main__":
- main()
diff --git a/extras/win32-portable/create_portable.txt b/extras/win32-portable/create_portable.txt
deleted file mode 100644
index a7138c19b..000000000
--- a/extras/win32-portable/create_portable.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-How to create a new portable Windows distribution of OpenSlides:
-----------------------------------------------------------------
-
-1. Install Python 2.7.x and Setuptools
- Follow the instructions in the README, section III (Windows installation), step 1.
-
-
-2. Install all required python packages from requirements_production.txt:
- (Note: You have to use 'easy_install -Z $PACKAGENAME')
-
- python install-requirements.py
-
-
-3. Install pywin32 from binary installer:
- http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/pywin32-219.win32-py2.7.exe/download
-
- Pywin32 is used to update the version resource of the prebuild openslides.exe.
- It is not strictly required but at least for published releases it is highly advisable.
-
-
-4. Install wxPython from binary installer:
- http://sourceforge.net/projects/wxpython/files/wxPython/2.8.12.1/wxPython2.8-win32-unicode-2.8.12.1-py27.exe/download
-
- WxPython is required to build the OpenSlides GUI frontend.
-
-
-5. Run in the main directory of the OpenSlides checkout:
-
- python extras\win32-portable\prepare_portable.py
-
-
-=> The portable OpenSlides distribution is created as a zip archive in
- the 'dist' directory of OpenSlides checkout.
-
-
-NOTE: Creating the portable Windows distribution of OpenSlides is not possible
-if Python is installed in 64-bit(!) version.
-
diff --git a/extras/win32-portable/install-requirements.py b/extras/win32-portable/install-requirements.py
deleted file mode 100644
index c2dfaa3c2..000000000
--- a/extras/win32-portable/install-requirements.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import os
-
-f = open("../../requirements_production.txt")
-reqs = f.read().split("\n")
-
-for req in reqs:
- # ignore comments or pip options
- if req.startswith('--') or req.startswith('#'):
- continue
- # ignore blank lines
- if len(req) > 0:
- os.system('easy_install -Z -U "%s"' % req)
diff --git a/extras/win32-portable/licenses/backports.ssl_match_hostname b/extras/win32-portable/licenses/backports.ssl_match_hostname
deleted file mode 100644
index 58058f1bb..000000000
--- a/extras/win32-portable/licenses/backports.ssl_match_hostname
+++ /dev/null
@@ -1,51 +0,0 @@
-Python License (Python-2.0)
-
-Python License, Version 2 (Python-2.0)
-
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python
-alone or in any derivative version, provided, however, that PSF's
-License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
-2001-2013 Python Software Foundation; All Rights Reserved" are retained in
-Python alone or in any derivative version prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
diff --git a/extras/win32-portable/licenses/beautifulsoup4 b/extras/win32-portable/licenses/beautifulsoup4
deleted file mode 100644
index 8501362df..000000000
--- a/extras/win32-portable/licenses/beautifulsoup4
+++ /dev/null
@@ -1,26 +0,0 @@
-Beautiful Soup is made available under the MIT license:
-
- Copyright (c) 2004-2012 Leonard Richardson
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE, DAMMIT.
-
-Beautiful Soup incorporates code from the html5lib library, which is
-also made available under the MIT license.
diff --git a/extras/win32-portable/licenses/django b/extras/win32-portable/licenses/django
deleted file mode 100644
index ce8fd060b..000000000
--- a/extras/win32-portable/licenses/django
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) Django Software Foundation and individual contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of Django nor the names of its contributors may be used
- to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/extras/win32-portable/licenses/django-ckeditor b/extras/win32-portable/licenses/django-ckeditor
deleted file mode 100644
index fb62af2a2..000000000
--- a/extras/win32-portable/licenses/django-ckeditor
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright (c) Shaun Sephton
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Shaun Sephton nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL SHAUN SEPHTON BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/extras/win32-portable/licenses/django-haystack b/extras/win32-portable/licenses/django-haystack
deleted file mode 100644
index f80cad874..000000000
--- a/extras/win32-portable/licenses/django-haystack
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 2009-2013, Daniel Lindsley.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of Haystack nor the names of its contributors may be used
- to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
----
-
-Prior to April 17, 2009, this software was released under the MIT license.
diff --git a/extras/win32-portable/licenses/django-mptt b/extras/win32-portable/licenses/django-mptt
deleted file mode 100644
index 686fd1176..000000000
--- a/extras/win32-portable/licenses/django-mptt
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright (c) 2007, Jonathan Buchanan
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/extras/win32-portable/licenses/html5lib b/extras/win32-portable/licenses/html5lib
deleted file mode 100644
index 61a275a14..000000000
--- a/extras/win32-portable/licenses/html5lib
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2006-2013 James Graham and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/extras/win32-portable/licenses/jsonfield b/extras/win32-portable/licenses/jsonfield
deleted file mode 100644
index 46bbd542a..000000000
--- a/extras/win32-portable/licenses/jsonfield
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2012 Brad Jasper
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/extras/win32-portable/licenses/natsort b/extras/win32-portable/licenses/natsort
deleted file mode 100644
index 993858af2..000000000
--- a/extras/win32-portable/licenses/natsort
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2012 Seth M. Morton
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/extras/win32-portable/licenses/openslides b/extras/win32-portable/licenses/openslides
deleted file mode 100644
index 26a03f0ea..000000000
--- a/extras/win32-portable/licenses/openslides
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2011-2015 OpenSlides Team
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/extras/win32-portable/licenses/reportlab b/extras/win32-portable/licenses/reportlab
deleted file mode 100644
index e714d0348..000000000
--- a/extras/win32-portable/licenses/reportlab
+++ /dev/null
@@ -1,29 +0,0 @@
-#####################################################################################
-#
-# Copyright (c) 2000-2010, ReportLab Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of the company nor the names of its contributors may be
-# used to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE OFFICERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-#####################################################################################
diff --git a/extras/win32-portable/licenses/six b/extras/win32-portable/licenses/six
deleted file mode 100644
index d76e02426..000000000
--- a/extras/win32-portable/licenses/six
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright (c) 2010-2014 Benjamin Peterson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/extras/win32-portable/licenses/sockjs-tornado b/extras/win32-portable/licenses/sockjs-tornado
deleted file mode 100644
index 578bbb425..000000000
--- a/extras/win32-portable/licenses/sockjs-tornado
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (C) 2011 Serge S. Koval
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/extras/win32-portable/licenses/tornado b/extras/win32-portable/licenses/tornado
deleted file mode 100644
index 7995af0ef..000000000
--- a/extras/win32-portable/licenses/tornado
+++ /dev/null
@@ -1,4 +0,0 @@
-Tornado is one of `Facebook's open source technologies
-`_. It is available under
-the `Apache License, Version 2.0
-`_.
diff --git a/extras/win32-portable/licenses/whoosh b/extras/win32-portable/licenses/whoosh
deleted file mode 100644
index 81485cb4e..000000000
--- a/extras/win32-portable/licenses/whoosh
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2011 Matt Chaput. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY MATT CHAPUT ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-EVENT SHALL MATT CHAPUT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-The views and conclusions contained in the software and documentation are
-those of the authors and should not be interpreted as representing official
-policies, either expressed or implied, of Matt Chaput.
diff --git a/extras/win32-portable/licenses/wxpython b/extras/win32-portable/licenses/wxpython
deleted file mode 100644
index a25356ad2..000000000
--- a/extras/win32-portable/licenses/wxpython
+++ /dev/null
@@ -1,46 +0,0 @@
-The wxWindows Library Licence
-
-Copyright (c) 1998 Julian Smart, Robert Roebling [, ...]
-
-Everyone is permitted to copy and distribute verbatim copies of this licence
-document, but changing it is not allowed.
-
-WXWINDOWS LIBRARY LICENCE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
-MODIFICATION
-
-This library is free software; you can redistribute it and/or modify it under
-the terms of the GNU Library General Public Licence as published by the Free
-Software Foundation; either version 2 of the Licence, or (at your option) any
-later version.
-
-This library is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Library General Public Licence for more details.
-
-You should have received a copy of the GNU Library General Public Licence along
-with this software, usually in a file named COPYING.LIB. If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-EXCEPTION NOTICE
-
-1. As a special exception, the copyright holders of this library give permission
-for additional uses of the text contained in this release of the library as
-licenced under the wxWindows Library Licence, applying either version 3 of the
-Licence, or (at your option) any later version of the Licence as published by
-the copyright holders of version 3 of the Licence document.
-
-2. The exception is that you may use, copy, link, modify and distribute under
-the user's own terms, binary object code versions of works based on the Library.
-
-3. If you copy code from files distributed under the terms of the GNU General
-Public Licence or the GNU Library General Public Licence into a copy of this
-library, as this licence permits, the exception does not apply to the code that
-you add in this way. To avoid misleading anyone as to the status of such
-modified files, you must delete this exception notice from such code and/or
-adjust the licensing conditions notice accordingly.
-
-4. If you write modifications of your own for this library, it is your choice
-whether to permit this exception to apply to your modifications. If you do not
-wish that, you must delete the exception notice from such code and/or adjust the
-licensing conditions notice accordingly.
diff --git a/extras/win32-portable/openslides.c b/extras/win32-portable/openslides.c
deleted file mode 100644
index 1eb9c19b1..000000000
--- a/extras/win32-portable/openslides.c
+++ /dev/null
@@ -1,212 +0,0 @@
-#include
-#include
-#include
-
-#define _WIN32_LEAN_AND_MEAN
-#include
-
-#include
-
-#define PYTHON_DLL_PATH "\\Dlls\\python27.dll"
-
-static void (*py_initialize)(void) = 0;
-static void (*py_finalize)(void) = 0;
-static void (*py_set_program_name)(char *) = 0;
-static void (*py_set_python_home)(char *) = 0;
-static int (*py_run_simple_string_flags)(const char *, PyCompilerFlags *) = 0;
-static void (*py_sys_set_argv_ex)(int, char **, int) = 0;
-static int (*py_main)(int, char **) = 0;
-static int *py_ignore_environment_flag = 0;
-
-static const char *run_openslides_code =
- "import openslides_gui.gui;"
- "openslides_gui.gui.main()";
-
-/* determine the path to the executable
- * NOTE: Py_GetFullProgramPath() can't be used because
- * this would trigger pythons search-path initialization
- * But we need this to initialize PYTHONHOME before this happens
- */
-static char *
-_get_module_name()
-{
- size_t size = 1;
- char *name = NULL;
- int i;
-
- /* a path > 40k would be insane, it is more likely something
- * else has gone very wrong on the system
- */
- for (i = 0;i < 10; i++)
- {
- DWORD res;
- char *n;
-
- n = realloc(name, size);
- if (!n)
- {
- free(name);
- return NULL;
- }
- name = n;
-
- res = GetModuleFileNameA(NULL, name, size);
- if (res != 0 && res < size)
- {
- return name;
- }
- else if (res == size)
- {
- /* NOTE: Don't check GetLastError() == ERROR_INSUFFICIENT_BUFFER
- * here, it isn't set consistently across all platforms
- */
-
- size += 4096;
- }
- else
- {
- DWORD err = GetLastError();
- fprintf(stderr, "WARNING: GetModuleFileName() failed "
- "(res = %d, err = %d)", res, err);
- free(name);
- return NULL;
-
- }
- }
-
- return NULL;
-}
-
-static void
-_fatal_error(const char *text)
-{
- MessageBoxA(NULL, text, "Fatal error", MB_OK | MB_ICONERROR);
- exit(1);
-}
-
-static void
-_fatal_error_fmt(const char *fmt, ...)
-{
- int size = 512;
- char *buf = malloc(size);
- va_list args;
- int bytes_written;
-
- if (!buf)
- abort();
-
- va_start(args, fmt);
- for (;;)
- {
- bytes_written = vsnprintf(buf, size, fmt, args);
- if (bytes_written > -1 && bytes_written < size)
- break;
- else if (bytes_written > size)
- size = bytes_written + 1;
- else
- size *= 2;
-
- buf = realloc(buf, size);
- if (!buf)
- abort();
- }
- va_end(args);
-
- _fatal_error(buf);
-}
-
-static void *
-_load_func(HMODULE module, const char *name)
-{
- void *address = GetProcAddress(module, name);
- if (!address)
- _fatal_error_fmt("Failed to look up symbol %s", name);
- return address;
-}
-
-static void
-_load_python(const char *pyhome)
-{
- size_t pyhome_len = strlen(pyhome);
- size_t size = pyhome_len + strlen(PYTHON_DLL_PATH) + 1;
- char *buf = malloc(size);
- HMODULE py_dll;
-
- if (!buf)
- abort();
- memcpy(buf, pyhome, pyhome_len);
- memcpy(buf + pyhome_len, PYTHON_DLL_PATH, sizeof(PYTHON_DLL_PATH));
- buf[size - 1] = '\0';
-
- py_dll = LoadLibrary(buf);
- if (!py_dll)
- {
- DWORD error = GetLastError();
- _fatal_error_fmt("Failed to load %s (error %d)", buf, error);
- }
-
- py_initialize = (void (*)(void))_load_func(py_dll, "Py_Initialize");
- py_finalize = (void (*)(void))_load_func(py_dll, "Py_Finalize");
- py_set_program_name = (void (*)(char *))
- _load_func(py_dll, "Py_SetProgramName");
- py_set_python_home = (void (*)(char *))
- _load_func(py_dll, "Py_SetPythonHome");
- py_run_simple_string_flags = (int (*)(const char *, PyCompilerFlags *))
- _load_func(py_dll, "PyRun_SimpleStringFlags");
- py_sys_set_argv_ex = (void (*)(int, char **, int))
- _load_func(py_dll, "PySys_SetArgvEx");
- py_main = (int (*)(int, char **))_load_func(py_dll, "Py_Main");
- py_ignore_environment_flag = (int *)
- _load_func(py_dll, "Py_IgnoreEnvironmentFlag");
-}
-
-static int
-_run()
-{
- if (py_run_simple_string_flags(run_openslides_code, NULL) != 0)
- _fatal_error("Failed to execute openslides");
-
- return 0;
-}
-
-
-int WINAPI
-WinMain(HINSTANCE inst, HINSTANCE prev_inst, LPSTR cmdline, int show)
-{
- int returncode;
- int run_py_main = __argc > 1;
- char *py_home, *sep = NULL;
-
- py_home = _get_module_name();
- if (!py_home)
- _fatal_error("Could not determine portable root directory");
-
- sep = strrchr(py_home, '\\');
- /* should always be the true */
- if (sep)
- *sep = '\0';
-
- _load_python(py_home);
- py_set_program_name(__argv[0]);
- py_set_python_home(py_home);
- *py_ignore_environment_flag = 1;
-
- if (run_py_main)
- {
- /* we where given extra arguments, behave like python.exe */
- returncode = py_main(__argc, __argv);
- }
- else
- {
- /* no arguments given => start openslides gui */
- py_initialize();
- py_sys_set_argv_ex(__argc, __argv, 0);
-
- returncode = _run();
- py_finalize();
- }
-
- free(py_home);
-
- return returncode;
-}
diff --git a/extras/win32-portable/openslides.exe b/extras/win32-portable/openslides.exe
deleted file mode 100644
index 96fb7ae1f..000000000
Binary files a/extras/win32-portable/openslides.exe and /dev/null differ
diff --git a/extras/win32-portable/prepare_portable.py b/extras/win32-portable/prepare_portable.py
deleted file mode 100755
index 36cb18c2d..000000000
--- a/extras/win32-portable/prepare_portable.py
+++ /dev/null
@@ -1,542 +0,0 @@
-#!/usr/bin/env python
-
-import errno
-import glob
-import os
-import re
-import shutil
-import sys
-import zlib
-zlib.Z_DEFAULT_COMPRESSION = zlib.Z_BEST_COMPRESSION
-import zipfile
-
-import distutils.ccompiler
-import distutils.sysconfig
-
-import pkg_resources
-
-import wx
-
-sys.path.insert(0, os.getcwd())
-sys.path.insert(1, os.path.join(os.getcwd(), "extras"))
-import openslides
-import openslides_gui
-
-COMMON_EXCLUDE = [
- r".pyc$",
- r".pyo$",
- r".po$",
- r".egg-info",
- r"\blocale/(?!de/|en/|fr/)[^/]+/"
-]
-
-LIBEXCLUDE = [
- r"^site-packages/",
- r"^test/",
- r"^curses/",
- r"^idlelib/",
- r"^lib2to3/",
- r"^lib-tk/",
- r"^msilib/",
-]
-
-
-SITE_PACKAGES = {
- "backports.ssl_match_hostname": {
- "copy": ["backports"],
- },
- "beautifulsoup4": {
- "copy": ["bs4"],
- },
- "html5lib": {
- "copy": ["html5lib"],
- },
- "django": {
- "copy": ["django"],
- "exclude": [
- r"^django/contrib/admindocs/",
- r"^django/contrib/comments/",
- r"^django/contrib/databrowse/",
- r"^django/contrib/flatpages/",
- r"^django/contrib/formtools/",
- r"^django/contrib/gis/",
- r"^django/contrib/localflavor/",
- r"^django/contrib/markup/",
- r"^django/contrib/redirects/",
- r"^django/contrib/sitemaps/",
- r"^django/contrib/syndication/",
- r"^django/contrib/webdesign/",
- ]
- },
- "django_ckeditor_updated": {
- "copy": ["ckeditor"],
- },
- "django-haystack": {
- "copy": ["haystack"],
- },
- "jsonfield": {
- "copy": ["jsonfield"],
- },
- "reportlab": {
- "copy": [
- "reportlab",
- "_renderPM.pyd",
- "_rl_accel.pyd",
- "pyHnj.pyd",
- "sgmlop.pyd",
- ],
- },
- "roman": {
- "copy": ["roman.py"],
- },
- "setuptools": {
- "copy": [
- "setuptools",
- "easy_install.py",
- "pkg_resources.py"
- ],
- },
- "six": {
- "copy": ["six.py"],
- },
- "sockjs-tornado": {
- "copy": ["sockjs"],
- },
- "tornado": {
- "copy": ["tornado"],
- },
- "natsort": {
- "copy": ["natsort"],
- },
- "whoosh": {
- "copy": ["whoosh"],
- },
- "wx": {
- # NOTE: wxpython is a special case, see copy_wx
- "copy": [],
- "exclude": [
- r"^wx/tools/",
- r"^wx/py/",
- r"^wx/build/",
- r"^wx/lib/",
- r"wx/_activex.pyd",
- r"wx/_animate.pyd",
- r"wx/_aui.pyd",
- r"wx/_calendar.pyd",
- r"wx/_combo.pyd",
- r"wx/_gizmos.pyd",
- r"wx/_glcanvas.pyd",
- r"wx/_grid.pyd",
- r"wx/_html.pyd",
- r"wx/_media.pyd",
- r"wx/_richtext.pyd",
- r"wx/_stc.pyd",
- r"wx/_webkit.pyd",
- r"wx/_wizard.pyd",
- r"wx/_xrc.pyd",
- r"wx/gdiplus.dll",
- r"wx/wxbase28uh_xml_vc.dll",
- r"wx/wxmsw28uh_aui_vc.dll",
- r"wx/wxmsw28uh_gizmos_vc.dll",
- r"wx/wxmsw28uh_gizmos_xrc_vc.dll",
- r"wx/wxmsw28uh_gl_vc.dll",
- r"wx/wxmsw28uh_media_vc.dll",
- r"wx/wxmsw28uh_qa_vc.dll",
- r"wx/wxmsw28uh_richtext_vc.dll",
- r"wx/wxmsw28uh_stc_vc.dll",
- r"wx/wxmsw28uh_xrc_vc.dll",
- ],
- },
-}
-
-PY_DLLS = [
- "unicodedata.pyd",
- "sqlite3.dll",
- "_sqlite3.pyd",
- "_socket.pyd",
- "select.pyd",
- "_ctypes.pyd",
- "_ssl.pyd",
- "_multiprocessing.pyd",
- "pyexpat.pyd",
-]
-
-MSVCR_PUBLIC_KEY = "1fc8b3b9a1e18e3b"
-MSVCR_VERSION = "9.0.21022.8"
-MSVCR_NAME = "Microsoft.VC90.CRT"
-
-OPENSLIDES_RC_TMPL = """
-#include
-
-#define ID_ICO_OPENSLIDES 1
-
-ID_ICO_OPENSLIDES ICON "openslides.ico"
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION {version[0]},{version[1]},{version[2]},{version[4]}
- PRODUCTVERSION {version[0]},{version[1]},{version[2]},{version[4]}
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS {file_flags}
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_APP
- FILESUBTYPE VFT2_UNKNOWN
-
- BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904E4"
- BEGIN
- VALUE "CompanyName", "OpenSlides team\\0"
- VALUE "FileDescription", "OpenSlides\\0"
- VALUE "FileVersion", "{version_str}\\0"
- VALUE "InternalName", "OpenSlides\\0"
- VALUE "LegalCopyright", "Copyright \\251 2011-2015\\0"
- VALUE "OriginalFilename", "openslides.exe\\0"
- VALUE "ProductName", "OpenSlides\\0"
- VALUE "ProductVersion", "{version_str}\\0"
- END
- END
-
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 0x4E4
- END
- END
-"""
-
-
-def compile_re_list(patterns):
- expr = "|".join("(?:{0})".format(x) for x in patterns)
- return re.compile(expr)
-
-
-def relpath(base, path, addslash=False):
- b = os.path.normpath(os.path.abspath(base))
- p = os.path.normpath(os.path.abspath(path))
- if p == b:
- p = "."
- if addslash:
- p += "/"
- return p
-
- b += os.sep
- if not p.startswith(b):
- raise ValueError("{0!r} is not relative to {1!r}".format(path, base))
- p = p[len(b):].replace(os.sep, "/")
- if addslash:
- p += "/"
-
- return p
-
-
-def filter_excluded_dirs(exclude_pattern, basedir, dirpath, dnames):
- i, l = 0, len(dnames)
- while i < l:
- rp = relpath(basedir, os.path.join(dirpath, dnames[i]), True)
- if exclude_pattern.search(rp):
- del dnames[i]
- l -= 1
- else:
- i += 1
-
-
-def copy_dir_exclude(exclude, basedir, srcdir, destdir):
- for dp, dnames, fnames in os.walk(srcdir):
- filter_excluded_dirs(exclude, basedir, dp, dnames)
-
- rp = relpath(basedir, dp)
- target_dir = os.path.join(destdir, rp)
- if not os.path.exists(target_dir):
- os.makedirs(target_dir)
-
- for fn in fnames:
- fp = os.path.join(dp, fn)
- rp = relpath(basedir, fp)
- if exclude.search(rp):
- continue
-
- shutil.copyfile(fp, os.path.join(destdir, rp))
-
-
-def collect_lib(libdir, odir):
- exclude = compile_re_list(COMMON_EXCLUDE + LIBEXCLUDE)
- copy_dir_exclude(exclude, libdir, libdir, os.path.join(odir, "Lib"))
-
-
-def get_pkg_exclude(name, extra=()):
- exclude = COMMON_EXCLUDE[:]
- exclude.extend(SITE_PACKAGES.get(name, {}).get("exclude", []))
- exclude.extend(extra)
- return compile_re_list(exclude)
-
-
-def copy_package(name, info, odir):
- copy_things = info.get("copy", [])
- if not copy_things:
- return
-
- dist = pkg_resources.get_distribution(name)
- exclude = get_pkg_exclude(name)
-
- site_dir = dist.location
- for thing in copy_things:
- fp = os.path.join(site_dir, thing)
- if not os.path.isdir(fp):
- rp = relpath(site_dir, fp)
- ofp = os.path.join(odir, rp)
- shutil.copyfile(fp, ofp)
- else:
- copy_dir_exclude(exclude, site_dir, fp, odir)
-
-
-def copy_wx(odir):
- base_dir = os.path.dirname(os.path.dirname(wx.__file__))
- wx_dir = os.path.join(base_dir, "wx")
- exclude = get_pkg_exclude("wx")
- copy_dir_exclude(exclude, base_dir, wx_dir, odir)
-
-
-def collect_site_packages(sitedir, odir):
- if not os.path.exists(odir):
- os.makedirs(odir)
-
- for name, info in SITE_PACKAGES.iteritems():
- copy_package(name, info, odir)
-
- assert "wx" in SITE_PACKAGES
- copy_wx(odir)
-
-
-def compile_openslides_launcher():
- try:
- cc = distutils.ccompiler.new_compiler()
- if not cc.initialized:
- cc.initialize()
- except distutils.errors.DistutilsError:
- return False
-
- cc.add_include_dir(distutils.sysconfig.get_python_inc())
- cc.define_macro("_CRT_SECURE_NO_WARNINGS")
-
- gui_data_dir = os.path.dirname(openslides_gui.__file__)
- gui_data_dir = os.path.join(gui_data_dir, "data")
- shutil.copyfile(
- os.path.join(gui_data_dir, "openslides.ico"),
- "extras/win32-portable/openslides.ico")
- rcfile = "extras/win32-portable/openslides.rc"
- with open(rcfile, "w") as f:
- if openslides.VERSION[3] == "final":
- file_flags = "0"
- else:
- file_flags = "VS_FF_PRERELEASE"
-
- f.write(OPENSLIDES_RC_TMPL.format(
- version=openslides.VERSION,
- version_str=openslides.get_version(),
- file_flags=file_flags))
-
- objs = cc.compile([
- "extras/win32-portable/openslides.c",
- rcfile,
- ])
- cc.link_executable(
- objs, "extras/win32-portable/openslides",
- extra_preargs=["/subsystem:windows", "/nodefaultlib:python27.lib"],
- libraries=["user32"]
- )
- return True
-
-
-def openslides_launcher_update_version_resource():
- try:
- import win32api
- import win32verstamp
- except ImportError:
- sys.stderr.write(
- "Using precompiled executable and pywin32 is not available - "
- "version resource may be out of date!\n")
- return False
- import struct
-
- sys.stdout.write("Updating version resource")
- # code based on win32verstamp.stamp() with some minor differences in
- # version handling
- major, minor, sub = openslides.VERSION[:3]
- build = openslides.VERSION[4]
- pre_release = openslides.VERSION[3] != "final"
- version_str = openslides.get_version()
-
- sdata = {
- "CompanyName": "OpenSlides team",
- "FileDescription": "OpenSlides",
- "FileVersion": version_str,
- "InternalName": "OpenSlides",
- "LegalCopyright": u"Copyright \xa9 2011-2015",
- "OriginalFilename": "openslides.exe",
- "ProductName": "OpenSlides",
- "ProductVersion": version_str,
- }
- vdata = {
- "Translation": struct.pack("hh", 0x409, 0x4e4),
- }
-
- vs = win32verstamp.VS_VERSION_INFO(
- major, minor, sub, build, sdata, vdata, pre_release, False)
- h = win32api.BeginUpdateResource("extras/win32-portable/openslides.exe", 0)
- win32api.UpdateResource(h, 16, 1, vs)
- win32api.EndUpdateResource(h, 0)
-
-
-def copy_dlls(odir):
- dll_src = os.path.join(sys.exec_prefix, "DLLs")
- dll_dest = os.path.join(odir, "DLLs")
- if not os.path.exists(dll_dest):
- os.makedirs(dll_dest)
-
- for dll_name in PY_DLLS:
- src = os.path.join(dll_src, dll_name)
- dest = os.path.join(dll_dest, dll_name)
- shutil.copyfile(src, dest)
-
- pydllname = "python{0}{1}.dll".format(*sys.version_info[:2])
- src = os.path.join(os.environ["WINDIR"], "System32", pydllname)
- dest = os.path.join(dll_dest, pydllname)
- shutil.copyfile(src, dest)
-
-
-def copy_msvcr(odir):
- candidates = glob.glob("{0}/x86_*{1}_{2}*".format(
- os.path.join(os.environ["WINDIR"], "winsxs"),
- MSVCR_NAME, MSVCR_PUBLIC_KEY))
-
- msvcr_local_name = None
- msvcr_dll_dir = None
- for dp in candidates:
- bn = os.path.basename(dp)
- if MSVCR_VERSION in bn:
- msvcr_local_name = bn
- msvcr_dll_dir = dp
- break
- else:
- sys.stderr.write(
- "Warning could not determine msvcr runtime location\n"
- "Private asssembly for VC runtime must be added manually\n")
- return
-
- msvcr_dest_dir = os.path.join(odir, MSVCR_NAME)
- if not os.path.exists(msvcr_dest_dir):
- os.makedirs(msvcr_dest_dir)
-
- for fn in os.listdir(msvcr_dll_dir):
- src = os.path.join(msvcr_dll_dir, fn)
- dest = os.path.join(msvcr_dest_dir, fn)
- shutil.copyfile(src, dest)
-
- src = os.path.join(
- os.environ["WINDIR"], "winsxs", "Manifests",
- "{0}.manifest".format(msvcr_local_name))
- dest = os.path.join(msvcr_dest_dir, "{0}.manifest".format(MSVCR_NAME))
- shutil.copyfile(src, dest)
-
-
-def write_package_info_content(outfile):
- """
- Writes a list of all included packages into outfile.
- """
- text = ['Included Packages\n', 17 * '=' + '\n', '\n']
- for pkg in sorted(SITE_PACKAGES):
- if pkg == "wx":
- # wxpython comes from an installer and has no distribution
- # --> handle it separately
- text.append("wxpython-{0}\n".format(wx.__version__))
- else:
- dist = pkg_resources.get_distribution(pkg)
- text.append("{0}-{1}\n".format(dist.project_name, dist.version))
- with open(outfile, "w") as f:
- f.writelines(text)
-
-
-def write_metadatafile(infile, outfile):
- """
- Writes content from metadata files like README, AUTHORS and LICENSE into
- outfile.
- """
- with open(infile, "rU") as f:
- text = [l for l in f]
- with open(outfile, "w") as f:
- f.writelines(text)
-
-
-def main():
- prefix = os.path.dirname(sys.executable)
- libdir = os.path.join(prefix, "Lib")
- sitedir = os.path.join(libdir, "site-packages")
- odir = "dist/openslides-{0}-portable".format(openslides.get_version())
-
- try:
- shutil.rmtree(odir)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
-
- os.makedirs(odir)
- out_site_packages = os.path.join(odir, "Lib", "site-packages")
-
- collect_lib(libdir, odir)
- collect_site_packages(sitedir, out_site_packages)
-
- exclude = get_pkg_exclude("openslides")
- copy_dir_exclude(exclude, ".", "openslides", out_site_packages)
-
- if not compile_openslides_launcher():
- sys.stdout.write("Using prebuild openslides.exe\n")
- openslides_launcher_update_version_resource()
-
- shutil.copyfile(
- "extras/win32-portable/openslides.exe",
- os.path.join(odir, "openslides.exe"))
-
- shutil.copytree(
- "extras/openslides_gui",
- os.path.join(out_site_packages, "openslides_gui"))
-
- copy_dlls(odir)
- copy_msvcr(odir)
-
- # Info on included packages
- shutil.copytree(
- "extras/win32-portable/licenses",
- os.path.join(odir, "packages-info"))
- write_package_info_content(os.path.join(odir, 'packages-info', 'PACKAGES.txt'))
-
- # Create plugins directory with README.txt
- plugindir = os.path.join(odir, "openslides", "plugins")
- os.makedirs(plugindir)
- readmetext = ["Please copy your plugin directory into this directory.\n", "\n",
- "For more information about OpenSlides plugins see:\n",
- "https://github.com/OpenSlides/OpenSlides/wiki/De%3APlugins\n"]
- with open(os.path.join(plugindir, 'README.txt'), "w") as readme:
- readme.writelines(readmetext)
-
- # AUTHORS, LICENSE, README
- write_metadatafile('AUTHORS', os.path.join(odir, 'AUTHORS.txt'))
- write_metadatafile('LICENSE', os.path.join(odir, 'LICENSE.txt'))
- write_metadatafile('README.rst', os.path.join(odir, 'README.txt'))
-
- zip_fp = os.path.join(
- "dist", "openslides-{0}-portable.zip".format(
- openslides.get_version()))
-
-
- with zipfile.ZipFile(zip_fp, "w", zipfile.ZIP_DEFLATED) as zf:
- for dp, dnames, fnames in os.walk(odir):
- for fn in fnames:
- fp = os.path.join(dp, fn)
- rp = relpath(odir, fp)
- zf.write(fp, rp)
-
- print("Successfully build {0}".format(zip_fp))
-
-
-if __name__ == "__main__":
- main()