diff --git a/boards/models.py b/boards/models.py --- a/boards/models.py +++ b/boards/models.py @@ -35,9 +35,42 @@ RANK_MODERATOR = 10 RANK_USER = 100 +class User(models.Model): + + user_id = models.CharField(max_length=50) + rank = models.IntegerField() + + def save_setting(self, name, value): + setting, created = Setting.objects.get_or_create(name=name, user=self) + setting.value = value + setting.save() + + return setting + + def get_setting(self, name): + settings = Setting.objects.filter(name=name, user=self) + if len(settings) > 0: + setting = settings[0] + else: + setting = None + + if setting: + setting_value = setting.value + else: + setting_value = None + + return setting_value + + def is_moderator(self): + return RANK_MODERATOR >= self.rank + + def __unicode__(self): + return self.user_id + + class PostManager(models.Manager): def create_post(self, title, text, image=None, parent_id=NO_PARENT, - ip=NO_IP, tags=None): + ip=NO_IP, tags=None, user=None): post = self.create(title=title, text=text, pub_time=timezone.now(), @@ -45,7 +78,8 @@ class PostManager(models.Manager): image=image, poster_ip=ip, poster_user_agent=UNKNOWN_UA, - last_edit_time=timezone.now()) + last_edit_time=timezone.now(), + user=user) if tags: map(post.tags.add, tags) @@ -224,6 +258,7 @@ class Post(models.Model): parent = models.BigIntegerField() tags = models.ManyToManyField(Tag) last_edit_time = models.DateTimeField() + user = models.ForeignKey(User, null=True, default=None) def __unicode__(self): return '#' + str(self.id) + ' ' + self.title + ' (' + self.text.raw + \ @@ -293,39 +328,6 @@ class Admin(models.Model): return self.name + '/' + '*' * len(self.password) -class User(models.Model): - - user_id = models.CharField(max_length=50) - rank = models.IntegerField() - - def save_setting(self, name, value): - setting, created = Setting.objects.get_or_create(name=name, user=self) - setting.value = value - setting.save() - - return setting - - def get_setting(self, name): - settings = Setting.objects.filter(name=name, user=self) - if len(settings) > 0: - setting = settings[0] - else: - setting = None - - if setting: - setting_value = setting.value - else: - setting_value = None - - return setting_value - - def is_moderator(self): - return RANK_MODERATOR >= self.rank - - def __unicode__(self): - return self.user_id - - class Setting(models.Model): name = models.CharField(max_length=50) diff --git a/boards/thumbs.py b/boards/thumbs.py --- a/boards/thumbs.py +++ b/boards/thumbs.py @@ -9,6 +9,7 @@ from PIL import Image from django.core.files.base import ContentFile import cStringIO + def generate_thumb(img, thumb_size, format): """ Generates a thumbnail image and returns a ContentFile object with the thumbnail @@ -22,10 +23,10 @@ def generate_thumb(img, thumb_size, form format format of the original image ('jpeg','gif','png',...) (this format will be used for the generated thumbnail, too) """ - + img.seek(0) # see http://code.djangoproject.com/ticket/8222 for details image = Image.open(img) - + # get size thumb_w, thumb_h = thumb_size # If you want to generate a square thumbnail @@ -33,12 +34,13 @@ def generate_thumb(img, thumb_size, form # quad xsize, ysize = image.size # get minimum size - minsize = min(xsize,ysize) + minsize = min(xsize, ysize) # largest square possible in the image - xnewsize = (xsize-minsize)/2 - ynewsize = (ysize-minsize)/2 + xnewsize = (xsize - minsize) / 2 + ynewsize = (ysize - minsize) / 2 # crop it - image2 = image.crop((xnewsize, ynewsize, xsize-xnewsize, ysize-ynewsize)) + image2 = image.crop( + (xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize)) # load is necessary after crop image2.load() # thumbnail of the cropped image (with ANTIALIAS to make it look better) @@ -47,66 +49,70 @@ def generate_thumb(img, thumb_size, form # not quad image2 = image image2.thumbnail(thumb_size, Image.ANTIALIAS) - + io = cStringIO.StringIO() # PNG and GIF are the same, JPG is JPEG - if format.upper()=='JPG': + if format.upper() == 'JPG': format = 'JPEG' - + image2.save(io, format) - return ContentFile(io.getvalue()) + return ContentFile(io.getvalue()) + class ImageWithThumbsFieldFile(ImageFieldFile): """ See ImageWithThumbsField for usage example """ + def __init__(self, *args, **kwargs): super(ImageWithThumbsFieldFile, self).__init__(*args, **kwargs) self.sizes = self.field.sizes - + if self.sizes: def get_size(self, size): if not self: return '' else: - split = self.url.rsplit('.',1) - thumb_url = '%s.%sx%s.%s' % (split[0],w,h,split[1]) + split = self.url.rsplit('.', 1) + thumb_url = '%s.%sx%s.%s' % (split[0], w, h, split[1]) return thumb_url - + for size in self.sizes: - (w,h) = size - setattr(self, 'url_%sx%s' % (w,h), get_size(self, size)) - + (w, h) = size + setattr(self, 'url_%sx%s' % (w, h), get_size(self, size)) + def save(self, name, content, save=True): super(ImageWithThumbsFieldFile, self).save(name, content, save) - + if self.sizes: for size in self.sizes: - (w,h) = size - split = self.name.rsplit('.',1) - thumb_name = '%s.%sx%s.%s' % (split[0],w,h,split[1]) - + (w, h) = size + split = self.name.rsplit('.', 1) + thumb_name = '%s.%sx%s.%s' % (split[0], w, h, split[1]) + # you can use another thumbnailing function if you like thumb_content = generate_thumb(content, size, split[1]) - - thumb_name_ = self.storage.save(thumb_name, thumb_content) - + + thumb_name_ = self.storage.save(thumb_name, thumb_content) + if not thumb_name == thumb_name_: - raise ValueError('There is already a file named %s' % thumb_name) - + raise ValueError( + 'There is already a file named %s' % thumb_name) + def delete(self, save=True): - name=self.name + name = self.name super(ImageWithThumbsFieldFile, self).delete(save) if self.sizes: for size in self.sizes: - (w,h) = size - split = name.rsplit('.',1) - thumb_name = '%s.%sx%s.%s' % (split[0],w,h,split[1]) + (w, h) = size + split = name.rsplit('.', 1) + thumb_name = '%s.%sx%s.%s' % (split[0], w, h, split[1]) try: self.storage.delete(thumb_name) except: pass - + + class ImageWithThumbsField(ImageField): attr_class = ImageWithThumbsFieldFile """ @@ -151,10 +157,17 @@ class ImageWithThumbsField(ImageField): Add method to regenerate thubmnails """ - def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, sizes=None, **kwargs): - self.verbose_name=verbose_name - self.name=name - self.width_field=width_field - self.height_field=height_field + + def __init__(self, verbose_name=None, name=None, width_field=None, + height_field=None, sizes=None, **kwargs): + self.verbose_name = verbose_name + self.name = name + self.width_field = width_field + self.height_field = height_field self.sizes = sizes - super(ImageField, self).__init__(**kwargs) \ No newline at end of file + super(ImageField, self).__init__(**kwargs) + + +from south.modelsinspector import add_introspection_rules + +add_introspection_rules([], ["^boards\.thumbs\.ImageWithThumbsField"]) \ No newline at end of file diff --git a/neboard/settings.py b/neboard/settings.py --- a/neboard/settings.py +++ b/neboard/settings.py @@ -140,6 +140,7 @@ INSTALLED_APPS = ( 'django_cleanup', 'boards', 'captcha', + 'south', ) # TODO: NEED DESIGN FIXES @@ -187,13 +188,14 @@ SITE_NAME = 'Neboard' THEMES = [ ('md', 'Mystic Dark'), - ('sw', 'Snow White') ] + ('sw', 'Snow White') +] DEFAULT_THEME = 'md' POPULAR_TAGS = 10 LAST_REPLIES_COUNT = 3 -ENABLE_CAPTCHA = True +ENABLE_CAPTCHA = False # if user tries to post before CAPTCHA_DEFAULT_SAFE_TIME. Captcha will be shown CAPTCHA_DEFAULT_SAFE_TIME = 30 # seconds