Automated merge with ssh://openslides.org/openslides
This commit is contained in:
commit
81f4a8c5d5
12
extras/win32-portable/create_portable.txt
Normal file
12
extras/win32-portable/create_portable.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
How to create a new portable windows distribution of openslides:
|
||||||
|
----------------------------------------------------------------
|
||||||
|
1.) Follow the openslides installation instructions for windows, but add
|
||||||
|
the option "-Z" when executing easy_install e.g.:
|
||||||
|
easy_install -Z django django-mptt reportlab pil
|
||||||
|
|
||||||
|
2.) in the main directory of the openslides checkout execute:
|
||||||
|
python extras/win32-portable/prepare_portable.py
|
||||||
|
|
||||||
|
|
||||||
|
3.) The portable openslides distribution is now ready as a zip in the dist/
|
||||||
|
directory
|
125
extras/win32-portable/openslides.c
Normal file
125
extras/win32-portable/openslides.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define _WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
static const char *site_code =
|
||||||
|
"import sys;"
|
||||||
|
"import os;"
|
||||||
|
"import site;"
|
||||||
|
"path = os.path.dirname(sys.executable);"
|
||||||
|
"site_dir = os.path.join(path, \"site-packages\");"
|
||||||
|
"site.addsitedir(site_dir);"
|
||||||
|
"sys.path.append(path)";
|
||||||
|
|
||||||
|
static const char *run_openslides_code =
|
||||||
|
"import openslides.main;"
|
||||||
|
"openslides.main.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 consisntently 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 int
|
||||||
|
_run()
|
||||||
|
{
|
||||||
|
if (PyRun_SimpleString(site_code) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: failed to initialize site path\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyRun_SimpleString(run_openslides_code) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: failed to execute openslides\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int returncode;
|
||||||
|
char *py_home, *sep = NULL;
|
||||||
|
|
||||||
|
Py_SetProgramName(argv[0]);
|
||||||
|
|
||||||
|
py_home = _get_module_name();
|
||||||
|
|
||||||
|
if (py_home)
|
||||||
|
sep = strrchr(py_home, '\\');
|
||||||
|
/* should always be the true */
|
||||||
|
if (sep)
|
||||||
|
{
|
||||||
|
*sep = '\0';
|
||||||
|
Py_SetPythonHome(py_home);
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_Initialize();
|
||||||
|
PySys_SetArgvEx(argc, argv, 0);
|
||||||
|
|
||||||
|
returncode = _run();
|
||||||
|
|
||||||
|
Py_Finalize();
|
||||||
|
free(py_home);
|
||||||
|
|
||||||
|
return returncode;
|
||||||
|
}
|
BIN
extras/win32-portable/openslides.exe
Normal file
BIN
extras/win32-portable/openslides.exe
Normal file
Binary file not shown.
292
extras/win32-portable/prepare_portable.py
Normal file
292
extras/win32-portable/prepare_portable.py
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
from contextlib import nested
|
||||||
|
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
|
sys.path.insert(0, os.getcwd())
|
||||||
|
import openslides
|
||||||
|
|
||||||
|
COMMON_EXCLUDE = [
|
||||||
|
r".pyc$",
|
||||||
|
r".pyo$",
|
||||||
|
r".po$",
|
||||||
|
r".egg-info",
|
||||||
|
r"\blocale/(?!de/|en/)[^/]+/"
|
||||||
|
]
|
||||||
|
|
||||||
|
LIBEXCLUDE = [
|
||||||
|
r"^site-packages/",
|
||||||
|
r"^test/",
|
||||||
|
r"^curses/",
|
||||||
|
r"^idlelib/",
|
||||||
|
r"^lib2to3/",
|
||||||
|
r"^lib-tk/",
|
||||||
|
r"^msilib/",
|
||||||
|
r"^multiprocessing/",
|
||||||
|
r"^unittest/",
|
||||||
|
]
|
||||||
|
|
||||||
|
OPENSLIDES_EXCLUDE = [
|
||||||
|
r"^openslides/settings.py"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
SITE_PACKAGES = {
|
||||||
|
"django": {
|
||||||
|
"copy": ["django"],
|
||||||
|
"exclude": [
|
||||||
|
r"^contrib/admindocs/",
|
||||||
|
r"^contrib/comments/",
|
||||||
|
r"^contrib/databrowse/",
|
||||||
|
r"^contrib/flatpages/",
|
||||||
|
r"^contrib/formtools/",
|
||||||
|
r"^contrib/gis/",
|
||||||
|
r"^contrib/humanize/",
|
||||||
|
r"^contrib/localflavor/",
|
||||||
|
r"^contrib/markup/",
|
||||||
|
r"^contrib/redirects/",
|
||||||
|
r"^contrib/sitemaps/",
|
||||||
|
r"^contrib/syndication/",
|
||||||
|
r"^contrib/webdesign/",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"django-mptt": {
|
||||||
|
"copy": ["mptt"],
|
||||||
|
},
|
||||||
|
"reportlab": {
|
||||||
|
"copy": [
|
||||||
|
"reportlab",
|
||||||
|
"_renderPM.pyd",
|
||||||
|
"_rl_accel.pyd",
|
||||||
|
"sgmlop.pyd",
|
||||||
|
"pyHnj.pyd",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"pil": {
|
||||||
|
# NOTE: PIL is a special case, see copy_pil
|
||||||
|
"copy": [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PY_DLLS = [
|
||||||
|
"unicodedata.pyd",
|
||||||
|
"sqlite3.dll",
|
||||||
|
"_sqlite3.pyd",
|
||||||
|
"_socket.pyd",
|
||||||
|
"select.pyd",
|
||||||
|
]
|
||||||
|
|
||||||
|
MSVCR_PUBLIC_KEY = "1fc8b3b9a1e18e3b"
|
||||||
|
MSVCR_VERSION = "9.0.21022.8"
|
||||||
|
MSVCR_NAME = "Microsoft.VC90.CRT"
|
||||||
|
|
||||||
|
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):
|
||||||
|
dist = pkg_resources.get_distribution(name)
|
||||||
|
exclude = get_pkg_exclude(name)
|
||||||
|
|
||||||
|
site_dir = dist.location
|
||||||
|
for thing in info.get("copy", []):
|
||||||
|
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_pil(odir):
|
||||||
|
dist = pkg_resources.get_distribution("pil")
|
||||||
|
exclude = get_pkg_exclude("pil")
|
||||||
|
|
||||||
|
dest_dir = os.path.join(odir, "PIL")
|
||||||
|
copy_dir_exclude(exclude, dist.location, dist.location, dest_dir)
|
||||||
|
fp = os.path.join(dest_dir, "PIL.pth")
|
||||||
|
if os.path.isfile(fp):
|
||||||
|
os.rename(fp, os.path.join(odir, "PIL.pth"))
|
||||||
|
else:
|
||||||
|
fp = os.path.join(os.path.dirname(dist.location), "PIL.pth")
|
||||||
|
shutil.copyfile(fp, os.path.join(odir, "PIL.pth"))
|
||||||
|
|
||||||
|
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 "pil" in SITE_PACKAGES
|
||||||
|
copy_pil(odir)
|
||||||
|
|
||||||
|
def compile_openslides_launcher():
|
||||||
|
cc = distutils.ccompiler.new_compiler()
|
||||||
|
cc.add_include_dir(distutils.sysconfig.get_python_inc())
|
||||||
|
cc.add_library_dir(os.path.join(sys.exec_prefix, "Libs"))
|
||||||
|
|
||||||
|
objs = cc.compile(["extras/win32-portable/openslides.c"])
|
||||||
|
cc.link_executable(objs, "extras/win32-portable/openslides")
|
||||||
|
|
||||||
|
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(odir, 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")
|
||||||
|
sys.stderr.write("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 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)
|
||||||
|
|
||||||
|
collect_lib(libdir, odir)
|
||||||
|
collect_site_packages(sitedir, os.path.join(odir, "site-packages"))
|
||||||
|
|
||||||
|
exclude = get_pkg_exclude("openslides", OPENSLIDES_EXCLUDE)
|
||||||
|
copy_dir_exclude(exclude, ".", "openslides", odir)
|
||||||
|
|
||||||
|
try:
|
||||||
|
compile_openslides_launcher()
|
||||||
|
except distutils.errors.DistutilsError:
|
||||||
|
sys.stderr.write("openslides.exe could not be build, "
|
||||||
|
"trying to use existing file\n")
|
||||||
|
|
||||||
|
shutil.copyfile("extras/win32-portable/openslides.exe",
|
||||||
|
os.path.join(odir, "openslides.exe"))
|
||||||
|
|
||||||
|
copy_dlls(odir)
|
||||||
|
copy_msvcr(odir)
|
||||||
|
|
||||||
|
fp = os.path.join("dist", "openslides-{0}-portable.zip".format(
|
||||||
|
openslides.get_version()))
|
||||||
|
|
||||||
|
with zipfile.ZipFile(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)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -117,7 +117,7 @@ class Item(MPTTModel, SlideMixin):
|
|||||||
order_insertion_by = ['weight', 'title']
|
order_insertion_by = ['weight', 'title']
|
||||||
|
|
||||||
|
|
||||||
register_slidemodel(Item, model_name=_('Agenda Item'))
|
register_slidemodel(Item)
|
||||||
|
|
||||||
# TODO: put this in another file
|
# TODO: put this in another file
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ from django.db.models.query import EmptyQuerySet
|
|||||||
from projector.api import get_active_slide
|
from projector.api import get_active_slide
|
||||||
|
|
||||||
from agenda.models import Item
|
from agenda.models import Item
|
||||||
from agenda.api import is_summary
|
|
||||||
|
|
||||||
class ItemTest(TestCase):
|
class ItemTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -90,28 +89,16 @@ class ViewTest(TestCase):
|
|||||||
def testActivate(self):
|
def testActivate(self):
|
||||||
c = self.adminClient
|
c = self.adminClient
|
||||||
|
|
||||||
response = c.get('/agenda/%d/activate/' % self.item1.id)
|
response = c.get('/projector/activate/%s/' % self.item1.sid)
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertTrue(self.item1.active)
|
self.assertTrue(self.item1.active)
|
||||||
self.assertFalse(self.item2.active)
|
self.assertFalse(self.item2.active)
|
||||||
self.assertFalse(is_summary())
|
|
||||||
|
|
||||||
response = c.get('/agenda/%d/activate/summary/' % self.item2.id)
|
response = c.get('/projector/activate/%s/' % 'agenda')
|
||||||
self.assertEqual(response.status_code, 302)
|
|
||||||
self.assertTrue(self.item2.active)
|
|
||||||
self.assertFalse(self.item1.active)
|
|
||||||
self.assertTrue(is_summary())
|
|
||||||
|
|
||||||
response = c.get('/agenda/%d/activate/' % 0)
|
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertFalse(self.item2.active)
|
self.assertFalse(self.item2.active)
|
||||||
self.assertFalse(self.item1.active)
|
self.assertFalse(self.item1.active)
|
||||||
self.assertEqual(get_active_slide(only_sid=True), 'agenda_show')
|
self.assertEqual(get_active_slide(only_sid=True), 'agenda')
|
||||||
|
|
||||||
response = c.get('/agenda/%d/activate/' % 10000)
|
|
||||||
self.assertEqual(response.status_code, 404)
|
|
||||||
self.assertFalse(self.item2.active)
|
|
||||||
self.assertFalse(self.item1.active)
|
|
||||||
|
|
||||||
def testClose(self):
|
def testClose(self):
|
||||||
c = self.adminClient
|
c = self.adminClient
|
||||||
|
152
openslides/main.py
Normal file
152
openslides/main.py
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
from __future__ import with_statement
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import optparse
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import webbrowser
|
||||||
|
from contextlib import nested
|
||||||
|
|
||||||
|
import django.conf
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
from django.utils.crypto import get_random_string
|
||||||
|
|
||||||
|
import openslides
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv = None):
|
||||||
|
if argv is None:
|
||||||
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
|
parser = optparse.OptionParser(description = "Run openslides using "
|
||||||
|
"django's builtin webserver")
|
||||||
|
parser.add_option("-a", "--address", help = "IP Address to listen on")
|
||||||
|
parser.add_option("-p", "--port", type = "int", help = "Port to listen on")
|
||||||
|
parser.add_option("--nothread", action = "store_true",
|
||||||
|
help = "Do not use threading")
|
||||||
|
parser.add_option("--syncdb", action = "store_true",
|
||||||
|
help = "Update/create database before starting the server")
|
||||||
|
parser.add_option("--reset-admin", action = "store_true",
|
||||||
|
help = "Make sure the user 'admin' exists and uses 'admin' as password")
|
||||||
|
|
||||||
|
opts, args = parser.parse_args(argv)
|
||||||
|
if args:
|
||||||
|
sys.stderr.write("This command does not take arguments!\n\n")
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not prepare_openslides(opts.syncdb):
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if opts.reset_admin:
|
||||||
|
create_or_reset_admin_user()
|
||||||
|
|
||||||
|
argv = ["", "runserver", "--noreload"]
|
||||||
|
if opts.nothread:
|
||||||
|
argv.append("--nothread")
|
||||||
|
|
||||||
|
addr, port = detect_listen_opts(opts.address, opts.port)
|
||||||
|
argv.append("%s:%d" % (addr, port))
|
||||||
|
|
||||||
|
start_browser(addr, port)
|
||||||
|
execute_from_command_line(argv)
|
||||||
|
|
||||||
|
def detect_listen_opts(address, port):
|
||||||
|
if address is None:
|
||||||
|
address = socket.gethostbyname(socket.gethostname())
|
||||||
|
|
||||||
|
if port is None:
|
||||||
|
# test if we can use port 80
|
||||||
|
s = socket.socket()
|
||||||
|
port = 80
|
||||||
|
try:
|
||||||
|
s.bind((address, port))
|
||||||
|
s.listen(-1)
|
||||||
|
except socket.error:
|
||||||
|
port = 8000
|
||||||
|
finally:
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
return address, port
|
||||||
|
|
||||||
|
def start_browser(addr, port):
|
||||||
|
if port == 80:
|
||||||
|
url = "http://%s" % (addr, )
|
||||||
|
else:
|
||||||
|
url = "http://%s:%d" % (addr, port)
|
||||||
|
browser = webbrowser.get()
|
||||||
|
def f():
|
||||||
|
time.sleep(1)
|
||||||
|
browser.open(url)
|
||||||
|
|
||||||
|
t = threading.Thread(target = f)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
def prepare_openslides(always_syncdb = False):
|
||||||
|
settings_module = os.environ.get(django.conf.ENVIRONMENT_VARIABLE)
|
||||||
|
if not settings_module:
|
||||||
|
os.environ[django.conf.ENVIRONMENT_VARIABLE] = "openslides.settings"
|
||||||
|
settings_module = "openslides.settings"
|
||||||
|
|
||||||
|
try:
|
||||||
|
# settings is a lazy object, force the settings module
|
||||||
|
# to be imported
|
||||||
|
dir(django.conf.settings)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if always_syncdb:
|
||||||
|
run_syncdb()
|
||||||
|
return True # import worked, settings are already configured
|
||||||
|
|
||||||
|
|
||||||
|
if settings_module != "openslides.settings":
|
||||||
|
sys.stderr.write("Settings module '%s' cannot be imported.\n"
|
||||||
|
% (django.conf.ENVIRONMENT_VARIABLE, ))
|
||||||
|
return False
|
||||||
|
|
||||||
|
openslides_dir = os.path.dirname(openslides.__file__)
|
||||||
|
src_fp = os.path.join(openslides_dir, "default.settings.py")
|
||||||
|
dest_fp = os.path.join(openslides_dir, "settings.py")
|
||||||
|
|
||||||
|
with nested(open(dest_fp, "w"), open(src_fp, "r")) as (dest, src):
|
||||||
|
for l in src:
|
||||||
|
if l.startswith("SECRET_KEY ="):
|
||||||
|
l = "SECRET_KEY = '%s'\n" % (generate_secret_key(), )
|
||||||
|
dest.write(l)
|
||||||
|
|
||||||
|
|
||||||
|
run_syncdb()
|
||||||
|
create_or_reset_admin_user()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def run_syncdb():
|
||||||
|
# now initialize the database
|
||||||
|
argv = ["", "syncdb", "--noinput"]
|
||||||
|
execute_from_command_line(argv)
|
||||||
|
|
||||||
|
def create_or_reset_admin_user():
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj = User.objects.get(username = "admin")
|
||||||
|
except User.DoesNotExist:
|
||||||
|
User.objects.create_superuser(
|
||||||
|
username = "admin",
|
||||||
|
password = "admin",
|
||||||
|
email = "admin@example.com")
|
||||||
|
return
|
||||||
|
|
||||||
|
obj.set_password("admin")
|
||||||
|
obj.save()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_secret_key():
|
||||||
|
# same chars/ length as used in djangos startproject command
|
||||||
|
chars = "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)"
|
||||||
|
return get_random_string(50, chars)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user