2012-04-25 22:29:19 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
openslides.main
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Main script to start and set up OpenSlides.
|
|
|
|
|
|
|
|
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
|
|
|
:license: GNU GPL, see LICENSE for more details.
|
|
|
|
"""
|
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
# for python 2.5 support
|
2012-04-15 16:04:08 +02:00
|
|
|
from __future__ import with_statement
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import optparse
|
|
|
|
import socket
|
|
|
|
import time
|
|
|
|
import threading
|
2012-08-04 20:59:27 +02:00
|
|
|
import base64
|
2012-04-15 16:04:08 +02:00
|
|
|
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
|
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
CONFIG_TEMPLATE = """
|
|
|
|
from openslides.openslides_settings import *
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-05 09:52:00 +02:00
|
|
|
# Use 'DEBUG = True' to get more details for server errors
|
|
|
|
# (Default for relaeses: 'False')
|
2012-08-04 20:59:27 +02:00
|
|
|
DEBUG = False
|
|
|
|
TEMPLATE_DEBUG = DEBUG
|
|
|
|
|
|
|
|
DBPATH = %(dbpath)r
|
|
|
|
|
|
|
|
DATABASES = {
|
|
|
|
'default': {
|
|
|
|
'ENGINE': 'django.db.backends.sqlite3',
|
|
|
|
'NAME': DBPATH,
|
|
|
|
'USER': '',
|
|
|
|
'PASSWORD': '',
|
|
|
|
'HOST': '',
|
|
|
|
'PORT': '',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Set timezone
|
|
|
|
TIME_ZONE = 'Europe/Berlin'
|
|
|
|
|
|
|
|
# Make this unique, and don't share it with anybody.
|
|
|
|
SECRET_KEY = %(default_key)r
|
|
|
|
|
|
|
|
# Add OpenSlides plugins to this list (see example entry in comment)
|
|
|
|
INSTALLED_PLUGINS = (
|
|
|
|
# 'pluginname',
|
|
|
|
)
|
|
|
|
|
|
|
|
INSTALLED_APPS += INSTALLED_PLUGINS
|
|
|
|
"""
|
|
|
|
|
|
|
|
KEY_LENGTH = 30
|
|
|
|
|
|
|
|
def main(argv=None):
|
2012-04-15 16:04:08 +02:00
|
|
|
if argv is None:
|
|
|
|
argv = sys.argv[1:]
|
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
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")
|
2012-04-15 16:04:08 +02:00
|
|
|
|
|
|
|
opts, args = parser.parse_args(argv)
|
2012-08-04 20:59:27 +02:00
|
|
|
if not args:
|
2012-08-05 09:52:00 +02:00
|
|
|
main(argv + ['init', 'openslides'])
|
|
|
|
main(argv + ['start', 'openslides'])
|
|
|
|
return 0
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
command = args[0]
|
|
|
|
|
2012-05-31 00:27:47 +02:00
|
|
|
addr, port = detect_listen_opts(opts.address, opts.port)
|
|
|
|
if port == 80:
|
|
|
|
url = "http://%s" % (addr, )
|
|
|
|
else:
|
|
|
|
url = "http://%s:%d" % (addr, port)
|
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
try:
|
|
|
|
environment_name = args[1]
|
|
|
|
except IndexError:
|
|
|
|
environment_name = None
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
if command == 'init':
|
2012-08-05 09:52:00 +02:00
|
|
|
if check_environment(environment_name):
|
|
|
|
print "'%s' is allready an environment" % environment_name
|
|
|
|
return 1
|
2012-08-04 20:59:27 +02:00
|
|
|
create_environment(environment_name or 'openslides', url)
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
elif command == 'start':
|
2012-08-05 09:52:00 +02:00
|
|
|
set_settings_environment(environment_name or os.getcwd())
|
|
|
|
if not check_environment():
|
|
|
|
print "'%s' is not a valid OpenSlides environment." % environment_name
|
|
|
|
sys.exit(1)
|
2012-08-04 20:59:27 +02:00
|
|
|
# NOTE: --insecure is needed so static files will be served if
|
|
|
|
# DEBUG is set to False
|
|
|
|
argv = ["", "runserver", "--noreload", "--insecure"]
|
|
|
|
if opts.nothread:
|
|
|
|
argv.append("--nothread")
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
argv.append("%s:%d" % (addr, port))
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
start_browser(url)
|
|
|
|
execute_from_command_line(argv)
|
|
|
|
|
|
|
|
|
2012-08-05 09:52:00 +02:00
|
|
|
def set_settings_environment(environment):
|
2012-08-04 20:59:27 +02:00
|
|
|
sys.path.append(environment)
|
|
|
|
os.environ[django.conf.ENVIRONMENT_VARIABLE] = 'settings'
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
|
2012-04-15 16:04:08 +02:00
|
|
|
def detect_listen_opts(address, port):
|
|
|
|
if address is None:
|
2012-04-27 22:54:20 +02:00
|
|
|
try:
|
|
|
|
address = socket.gethostbyname(socket.gethostname())
|
|
|
|
except socket.error:
|
|
|
|
address = "127.0.0.1"
|
2012-04-15 16:04:08 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
|
2012-05-31 00:27:47 +02:00
|
|
|
def start_browser(url):
|
2012-04-15 16:04:08 +02:00
|
|
|
browser = webbrowser.get()
|
|
|
|
def f():
|
|
|
|
time.sleep(1)
|
|
|
|
browser.open(url)
|
|
|
|
|
|
|
|
t = threading.Thread(target = f)
|
|
|
|
t.start()
|
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
def create_environment(environment, url=None):
|
2012-08-05 09:52:00 +02:00
|
|
|
setting_content = CONFIG_TEMPLATE % dict(
|
2012-08-04 20:59:27 +02:00
|
|
|
default_key=base64.b64encode(os.urandom(KEY_LENGTH)),
|
|
|
|
dbpath=os.path.join(os.path.abspath(environment), 'database.db'))
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
dirname = environment
|
|
|
|
if dirname and not os.path.exists(dirname):
|
|
|
|
os.makedirs(dirname)
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-05 09:52:00 +02:00
|
|
|
settings = os.path.join(environment, 'settings.py')
|
|
|
|
if not os.path.exists(settings):
|
|
|
|
with open(settings, 'w') as fp:
|
|
|
|
fp.write(setting_content)
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-08-05 09:52:00 +02:00
|
|
|
set_settings_environment(environment)
|
2012-04-15 16:04:08 +02:00
|
|
|
|
2012-05-31 00:27:47 +02:00
|
|
|
run_syncdb(url)
|
2012-04-15 16:04:08 +02:00
|
|
|
create_or_reset_admin_user()
|
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
def run_syncdb(url=None):
|
2012-04-15 16:04:08 +02:00
|
|
|
# now initialize the database
|
|
|
|
argv = ["", "syncdb", "--noinput"]
|
|
|
|
execute_from_command_line(argv)
|
|
|
|
|
2012-08-04 20:59:27 +02:00
|
|
|
if url is not None:
|
|
|
|
set_system_url(url)
|
2012-05-31 00:27:47 +02:00
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
|
2012-08-05 09:52:00 +02:00
|
|
|
def check_environment(environment=None):
|
|
|
|
if environment is not None:
|
|
|
|
set_settings_environment(environment)
|
|
|
|
try:
|
|
|
|
import settings
|
|
|
|
except ImportError:
|
|
|
|
return False
|
|
|
|
if not check_database():
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def check_database():
|
2012-04-25 19:37:51 +02:00
|
|
|
"""Detect if database was deleted and recreate if necessary"""
|
2012-04-27 01:09:12 +02:00
|
|
|
# can't be imported in global scope as they already require
|
|
|
|
# the settings module during import
|
|
|
|
from django.db import DatabaseError
|
|
|
|
from django.contrib.auth.models import User
|
2012-04-25 19:37:51 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
User.objects.count()
|
|
|
|
except DatabaseError:
|
2012-08-05 09:52:00 +02:00
|
|
|
return False
|
|
|
|
else:
|
2012-04-25 19:37:51 +02:00
|
|
|
return True
|
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
|
2012-04-15 16:04:08 +02:00
|
|
|
def create_or_reset_admin_user():
|
2012-04-27 01:09:12 +02:00
|
|
|
# can't be imported in global scope as it already requires
|
|
|
|
# the settings module during import
|
|
|
|
from django.contrib.auth.models import User
|
2012-07-18 10:46:07 +02:00
|
|
|
from openslides.config.models import config
|
2012-04-15 16:04:08 +02:00
|
|
|
try:
|
|
|
|
obj = User.objects.get(username = "admin")
|
|
|
|
except User.DoesNotExist:
|
|
|
|
User.objects.create_superuser(
|
2012-07-18 10:46:07 +02:00
|
|
|
username="admin",
|
|
|
|
password="admin",
|
|
|
|
email="admin@example.com")
|
|
|
|
config['admin_password'] = "admin"
|
2012-04-25 19:37:51 +02:00
|
|
|
print("Created default admin user")
|
2012-04-15 16:04:08 +02:00
|
|
|
return
|
|
|
|
|
2012-04-25 19:37:51 +02:00
|
|
|
print("Password for user admin was reset to 'admin'")
|
2012-04-15 16:04:08 +02:00
|
|
|
obj.set_password("admin")
|
|
|
|
obj.save()
|
|
|
|
|
2012-07-10 14:00:51 +02:00
|
|
|
|
2012-05-31 00:27:47 +02:00
|
|
|
def set_system_url(url):
|
|
|
|
# can't be imported in global scope as it already requires
|
|
|
|
# the settings module during import
|
|
|
|
from openslides.config.models import config
|
|
|
|
|
|
|
|
key = "participant_pdf_system_url"
|
2012-07-07 14:48:21 +02:00
|
|
|
if key in config:
|
|
|
|
return
|
2012-05-31 00:27:47 +02:00
|
|
|
config[key] = url
|
|
|
|
|
2012-04-15 16:04:08 +02:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|