Browse Source

Premier commit

fanch 1 year ago
parent
commit
40bc22a427

+ 236 - 0
src/djangotools/cmdline/commands/backup/__init__.py

@@ -0,0 +1,236 @@
+import datetime
+import json
+import re
+import shutil
+import tempfile
+import time
+from zipfile import ZipFile
+from pathlib import Path
+
+from djangotools.cmdline.common.command import Command, Argument
+from djangotools.common.date import CurrentDate
+from djangotools.config import app_dir
+
+from djangotools.config import get_settings
+JOURS = ["Lundi", "Mardi", "Mercredi",  "Jeudi", "Vendredi", "Samedi", "Dimanche"]
+MOIS = ["", "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre"]
+
+def period_to_str(period, date):
+    if period == "daliy":
+        return f"journalière du {date}"
+    if period == "weekly":
+        return f"hebdomadaire de la semaine {date}"
+    if period == "monthly":
+        return f"mensuelle du mois de {date}"
+
+
+
+class BackupFile:
+
+    def __init__(self, dir, quiet):
+        self.quiet = quiet
+        self.file = Path(dir) / "backup.json"
+        self.log_file = Path(dir) / "backup.log"
+        self.log_messages = []
+        if self.file.is_file():
+            self.content = json.loads(self.file.read_text())
+        else:
+            self.content = {
+                "daily" : {
+                    "last" : None,
+                    "file" : None,
+                    "date" : None
+                },
+                "weekly" : {
+                    "last" : None,
+                    "file" : None,
+                    "date" : None
+                },
+                "monthly" : {
+                    "last" : None,
+                    "file" : None,
+                    "date" : None
+                }
+            }
+
+    @staticmethod
+    def get_wwek_number(now=None):
+        now = now or CurrentDate.now()
+        first_day = datetime.datetime(now.year, 1, 1)
+        nb = (now-first_day).days + first_day.weekday()
+        return nb // 7
+
+
+    @classmethod
+    def get_date(cls, period, now = None):
+        now = now or CurrentDate.now()
+        date = None
+        if period == "daily":
+            date =  JOURS[now.weekday()]
+        elif period == "weekly":
+            date = cls.get_wwek_number()
+        elif period == "monthly":
+            date = MOIS[now.month]
+        return date
+
+    def get_todo(self):
+        periods = ["daily", "weekly", "monthly"]
+        ret = []
+        for period in periods:
+            if self.content[period]["date"] != self.get_date(period):
+                ret.append(period)
+        return ret
+
+    def _log(self, type, *args):
+        line = None
+        if type=="backup":
+            line = f"{args[0]} : Sauvegarde {period_to_str(args[1], args[3])} dans {args[2]}"
+        elif type == "message":
+            line = f"{args[0]} : {args[1]}"
+        else:
+            raise ValueError(f"Erreur le type de message '{type}' est inconnu")
+        self.log_messages.append(line)
+        if not self.quiet: print(line)
+
+    def log(self, message):
+        now = CurrentDate.now()
+        t = now.strftime("%d/%m/%Y %H:%M:%S")
+        self._log("message", t, message)
+
+    def do_backup(self, period, file):
+        if period not in self.content:
+            raise ValueError(f"La période de backup '{period}' est inconnu")
+        now = CurrentDate.now()
+        t = now.strftime("%d/%m/%Y %H:%M:%S")
+        date = self.get_date(period)
+        self._log("backup", t, period, file, date)
+
+        self.content[period] = {
+            "last" : t,
+            "file" : str(file),
+            "date" : date
+        }
+
+    def save(self):
+        log = "\n".join(self.log_messages)+"\n"
+        with open(self.log_file, "a") as fd:
+            fd.write(log)
+        self.file.write_text(json.dumps(self.content, indent=2))
+
+class BackupCommand(Command):
+    NAME = "backup"
+    ALIASES = ["ba"]
+    PREFIX = "backup"
+    HELP = "Execute une sauvegarde"
+
+    ARGUMENT = [
+        Argument("--daily", "-d", action = "store_true", help="Execute le backup journalier"),
+        Argument("--weekly", "-w", action = "store_true",  help="Execute le backup hebdomadaire"),
+        Argument("--monthly", "-m", action = "store_true",  help="Execute le backup mensuel"),
+        Argument("--quiet", "-q", action = "store_true", help="Mode silencieux"),
+        Argument("--prefix", "-p", help="Prefix des fichier zip de backup"),
+
+    ]
+
+    def __init__(self):
+        super().__init__()
+        self.settings = get_settings()
+        self.backup_dir = self.settings.CONFIG.backup_dir
+        self._lock_file = self.backup_dir / "lock"
+        self.backup_dir_daily = self.backup_dir / "daliy"
+        self.backup_dir_weekly = self.backup_dir / "weekly"
+        self.backup_dir_monthly = self.backup_dir / "monthly"
+
+        for dir in [self.backup_dir_daily, self.backup_dir_weekly, self.backup_dir_monthly, self._lock_file.parent]:
+            dir.mkdir(exist_ok=True, parents=True)
+
+
+    def get_name(self):
+        now = CurrentDate.now()
+        return f"{self.PREFIX}-{str(now.year).zfill(4)}_{str(now.month).zfill(2)}_{str(now.day).zfill(2)}.zip"
+
+    def get_date(self, file):
+        file = Path(file)
+        for x in re.findall(r"\d{4}_\d{2}_\d{2}.zip$", file.name):
+            x = [int(n) for n in x.replace(".zip", "").split("_")]
+            return datetime.datetime(*x)
+        return None
+
+    def gen_backup(self, output):
+        root = self.settings.DATA_DIR
+        queue = [root]
+        with ZipFile(output, "w") as zip:
+            while queue:
+                curr = queue.pop(0)
+                for file in curr.iterdir():
+                    if file.is_dir():
+                        if file == self.backup_dir: continue
+                        queue.append(file)
+                    else:
+                        zip.write(file, file.relative_to(root.parent))
+
+    def lock(self):
+        while self._lock_file.is_file():
+            time.sleep(1)
+        self._lock_file.touch()
+
+    def unlock(self):
+        if self._lock_file.is_file():
+            self._lock_file.unlink()
+
+    def __enter__(self):
+        self.lock()
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.unlock()
+
+    def clean(self):
+        now = CurrentDate.now()
+        for file in list(self.backup_dir_daily.iterdir()):
+            date = self.get_date(file)
+            if not date: continue
+            if date + datetime.timedelta(days=8) < now:
+                file.unlink()
+
+        for file in list(self.backup_dir_weekly.iterdir()):
+            date = self.get_date(file)
+            if not date: continue
+            if date + datetime.timedelta(days=32) < now:
+                file.unlink()
+
+        for file in list(self.backup_dir_monthly.iterdir()):
+            date = self.get_date(file)
+            if not date: continue
+            if date + datetime.timedelta(days=366) < now:
+                file.unlink()
+
+    def run(self, data):
+        with tempfile.TemporaryDirectory() as temp:
+            temp = Path(temp) / "data.zip"
+            self.clean()
+            back = BackupFile(self.backup_dir, data.quiet)
+
+            with self:
+                self.gen_backup(temp)
+                if not any(getattr(data, x) for x in ("daily", "weekly", "monthly") ):
+                    todo = set(back.get_todo())
+                    data.daily = data.daily or (todo & {"daily"})
+                    data.weekly = data.weekly or (todo & {"weekly"})
+                    data.monthly = data.monthly or (todo & {"monthly"})
+
+                name = self.get_name()
+
+                if data.daily:
+                    back.do_backup("daily", self.backup_dir_daily / name)
+                    shutil.copy(temp, self.backup_dir_daily / name)
+                if data.weekly:
+                    back.do_backup("weekly", self.backup_dir_weekly / name)
+                    shutil.copy(temp, self.backup_dir_weekly / name)
+                if data.monthly:
+                    back.do_backup("monthly", self.backup_dir_monthly / name)
+                    shutil.copy(temp, self.backup_dir_monthly / name)
+
+                back.save()
+
+
+

+ 0 - 227
src/djangotools/cmdline/commands/backup/base.py

@@ -1,227 +0,0 @@
-import datetime
-import json
-import re
-import shutil
-import tempfile
-import time
-from zipfile import ZipFile
-from pathlib import Path
-
-from djangotools.cmdline.common.command import Command
-from djangotools.common.date import CurrentDate
-from djangotools.config import app_dir
-
-JOURS = ["Lundi", "Mardi", "Mercredi",  "Jeudi", "Vendredi", "Samedi", "Dimanche"]
-MOIS = ["", "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre"]
-
-def period_to_str(period, date):
-    if period == "daliy":
-        return f"journalière du {date}"
-    if period == "weekly":
-        return f"hebdomadaire de la semaine {date}"
-    if period == "monthly":
-        return f"mensuelle du mois de {date}"
-
-
-
-class BackupFile:
-
-    def __init__(self, dir, quiet):
-        self.quiet = quiet
-        self.file = Path(dir) / "backup.json"
-        self.log_file = Path(dir) / "backup.log"
-        self.log_messages = []
-        if self.file.is_file():
-            self.content = json.loads(self.file.read_text())
-        else:
-            self.content = {
-                "daily" : {
-                    "last" : None,
-                    "file" : None,
-                    "date" : None
-                },
-                "weekly" : {
-                    "last" : None,
-                    "file" : None,
-                    "date" : None
-                },
-                "monthly" : {
-                    "last" : None,
-                    "file" : None,
-                    "date" : None
-                }
-            }
-
-    @staticmethod
-    def get_wwek_number(now=None):
-        now = now or CurrentDate.now()
-        first_day = datetime.datetime(now.year, 1, 1)
-        nb = (now-first_day).days + first_day.weekday()
-        return nb // 7
-
-
-    @classmethod
-    def get_date(cls, period, now = None):
-        now = now or CurrentDate.now()
-        date = None
-        if period == "daily":
-            date =  JOURS[now.weekday()]
-        elif period == "weekly":
-            date = cls.get_wwek_number()
-        elif period == "monthly":
-            date = MOIS[now.month]
-        return date
-
-    def get_todo(self):
-        periods = ["daily", "weekly", "monthly"]
-        ret = []
-        for period in periods:
-            if self.content[period]["date"] != self.get_date(period):
-                ret.append(period)
-        return ret
-
-    def _log(self, type, *args):
-        line = None
-        if type=="backup":
-            line = f"{args[0]} : Sauvegarde {period_to_str(args[1], args[3])} dans {args[2]}"
-        elif type == "message":
-            line = f"{args[0]} : {args[1]}"
-        else:
-            raise ValueError(f"Erreur le type de message '{type}' est inconnu")
-        self.log_messages.append(line)
-        if not self.quiet: print(line)
-
-    def log(self, message):
-        now = CurrentDate.now()
-        t = now.strftime("%d/%m/%Y %H:%M:%S")
-        self._log("message", t, message)
-
-    def do_backup(self, period, file):
-        if period not in self.content:
-            raise ValueError(f"La période de backup '{period}' est inconnu")
-        now = CurrentDate.now()
-        t = now.strftime("%d/%m/%Y %H:%M:%S")
-        date = self.get_date(period)
-        self._log("backup", t, period, file, date)
-
-        self.content[period] = {
-            "last" : t,
-            "file" : str(file),
-            "date" : date
-        }
-
-    def save(self):
-        log = "\n".join(self.log_messages)+"\n"
-        with open(self.log_file, "a") as fd:
-            fd.write(log)
-        self.file.write_text(json.dumps(self.content, indent=2))
-
-class BackupCommand(Command):
-
-
-    def __init__(self):
-        super().__init__()
-        self.settings = app_dir
-        self.backup_dir = self.settings
-        self._lock_file = self.backup_dir / "lock"
-        self.backup_dir_daily = self.backup_dir / "daliy"
-        self.backup_dir_weekly = self.backup_dir / "weekly"
-        self.backup_dir_monthly = self.backup_dir / "monthly"
-
-        for dir in [self.backup_dir_daily, self.backup_dir_weekly, self.backup_dir_monthly, self._lock_file.parent]:
-            dir.mkdir(exist_ok=True, parents=True)
-
-
-    def get_name(self):
-        now = CurrentDate.now()
-        return f"{self.PREFIX}-{str(now.year).zfill(4)}_{str(now.month).zfill(2)}_{str(now.day).zfill(2)}.zip"
-
-    def get_date(self, file):
-        file = Path(file)
-        for x in re.findall(r"\d{4}_\d{2}_\d{2}.zip$", file.name):
-            x = [int(n) for n in x.replace(".zip", "").split("_")]
-            return datetime.datetime(*x)
-        return None
-
-
-
-    def gen_backup(self, output):
-        root = self.settings.DATA_DIR
-        queue = [root]
-        with ZipFile(output, "w") as zip:
-            while queue:
-                curr = queue.pop(0)
-                for file in curr.iterdir():
-                    if file.is_dir():
-                        if file == self.backup_dir: continue
-                        queue.append(file)
-                    else:
-                        zip.write(file, file.relative_to(root.parent))
-
-    def lock(self):
-        while self._lock_file.is_file():
-            time.sleep(1)
-        self._lock_file.touch()
-
-    def unlock(self):
-        if self._lock_file.is_file():
-            self._lock_file.unlink()
-
-
-    def __enter__(self):
-        self.lock()
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        self.unlock()
-
-    def clean(self):
-        now = CurrentDate.now()
-        for file in list(self.backup_dir_daily.iterdir()):
-            date = self.get_date(file)
-            if not date: continue
-            if date + datetime.timedelta(days=8) < now:
-                file.unlink()
-
-        for file in list(self.backup_dir_weekly.iterdir()):
-            date = self.get_date(file)
-            if not date: continue
-            if date + datetime.timedelta(days=32) < now:
-                file.unlink()
-
-        for file in list(self.backup_dir_monthly.iterdir()):
-            date = self.get_date(file)
-            if not date: continue
-            if date + datetime.timedelta(days=366) < now:
-                file.unlink()
-
-    def run(self, data):
-        with tempfile.TemporaryDirectory() as temp:
-            temp = Path(temp) / "data.zip"
-            self.clean()
-            back = BackupFile(self.backup_dir, data.quiet)
-
-            with self:
-                self.gen_backup(temp)
-                if not any(getattr(data, x) for x in ("daily", "weekly", "monthly") ):
-                    todo = set(back.get_todo())
-                    data.daily = data.daily or (todo & {"daily"})
-                    data.weekly = data.weekly or (todo & {"weekly"})
-                    data.monthly = data.monthly or (todo & {"monthly"})
-
-                name = self.get_name()
-
-                if data.daily:
-                    back.do_backup("daily", self.backup_dir_daily / name)
-                    shutil.copy(temp, self.backup_dir_daily / name)
-                if data.weekly:
-                    back.do_backup("weekly", self.backup_dir_weekly / name)
-                    shutil.copy(temp, self.backup_dir_weekly / name)
-                if data.monthly:
-                    back.do_backup("monthly", self.backup_dir_monthly / name)
-                    shutil.copy(temp, self.backup_dir_monthly / name)
-
-
-                back.save()
-
-
-

+ 37 - 0
src/djangotools/cmdline/commands/cron/__init__.py

@@ -0,0 +1,37 @@
+from collections import defaultdict
+
+from djangotools.cmdline import Command, CronManager, Argument, CommandData
+
+from djangotools.cmdline import tasks
+from djangotools.config import get_settings
+
+
+class CronCommand(Command):
+    NAME = "cron"
+    ALIASES = ["cr"]
+
+    HELP = "Lance le serive de cron"
+    ARGUMENT = [
+        Argument("options", nargs="*", help="Liste des options à passer au cron au format {CRON_NAME}.{Parameter}={Value}")
+    ]
+    def __init__(self):
+        super().__init__()
+        self.settings = get_settings()
+        self.manager = CronManager(resolution=10)
+
+
+
+        for cron in getattr(self.settings, "CRON", None) or []:
+            self.manager.add_task(cron)
+
+    def run(self, data):
+        if not isinstance(data, dict):
+            opt = defaultdict(CommandData)
+            for x in data.options:
+                left, _, value =  x.partition("=")
+                cron_name, name = left.split(".")
+                setattr(opt[cron_name], name, value)
+        else:
+            opt = data
+
+        self.manager.schedule(opt)

+ 53 - 0
src/djangotools/cmdline/commands/run/__init__.py

@@ -0,0 +1,53 @@
+import os
+import subprocess
+import time
+from pathlib import Path
+
+
+from djangotools.cmdline import Command, Argument, CommandData
+
+from djangotools.cmdline.commands.cron import CronCommand
+from djangotools.config import get_settings
+from djangotools.run import Server
+
+
+class RunCommand(Command):
+
+    NAME = "run"
+    HELP = "Lance le serveur avec la config de production"
+
+    ARGUMENT = [
+        Argument("-p", "--pid-file", help="Chemin du ficher PID" ),
+        Argument("-o", "--stdout", nargs=1, help="Crée le server dans un autre processus"),
+        Argument("-e", "--stderr", nargs=1, help="Crée le server dans un autre processus"),
+        Argument("-b", "--bind",  help="Adresse d'écoute du serveur exemple localhost:8080"),
+        Argument("-C", "--no-cron", action="store_true", help="Ne pas lancer le cron"),
+    ]
+
+    def start_cron(self, hostname):
+        self.cron = CronCommand.thread_run(CommandData(url=f"http://{hostname}"))
+
+
+    def wait_cron_ends(self):
+        self.cron.join()
+
+    def run(self, data):
+        settings = get_settings()
+        if data.bind:
+            host_name = data.bind
+        else:
+            host_name = settings.HOSTNAME
+
+        if not data.no_cron:
+            self.start_cron(host_name)
+
+        pid_file = Path(data.pid_file or settings.CONFIG.pid_file)
+        if not pid_file.parent.is_dir():
+            pid_file.parent.mkdir(exist_ok=True, parents=True)
+        pid_file.write_text(str(os.getpid()))
+
+        server = Server()
+        server.handle(addrport=host_name)
+
+        if not data.no_cron:
+            self.wait_cron_ends()

+ 1 - 2
src/djangotools/cmdline/common/args.py

@@ -4,7 +4,7 @@ import sys
 
 
 from djangotools.cmdline.common.command import Command
 from djangotools.cmdline.common.command import Command
 from djangotools.config import load_app
 from djangotools.config import load_app
-
+from django.conf import settings
 
 
 class ArgsParser(argparse.ArgumentParser):
 class ArgsParser(argparse.ArgumentParser):
 
 
@@ -16,7 +16,6 @@ class ArgsParser(argparse.ArgumentParser):
         parser = self.add_subparsers(parser_class=argparse.ArgumentParser)
         parser = self.add_subparsers(parser_class=argparse.ArgumentParser)
         self.add_argument("-a", "--app-dir",  help="Dossier de données du serveur")
         self.add_argument("-a", "--app-dir",  help="Dossier de données du serveur")
         self.add_argument("-s", "--settings",  help="Module de settings à utiliser")
         self.add_argument("-s", "--settings",  help="Module de settings à utiliser")
-
         for cmd in Command.load(commands_dirs):
         for cmd in Command.load(commands_dirs):
             kwargs = {}
             kwargs = {}
             if cmd.HELP: kwargs["help"] = cmd.HELP
             if cmd.HELP: kwargs["help"] = cmd.HELP

+ 14 - 7
src/djangotools/cmdline/common/command.py

@@ -1,6 +1,8 @@
 import threading
 import threading
 from pathlib import Path
 from pathlib import Path
 
 
+from django.core.exceptions import ImproperlyConfigured
+
 
 
 class CommandData:
 class CommandData:
 
 
@@ -43,13 +45,14 @@ class Command:
     @classmethod
     @classmethod
     def thread_run(cls, data):
     def thread_run(cls, data):
         cmd = cls()
         cmd = cls()
-        thread = ThreadWrapper(lambda x=data: cmd.run(x))
+        dd = {cmd.NAME: data}
+        thread = ThreadWrapper(lambda x=dd: cmd.run(x))
         thread.start()
         thread.start()
         return thread
         return thread
 
 
     @staticmethod
     @staticmethod
     def _load(root_module):
     def _load(root_module):
-        ret = set()
+        ret = {}
         root = Path(root_module.__file__).parent
         root = Path(root_module.__file__).parent
         queue = [root]
         queue = [root]
         root_module_str = root_module.__name__
         root_module_str = root_module.__name__
@@ -67,22 +70,26 @@ class Command:
                     module = __import__(module_name, fromlist=['object'])
                     module = __import__(module_name, fromlist=['object'])
                     for x in dir(module):
                     for x in dir(module):
                         data = getattr(module, x)
                         data = getattr(module, x)
-                        if isinstance(data, type) and issubclass(data, Command) and data != Command and data.NAME is not None:
-                            ret.add(data)
+                        try:
+                            if (isinstance(data, type) and issubclass(data, Command)
+                                    and data != Command and data.NAME is not None):
+                                ret[data.NAME]=data
+                        except ImproperlyConfigured:
+                            pass
         return ret
         return ret
 
 
     @staticmethod
     @staticmethod
     def load(commands_dirs=None):
     def load(commands_dirs=None):
         if isinstance(commands_dirs, str): commands_dirs = [commands_dirs]
         if isinstance(commands_dirs, str): commands_dirs = [commands_dirs]
         from djangotools.cmdline import commands
         from djangotools.cmdline import commands
-        ret = set()
+        ret = {}
         commands_dirs = [commands]+list(commands_dirs or [])
         commands_dirs = [commands]+list(commands_dirs or [])
         for commands_dir in commands_dirs:
         for commands_dir in commands_dirs:
             if isinstance(commands_dir, str):
             if isinstance(commands_dir, str):
                 commands_dir = __import__(commands_dir, fromlist=['object'])
                 commands_dir = __import__(commands_dir, fromlist=['object'])
-            ret |= Command._load(commands_dir)
+            ret.update(Command._load(commands_dir))
 
 
-        return ret
+        return set(ret.values())
 
 
 
 
 
 

+ 3 - 2
src/djangotools/cmdline/common/cron.py

@@ -81,7 +81,7 @@ class Task:
             if timer.poll():
             if timer.poll():
                 print(f"Execute task: {self.NAME}")
                 print(f"Execute task: {self.NAME}")
                 try:
                 try:
-                    self.run(data)
+                    self.run(data.get(self.NAME))
                 except Exception as err:
                 except Exception as err:
                     print(f"Erreur dans l'execution de la tache {self.NAME}", file=sys.stderr)
                     print(f"Erreur dans l'execution de la tache {self.NAME}", file=sys.stderr)
                     traceback.print_exc()
                     traceback.print_exc()
@@ -116,7 +116,6 @@ class CronManager:
             task = task_classe(*args, **kwargs)
             task = task_classe(*args, **kwargs)
 
 
             for type, *args in timers:
             for type, *args in timers:
-                timer_classe = None
                 if type == "daily":
                 if type == "daily":
                     timer_classe = CronTimerDaily
                     timer_classe = CronTimerDaily
                 else:
                 else:
@@ -132,10 +131,12 @@ class CronManager:
                 next = min(next, task.poll(data))
                 next = min(next, task.poll(data))
 
 
             sleep = next - time.time()
             sleep = next - time.time()
+            print("time to sleep", sleep)
             time.sleep(sleep)
             time.sleep(sleep)
 
 
     @staticmethod
     @staticmethod
     def register(task_calsse):
     def register(task_calsse):
         CronManager.TASK_CLASS[task_calsse.NAME] = task_calsse
         CronManager.TASK_CLASS[task_calsse.NAME] = task_calsse
+        return task_calsse
 
 
 
 

+ 14 - 0
src/djangotools/cmdline/tasks/__init__.py

@@ -0,0 +1,14 @@
+from djangotools.cmdline import CronManager, Task, CommandData
+
+
+@CronManager.register
+class BackupTask(Task):
+    NAME="backup"
+    def run(self, data):
+
+        from djangotools.cmdline.commands.backup import BackupCommand
+        cmd = BackupCommand()
+        cmd.execute(CommandData(daily=None, weekly=None, monthly=None, quiet=None, prefix=None))
+
+
+

+ 5 - 2
src/djangotools/common/route.py

@@ -5,6 +5,7 @@ from django.db.models.base import ModelBase
 from djangotools.common import response
 from djangotools.common import response
 from djangotools.common.path import PointPath, ModelPath, AttributePath
 from djangotools.common.path import PointPath, ModelPath, AttributePath
 from djangotools.model.serializedmodel import SerializableModel
 from djangotools.model.serializedmodel import SerializableModel
+from djangotools.view.utils import debug_login
 
 
 
 
 class Route:
 class Route:
@@ -41,8 +42,10 @@ class RegisteredRoute:
 
 
     def __call__(self, req, *args, **kwargs):
     def __call__(self, req, *args, **kwargs):
         obj = None
         obj = None
-        if self._default_user_id_:
-            req.user = User.objects.get(id=self._default_user_id_)
+        debug_login(req, self._default_user_id_)
+        user = req.user
+        if "need_auth" and  not user.is_authenticated:
+            return response.serv_json_not_logged()
 
 
 
 
         for part in self.route.path.iter_models():
         for part in self.route.path.iter_models():

+ 5 - 0
src/djangotools/config/__init__.py

@@ -14,6 +14,11 @@ def load_settings(module, base_dir=None, **kwargs):
 
 
 loaded = False
 loaded = False
 
 
+def get_settings():
+    from django.conf import settings
+    return settings
+
+
 def load_app(settings_module, app_dir=None, populate=True):
 def load_app(settings_module, app_dir=None, populate=True):
     global loaded
     global loaded
     if loaded: return
     if loaded: return

+ 2 - 2
src/djangotools/config/base.py

@@ -108,10 +108,10 @@ class ConfigLoader:
         self.backup_dir = Directory(self.app_dir /  self.BACKUP)
         self.backup_dir = Directory(self.app_dir /  self.BACKUP)
         self.logs_dir = Directory(self.app_dir /  self.LOGS)
         self.logs_dir = Directory(self.app_dir /  self.LOGS)
         self.run_dir = Directory(self.app_dir /  self.RUN)
         self.run_dir = Directory(self.app_dir /  self.RUN)
-        self.run_file = File(self.app_dir /  self.RUN_FILE)
+        self.pid_file = File(self.app_dir /  self.RUN_FILE)
         self.django_secret_file = File(self.app_dir / self.DJANGO_SECRET_FILE)
         self.django_secret_file = File(self.app_dir / self.DJANGO_SECRET_FILE)
 
 
-        for path in [self.app_dir, self.data_dir, self.backup_dir, self.secret_dir, self.config_dir, self.logs_dir]:
+        for path in [self.app_dir, self.data_dir, self.backup_dir, self.secret_dir, self.config_dir, self.logs_dir, self.run_dir]:
             if not path.exists(): path.mkdir(parents=True)
             if not path.exists(): path.mkdir(parents=True)
 
 
         if not self.config_file.is_file():
         if not self.config_file.is_file():

+ 20 - 0
src/djangotools/view/utils.py

@@ -0,0 +1,20 @@
+from django.contrib.auth import login
+from django.contrib.auth.models import User
+
+from djangotools.config import settings
+
+def debug_login(request, fallback_id=None):
+    if settings.ALLOW_AUTO_LOGIN and not request.user.is_authenticated and settings.AUTO_LOGIN:
+        try:
+            user = User.objects.get(username=settings.AUTO_LOGIN)
+        except User.DoesNotExist:
+            if fallback_id is not None:
+                user = User.objects.get(id=fallback_id)
+            else:
+                raise Exception()
+        login(request, user)
+
+
+def check_auth(request):
+    debug_login(request)
+    return request.user.is_authenticated