Browse Source

Management commands moved over

Ralfp 12 years ago
parent
commit
52fc856a9d

+ 38 - 0
misago/management/commands/adduser.py

@@ -0,0 +1,38 @@
+from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
+from django.core.management.base import BaseCommand, CommandError
+from django.utils import timezone
+from optparse import make_option
+from misago.models import Role, User
+
+class Command(BaseCommand):
+    args = 'username email password'
+    help = 'Creates new user account'
+    option_list = BaseCommand.option_list + (
+        make_option('--admin',
+            action='store_true',
+            dest='admin',
+            default=False,
+            help='Make a new user an administrator'),
+        )
+
+    def handle(self, *args, **options):
+        if len(args) < 3:
+            raise CommandError('adduser requires exactly three arguments: user name, e-mail address and password')
+
+        # Set user
+        try:
+            new_user = User.objects.create_user(args[0], args[1], args[2])
+        except ValidationError as e:
+            raise CommandError("New user cannot be created because of following errors:\n\n%s" % '\n'.join(e.messages))
+
+        # Set admin role
+        if options['admin']:
+            new_user.roles.add(Role.objects.get(token='admin'))
+            new_user.make_acl_key(True)
+            new_user.save(force_update=True)
+
+        if options['admin']:
+            self.stdout.write('Successfully created new administrator "%s"' % args[0])
+        else:
+            self.stdout.write('Successfully created new user "%s"' % args[0])
+        self.stdout.write('\n\nNew user should use "%s" e-mail address and "%s" password to sign in.\n' % (args[1], args[2]))

+ 13 - 0
misago/management/commands/clearalerts.py

@@ -0,0 +1,13 @@
+from datetime import timedelta
+from django.core.management.base import BaseCommand
+from django.utils import timezone
+from misago.models import Alert
+
+class Command(BaseCommand):
+    """
+    This command is intended to work as CRON job fired every few days to delete old alerts
+    """
+    help = 'Clears old alerts'
+    def handle(self, *args, **options):
+        Alert.objects.filter(date__lte=timezone.now() - timedelta(days=14)).delete()
+        self.stdout.write('Old Alerts have been cleared.\n')

+ 1 - 1
misago/management/commands/clearattempts.py

@@ -1,6 +1,6 @@
 from datetime import timedelta
 from django.utils import timezone
-from misago.bruteforce.models import SignInAttempt
+from misago.models import SignInAttempt
 
 class Command(BaseCommand):
     """

+ 15 - 0
misago/management/commands/cleartracker.py

@@ -0,0 +1,15 @@
+from datetime import timedelta
+from django.conf import settings
+from django.core.management.base import BaseCommand
+from django.utils import timezone
+from misago.models import ForumRead, ThreadRead
+
+class Command(BaseCommand):
+    """
+    This command is intended to work as CRON job fired every few days to remove old reads tracker entries
+    """
+    help = 'Clears Reads Tracker memory'
+    def handle(self, *args, **options):
+        ForumRead.objects.filter(updated__lte=timezone.now() - timedelta(days=settings.READS_TRACKER_LENGTH)).delete()
+        ThreadRead.objects.filter(updated__lte=timezone.now() - timedelta(days=settings.READS_TRACKER_LENGTH)).delete()
+        self.stdout.write('Reads tracker has been cleared.\n')        

+ 67 - 0
misago/management/commands/genavatars.py

@@ -0,0 +1,67 @@
+from django.core.management.base import BaseCommand, CommandError
+from django.conf import settings
+from path import path
+try:
+    from PIL import Image
+    has_pil = True
+except ImportError:
+    has_pil = False
+from misago.models import User
+from misago.utils.avatars import resizeimage
+
+class Command(BaseCommand):
+    help = 'Regenerates avatar images for new dimensions'
+    def handle(self, *args, **options):
+        if not has_pil:
+            raise CommandError('genavatars requires Python Imaging Library to be installed in order to run')
+        self.scale_user_avatars()
+        self.scale_gallery_avatars()
+        self.stdout.write('\n\nAvatar images have been regenerated.\n')
+
+    def scale_image(self, image_src, image_dir=None):
+        image_name = path.basename(path(image_src))
+        if not image_dir:
+            image_dir = path.dirname(path(image_src)) + '/%s_'
+        for size in settings.AVATAR_SIZES[1:]:
+            resizeimage(image_src, size, image_dir % size + image_name)
+
+    def scale_user_avatars(self):
+        for user in User.objects.filter(avatar_type='upload').iterator():
+            for image in path(settings.MEDIA_ROOT).joinpath('avatars').files('*_%s' % user.avatar_image):
+                if not image.isdir():
+                    image.remove()
+            self.scale_image(settings.MEDIA_ROOT + 'avatars/' + user.avatar_image)
+
+    def scale_gallery_avatars(self):
+        try:
+            thumb_dir = path(settings.STATICFILES_DIRS[0]).joinpath('avatars').joinpath('_thumbs')
+            items = [thumb_dir]
+            for item in thumb_dir.walk():
+                items.append(item)
+            for item in reversed(items):
+                if item.isdir():
+                    item.rmdir()
+                else:
+                    item.remove()
+        except Exception:
+            pass
+        avatars_dir = path(settings.STATICFILES_DIRS[0]).joinpath('avatars')
+        avatars_len = len(avatars_dir)
+        avatars_list = []
+        for directory in avatars_dir.dirs():
+            avatars_list += directory.files('*.gif')
+            avatars_list += directory.files('*.jpg')
+            avatars_list += directory.files('*.jpeg')
+            avatars_list += directory.files('*.png')
+        thumb_dir = path(settings.STATICFILES_DIRS[0]).joinpath('avatars').joinpath('_thumbs')
+        thumb_dir.mkdir(777)
+        for size in settings.AVATAR_SIZES[1:]:
+            thumb_dir.joinpath(str(size)).mkdir(777)
+        for directory in avatars_dir.dirs():
+            dirname = path(directory[avatars_len:]).basename()
+            if dirname != '_thumbs':
+                for size in settings.AVATAR_SIZES[1:]:
+                    thumb_dir.joinpath(str(size)).joinpath(dirname).mkdir(777)
+        for avatar in avatars_list:
+            self.scale_image(avatar,
+                             thumb_dir + '/%s' + avatar.dirname()[avatars_len:] + '/')

+ 0 - 0
misago/management/commands/initmisago.py → misago/management/commands/startmisago.py


+ 12 - 0
misago/management/commands/syncdeltas.py

@@ -0,0 +1,12 @@
+from django.core.management.base import BaseCommand
+from django.db.models import F
+from misago.models import Forum
+
+class Command(BaseCommand):
+    """
+    This command is intended to work as CRON job fired every few hours to update threads/posts/clicks history on forum
+    """
+    help = 'Clears users sessions'
+    def handle(self, *args, **options):
+        Forum.objects.all().update(threads_delta=F('threads'), posts_delta=F('posts'), redirects_delta=F('redirects'))
+        self.stdout.write('Forums deltas have been synced.\n')

+ 16 - 12
misago/management/commands/syncfixtures.py

@@ -1,4 +1,5 @@
 from optparse import make_option
+import traceback
 import os.path
 import pkgutil
 from django.core.management.base import BaseCommand
@@ -31,18 +32,21 @@ class Command(BaseCommand):
         updated = 0
         
         fixtures_path = os.path.dirname(misago.fixtures.__file__)
-        for _, name, _ in pkgutil.iter_modules([fixtures_path]):
-            if name in fixture_data:
-                if update_fixture('misago.fixtures.' + name):
-                    updated += 1
-                    if not options['quiet']:
-                        self.stdout.write('Updating "%s" fixture...' % name)
-            else:
-                if load_fixture('misago.fixtures.' + name):
-                    loaded += 1
-                    Fixture.objects.create(name=name)
-                    if not options['quiet']:
-                        self.stdout.write('Loading "%s" fixture...' % name)
+        try:
+            for _, name, _ in pkgutil.iter_modules([fixtures_path]):
+                if name in fixture_data:
+                    if update_fixture('misago.fixtures.' + name):
+                        updated += 1
+                        if not options['quiet']:
+                            self.stdout.write('Updating "%s" fixture...' % name)
+                else:
+                    if load_fixture('misago.fixtures.' + name):
+                        loaded += 1
+                        Fixture.objects.create(name=name)
+                        if not options['quiet']:
+                            self.stdout.write('Loading "%s" fixture...' % name)
+        except:
+            self.stderr.write(traceback.format_exc())
 
         if not options['quiet']:
             self.stdout.write('\nLoaded %s fixtures and updated %s fixtures.\n' % (loaded, updated))

+ 12 - 0
misago/management/commands/syncusermonitor.py

@@ -0,0 +1,12 @@
+from django.core.management.base import BaseCommand
+from django.utils import timezone
+from optparse import make_option
+from misago.monitor import Monitor
+from misago.models import User
+
+class Command(BaseCommand):
+    help = 'Updates forum monitor to contain to date user information'
+
+    def handle(self, *args, **options):
+        User.objects.resync_monitor(Monitor())
+        self.stdout.write('\nForum monitor has been updated to contain to date user information.\n')

+ 0 - 0
misago/management/commands/updmisago.py → misago/management/commands/updatemisago.py


+ 36 - 0
misago/management/commands/updateranking.py

@@ -0,0 +1,36 @@
+from django.core.management.base import BaseCommand, CommandError
+from django.db.models import F
+from misago.dbsettings import DBSettings
+from misago.models import Rank, User
+
+class Command(BaseCommand):
+    """
+    This command is intended to work as CRON job fired of once per day or less if you have more users to update user ranking.
+    """
+    help = 'Updates users ranking'
+    def handle(self, *args, **options):
+        # Find special ranks
+        special_ranks = []
+        for rank in Rank.objects.filter(special=1):
+            special_ranks.append(str(rank.pk))
+
+        # Count users that are in ranking
+        users_total = User.objects.exclude(rank__in=special_ranks).count()
+
+        # Update Ranking
+        defaulted_ranks = False
+        for rank in Rank.objects.filter(special=0).order_by('order'):
+            if defaulted_ranks:
+                # Set ranks according to ranking
+                rank.assign_rank(users_total, special_ranks)
+            else:
+                # Set default rank first
+                User.objects.exclude(rank__in=special_ranks).update(rank=rank)
+                defaulted_ranks = True
+
+        # Inflate scores
+        settings = DBSettings()
+        inflation = float(100 - settings['ranking_inflation']) / 100
+        User.objects.all().update(score=F('score') * inflation, ranking=0)
+
+        self.stdout.write('Users ranking for has been updated.\n')

+ 18 - 0
misago/management/commands/updatethreadranking.py

@@ -0,0 +1,18 @@
+from django.core.management.base import BaseCommand
+from django.db.models import F
+from misago.dbsettings import DBSettings
+from misago.models import Thread
+
+class Command(BaseCommand):
+    """
+    This command is intended to work as CRON job fired every few days to update thread popularity ranking
+    """
+    help = 'Updates Popular Threads ranking'
+    def handle(self, *args, **options):
+        settings = DBSettings()
+        if settings['thread_ranking_inflation'] > 0:
+            inflation = float(100 - settings['thread_ranking_inflation']) / 100
+            Thread.objects.all().update(score=F('score') * inflation)
+            self.stdout.write('Thread ranking has been updated.\n')
+        else:
+            self.stdout.write('Thread ranking inflation is disabled.\n')