summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/Setup.py (renamed from module/setup/Setup.py)193
-rw-r--r--module/UserManager.py23
-rw-r--r--module/network/HTTPDownload.py6
-rw-r--r--module/setup/Questions.py50
-rw-r--r--module/setup/__init__.py0
-rw-r--r--module/utils/fs.py8
-rw-r--r--module/web/ServerThread.py84
-rw-r--r--module/web/setup_app.py13
-rw-r--r--module/web/utils.py7
-rwxr-xr-xpyLoadCore.py11
10 files changed, 154 insertions, 241 deletions
diff --git a/module/setup/Setup.py b/module/Setup.py
index 58506d8c2..4e89ed0f2 100644
--- a/module/setup/Setup.py
+++ b/module/Setup.py
@@ -1,144 +1,88 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: RaNaN
-"""
-from getpass import getpass
+
+###############################################################################
+# Copyright(c) 2008-2012 pyLoad Team
+# http://www.pyload.org
+#
+# This file is part of pyLoad.
+# pyLoad is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# Subjected to the terms and conditions in LICENSE
+#
+# @author: RaNaN
+###############################################################################
+
import module.common.pylgettext as gettext
import os
-from os import makedirs
-from os.path import abspath, dirname, exists, join
-from subprocess import PIPE, call
import sys
+import socket
+import webbrowser
+
+from getpass import getpass
+from time import time
from sys import exit
+
+from module.utils.fs import abspath, dirname, exists, join, makedirs
from module.utils import get_console_encoding
-from module.setup.System_Checks import System_Checks
-from module.setup.Questions import Questions, Ask
+from module.web.ServerThread import WebServer
+
+
class Setup():
"""
- pyLoads initial setup configuration assistent
+ pyLoads initial setup configuration assistant
"""
def __init__(self, path, config):
self.path = path
self.config = config
self.stdin_encoding = get_console_encoding(sys.stdin.encoding)
+ self.lang = None
+ # We will create a timestamp so that the setup will be completed in a specific interval
+ self.timestamp = time()
+
+ # TODO: probably unneeded
self.yes = "yes"
self.no = "no"
- self.lang = None
- self.page = 0
-
-
+
+
def start(self):
+ web = WebServer(pysetup=self)
+ web.start()
+
+ error = web.check_error()
+ if error: #todo errno 44 port already in use
+ print error
+
+ url = "http://%s:%d/" % (socket.gethostbyname(socket.gethostname()), web.port)
+
+ print "Setup is started"
+
+ opened = webbrowser.open_new_tab(url)
+ if not opened:
+ print "Please point your browser to %s" % url
+
+
self.ask_lang()
- checker = System_Checks()
- result_s, result_b = checker.check_basic()
- if not result_b:
- print result_s
-
+
print ""
print _("Would you like to configure pyLoad via Webinterface?")
print _("You need a Browser and a connection to this PC for it.")
print _("Url would be: http://hostname:8000/")
- viaweb = self.ask_cli(_("Start initial webinterface for configuration?"), self.yes, bool=True)
+ viaweb = self.ask(_("Start initial webinterface for configuration?"), self.yes, bool=True)
if viaweb:
self.start_web()
else:
self.start_cli()
- def ask_lang(self):
- if self.lang == None:
- langs = self.config.getMetaData("general", "language").type.split(";")
- self.lang = self.ask_cli(u"Choose your Language / Wähle deine Sprache", "en", langs)
- gettext.setpaths([join(os.sep, "usr", "share", "pyload", "locale"), None])
- translation = gettext.translation("setup", join(self.path, "locale"), languages=[self.lang, "en"], fallback=True)
- translation.install(True)
-
- #l10n Input shorthand for yes
- self.yes = _("y")
- #l10n Input shorthand for no
- self.no = _("n")
-
- def get_page_next(self):
- self.__print_start()
- if self.page == 0:
- # system check
- self.basic, self.ssl, self.captcha, self.web, self.js = self.system_check()
- if not basic:
- self.__print( _("You need pycurl, sqlite and python 2.5, 2.6 or 2.7 to run pyLoad."))
- self.__print( _("Please correct this and re-run pyLoad."))
- self.__print( _("Setup will now close."))
- self.__print_end()
- return False
- self.__print("")
- self.__print(_("## Status ##"))
- self.__print("")
-
- avail = []
- if self.check_module("Crypto"): avail.append(_("container decrypting"))
- if ssl: avail.append(_("ssl connection"))
- if captcha: avail.append(_("automatic captcha decryption"))
- if web: avail.append(_("Webinterface"))
- if js: avail.append(_("extended Click'N'Load"))
-
- string = ""
- for av in avail:
- string += ", " + av
- # List available Features
- self.__print(_("Features available:") + string[1:])
- self.__print("")
-
- return self.printer
-
- def __print(self, text):
- if self.web == True:
- self.printer += "<br />" + text
- else:
- print text
-
- def __print_start(self):
- if self.web == True:
- self.printer = ""
- else:
- print ""
-
- def __print_end(self):
- if self.web == True:
- self.printer = ""
- else:
- raw_input()
-
- def ask(self, qst, default, answers=[], bool=False, password=False):
- if self.web == True:
- self.ask_web(qst, default, answers, bool, password)
- else:
- self.ask_cli(qst, default, answers, bool, password)
-
def start_cli(self):
- for ask in Questions.questions:
- if ask.webonly: continue
- for line in ask.sqt:
- print line
- if default == None:
- raw_input()
-
print _("Welcome to the pyLoad Configuration Assistent.")
print _("It will check your system and make a basic setup in order to run pyLoad.")
print ""
@@ -155,10 +99,6 @@ class Setup():
#self.get_page_next()
-
-
-
-
if len(avail) < 5:
print _("Features missing: ")
print
@@ -226,8 +166,8 @@ class Setup():
print _("Hit enter to exit and restart pyLoad")
raw_input()
return True
-
-
+
+
def start_web(self):
print ""
print _("Webinterface running for setup.")
@@ -245,7 +185,6 @@ class Setup():
self.start_cli()
-
def conf_basic(self):
print ""
print _("## Basic Setup ##")
@@ -294,7 +233,6 @@ class Setup():
self.config["webinterface"]["port"] = self.ask(_("Port"), "8000")
print ""
print _("pyLoad offers several server backends, now following a short explanation.")
- print "builtin:", _("laggy, but useful if RAM ")
print "threaded:", _("Default server, this server offers SSL and is a good alternative to builtin.")
print "fastcgi:", _(
"Can be used by apache, lighttpd, requires you to configure them, which is not too easy job.")
@@ -398,11 +336,21 @@ class Setup():
print _("Setting config path failed: %s") % str(e)
+ def ask_lang(self):
+ langs = self.config.getMetaData("general", "language").type.split(";")
+ self.lang = self.ask(u"Choose your Language / Wähle deine Sprache", "en", langs)
+ gettext.setpaths([join(os.sep, "usr", "share", "pyload", "locale"), None])
+ translation = gettext.translation("setup", join(self.path, "locale"), languages=[self.lang, "en"], fallback=True)
+ translation.install(True)
+ #l10n Input shorthand for yes
+ self.yes = _("y")
+ #l10n Input shorthand for no
+ self.no = _("n")
+ def ask(self, qst, default, answers=[], bool=False, password=False):
+ """ Generate dialog on command line """
-
- def ask_cli(self, qst, default, answers=[], bool=False, password=False):
if answers:
info = "("
for i, answer in enumerate(answers):
@@ -436,14 +384,9 @@ class Setup():
return p1
else:
print _("Passwords did not match.")
-
- while True:
- try:
- input = raw_input(qst + " %s: " % info)
- except KeyboardInterrupt:
- print "\nSetup interrupted"
- exit()
+ while True:
+ input = raw_input(qst + " %s: " % info)
input = input.decode(self.stdin_encoding)
if input.strip() == "":
diff --git a/module/UserManager.py b/module/UserManager.py
deleted file mode 100644
index 9d5e8c5db..000000000
--- a/module/UserManager.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: RaNaN
-"""
-
-class UserManager:
- """
- Manager class to handle all user related stuff
- """ \ No newline at end of file
diff --git a/module/network/HTTPDownload.py b/module/network/HTTPDownload.py
index 5a4436529..498cd5979 100644
--- a/module/network/HTTPDownload.py
+++ b/module/network/HTTPDownload.py
@@ -205,6 +205,7 @@ class HTTPDownload():
t = time()
# reduce these calls
+ # when num_q is 0, the loop is exited
while lastFinishCheck + 0.5 < t:
# list of failed curl handles
failed = []
@@ -240,10 +241,10 @@ class HTTPDownload():
ex = e
else:
chunksDone.add(curl)
- if not num_q: # no more infos to get
+ if not num_q: # no more info to get
# check if init is not finished so we reset download connections
- # note that other chunks are closed and downloaded with init too
+ # note that other chunks are closed and everything downloaded with initial connection
if failed and init not in failed and init.c not in chunksDone:
self.log.error(_("Download chunks failed, fallback to single connection | %s" % (str(ex))))
@@ -288,7 +289,6 @@ class HTTPDownload():
if self.abort:
raise Abort()
- #sleep(0.003) #suppress busy waiting - limits dl speed to (1 / x) * buffersize
self.m.select(1)
for chunk in self.chunks:
diff --git a/module/setup/Questions.py b/module/setup/Questions.py
deleted file mode 100644
index 08bff8deb..000000000
--- a/module/setup/Questions.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: RaNaN
-"""
-from getpass import getpass
-import module.common.pylgettext as gettext
-import os
-from os import makedirs
-from os.path import abspath, dirname, exists, join
-from subprocess import PIPE, call
-import sys
-from sys import exit
-from module.utils import get_console_encoding
-
-class Questions():
-
- questions = [
- Ask(["Welcome to the pyLoad Configuration Assistent.",
- "It will check your system and make a basic setup in order to run pyLoad.",
- "If you don't know which value to choose, take the deafault one.",
- "Don't forget: You can always rerun this assistent with --setup or -s parameter, when you start pyLoadCore."]),
- Ask(["The value in brackets [] always is the default value",
- "When you are ready, hit Enter"], clionly=True)
-
- ]
-
-
-class Ask():
- def __init__(self, qst, default = None, answers=[], bool=False, password=False, webonly=False, clionly=False):
- self.qst = qst
- self.default = default
- self.answers = answers
- self.bool = bool
- self. password = password
-
-
diff --git a/module/setup/__init__.py b/module/setup/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/module/setup/__init__.py
+++ /dev/null
diff --git a/module/utils/fs.py b/module/utils/fs.py
index 1894bc49a..92cc605e7 100644
--- a/module/utils/fs.py
+++ b/module/utils/fs.py
@@ -26,6 +26,12 @@ def chmod(path, mode):
except :
pass
+def dirname(path):
+ return fs_decode(os.path.dirname(fs_encode(path)))
+
+def abspath(path):
+ return fs_decode(os.path.abspath(fs_encode(path)))
+
def chown(path, uid, gid):
return os.chown(fs_encode(path), uid, gid)
@@ -40,7 +46,7 @@ def makedirs(path, mode=0755):
# fs_decode?
def listdir(path):
- return os.listdir(fs_encode(path))
+ return [fs_decode(x) for x in os.listdir(fs_encode(path))]
def save_filename(name):
#remove some chars
diff --git a/module/web/ServerThread.py b/module/web/ServerThread.py
index bf5ba8373..b4854e1f4 100644
--- a/module/web/ServerThread.py
+++ b/module/web/ServerThread.py
@@ -1,32 +1,43 @@
#!/usr/bin/env python
from __future__ import with_statement
-from os.path import exists
+from time import time, sleep
-import os
import threading
import logging
+from module.utils.fs import exists
+
core = None
setup = None
log = logging.getLogger("log")
class WebServer(threading.Thread):
- def __init__(self, pycore):
- global core
+ def __init__(self, pycore=None, pysetup=None):
+ global core, setup
threading.Thread.__init__(self)
- self.core = pycore
- core = pycore
- self.running = True
- self.server = pycore.config['webinterface']['server']
- self.https = pycore.config['webinterface']['https']
- self.cert = pycore.config["ssl"]["cert"]
- self.key = pycore.config["ssl"]["key"]
- self.host = pycore.config['webinterface']['host']
- self.port = pycore.config['webinterface']['port']
+
+ if pycore:
+ core = pycore
+ config = pycore.config
+ elif pysetup:
+ setup = pysetup
+ config = pysetup.config
+ else:
+ raise Exception("No config context provided")
+
+ self.server = config['webinterface']['server']
+ self.https = config['webinterface']['https']
+ self.cert = config["ssl"]["cert"]
+ self.key = config["ssl"]["key"]
+ self.host = config['webinterface']['host']
+ self.port = config['webinterface']['port']
+ self.error = None
self.setDaemon(True)
def run(self):
+ self.running = True
+
import webinterface
global webinterface
@@ -56,42 +67,47 @@ class WebServer(threading.Thread):
if self.server == "builtin":
self.server = "threaded"
- if self.server == "fastcgi":
- self.start_fcgi()
- elif self.server == "threaded":
- self.start_threaded()
- elif self.server == "lightweight":
- self.start_lightweight()
- else:
- self.start_fallback()
+ try:
+ if self.server == "fastcgi":
+ self.start_fcgi()
+ elif self.server == "threaded":
+ self.start_threaded()
+ elif self.server == "lightweight":
+ self.start_lightweight()
+ else:
+ self.start_fallback()
+ except Exception, e:
+ log.error(_("Failed starting webserver: " + e.message))
+ self.error = e
+ if core:
+ core.print_exc()
def start_fallback(self):
-
if self.https:
log.warning(_("This server offers no SSL, please consider using threaded instead"))
- self.core.log.info(_("Starting builtin webserver: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
+ log.info(_("Starting builtin webserver: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
webinterface.run_simple(host=self.host, port=self.port)
def start_threaded(self):
if self.https:
- self.core.log.info(_("Starting threaded SSL webserver: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
+ log.info(_("Starting threaded SSL webserver: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
else:
self.cert = ""
self.key = ""
- self.core.log.info(_("Starting threaded webserver: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
+ log.info(_("Starting threaded webserver: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
webinterface.run_threaded(host=self.host, port=self.port, cert=self.cert, key=self.key)
def start_fcgi(self):
-
from flup.server.threadedserver import ThreadedServer
+
def noop(*args, **kwargs):
pass
ThreadedServer._installSignalHandlers = noop
- self.core.log.info(_("Starting fastcgi server: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
+ log.info(_("Starting fastcgi server: %(host)s:%(port)d") % {"host": self.host, "port": self.port})
webinterface.run_fcgi(host=self.host, port=self.port)
@@ -99,8 +115,16 @@ class WebServer(threading.Thread):
if self.https:
log.warning(_("This server offers no SSL, please consider using threaded instead"))
- self.core.log.info(_("Starting lightweight webserver (bjoern): %(host)s:%(port)d") % {"host": self.host, "port": self.port})
+ log.info(
+ _("Starting lightweight webserver (bjoern): %(host)s:%(port)d") % {"host": self.host, "port": self.port})
webinterface.run_lightweight(host=self.host, port=self.port)
- def quit(self):
- self.running = False
+
+ # check if an error was raised for n seconds
+ def check_error(self, n=1):
+ t = time() + n
+ while time() < t:
+ if self.error:
+ return self.error
+ sleep(0.1)
+
diff --git a/module/web/setup_app.py b/module/web/setup_app.py
index 055cb2a81..68da474bb 100644
--- a/module/web/setup_app.py
+++ b/module/web/setup_app.py
@@ -1,13 +1,24 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-from bottle import route, request, response, HTTPError
+from bottle import route, request, response, HTTPError, redirect
from webinterface import PROJECT_DIR, SETUP, env
from utils import render_to_response
+def setup_required(func):
+ def _view(*args, **kwargs):
+
+ # setup needs to be running
+ if SETUP is None:
+ redirect("/nopermission")
+
+ return func(*args, **kwargs)
+ return _view
+
@route("/setup")
+@setup_required
def setup():
return render_to_response('setup.html')
diff --git a/module/web/utils.py b/module/web/utils.py
index ba6a6a59e..236a9244e 100644
--- a/module/web/utils.py
+++ b/module/web/utils.py
@@ -19,7 +19,7 @@
import re
from bottle import request, HTTPError, redirect, ServerAdapter
-from webinterface import env, TEMPLATE, PYLOAD
+from webinterface import env, TEMPLATE, PYLOAD, SETUP
# TODO: useful but needs a rewrite, too
def render_to_response(name, args={}, proc=[]):
@@ -75,6 +75,11 @@ def is_mobile():
def login_required(perm=None):
def _dec(func):
def _view(*args, **kwargs):
+
+ # In case of setup, no login methods can be accessed
+ if SETUP is not None:
+ redirect("/setup")
+
s = request.environ.get('beaker.session')
api = get_user_api(s)
if api is not None:
diff --git a/pyLoadCore.py b/pyLoadCore.py
index f005d9208..21d6603e5 100755
--- a/pyLoadCore.py
+++ b/pyLoadCore.py
@@ -117,24 +117,21 @@ class Core(object):
elif option in ("-d", "--debug"):
self.doDebug = True
elif option in ("-u", "--user"):
- from module.setup.Setup import Setup
+ from module.Setup import Setup
self.config = ConfigParser()
s = Setup(pypath, self.config)
s.set_user()
exit()
elif option in ("-s", "--setup"):
- from module.setup.Setup import Setup
+ from module.Setup import Setup
self.config = ConfigParser()
s = Setup(pypath, self.config)
- if argument == "web":
- s.start_web()
- else:
- s.start()
+ s.start()
exit()
elif option == "--changedir":
- from module.setup.Setup import Setup
+ from module.Setup import Setup
self.config = ConfigParser()
s = Setup(pypath, self.config)