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()