class WorkPhoto(models.Model): work = models.ForeignKey(Work, on_delete=models.CASCADE, related_name="photo_work", blank=True) file = ProcessedImageField( format='JPEG', options={'quality': 90}, upload_to="work/", processors=[Transpose(), ResizeToFit(width=1024, upscale=False)]) preview = ProcessedImageField( format='JPEG', options={'quality': 60}, upload_to="work/", processors=[Transpose(), ResizeToFit(width=102, upscale=False)]) created = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Создано") class Meta: indexes = (BrinIndex(fields=['created']), ) verbose_name = 'Фото' verbose_name_plural = 'Фото' ordering = ["-created"]
def save(self, force_insert=True, force_update=False, using=None): super(VendorPhoto, self).save() path = str(self.image.path) img = Image.open(path) processor = Transpose() img = processor.process(img) img.thumbnail((500, 300), Image.ANTIALIAS) img.save(path)
def generate_image(source, outname, settings, options=None): """Image processor, rotate and resize the image. :param source: path to an image :param outname: output filename :param settings: settings dict :param options: dict with PIL options (quality, optimize, progressive) """ logger = logging.getLogger(__name__) if settings['use_orig']: utils.copy(source, outname, symlink=settings['orig_link']) return img = PILImage.open(source) original_format = img.format if settings['copy_exif_data'] and settings['autorotate_images']: logger.warning("The 'autorotate_images' and 'copy_exif_data' settings " "are not compatible because Sigal can't save the " "modified Orientation tag.") # Preserve EXIF data if settings['copy_exif_data'] and _has_exif_tags(img): if options is not None: options = deepcopy(options) else: options = {} options['exif'] = img.info['exif'] # Rotate the img, and catch IOError when PIL fails to read EXIF if settings['autorotate_images']: try: img = Transpose().process(img) except (IOError, IndexError): pass # Resize the image if settings['img_processor']: try: logger.debug('Processor: %s', settings['img_processor']) processor_cls = getattr(pilkit.processors, settings['img_processor']) except AttributeError: logger.error('Wrong processor name: %s', settings['img_processor']) sys.exit() processor = processor_cls(*settings['img_size'], upscale=False) img = processor.process(img) # signal.send() does not work here as plugins can modify the image, so we # iterate other the receivers to call them with the image. for receiver in signals.img_resized.receivers_for(img): img = receiver(img, settings=settings) outformat = img.format or original_format or 'JPEG' logger.debug(u'Save resized image to {0} ({1})'.format(outname, outformat)) save_image(img, outname, outformat, options=options, autoconvert=True)
class WebSpec(ImageSpec): format = 'JPEG' options = {'quality': 90} processors = [ Transpose(Transpose.AUTO), ResizeToFit(1600, 1600, upscale=False) ]
def generate_thumbnail( source, outname, box, fit=True, options=None, thumb_fit_centering=(0.5, 0.5) ): """Create a thumbnail image.""" logger = logging.getLogger(__name__) img = _read_image(source) img = Transpose().process(img) original_format = img.format if fit: img = ImageOps.fit(img, box, PILImage.ANTIALIAS, centering=thumb_fit_centering) else: img.thumbnail(box, PILImage.ANTIALIAS) outformat = img.format or original_format or 'JPEG' logger.debug('Save thumnail image: %s (%s)', outname, outformat) save_image(img, outname, outformat, options=options, autoconvert=True)
def generate_image(source, outname, settings, options=None): """Image processor, rotate and resize the image. :param source: path to an image :param outname: output filename :param settings: settings dict :param options: dict with PIL options (quality, optimize, progressive) """ logger = logging.getLogger(__name__) img = PILImage.open(source) original_format = img.format # Preserve EXIF data if settings['copy_exif_data'] and _has_exif_tags(img): if options is not None: options = deepcopy(options) else: options = {} options['exif'] = img.info['exif'] # Rotate the img, and catch IOError when PIL fails to read EXIF try: img = Transpose().process(img) except (IOError, IndexError): pass # Resize the image if settings['img_processor']: try: logger.debug('Processor: %s', settings['img_processor']) processor_cls = getattr(pilkit.processors, settings['img_processor']) except AttributeError: logger.error('Wrong processor name: %s', settings['img_processor']) sys.exit() processor = processor_cls(*settings['img_size'], upscale=False) img = processor.process(img) # Adjust the image after resizing img = Adjust(**settings['adjust_options']).process(img) if settings['copyright']: add_copyright(img, settings['copyright']) outformat = img.format or original_format or 'JPEG' logger.debug(u'Save resized image to {0} ({1})'.format(outname, outformat)) save_image(img, outname, outformat, options=options, autoconvert=True)
class ProductThumbnailImage(models.Model): p_target_product_id = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='product_thumbnails', verbose_name='p_target_product_id') p_thumbnail = ProcessedImageField(upload_to='product_thumbnails', processors=[ Transpose(), Thumbnail(300, 300)], format='JPEG', options={'quality': 60}, null=True, blank=True) def __str__(self): return str(self.p_target_product_id)
def get_destination(source, name, type, width, bytes): if not type.startswith('image'): return format = type.split('/')[1] if format == '*': format = '' try: format = name.split('.')[-1].lower() except Exception: pass if not format: format = 'png' if format == 'jpg': format = 'jpeg' _, destination = mkstemp() quality = 75 while True: try: ProcessorPipeline([ Transpose(), ResizeToFit(width=width, upscale=False), ]).process(Image.open(source), ).save( destination, format=format, optimize=True, quality=quality, ) except IOError: break if not bytes: break if getsize(destination) <= bytes: break if quality <= 5: break quality = quality - 5 return destination
class ProjectImage(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="projectimages") title = models.CharField(max_length=50, blank=True) image = ProcessedImageField(upload_to=RandomFileName('projects/images/'), processors=[Transpose(Transpose.AUTO)], format='JPEG', options={'quality': 100}) image_icon = ImageSpecField(source='image', processors=[ResizeToFill(56, 42)], format='JPEG', options={'quality': 75}) image_thumbnail = ImageSpecField(source='image', processors=[ResizeToFill(640, 480)], format='JPEG', options={'quality': 100}) description = models.TextField(max_length=100, blank=True) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) class Meta: ordering = ["timestamp"] def __str__(self): return self.image.name
def save_normalized_image(data_dir, filename, data): from PIL import Image, ImageFile from pilkit.processors import Transpose if not os.path.isdir(config.DATA_DIR): try: # Reset saved files on each start # rmtree(DATA_DIR, True) os.mkdir(config.DATA_DIR) except OSError: raise return False path = os.path.join(data_dir, filename) orig_store_path = os.path.join(config.DATA_DIR, filename) image_parser = ImageFile.Parser() try: image_parser.feed(data) image = image_parser.close() except IOError: raise return False image.save(orig_store_path) try: image = Transpose().process(image) except (IOError, IndexError): pass image.thumbnail(config.MAX_IMAGE_SIZE, Image.ANTIALIAS) if image.mode != 'RGB': image = image.convert('RGB') image.save(path) return True
class ThumbnailSpec(ImageSpec): format = 'JPEG' options = {'quality': 80} processors = [Transpose(Transpose.AUTO), ResizeToFit(450, 450)]
class SoundList(models.Model): MAIN, LIST, MANAGER, PROCESSING, PRIVATE = 'MAI', 'LIS', 'MAN', '_PRO', 'PRI' DELETED, DELETED_PRIVATE, DELETED_MANAGER = '_DEL', '_DELP', '_DELM' CLOSED, CLOSED_PRIVATE, CLOSED_MAIN, CLOSED_MANAGER = '_CLO', '_CLOP', '_CLOM', '_CLOMA' TYPE = ( (MAIN, 'Основной'),(LIST, 'Пользовательский'),(PRIVATE, 'Приватный'),(MANAGER, 'Созданный персоналом'),(PROCESSING, 'Обработка'), (DELETED, 'Удалённый'),(DELETED_PRIVATE, 'Удалённый приватный'),(DELETED_MANAGER, 'Удалённый менеджерский'), (CLOSED, 'Закрытый менеджером'),(CLOSED_PRIVATE, 'Закрытый приватный'),(CLOSED_MAIN, 'Закрытый основной'),(CLOSED_MANAGER, 'Закрытый менеджерский'), ) name = models.CharField(max_length=255) creator = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='playlist_creator', db_index=False, on_delete=models.CASCADE, verbose_name="Создатель") type = models.CharField(max_length=6, choices=TYPE, default=PROCESSING, verbose_name="Тип") order = models.PositiveIntegerField(default=0) uuid = models.UUIDField(default=uuid.uuid4, verbose_name="uuid") image = ProcessedImageField(format='JPEG', blank=True, options={'quality': 100}, upload_to=upload_to_music_directory, processors=[Transpose(), ResizeToFit(width=400, height=400)]) community = models.ForeignKey('communities.Community', related_name='playlist_community', on_delete=models.CASCADE, null=True, blank=True, verbose_name="Сообщество") description = models.CharField(max_length=200, blank=True, verbose_name="Описание") users = models.ManyToManyField("users.User", blank=True, related_name='+') communities = models.ManyToManyField('communities.Community', blank=True, related_name='+') def __str__(self): return self.name + " " + self.creator.get_full_name() class Meta: verbose_name = "список треков" verbose_name_plural = "списки треков" ordering = ['order'] @receiver(post_save, sender=Community) def create_c_model(sender, instance, created, **kwargs): if created: SoundList.objects.create(community=instance, type=SoundList.MAIN, name="Основной список", order=0, creator=instance.creator) @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_u_model(sender, instance, created, **kwargs): if created: SoundList.objects.create(creator=instance, type=SoundList.MAIN, name="Основной список", order=0) def is_item_in_list(self, item_id): return self.playlist.filter(pk=item_id).exists() def is_not_empty(self): query = Q(list=self) query.add(~Q(type__contains="_"), Q.AND) return self.playlist.filter(query).values("pk").exists() def get_staff_items(self): query = Q(type="PUB")|Q(type="PRI") queryset = self.playlist.filter(query) return queryset def get_items(self): query = Q(type="PUB") queryset = self.playlist.filter(query) return queryset def get_penalty_items(self): return self.playlist.filter(type__contains="_CLO") def get_users_ids(self): users = self.users.exclude(type__contains="_").values("pk") return [i['pk'] for i in users] def get_communities_ids(self): communities = self.communities.exclude(type__contains="_").values("pk") return [i['pk'] for i in communities] def is_user_can_add_list(self, user_id): return self.creator.pk != user_id and user_id not in self.get_users_ids() and self.is_open() def is_user_can_delete_list(self, user_id): return self.creator.pk != user_id and user_id in self.get_users_ids() def get_remote_image(self, image_url): import os from django.core.files import File from urllib import request result = request.urlretrieve(image_url) self.image.save( os.path.basename(image_url), File(open(result[0], 'rb')) ) self.save() def count_items(self): query = Q(type="PUB") | Q(type="MAN") return self.playlist.filter(query).values("pk").count() def is_main(self): return self.type == self.MAIN def is_list(self): return self.type == self.LIST def is_private(self): return self.type == self.PRIVATE def is_deleted(self): return self.type[:4] == "_DEL" def is_closed(self): return self.type[:4] == "_CLO" def is_suspended(self): return False def is_open(self): return self.type == self.LIST or self.type == self.MAIN or self.type == self.MANAGER def make_private(self): from notify.models import Notify, Wall self.type = SoundList.PRIVATE self.save(update_fields=['type']) if Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="C") def make_publish(self): from notify.models import Notify, Wall self.type = SoundList.LIST self.save(update_fields=['type']) if Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="R") def delete_list(self): from notify.models import Notify, Wall if self.type == "LIS": self.type = SoundList.DELETED elif self.type == "PRI": self.type = SoundList.DELETED_PRIVATE elif self.type == "MAN": self.type = SoundList.DELETED_MANAGER self.save(update_fields=['type']) if Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="C") def abort_delete_list(self): from notify.models import Notify, Wall if self.type == "_DEL": self.type = SoundList.LIST elif self.type == "_DELP": self.type = SoundList.PRIVATE elif self.type == "_DELM": self.type = SoundList.MANAGER self.save(update_fields=['type']) if Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="R") def close_item(self, community): from notify.models import Notify, Wall if self.type == "LIS": self.type = SoundList.CLOSED elif self.type == "MAI": self.type = SoundList.CLOSED_MAIN elif self.type == "PRI": self.type = SoundList.CLOSED_PRIVATE elif self.type == "MAN": self.type = SoundList.CLOSED_MANAGER self.save(update_fields=['type']) if Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="C") def abort_close_item(self, community): from notify.models import Notify, Wall if self.type == "_CLO": self.type = SoundList.LIST elif self.type == "_CLOM": self.type = SoundList.MAIN elif self.type == "_CLOP": self.type = SoundList.PRIVATE elif self.type == "_CLOMA": self.type = SoundList.MANAGER self.save(update_fields=['type']) if Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUL", object_id=self.pk, verb="ITE").update(status="R") @classmethod def get_user_staff_lists(cls, user_pk): query = Q(creator_id=user_pk, community__isnull=True)|Q(users__id=user_pk) query.add(~Q(type__contains="_"), Q.AND) query.add(~Q(Q(type="MAI")&Q(creator_id=user_pk)), Q.AND) return cls.objects.filter(query) @classmethod def get_user_lists(cls, user_pk): query = Q(creator_id=user_pk, community__isnull=True)|Q(users__id=user_pk) query.add(Q(type="LIS"), Q.AND) return cls.objects.filter(query) @classmethod def get_user_lists_count(cls, user_pk): query = Q(creator_id=user_pk, community__isnull=True)|Q(users__id=user_pk) query.add(Q(Q(type="MAI")|Q(type="LIS")), Q.AND) return cls.objects.filter(query).values("pk").count() @classmethod def get_user_lists_not_empty(cls, user_pk): query = Q(creator_id=user_pk, community__isnull=True)|Q(users__id=user_pk) query.add(~Q(Q(type__contains="_")&Q(playlist__isnull=True)), Q.AND) return cls.objects.filter(query) @classmethod def is_user_can_added_list(cls, user_pk): from django.conf import settings return cls.get_user_lists_count(user_pk) <= settings.USER_MAX_MUSIC_LISTS @classmethod def get_community_staff_lists(cls, community_pk): query = Q(community_id=community_pk)|Q(communities__id=community_pk) query.add(~Q(type__contains="_"), Q.AND) query.add(~Q(Q(type="MAI")&Q(community_id=community_id)), Q.AND) return cls.objects.filter(query) @classmethod def get_community_lists(cls, community_pk): query = Q(community_id=community_pk)|Q(communities__id=community_pk) query.add(Q(type="LIS"), Q.AND) return cls.objects.filter(query).order_by("order") @classmethod def get_community_lists_count(cls, community_pk): query = Q(community_id=community_pk)|Q(communities__id=community_pk) query.add(Q(Q(type="MAI")|Q(type="LIS")), Q.AND) return cls.objects.filter(query).values("pk").count() @classmethod def create_list(cls, creator, name, description, order, community, is_public): from notify.models import Notify, Wall from common.processing import get_playlist_processing if not SoundList.is_user_can_added_list(creator.pk): pass if not order: order = 1 if community: list = cls.objects.create(creator=creator,name=name,description=description, order=order, community=community) if is_public: from common.notify.progs import community_send_notify, community_send_wall #Wall.objects.create(creator_id=creator.pk, community_id=community.pk, type="MUL", object_id=list.pk, verb="ITE") #community_send_wall(list.pk, creator.pk, community.pk, None, "create_c_music_list_wall") for user_id in community.get_member_for_notify_ids(): Notify.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="MUL", object_id=list.pk, verb="ITE") community_send_notify(list.pk, creator.pk, user_id, community.pk, None, "create_c_music_list_notify") else: list = cls.objects.create(creator=creator,name=name,description=description, order=order) if is_public: from common.notify.progs import user_send_notify, user_send_wall #Wall.objects.create(creator_id=creator.pk, type="MUL", object_id=list.pk, verb="ITE") #user_send_wall(list.pk, None, "create_u_music_list_wall") for user_id in creator.get_user_news_notify_ids(): Notify.objects.create(creator_id=creator.pk, recipient_id=user_id, type="MUL", object_id=list.pk, verb="ITE") user_send_notify(list.pk, creator.pk, user_id, None, "create_u_music_list_notify") get_playlist_processing(list, SoundList.LIST) return list @classmethod def create_manager_list(cls, creator, name, description, order): from common.processing import get_playlist_processing from logs.model.manage_audio import AudioManageLog if not order: order = 1 list = cls.objects.create(creator=creator,name=name,description=description,order=order) get_playlist_processing(list, SoundList.MANAGER) AudioManageLog.objects.create(item=self.pk, manager=creator.pk, action_type=AudioManageLog.LIST_CREATED) return list def edit_list(self, name, description, order, is_public): from common.processing import get_playlist_processing if not order: order = 1 self.name = name self.description = description self.order = order self.save() if is_public: get_playlist_processing(self, SoundList.LIST) self.make_publish() else: get_playlist_processing(self, SoundList.PRIVATE) self.make_private() return self def edit_manager_list(self, name, description, order, manager_id): from common.processing import get_playlist_processing from logs.model.manage_audio import AudioManageLog if not order: order = 1 self.name = name self.description = description self.order = order self.save() get_playlist_processing(self, SoundList.MANAGER) AudioManageLog.objects.create(item=self.pk, manager=manager_id, action_type=AudioManageLog.LIST_EDITED) return self
class Survey(models.Model): THIS_PROCESSING, MANAGER, PUBLISHED = '_PRO', 'PUB', 'MAN' THIS_DELETED, THIS_DELETED_MANAGER = '_DEL', '_DELM' THIS_CLOSED, THIS_CLOSED_MANAGER = '_CLO', '_CLOM' TYPE = ( (THIS_PROCESSING, 'Обработка'),(MANAGER, 'Созданный персоналом'),(PUBLISHED, 'Опубликовано'), (THIS_DELETED, 'Удалено'),(THIS_DELETED_MANAGER, 'Удален менеджерский'), (THIS_CLOSED, 'Закрыто модератором'),(THIS_CLOSED_MANAGER, 'Закрыт менеджерский'), ) title = models.CharField(max_length=250, verbose_name="Название") created = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Создан") creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='survey_creator', verbose_name="Создатель") is_anonymous = models.BooleanField(verbose_name="Анонимный", default=False) is_multiple = models.BooleanField(verbose_name="Несколько вариантов", default=False) is_no_edited = models.BooleanField(verbose_name="Запрет отмены голоса", default=False) order = models.PositiveSmallIntegerField(default=0, verbose_name="Порядковый номер") image = ProcessedImageField(verbose_name='Главное изображение', blank=True, format='JPEG',options={'quality': 90}, processors=[Transpose(), ResizeToFit(512,512)],upload_to=upload_to_user_directory) type = models.CharField(choices=TYPE, default=THIS_PROCESSING, max_length=5) time_end = models.DateTimeField(null=True, blank=True, verbose_name="Дата окончания") survey = models.ForeignKey(SurveyList, on_delete=models.CASCADE, related_name='survey_list', verbose_name="Список") community = models.ForeignKey('communities.Community', related_name='survey_community', on_delete=models.CASCADE, null=True, blank=True, verbose_name="Сообщество") is_survey = models.BooleanField(default=True) vote = models.PositiveIntegerField(default=0, verbose_name="Кол-во голосов") voter = models.PositiveIntegerField(default=0, verbose_name="Кол-во людей") repost = models.PositiveIntegerField(default=0, verbose_name="Кол-во репостов") class Meta: indexes = (BrinIndex(fields=['created']),) verbose_name = 'Опрос' verbose_name_plural = 'Опросы' def __str__(self): return self.title def get_lists(self): return self.list.all() def plus_reposts(self, count): self.repost += count return self.save(update_fields=['repost']) def minus_reposts(self, count): self.repost -= count return self.save(update_fields=['repost']) def plus_votes(self, count): self.vote += count return self.save(update_fields=['vote']) def minus_votes(self, count): self.vote -= count return self.save(update_fields=['vote']) def plus_voters(self, count): self.voter += count return self.save(update_fields=['voter']) def minus_voters(self, count): self.voter -= count return self.save(update_fields=['voter']) @classmethod def create_survey(cls, title, image, lists, creator, order, is_anonymous, is_multiple, is_no_edited, time_end, answers, community): from common.processing import get_survey_processing if not lists: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового документа") survey = cls.objects.create(title=title,image=image,creator=creator,order=order,is_anonymous=is_anonymous,is_multiple=is_multiple,is_no_edited=is_no_edited,time_end=time_end) for answer in answers: Answer.objects.create(survey=survey, text=answer) for list_id in lists: list = SurveyList.objects.get(pk=list_id) list.survey_list.add(survey) get_survey_processing(survey, Survey.PUBLISHED) if community: from common.notify.progs import community_send_notify, community_send_wall from notify.models import Notify, Wall community.plus_surveys(1) #Wall.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="SUR", object_id=survey.pk, verb="ITE") #community_send_wall(doc.pk, creator.pk, community.pk, None, "create_c_survey_wall") for user_id in community.get_member_for_notify_ids(): Notify.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="SUR", object_id=survey.pk, verb="ITE") community_send_notify(doc.pk, creator.pk, user_id, community.pk, None, "create_c_survey_notify") else: from common.notify.progs import user_send_notify, user_send_wall from notify.models import Notify, Wall creator.plus_surveys(1) #Wall.objects.create(creator_id=creator.pk, type="SUR", object_id=survey.pk, verb="ITE") #user_send_wall(survey.pk, None, "create_u_survey_wall") for user_id in creator.get_user_news_notify_ids(): Notify.objects.create(creator_id=creator.pk, recipient_id=user_id, type="SUR", object_id=survey.pk, verb="ITE") user_send_notify(survey.pk, creator.pk, user_id, None, "create_u_survey_notify") return survey @classmethod def create_manager_survey(cls, title, image, lists, creator, order, is_anonymous, is_multiple, is_no_edited, time_end, answers): from common.processing import get_survey_processing from logs.model.manage_survey import SurveyManageLog if not lists: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового элемента") survey = cls.objects.create(title=title,image=image,creator=creator,order=order,is_anonymous=is_anonymous,is_multiple=is_multiple,is_no_edited=is_no_edited,time_end=time_end) for list_id in lists: survey_list = SurveyList.objects.get(pk=list_id) survey_list.survey_list.add(survey) get_survey_processing(survey, Survey.MANAGER) from common.notify.progs import user_send_notify, user_send_wall #for user_id in creator.get_user_news_notify_ids(): # Notify.objects.create(creator_id=creator.pk, recipient_id=user_id, type="SUR", object_id=survey.pk, verb="ITE") # user_send_notify(survey.pk, creator.pk, user_id, None, "create_manager_survey_notify") SurveyManageLog.objects.create(item=self.pk, manager=creator.pk, action_type=SurveyManageLog.ITEM_CREATED) return survey def edit_survey(self, title, image, lists, order, is_anonymous, is_multiple, is_no_edited, time_end, answers): from common.processing import get_survey_processing get_survey_processing(self, Survey.PUBLISHED) self.title = title self.image = image self.lists = lists self.order = order self.is_anonymous = is_anonymous self.is_multiple = is_multiple self.is_no_edited = is_no_edited self.time_end = time_end self.save() if set(answers) != set(self.get_answers()): self.survey.all().delete() for answer in answers: Answer.objects.create(survey=survey, text=answer) return survey def edit_manager_survey(self, title, image, lists, order, is_anonymous, is_multiple, is_no_edited, time_end, answers, manager_id): from common.processing import get_survey_processing from logs.model.manage_survey import SurveyManageLog self.title = title self.image = image self.lists = lists self.order = order self.is_anonymous = is_anonymous self.is_multiple = is_multiple self.is_no_edited = is_no_edited self.time_end = time_end get_survey_processing(self, Survey.MANAGER) SurveyManageLog.objects.create(item=self.pk, manager=manager_id, action_type=SurveyManageLog.ITEM_EDITED) return self.save() def is_user_voted(self, user_id): return SurveyVote.objects.filter(answer__survey_id=self.pk, user_id=user_id).exists() def is_time_end(self): if self.time_end: from datetime import datetime now = datetime.now() return self.time_end < now else: return False def get_answers(self): return self.survey.only("text") def get_all_count(self): if self.vote > 0: return self.vote def get_users(self): from users.models import User voter_ids = SurveyVote.objects.filter(answer__survey_id=self.pk).values("user_id") return User.objects.filter(id__in=[i['user_id'] for i in voter_ids]) def get_6_users(self): from users.models import User voter_ids = SurveyVote.objects.filter(answer__survey_id=self.pk).values("user_id")[:6] return User.objects.filter(id__in=[i['user_id'] for i in voter_ids]) def is_have_votes(self): return SurveyVote.objects.filter(answer__survey_id=self.pk).values("id").exists() def delete_survey(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Survey.THIS_DELETED elif self.type == "MAN": self.type = Survey.THIS_DELETED_MANAGER self.save(update_fields=['type']) if community: community.minus_surveys(1) else: self.creator.minus_surveys(1) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") def restore_survey(self, community): from notify.models import Notify, Wall if self.type == "_DEL": self.type = Survey.PUBLISHED elif self.type == "_DELM": self.type = Survey.MANAGER self.save(update_fields=['type']) if community: community.plus_surveys(1) else: self.creator.plus_surveys(1) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") def close_item(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Survey.THIS_CLOSED elif self.type == "MAN": self.type = Survey.THIS_CLOSED_MANAGER self.save(update_fields=['type']) if community: community.minus_surveys(1) else: self.creator.minus_surveys(1) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") def abort_close_item(self, community): from notify.models import Notify, Wall if self.type == "_CLO": self.type = Survey.PUBLISHED elif self.type == "_CLOM": self.type = Survey.MANAGER self.save(update_fields=['type']) if community: community.plus_surveys(1) else: self.creator.plus_surveys(1) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") def get_lists(self): return self.list.all() def is_deleted(self): return self.type[:4] == "_DEL" def is_private(self): return False def is_closed(self): return self.type[:4] == "_CLO" def is_suspended(self): return False
class Image(models.Model): """ Images liées à un instrument. La variable MAX_PIXEL_WIDTH définie la largeur maximale en pixels qu'une image peut avoir. Une librairie javascript (filepond) s'occupe de faire le redimensionnement directement dans le naviguateur. """ MAX_PIXEL_WIDTH = 2000 image = models.ImageField( upload_to=chemin_image, help_text= "Taille maximale : 2 Mo. Les images doivent être libres de droits.") is_principale = models.BooleanField(default=False, editable=False) legende = models.CharField(verbose_name="Légende", max_length=400, null=True, blank=True) credit = models.CharField(verbose_name="Crédit", max_length=200, null=True, blank=True) order = models.IntegerField(default=0, verbose_name="Ordre d'affichage") # Champs automatiques thumbnail_principale = ProcessedImageField( upload_to=chemin_image, processors=[Transpose(), ResizeToFill(600, 450)], format='JPEG', options={'quality': 100}) thumbnail = ImageSpecField( source='image', processors=[Transpose(), ResizeToFill(600, 450)], format='JPEG', options={'quality': 100}) orgue = models.ForeignKey(Orgue, null=True, on_delete=models.CASCADE, related_name="images") user = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL) created_date = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name='Creation date') modified_date = models.DateTimeField(auto_now=True, auto_now_add=False, verbose_name='Update date') def save(self, *args, **kwargs): self.orgue.completion = self.orgue.calcul_completion() super().save(*args, **kwargs) def is_blackandwhite(self): """ Vérifie si une image est en noir et blanc en analysant la couleur de 100 pixels """ if not self.image: return img = PilImage.open(self.thumbnail.path) width, height = img.size for x in range(0, width, width // 10): for y in range(0, height, height // 10): r, g, b = img.getpixel((x, y)) if abs(r - g) > 30 or abs(g - b) > 30: return False return True def delete(self): if self.image: self.image.delete() self.thumbnail_principale.delete() return super().delete() class Meta: ordering = ['order', 'created_date']
class U24Thumbnail(ImageSpec): processors = [Transpose(), ResizeToFill(800, 600)] format = 'JPEG' options = {'quality': 80}
class PreviewThumbnail(ImageSpec): processors = [Transpose(), ResizeToFill(100, 100)] format = 'JPEG' options = {'quality': 80}
class Survey(models.Model): PUBLISHED = 'PUB' DELETED = '_DEL' CLOSED = '_CLO' TYPE = ( (PUBLISHED, 'Опубликовано'), (DELETED, 'Удалено'), (CLOSED, 'Закрыто модератором'), ) title = models.CharField(max_length=250, verbose_name="Название") created = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Создан") creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='survey_creator', verbose_name="Создатель") is_anonymous = models.BooleanField(verbose_name="Анонимный", default=False) is_multiple = models.BooleanField(verbose_name="Несколько вариантов", default=False) is_no_edited = models.BooleanField(verbose_name="Запрет отмены голоса", default=False) order = models.PositiveSmallIntegerField(default=0, verbose_name="Порядковый номер") image = ProcessedImageField( verbose_name='Главное изображение', blank=True, format='JPEG', options={'quality': 90}, processors=[Transpose(), ResizeToFit(512, 512)], upload_to=upload_to_user_directory) type = models.CharField(choices=TYPE, default=PUBLISHED, max_length=5) time_end = models.DateTimeField(null=True, blank=True, verbose_name="Дата окончания") list = models.ForeignKey(SurveyList, on_delete=models.CASCADE, related_name='survey_list', verbose_name="Список") community = models.ForeignKey('communities.Community', related_name='survey_community', on_delete=models.CASCADE, null=True, blank=True, verbose_name="Сообщество") vote = models.PositiveIntegerField(default=0, verbose_name="Кол-во голосов") repost = models.PositiveIntegerField(default=0, verbose_name="Кол-во репостов") copy = models.PositiveIntegerField(default=0, verbose_name="Кол-во копий") class Meta: indexes = (BrinIndex(fields=['created']), ) verbose_name = 'Опрос' verbose_name_plural = 'Опросы' ordering = ["-order"] def __str__(self): return self.title def get_time_description(self): if self.time_end: from datetime import datetime, timedelta if self.time_end < datetime.now(): return '<p class="small">Время опроса вышло.</p>' else: from django.contrib.humanize.templatetags.humanize import naturaltime return '<p class="small">Окончание опроса истекает ' + naturaltime( self.time_end) + "</p>" else: return '<p class="small">Бессрочный опрос.</p>' def is_can_edit(self): from datetime import datetime, timedelta return datetime.now() < self.created + timedelta(minutes=60) def get_code(self): return "sur" + str(self.pk) def is_survey(self): return True def get_image(self): if self.image: return self.image.url else: return '/static/images/no_img/list.jpg' def is_user_can_edit_delete_item(self, user): if self.community and user.is_staff_of_community(self.community.pk): return True elif self.creator.pk == user.pk or self.list.creator.pk == user.pk: return True return False def get_description(self): if self.community: return 'опрос сообщества <a href="' + self.community.get_link( ) + '" target="_blank">' + self.community.name + '</a>' else: return 'опрос <a href="' + self.creator.get_link( ) + '" target="_blank">' + self.creator.get_full_name_genitive( ) + '</a>' def change_position(query): for item in query: i = Survey.objects.get(pk=item['key']) i.order = item['value'] i.save(update_fields=["order"]) def count_reposts(self): count = self.repost + self.copy if count == 0: return '' else: return count def plus_reposts(self, count): self.repost += count return self.save(update_fields=['repost']) def minus_reposts(self, count): self.repost -= count return self.save(update_fields=['repost']) def plus_votes(self, count): self.vote += count return self.save(update_fields=['vote']) def minus_votes(self, count): self.vote -= count return self.save(update_fields=['vote']) @classmethod def create_survey(cls, title, list, image, creator, is_anonymous, is_multiple, is_no_edited, time_end, answers, community): list.count += 1 list.save(update_fields=["count"]) survey = cls.objects.create(title=title, order=list.count, list=list, image=image, creator=creator, is_anonymous=is_anonymous, is_multiple=is_multiple, is_no_edited=is_no_edited, time_end=time_end) answer_order = 0 for answer in answers: answer_order += 1 Answer.objects.create(survey=survey, text=answer, order=answer_order) if community: from common.notify.progs import community_send_notify, community_send_wall from notify.models import Notify, Wall Wall.objects.create(creator_id=creator.pk, community_id=community.pk, type="SUR", object_id=survey.pk, verb="ITE") community_send_wall(doc.pk, creator.pk, community.pk, None, "create_c_survey_wall") for user_id in community.get_member_for_notify_ids(): Notify.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="SUR", object_id=survey.pk, verb="ITE") community_send_notify(doc.pk, creator.pk, user_id, community.pk, None, "create_c_survey_notify") else: from common.notify.progs import user_send_notify, user_send_wall from notify.models import Notify, Wall Wall.objects.create(creator_id=creator.pk, type="SUR", object_id=survey.pk, verb="ITE") user_send_wall(survey.pk, None, "create_u_survey_wall") for user_id in creator.get_user_main_news_ids(): Notify.objects.create(creator_id=creator.pk, recipient_id=user_id, type="SUR", object_id=survey.pk, verb="ITE") user_send_notify(survey.pk, creator.pk, user_id, None, "create_u_survey_notify") return survey def edit_survey(self, title, image, is_anonymous, is_multiple, is_no_edited, time_end, answers): self.title = title self.image = image self.is_anonymous = is_anonymous self.is_multiple = is_multiple self.is_no_edited = is_no_edited self.time_end = time_end self.save() answer_order = 0 Answer.objects.filter(survey=self).delete() for answer in answers: answer_order += 1 Answer.objects.create(survey=self, text=answer, order=answer_order) return self def is_user_voted(self, user_id): return not self.is_time_end() and SurveyVote.objects.filter( answer__survey_id=self.pk, user_id=user_id).exists() def is_time_end(self): if self.time_end: from datetime import datetime now = datetime.now() return self.time_end < now else: return False def get_answers(self): return Answer.objects.filter(survey_id=self.pk) def get_answers_count(self): return self.get_answers().values("pk").count() def is_full_answers(self): return self.get_answers_count() > 9 def get_all_count(self): if self.vote > 0: return self.vote def get_users(self): from users.models import User voter_ids = SurveyVote.objects.filter( answer__survey_id=self.pk).values("user_id") return User.objects.filter(id__in=[i['user_id'] for i in voter_ids]) def get_users_ru(self): count = self.vote a = count % 10 b = count % 100 if (a == 1) and (b != 11): return "Проголосовал " + str(count) + " человек" elif (a >= 2) and (a <= 4) and ((b < 10) or (b >= 20)): return "Проголосовали " + str(count) + " человека" else: return "Проголосовали " + str(count) + " людей" def get_6_users(self): from users.models import User voter_ids = SurveyVote.objects.filter( answer__survey_id=self.pk).values("user_id")[:6] list = '<hr class="m-1">' for voter in User.objects.filter( id__in=[i['user_id'] for i in voter_ids]): list += '<a class="pr-1" href="' + voter.get_link( ) + '" target="_blank" tooltip="' + voter.get_full_name( ) + '" flow="up">' + voter.get_s_avatar() + '</a>' return list def is_have_votes(self): return SurveyVote.objects.filter( answer__survey_id=self.pk).values("id").exists() def delete_item(self): from notify.models import Notify, Wall self.type = Survey.DELETED self.save(update_fields=['type']) self.list.count -= 1 self.list.save(update_fields=["count"]) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") def restore_item(self): from notify.models import Notify, Wall self.type = Survey.PUBLISHED self.save(update_fields=['type']) self.list.count += 1 self.list.save(update_fields=["count"]) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") def close_item(self): from notify.models import Notify, Wall if self.type == "PUB": self.type = Survey.CLOSED self.save(update_fields=['type']) self.list.count -= 1 self.list.save(update_fields=["count"]) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="C") def abort_close_item(self): from notify.models import Notify, Wall if self.type == "TCLO": self.type = Survey.PUBLISHED self.save(update_fields=['type']) self.list.count += 1 self.list.save(update_fields=["count"]) if Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") if Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").exists(): Wall.objects.filter(type="SUR", object_id=self.pk, verb="ITE").update(status="R") def is_deleted(self): return self.type[:4] == "_DEL" def is_closed(self): return self.type[:4] == "_CLO" def is_open(self): return self.type[0] != "_" def votes_create(self, user, votes): import json from datetime import datetime from django.http import HttpResponse if (self.time_end and self.time_end < datetime.now()) or user.is_voted_of_survey( self.pk): return HttpResponse() data = [] self.vote += 1 self.save(update_fields=["vote"]) for answer_id in votes: answer = Answer.objects.get(pk=answer_id) SurveyVote.objects.create(answer_id=answer_id, user=user) answer.vote += 1 answer.save(update_fields=["vote"]) data.append( str(answer_id) + "," + str(answer.get_count()) + "," + str(answer.get_procent()) + ";") if self.community: from common.notify.notify import community_notify, community_wall community = self.community community_notify(user, community, None, self.pk, "SUR", "c_survey_vote_notify", "SVO") community_wall(user, community, None, self.pk, "SUR", "c_survey_vote_wall", "SVO") else: from common.notify.notify import user_notify, user_wall user_notify(user, None, self.pk, "SUR", "u_survey_vote_notify", "SVO") user_wall(user, None, self.pk, "SUR", "u_survey_vote_wall", "SVO") return HttpResponse(data) def votes_delete(self, user): from django.http import HttpResponse if not user.is_voted_of_survey(self.pk) or self.is_no_edited: return HttpResponse() self.vote -= 1 self.save(update_fields=["vote"]) data = [] for answer in self.get_answers(): if SurveyVote.objects.filter(answer_id=answer.pk, user=user).exists(): SurveyVote.objects.filter(answer_id=answer.pk, user=user).delete() try: answer.vote -= 1 answer.save(update_fields=["vote"]) except: pass data.append( str(answer.pk) + "," + str(answer.get_count()) + "," + str(answer.get_procent()) + ";") return HttpResponse(data)
class Elect(models.Model): SUGGESTED, PUBLISHED, DELETED_SUGGESTED, DELETED_PUBLISHED = 'SUG', 'PUB', 'DES', 'DEP' TYPE = ( (SUGGESTED, 'на рассмотрении'), (PUBLISHED, 'опубликован'), (DELETED_SUGGESTED, 'удален предложенный'), (DELETED_PUBLISHED, 'удален опубликованый'), ) name = models.CharField(max_length=255, verbose_name="ФИО") image = ProcessedImageField( format='JPEG', blank=True, options={'quality': 100}, upload_to="elect/%Y/%m/%d/", processors=[Transpose(), ResizeToFit(width=500, upscale=False)], verbose_name="Аватар") description = models.CharField(max_length=700, blank=True, verbose_name="Образование") list = models.ManyToManyField('lists.AuthorityList', blank=True, related_name='elect_list', verbose_name="Орган гос. власти") region = models.ManyToManyField( Region, blank=True, related_name='elect_region', verbose_name="Регионы, за которым закреплен депутат") birthday = models.CharField(max_length=100, blank=True, null=True, verbose_name='Дата рождения') authorization = models.CharField( max_length=100, blank=True, null=True, verbose_name='Дата наделения полномочиями') term_of_office = models.CharField(max_length=100, blank=True, null=True, verbose_name='Срок окончания полномочий') election_information = models.CharField( max_length=200, blank=True, verbose_name="Сведения об избрании") fraction = models.ForeignKey('lists.Fraction', blank=True, null=True, on_delete=models.SET_NULL, verbose_name="Фракции") is_active = models.BooleanField(default=True, verbose_name="Активный депутат") post_2 = models.CharField(max_length=400, blank=True, null=True, verbose_name='Должность') area = models.ManyToManyField( 'district.District2', blank=True, related_name='elect_area', verbose_name="Районы, за которым закреплен депутат") okrug = models.ForeignKey('okrug.Okrug', blank=True, null=True, on_delete=models.SET_NULL, verbose_name="Одномандатный избирательный округ") vk = models.CharField(max_length=500, blank=True, default="", verbose_name='Ссылка на VK') fb = models.CharField(max_length=500, blank=True, default="", verbose_name='Ссылка на Facebook') ig = models.CharField(max_length=500, blank=True, default="", verbose_name='Ссылка на Instagram') tg = models.CharField(max_length=500, blank=True, default="", verbose_name='Ссылка на Telegram') tw = models.CharField(max_length=500, blank=True, default="", verbose_name='Ссылка на Twitter') mail = models.CharField(max_length=500, blank=True, default="", verbose_name='Электронная почта') phone = models.CharField(max_length=100, blank=True, default="", verbose_name='Телефон') address = models.CharField(max_length=500, blank=True, default="", verbose_name='Адрес (приёмная)') i_address = models.CharField(max_length=500, blank=True, default="", verbose_name='Интернет-приёмная') site = models.CharField(max_length=500, blank=True, default="", verbose_name='Сайт') view = models.PositiveIntegerField(default=0, verbose_name="Кол-во просмотров") like = models.PositiveIntegerField(default=0, verbose_name="Кол-во лайков") dislike = models.PositiveIntegerField(default=0, verbose_name="Кол-во дизлайков") inert = models.PositiveIntegerField(default=0, verbose_name="Кол-во inert") repost = models.PositiveIntegerField(default=0, verbose_name="Кол-во репостов") old = models.BooleanField(default=False, verbose_name="Старый депутат") is_deleted = models.BooleanField(default=False, verbose_name="Удаленный депутат") type = models.CharField(choices=TYPE, default=PUBLISHED, max_length=5, verbose_name="Статус депутата") class Meta: verbose_name = "Чиновник" verbose_name_plural = "Чиновники" ordering = ["name"] def __str__(self): return self.name def vk_links(self): import re ids = re.findall(r'https?://[\S]+', self.vk) text = "" for i in ids: text += '<a target="_blank" href="' + i + '">' + i + "</a><br>" return text.replace(",", "") def fb_links(self): import re ids = re.findall(r'https?://[\S]+', self.fb) text = "" for i in ids: text += '<a target="_blank" href="' + i + '">' + i + "</a><br>" return text.replace(",", "") def ig_links(self): import re ids = re.findall(r'https?://[\S]+', self.ig) text = "" for i in ids: text += '<a target="_blank" href="' + i + '">' + i + "</a><br>" return text.replace(",", "") def tg_links(self): import re ids = re.findall(r'https?://[\S]+', self.tg) text = "" for i in ids: text += '<a target="_blank" href="' + i + '">' + i + "</a><br>" return text.replace(",", "") def tw_links(self): import re ids = re.findall(r'https?://[\S]+', self.tw) text = "" for i in ids: text += '<a target="_blank" href="' + i + '">' + i + "</a><br>" return text.replace(",", "") def is_have_year(self): return len(self.birthday) == 2 def calculate_age(self): from datetime import date today = date.today() return today.year - self.birthday.year - ( (today.month, today.day) < (self.birthday.month, self.birthday.day)) def count_regions(self): return self.region.count() def get_region_cities(self): return self.region.all()[0].get_cities() def get_region_districts(self): return self.region.all()[0].get_districts() def get_cities(self): return self.city.all() def get_districts(self): return self.area.all() @classmethod def create_elect(cls, creator, name, description, image, list, region, area, birthday, fraction, post_2, vk, tg, tw, ig, fb, mail, phone, i_address, address, site, type): from logs.model.manage_elect_new import ElectManageLog name_2 = name.replace(" ", " ").replace(" ", " ").replace( " ", " ").replace(" ", " ").replace("ё", "е").replace("Ё", "Е") elect = cls.objects.create(name=name_2, description=description, post_2=post_2, image=image, birthday=birthday, fraction=fraction, vk=vk, tg=tg, tw=tw, ig=ig, fb=fb, mail=mail, phone=phone, i_address=i_address, address=address, site=site, type=type) if region: from region.models import Region for region_id in region: a = Region.objects.get(pk=region_id) elect.region.add(a) if area: from district.models import District2 for district_id in area: a = District2.objects.get(pk=district_id) elect.area.add(a) if list: from lists.models import AuthorityList for list_id in list: a = AuthorityList.objects.get(pk=list_id) elect.list.add(a) ElectManageLog.objects.create(item=elect.pk, manager=creator.pk, action_type=ElectManageLog.ITEM_CREATED) return list def get_region(self): from district.models import District2 if self.region: return self.region.all() elif self.area: return 0 elif self.okrug: return self.okrug.region else: return [] def edit_elect(self, name, description, image, list, region, area, birthday, fraction, manager_id, post_2, vk, tg, tw, ig, fb, mail, phone, address, i_address, site): from logs.model.manage_elect_new import ElectManageLog name_2 = name.replace(" ", " ").replace(" ", " ").replace( " ", " ").replace(" ", " ").replace("ё", "е").replace("Ё", "Е") self.name = name_2 self.post_2 = post_2 self.description = description self.image = image self.birthday = birthday self.fraction = fraction self.vk = vk self.fb = fb self.tg = tg self.ig = ig self.tw = tw self.mail = mail self.phone = phone self.address = address self.i_address = i_address self.site = site self.save() self.region.clear() self.area.clear() self.list.clear() if region: from region.models import Region for region_id in region: a = Region.objects.get(pk=region_id) self.region.add(a) if area: from district.models import District2 for district_id in area: a = District2.objects.get(pk=district_id) self.area.add(a) if list: from lists.models import AuthorityList for list_id in list: a = AuthorityList.objects.get(pk=list_id) self.list.add(a) ElectManageLog.objects.create(item=self.pk, manager=manager_id, action_type=ElectManageLog.ITEM_EDITED) def get_region_image(self): return '/static/images/test_2.jpg' def get_image(self): if self.image: return self.image.url else: return '/static/images/elect_image.png' def get_first_list(self): try: return self.get_lists().last() except: return "" def get_lists(self): return self.list.all().order_by("order") def get_regions(self): regions = self.region.all() return regions def get_districts(self): regions = self.area.all() return regions def get_xxx(self): if self.get_regions(): return self.get_regions() elif self.get_districts(): return self.get_districts()[0].region.name elif self.okrug: return [self.okrug.region] def get_news(self): return self.new_elect.filter(type="PUB") def get_last_news(self): return self.new_elect.filter(type="PUB")[:6] def get_remote_image(self, image_url): import os from django.core.files import File from urllib import request result = request.urlretrieve(image_url) self.image.save(os.path.basename(image_url), File(open(result[0], 'rb'))) self.save() def visits_count(self): if self.view > 0: return self.view else: return '' def likes_count(self): if self.like > 0: return self.like else: return '' def dislikes_count(self): if self.dislike > 0: return self.dislike else: return '' def inerts_count(self): if self.inert > 0: return self.inert else: return '' def likes(self): from common.model.votes import ElectVotes return ElectVotes.objects.filter(elect_id=self.pk, vote="LIK") def dislikes(self): from common.model.votes import ElectVotes return ElectVotes.objects.filter(elect_id=self.pk, vote="DIS") def inerts(self): from common.model.votes import ElectVotes return ElectVotes.objects.filter(elect_id=self.pk, vote="INE") def is_have_likes(self): return self.like > 0 def is_have_dislikes(self): return self.dislike > 0 def is_have_inerts(self): return self.inert > 0 def get_avatar(self): try: return self.image.url except: return '/static/images/user.png' def get_subscribers_ids(self): from users.models import User subscribers = SubscribeElect.objects.filter( elect_id=self.pk).values("user_id") return [i['user_id'] for i in subscribers] def get_subscribers(self): from users.models import User return User.objects.filter(id__in=self.get_subscribers_ids()) def is_have_subscribers(self): from users.models import User subscribers = SubscribeElect.objects.filter( elect_id=self.pk).values("user_id") user_ids = [i['user_id'] for i in subscribers] return User.objects.filter(id__in=user_ids).exists() def send_like(self, user): import json from common.model.votes import ElectVotes from django.http import HttpResponse try: item = ElectVotes.objects.get(elect=self, user=user) if item.vote == ElectVotes.DISLIKE: item.vote = ElectVotes.LIKE item.save(update_fields=['vote']) self.like += 1 self.dislike -= 1 self.save(update_fields=['like', 'dislike']) elif item.vote == ElectVotes.INERT: item.vote = ElectVotes.LIKE item.save(update_fields=['vote']) self.inert -= 1 self.like += 1 self.save(update_fields=['inert', 'like']) else: item.delete() self.like -= 1 self.save(update_fields=['like']) except ElectVotes.DoesNotExist: ElectVotes.objects.create(elect=self, user=user, vote=ElectVotes.LIKE) self.like += 1 self.save(update_fields=['like']) #from common.notify.notify import user_notify, user_wall #user_notify(user, None, self.pk, "ELE", "u_elec_notify", "LIK", self.pk) #user_wall(user, None, self.pk, "ELE", "u_elec_notify", "LIK") return HttpResponse(json.dumps({ "like_count": str(self.likes_count()), "dislike_count": str(self.dislikes_count()), "inert_count": str(self.inerts_count()) }), content_type="application/json") def send_dislike(self, user): import json from common.model.votes import ElectVotes from django.http import HttpResponse try: item = ElectVotes.objects.get(elect=self, user=user) if item.vote == ElectVotes.LIKE: item.vote = ElectVotes.DISLIKE item.save(update_fields=['vote']) self.like -= 1 self.dislike += 1 self.save(update_fields=['like', 'dislike']) elif item.vote == ElectVotes.INERT: item.vote = ElectVotes.DISLIKE item.save(update_fields=['vote']) self.inert -= 1 self.dislike += 1 self.save(update_fields=['inert', 'dislike']) else: item.delete() self.dislike -= 1 self.save(update_fields=['dislike']) except ElectVotes.DoesNotExist: ElectVotes.objects.create(elect=self, user=user, vote=ElectVotes.DISLIKE) self.dislike += 1 self.save(update_fields=['dislike']) #from common.notify.notify import user_notify, user_wall #user_notify(user, None, self.pk, "ELE", "u_elec_notify", "DIS", self.pk) #user_wall(user, None, self.pk, "ELE", "u_elec_notify", "DIS") return HttpResponse(json.dumps({ "like_count": str(self.likes_count()), "dislike_count": str(self.dislikes_count()), "inert_count": str(self.inerts_count()) }), content_type="application/json") def send_inert(self, user): import json from common.model.votes import ElectVotes from django.http import HttpResponse try: item = ElectVotes.objects.get(elect=self, user=user) if item.vote == ElectVotes.LIKE: item.vote = ElectVotes.INERT item.save(update_fields=['vote']) self.like -= 1 self.inert += 1 self.save(update_fields=['like', 'inert']) elif item.vote == ElectVotes.DISLIKE: item.vote = ElectVotes.INERT item.save(update_fields=['vote']) self.inert += 1 self.dislike -= 1 self.save(update_fields=['inert', 'dislike']) else: item.delete() self.inert -= 1 self.save(update_fields=['inert']) except ElectVotes.DoesNotExist: ElectVotes.objects.create(elect=self, user=user, vote=ElectVotes.INERT) self.inert += 1 self.save(update_fields=['inert']) #from common.notify.notify import user_notify, user_wall #user_notify(user, None, self.pk, "ELE", "u_elec_notify", "INE", self.pk) #user_wall(user, None, self.pk, "ELE", "u_elec_notify", "INE") return HttpResponse(json.dumps({ "like_count": str(self.likes_count()), "dislike_count": str(self.dislikes_count()), "inert_count": str(self.inerts_count()) }), content_type="application/json") def is_user_voted(self, user_id): from common.model.votes import ElectRating return ElectRating.objects.filter(elect_id=self.id, user_id=user_id).exists() def get_rating_voters(self): from users.models import User from common.model.votes import ElectRating ids = ElectRating.objects.filter(elect_id=self.id).values("user_id") return User.objects.filter(id__in=[i['user_id'] for i in ids]) def get_ratings(self): from common.model.votes import ElectRating return ElectRating.objects.filter(elect_id=self.id) def get_rating_list(self): from common.model.votes import ElectRating from django.db.models import Avg query = ElectRating.objects.filter(elect_id=self.id) vakcine = query.aggregate(Avg('vakcine'))['vakcine__avg'] pp_825 = query.aggregate(Avg('pp_825'))['pp_825__avg'] safe_family = query.aggregate(Avg('safe_family'))['safe_family__avg'] pro_life = query.aggregate(Avg('pro_life'))['pro_life__avg'] free_vacation = query.aggregate( Avg('free_vacation'))['free_vacation__avg'] query = [vakcine, pp_825, safe_family, pro_life, free_vacation] total = avg = sum(query) / len(query) query += [total] return query def get_vakcine_double(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<td style="background:#FFEB84;text-align: right;"><span>0</span></td>' else: from django.db.models import Avg _double = ElectRating.objects.filter(elect_id=self.id).aggregate( Avg('vakcine')) double = round(_double['vakcine__avg'], 1) if double < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<td style="background:' + color + ';text-align: right;"><span>' + str( double) + '</span></td>' def get_pp_825_double(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<td style="background:#FFEB84;text-align: right;"><span>0</span></td>' else: from django.db.models import Avg _double = ElectRating.objects.filter(elect_id=self.id).aggregate( Avg('pp_825')) double = round(_double['pp_825__avg'], 1) if double < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<td style="background:' + color + ';text-align: right;"><span>' + str( double) + '</span></td>' def get_safe_family_double(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<td style="background:#FFEB84;text-align: right;"><span>0</span></td>' else: from django.db.models import Avg _double = ElectRating.objects.filter(elect_id=self.id).aggregate( Avg('safe_family')) double = round(_double['safe_family__avg'], 1) if double < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<td style="background:' + color + ';text-align: right;"><span>' + str( double) + '</span></td>' def get_pro_life_double(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<td style="background:#FFEB84;text-align: right;"><span>0</span></td>' else: from django.db.models import Avg _double = ElectRating.objects.filter(elect_id=self.id).aggregate( Avg('pro_life')) double = round(_double['pro_life__avg'], 1) if double < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<td style="background:' + color + ';text-align: right;"><span>' + str( double) + '</span></td>' def get_free_vacation_double(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<td style="background:#FFEB84;text-align: right;"><span>0</span></td>' else: from django.db.models import Avg _double = ElectRating.objects.filter(elect_id=self.id).aggregate( Avg('free_vacation')) double = round(_double['free_vacation__avg'], 1) if double < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<td style="background:' + color + ';text-align: right;"><span>' + str( double) + '</span></td>' def get_total_rating_double(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<td style="background:#FFEB84;text-align: right;"><span>0</span></td>' else: from django.db.models import Avg query = ElectRating.objects.filter(elect_id=self.id) vakcine = query.aggregate(Avg('vakcine'))['vakcine__avg'] pp_825 = query.aggregate(Avg('pp_825'))['pp_825__avg'] safe_family = query.aggregate( Avg('safe_family'))['safe_family__avg'] pro_life = query.aggregate(Avg('pro_life'))['pro_life__avg'] free_vacation = query.aggregate( Avg('free_vacation'))['free_vacation__avg'] list = [vakcine, pp_825, safe_family, pro_life, free_vacation] avg = sum(list) / len(list) double = round(avg, 1) if double < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<td style="background:' + color + ';text-align: right;"><span>' + str( double) + '</span></td>' def get_manager_total_rating_double(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<td style="background:#FFEB84;text-align: center;"><span>0</span></td>' else: from django.db.models import Avg query = ElectRating.objects.filter(elect_id=self.id) vakcine = query.aggregate(Avg('vakcine'))['vakcine__avg'] pp_825 = query.aggregate(Avg('pp_825'))['pp_825__avg'] safe_family = query.aggregate( Avg('safe_family'))['safe_family__avg'] pro_life = query.aggregate(Avg('pro_life'))['pro_life__avg'] free_vacation = query.aggregate( Avg('free_vacation'))['free_vacation__avg'] list = [vakcine, pp_825, safe_family, pro_life, free_vacation] avg = sum(list) / len(list) double = round(avg, 1) if avg < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<td style="background:' + color + ';text-align: center;"><span>' + str( double) + '</span></td>' def get_total_rating_icon(self): from common.model.votes import ElectRating if not ElectRating.objects.filter(elect_id=self.id).exists(): return '<span class="elect_rating_icon"><span class="integer">0</span><svg fill="#FFEB84" enable-background="new 0 0 20 20" width="24" height="24" viewBox="0 0 24 24"><g><rect x="0"></rect><polygon points="14.43,10 12,2 9.57,10 2,10 8.18,14.41 5.83,22 12,17.31 18.18,22 15.83,14.41 22,10"></polygon></g></svg></span>' else: from django.db.models import Avg query = ElectRating.objects.filter(elect_id=self.id) vakcine = query.aggregate(Avg('vakcine'))['vakcine__avg'] pp_825 = query.aggregate(Avg('pp_825'))['pp_825__avg'] safe_family = query.aggregate( Avg('safe_family'))['safe_family__avg'] pro_life = query.aggregate(Avg('pro_life'))['pro_life__avg'] free_vacation = query.aggregate( Avg('free_vacation'))['free_vacation__avg'] list = [vakcine, pp_825, safe_family, pro_life, free_vacation] avg = sum(list) / len(list) double = round(avg, 1) if double < -2: color = "#FA9D75" elif -3 < double < -1: color = "#FCB77A" elif -2 < double < 0: color = "#FDD17F" elif -1 < double < 1: color = "#FFEB84" elif 0 < double < 2: color = "#E0E383" elif 1 < double < 3: color = "#C1DA81" else: color = "#A2D07F" return '<span class="elect_rating_icon"><span class="integer">' + str( double ) + '</span><svg fill="' + color + '" enable-background="new 0 0 20 20" width="24" height="24" viewBox="0 0 24 24"><g><rect x="0"></rect><polygon points="14.43,10 12,2 9.57,10 2,10 8.18,14.41 5.83,22 12,17.31 18.18,22 15.83,14.41 22,10"></polygon></g></svg></span>'
class Music(models.Model): PROCESSING, PUBLISHED, PRIVATE, MANAGER, DELETED, CLOSED = '_PRO','PUB','PRI', 'MAN', '_DEL', '_CLO' DELETED_PRIVATE, DELETED_MANAGER, CLOSED_PRIVATE, CLOSED_MANAGER = '_DELP', '_DELM', '_CLOP', '_CLOM' TYPE = ( (PROCESSING, 'Обработка'),(PUBLISHED, 'Опубликовано'),(DELETED, 'Удалено'),(PRIVATE, 'Приватно'),(CLOSED, 'Закрыто модератором'),(MANAGER, 'Созданный персоналом'), (DELETED_PRIVATE, 'Удалённый приватный'),(DELETED_MANAGER, 'Удалённый менеджерский'),(CLOSED_PRIVATE, 'Закрытый приватный'),(CLOSED_MANAGER, 'Закрытый менеджерский'), ) artwork_url = ProcessedImageField(format='JPEG', blank=True, options={'quality': 100}, upload_to=upload_to_music_directory, processors=[Transpose(), ResizeToFit(width=100, height=100)]) file = models.FileField(upload_to=upload_to_music_directory, validators=[validate_file_extension], verbose_name="Аудиозапись") created = models.DateTimeField(default=timezone.now) duration = models.CharField(max_length=255, blank=True, null=True) description = models.CharField(max_length=500, blank=True, null=True) title = models.CharField(max_length=255, blank=True, null=True) uri = models.CharField(max_length=255, blank=True, null=True) list = models.ManyToManyField(SoundList, related_name='playlist', blank=True) media_list = models.ManyToManyField("lists.MediaList", related_name='media_playlist', blank=True, verbose_name="Медиа-список") type = models.CharField(max_length=5, choices=TYPE, default=PROCESSING, verbose_name="Тип") creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, db_index=False, on_delete=models.CASCADE, verbose_name="Создатель") community = models.ForeignKey('communities.Community', related_name='track_community', on_delete=models.CASCADE, null=True, blank=True, verbose_name="Сообщество") is_track = models.BooleanField(default=True) def __str__(self): return self.title class Meta: verbose_name = "треки" verbose_name_plural = "треки" indexes = (BrinIndex(fields=['created']),) ordering = ['-created'] def get_lists(self): return self.list.all() def get_media_lists(self): return self.media_list.all() def is_item_in_user_media_list(self, user_id): from lists.models import MediaList if MediaList.objects.filter(owner_id=user_id).exists(): list = MediaList.objects.filter(owner_id=user_id)[0] return list.is_track_in_list(self.pk) return False def get_mp3(self): url = self.uri + '/stream?client_id=3ddce5652caa1b66331903493735ddd64d' url.replace("\\?", "%3f") url.replace("=", "%3d") return url def get_uri(self): if self.file: return self.file.url else: return self.uri def get_duration(self): if self.duration: return self.duration else: return 0 def get_remote_image(self, image_url): import os from django.core.files import File from urllib import request result = request.urlretrieve(image_url) self.artwork_url.save( os.path.basename(image_url), File(open(result[0], 'rb')) ) self.save() def make_private(self): from notify.models import Notify, Wall self.type = Music.PRIVATE self.save(update_fields=['type']) if Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="C") def make_publish(self): from notify.models import Notify, Wall self.type = Music.PUBLISHED self.save(update_fields=['type']) if Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="R") def is_private(self): return self.type == self.PRIVATE @classmethod def create_track(cls, creator, title, file, lists, is_public, community): from common.processing import get_music_processing if not lists: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового документа") private = 0 track = cls.objects.create(creator=creator,title=title,file=file) if community: community.plus_tracks(1) else: creator.plus_tracks(1) for list_id in lists: track_list = SoundList.objects.get(pk=list_id) track_list.playlist.add(track) if track_list.is_private(): private = 1 if not private and is_public: get_music_processing(track, Music.PUBLISHED) if community: from common.notify.progs import community_send_notify, community_send_wall from notify.models import Notify, Wall #Wall.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="MUS", object_id=track.pk, verb="ITE") #community_send_wall(track.pk, creator.pk, community.pk, None, "create_c_track_wall") for user_id in community.get_member_for_notify_ids(): Notify.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="MUS", object_id=track.pk, verb="ITE") community_send_notify(track.pk, creator.pk, user_id, community.pk, None, "create_c_track_notify") else: from common.notify.progs import user_send_notify, user_send_wall from notify.models import Notify, Wall #Wall.objects.create(creator_id=creator.pk, type="MUS", object_id=track.pk, verb="ITE") #user_send_wall(track.pk, None, "create_u_track_wall") for user_id in creator.get_user_news_notify_ids(): Notify.objects.create(creator_id=creator.pk, recipient_id=user_id, type="MUS", object_id=track.pk, verb="ITE") user_send_notify(track.pk, creator.pk, user_id, None, "create_u_track_notify") else: get_music_processing(track, Music.PRIVATE) return track @classmethod def create_manager_track(cls, creator, title, file, lists): from common.processing import get_music_processing from logs.model.manage_audio import AudioManageLog from lists.models import MediaList if not lists: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового элемента") track = cls.objects.create(creator=creator,title=title,file=file) for list_id in lists: list = MediaList.objects.get(pk=list_id) track.media_list.add(list) list.count += 1 list.save(update_fields=["count"]) get_music_processing(track, Music.MANAGER) AudioManageLog.objects.create(item=track.pk, manager=creator.pk, action_type=AudioManageLog.ITEM_CREATED) return track def edit_track(self, title, file, lists, is_public): from common.processing import get_music_processing if not lists: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового элемента") self.title = title self.file = file self.lists = lists if is_public: get_music_processing(self, Music.PUBLISHED) self.make_publish() else: get_music_processing(self, Music.PRIVATE) self.make_private() return self.save() def edit_manager_track(self, title, file, lists, manager_id): from common.processing import get_track_processing from logs.model.manage_track import AudioManageLog self.title = title self.file = file self.lists = lists get_track_processing(self, Music.MANAGER) AudioManageLog.objects.create(item=self.pk, manager=manager_id, action_type=AudioManageLog.ITEM_EDITED) return self.save() def delete_track(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Music.DELETED elif self.type == "PRI": self.type = Music.DELETED_PRIVATE elif self.type == "MAN": self.type = Music.DELETED_MANAGER self.save(update_fields=['type']) if community: community.minus_tracks(1) else: self.creator.minus_tracks(1) if Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="C") def abort_delete_track(self, community): from notify.models import Notify, Wall if self.type == "_DEL": self.type = Music.PUBLISHED elif self.type == "_DELP": self.type = Music.PRIVATE elif self.type == "_DELM": self.type = Music.MANAGER self.save(update_fields=['type']) if community: community.plus_tracks(1) else: self.creator.plus_tracks(1) if Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="R") def close_item(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Music.CLOSED elif self.type == "PRI": self.type = Music.CLOSED_PRIVATE elif self.type == "MAN": self.type = Music.CLOSED_MANAGER self.save(update_fields=['type']) if community: community.minus_tracks(1) else: self.creator.minus_tracks(1) if Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="C") def abort_close_item(self, community): from notify.models import Notify, Wall if self.type == "_CLO": self.type = Music.PUBLISHED elif self.type == "_CLOP": self.type = Music.PRIVATE elif self.type == "_CLOM": self.type = Music.MANAGER self.save(update_fields=['type']) if community: community.plus_tracks(1) else: self.creator.plus_tracks(1) if Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="MUS", object_id=self.pk, verb="ITE").update(status="R") def get_lists(self): return self.list.all() def is_private(self): return self.type == self.PRIVATE def is_open(self): return self.type == self.MANAGER or self.type == self.PUBLISHED def is_deleted(self): return self.type[:4] == "_DEL" def is_closed(self): return self.type[:4] == "_CLO" def is_suspended(self): return False
def generate_image(source, outname, settings, options=None): """Image processor, rotate and resize the image. :param source: path to an image :param outname: output filename :param settings: settings dict :param options: dict with PIL options (quality, optimize, progressive) """ logger = logging.getLogger(__name__) if settings['use_orig'] or source.endswith('.gif'): utils.copy(source, outname, symlink=settings['orig_link']) return img = _read_image(source) original_format = img.format if settings['copy_exif_data'] and settings['autorotate_images']: logger.warning("The 'autorotate_images' and 'copy_exif_data' settings " "are not compatible because Sigal can't save the " "modified Orientation tag.") # Preserve EXIF data if settings['copy_exif_data'] and _has_exif_tags(img): if options is not None: options = deepcopy(options) else: options = {} options['exif'] = img.info['exif'] # Rotate the img, and catch IOError when PIL fails to read EXIF if settings['autorotate_images']: try: img = Transpose().process(img) except (OSError, IndexError): pass # Resize the image if settings['img_processor']: try: logger.debug('Processor: %s', settings['img_processor']) processor_cls = getattr(pilkit.processors, settings['img_processor']) except AttributeError: logger.error('Wrong processor name: %s', settings['img_processor']) sys.exit() width, height = settings['img_size'] if img.size[0] < img.size[1]: # swap target size if image is in portrait mode height, width = width, height processor = processor_cls(width, height, upscale=False) img = processor.process(img) # signal.send() does not work here as plugins can modify the image, so we # iterate other the receivers to call them with the image. for receiver in signals.img_resized.receivers_for(img): img = receiver(img, settings=settings) # first, use hard-coded output format, or PIL format, or original image # format, or fall back to JPEG outformat = (settings.get('img_format') or img.format or original_format or 'JPEG') logger.debug('Save resized image to %s (%s)', outname, outformat) save_image(img, outname, outformat, options=options, autoconvert=True)
class Team(models.Model): name = models.CharField(verbose_name=_('team name'), max_length=255) status = models.CharField(verbose_name=_('team status'), choices=TEAM_STATUSES, max_length=30, default=TEAM_STATUS_ACTIVE) team_picture = ProcessedImageField(verbose_name=_('profile picture'), upload_to=partial(get_file_path, path='team/'), null=True, blank=True, processors=[ Transpose(Transpose.AUTO), SmartResize(PROFILE_PICTURE_WIDTH, PROFILE_PICTURE_HEIGHT), ], options={'quality': 100}) tagline = models.TextField(verbose_name=_('team tagline'), max_length=500, blank=True) location = models.CharField(verbose_name=_('team location'), max_length=255, blank=True) season = models.CharField(verbose_name=_('season'), max_length=25, blank=True) owner = models.ForeignKey(BaseCustomUser, related_name='team_ownership') sport = models.ForeignKey(Sport) athletes = models.ManyToManyField(AthleteUser, related_name='team_membership') coaches = models.ManyToManyField(CoachUser, related_name='team_membership') date_created = models.DateField(verbose_name=_('date created'), default=timezone.now) is_private = models.BooleanField(verbose_name=_('is private'), default=False, blank=True) organisation = models.ForeignKey(Organisation, verbose_name=_('organisation'), null=True, blank=True, related_name='teams') assessments = models.ManyToManyField('multidb_account.Assessment', verbose_name=_('private assessments'), related_name='teams') def __str__(self): return self.name def add_baseuser(self, base_user): if base_user.user_type == USER_TYPE_COACH: self.coaches.add(base_user.typeduser) if base_user.user_type == USER_TYPE_ATHLETE: self.athletes.add(base_user.typeduser) def get_all_coaches(self): return list(self.coaches.all()) def get_all_athletes(self): return list(self.athletes.all()) def get_all_members(self): return self.get_all_athletes() + self.get_all_coaches() def has_team_member(self, user: CoachUser or AthleteUser): return user in self.get_all_members()
class MobileSpec(ImageSpec): format = 'JPEG' options = {'quality': 80} processors = [Transpose(Transpose.AUTO), ResizeToFit(900, 900)]
class BaseCustomUser(AbstractBaseUser, PermissionsMixin): # Required fields email = models.EmailField(verbose_name=_('email address'), max_length=255, unique=True) country = models.CharField(verbose_name=_('country iso code'), max_length=7) # Optional fields province_or_state = models.CharField(verbose_name=_('province or state'), max_length=64, blank=True) city = models.CharField(verbose_name=_('city'), max_length=64, blank=True) first_name = models.CharField(verbose_name=_('first name'), max_length=128) last_name = models.CharField(verbose_name=_('last name'), max_length=128) date_of_birth = models.DateField(verbose_name=_('date of birth'), null=True, blank=True) newsletter = models.BooleanField(verbose_name=_('newsletter opt-in'), default=False) terms_conditions = models.BooleanField( verbose_name=_('terms and conditions agreement'), default=False) measuring_system = models.CharField( verbose_name=_('preferred measurind system'), choices=MEASURING, max_length=30, default='metric') profile_picture = ProcessedImageField(verbose_name=_('profile picture'), upload_to=partial(get_file_path, path='profile/'), null=True, blank=True, processors=[ Transpose(Transpose.AUTO), SmartResize( PROFILE_PICTURE_WIDTH, PROFILE_PICTURE_HEIGHT), ], options={'quality': 100}) tagline = models.TextField(verbose_name=_('tagline'), max_length=500, blank=True) is_active = models.BooleanField(verbose_name=_('active'), default=True) is_staff = models.BooleanField(verbose_name=_('staff status'), default=False) is_admin = models.BooleanField(verbose_name=_('superuser'), default=False) jwt_last_expired = models.DateTimeField(default=timezone.now) user_type = models.CharField(verbose_name=_('user type'), choices=USER_TYPES, max_length=50, default=USER_TYPE_ATHLETE) date_joined = models.DateTimeField(verbose_name=_('date joined'), default=timezone.now) phone_regex = RegexValidator( regex=r'^\+?1?\d{9,15}$', message= _('Phone number must be 9 to 15 digits entered in the format "+999999999" where "+" is optional' )) phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True) new_dashboard = models.BooleanField(verbose_name=_('new dashboard'), default=False) objects = CustomUserManager() def __unicode__(self): return self.email def __str__(self): return '%s %s <%s>' % (self.first_name, self.last_name, self.email) EMAIL_FIELD = 'email' USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['country'] class Meta: verbose_name = _('user') verbose_name_plural = _('users') @property def profile_complete(self): """Return the profile complete status.""" if self.user_type == USER_TYPE_ORG: return True return self.email and \ self.country and \ self.user_type and \ self.province_or_state and \ self.city and \ self.first_name and \ self.last_name and \ self.date_of_birth and \ self.terms_conditions and \ self.tagline def get_full_name(self): """Return the email.""" return self.email def get_short_name(self): """Return the email.""" return self.email def set_jwt_last_expired(self): self.jwt_last_expired = timezone.now() def deactivate(self): # Deactivate all JWT tokens self.set_jwt_last_expired() # Disable user self.is_active = False self.save() @property def typeduser(self): """ Returns typed instance of the user """ if self.user_type == USER_TYPE_ATHLETE: return self.athleteuser if self.user_type == USER_TYPE_COACH: return self.coachuser if self.user_type == USER_TYPE_ORG: return self.organisation def is_athlete(self): """ Get the user's assessor profile extension """ return self.user_type == USER_TYPE_ATHLETE def is_coach(self): """ Get the user's assessor profile extension """ return self.user_type == USER_TYPE_COACH def is_organisation(self): return self.user_type == USER_TYPE_ORG def get_assessor(self): """ Get the user's assessor profile extension """ return self.typeduser.assessor def get_assessed(self): """ Get the user's assessed profile extension """ return self.typeduser.assessed def is_connected_to(self, other_user_id): if self.user_type == USER_TYPE_ATHLETE: # Check if athlete is directly connected (Coaching) or connected through teams (Team) return self.athleteuser.coaching_set.filter(coach_id=other_user_id).exists() or \ self.athleteuser.team_membership.filter(coaches__user__id=other_user_id).exists() or \ self.athleteuser.team_membership.filter(owner_id=other_user_id) if self.user_type == USER_TYPE_COACH: # Check if coach is directly connected (Coaching) or connected through teams (Team) return self.coachuser.coaching_set.filter(athlete_id=other_user_id).exists() or \ self.team_ownership.filter(athletes__user__id=other_user_id).exists() or \ self.coachuser.team_membership.filter(athletes__user__id=other_user_id).exists() if self.user_type == USER_TYPE_ORG: # Check if organisation is directly connected or connected through teams return self.team_ownership.filter(athletes__user__id=other_user_id).exists() or \ self.organisation.teams.filter(athletes__user__id=other_user_id).exists() or \ self.organisation.teams.filter(coaches__user__id=other_user_id).exists() def delete_all_connections(self): # Delete all user's connections self.typeduser.assessed.delete_all_assessment_permissions() self.typeduser.assessor.delete_all_assessment_permissions() self.typeduser.coaching_set.all().delete() return True def send_welcome_email(self): context = { 'app_site': django_settings.PSR_APP_BASE_URL, 'api_site': django_settings.PSR_API_BASE_URL, 'user': self, # 'secure': self.request.is_secure(), } msg_plain = loader.render_to_string( django_settings.WELCOME_EMAIL_TEMPLATE + '.txt', context) msg_html = loader.render_to_string( django_settings.WELCOME_EMAIL_TEMPLATE + '.html', context) subject = _("Welcome to Personal Sport Record") send_mail(subject, msg_plain, django_settings.DEFAULT_FROM_EMAIL, [self.email], html_message=msg_html) def send_confirm_account_email(self): data = { 'user_id': self.id, 'localized_db': self.country, } context = { 'app_site': django_settings.PSR_APP_BASE_URL, 'api_site': django_settings.PSR_API_BASE_URL, 'confirm_account_path': django_settings.PSR_APP_CONFIRM_ACCOUNT_PATH, 'user': self, 'token': signing.dumps(data, salt=USER_CONFIRM_ACCOUNT_SALT), # 'secure': self.request.is_secure(), } msg_plain = loader.render_to_string( django_settings.CONFIRM_ACCOUNT_EMAIL_TEMPLATE + '.txt', context) msg_html = loader.render_to_string( django_settings.CONFIRM_ACCOUNT_EMAIL_TEMPLATE + '.html', context) subject = _("Confirm the email of your Personal Sport Record account") send_mail(subject, msg_plain, django_settings.DEFAULT_FROM_EMAIL, [self.email], html_message=msg_html) def get_linked_users(self): if self.user_type == USER_TYPE_ATHLETE: coaches = [] # one to one connections coaches.extend(list(self.athleteuser.coaches.all())) # connections through teams for team in self.athleteuser.team_membership.all(): coaches.extend(team.get_all_coaches()) return set(coaches) elif self.user_type == USER_TYPE_COACH: athletes = [] # one to one connections athletes.extend(list(self.coachuser.athleteuser_set.all())) # connections through teams for team in (self.coachuser.team_membership.all() | self.team_ownership.all()).distinct(): athletes.extend(team.get_all_athletes()) return set(athletes) @cached_property def organisation(self): return self.organisations.first()
class UserProfile(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True) name = models.CharField(max_length=255, blank=True) avatar = ProcessedImageField(upload_to=RandomFileName('avatars/'), processors=[Transpose(Transpose.AUTO)], format='JPEG', options={'quality': 100}, blank=True) avatar_icon = ImageSpecField(source='avatar', processors=[ResizeToFill(50, 50)], format='JPEG', options={'quality': 75}) avatar_thumbnail = ImageSpecField(source='avatar', processors=[ResizeToFill(250, 250)], format='JPEG', options={'quality': 100}) mobile = models.CharField(max_length=16, unique=True, blank=True, null=True) address = models.CharField(max_length=100, blank=True) city = models.CharField(max_length=50, blank=True) state = models.CharField(max_length=2, choices=STATE_CHOICES, default='-') zip = models.CharField(max_length=10, blank=True) car_make = models.CharField(max_length=50, blank=True) car_model = models.CharField(max_length=50, blank=True) car_year = models.CharField(max_length=4, blank=True) review_points = models.PositiveIntegerField(default=0, blank=False) is_mechanic = models.BooleanField(default=False, blank=False) mobile_verified = models.BooleanField(default=False, blank=False) short_bio = models.TextField(max_length=160, blank=True) add_info = models.TextField(max_length=1000, blank=True) skills = models.ManyToManyField(SkillChoice) profile_complete = models.BooleanField(default=False, blank=False) publish = models.BooleanField(default=False, blank=False) project_limit = models.PositiveIntegerField(default=9, blank=False) rating = models.PositiveSmallIntegerField(default=0, blank=False) rating_count = models.PositiveIntegerField(default=0, blank=False) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) updated = models.DateTimeField(auto_now_add=False, auto_now=True) def __str__(self): return "%s's profile" % self.user def save(self, url='', *args, **kwargs): if self.avatar == '' and url != '': image = download_image(url) try: filename = urllib.parse.urlparse(url).path.split('/')[-1] self.avatar = filename tempfile = image tempfile_io = BytesIO() tempfile.save(tempfile_io, format=image.format) self.avatar.save(filename, ContentFile(tempfile_io.getvalue()), save=False) except Exception: print("Error trying to save model: saving image failed: " + str(Exception)) pass super(UserProfile, self).save(*args, **kwargs)
class Photo(models.Model): PROCESSING, PUBLISHED, PRIVATE, MANAGER, DELETED, CLOSED = '_PRO', 'PUB', 'PRI', 'MAN', '_DEL', '_CLO' DELETED_PRIVATE, DELETED_MANAGER, CLOSED_PRIVATE, CLOSED_MANAGER = '_DELP', '_DELM', '_CLOP', '_CLOM' TYPE = ( (PROCESSING, 'Обработка'), (PUBLISHED, 'Опубликовано'), (DELETED, 'Удалено'), (PRIVATE, 'Приватно'), (CLOSED, 'Закрыто модератором'), (MANAGER, 'Созданный персоналом'), (DELETED_PRIVATE, 'Удалённый приватный'), (DELETED_MANAGER, 'Удалённый менеджерский'), (CLOSED_PRIVATE, 'Закрытый приватный'), (CLOSED_MANAGER, 'Закрытый менеджерский'), ) uuid = models.UUIDField(default=uuid.uuid4, verbose_name="uuid") list = models.ManyToManyField(PhotoList, related_name="photo_list", blank=True) media_list = models.ManyToManyField("lists.MediaList", related_name='photo_media_list', blank=True, verbose_name="Медиа-список") file = ProcessedImageField( format='JPEG', options={'quality': 100}, upload_to=upload_to_photo_directory, processors=[Transpose(), ResizeToFit(width=1024, upscale=False)]) preview = ProcessedImageField( format='JPEG', options={'quality': 60}, upload_to=upload_to_photo_directory, processors=[Transpose(), ResizeToFit(width=102, upscale=False)]) created = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Создано") creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='photo_creator', null=False, blank=False, verbose_name="Создатель") type = models.CharField(max_length=6, choices=TYPE, default=PROCESSING, verbose_name="Тип изображения") community = models.ForeignKey('communities.Community', related_name='photo_community', on_delete=models.CASCADE, null=True, blank=True, verbose_name="Сообщество") is_photo = models.BooleanField(default=True) class Meta: indexes = (BrinIndex(fields=['created']), ) verbose_name = 'Фото' verbose_name_plural = 'Фото' ordering = ["-created"] def get_mime_type(self): import magic file = self.file initial_pos = file.tell() file.seek(0) mime_type = magic.from_buffer(file.read(1024), mime=True) file.seek(initial_pos) return mime_type def get_lists(self): return self.list.all() def get_media_lists(self): return self.media_list.all() def is_item_in_user_media_list(self, user_id): from lists.models import MediaList if MediaList.objects.filter(owner_id=user_id).exists(): list = MediaList.objects.filter(owner_id=user_id)[0] return list.is_photo_in_list(self.pk) return False def get_list_uuid(self): return self.list.all()[0].uuid def get_media_list_uuid(self): return self.media_list.all()[0].uuid def get_created(self): from django.contrib.humanize.templatetags.humanize import naturaltime return naturaltime(self.created) @classmethod def create_photo(cls, creator, image, list): from common.processing import get_photo_processing photo = cls.objects.create(creator=creator, preview=image, file=image) list.photo_list.add(photo) if list.community: list.community.plus_photos(1) else: creator.plus_photos(1) if not list.is_private(): get_photo_processing(photo, Photo.PUBLISHED) if list.community: from common.notify.progs import community_send_notify, community_send_wall from notify.models import Notify, Wall community_id = community.pk #Wall.objects.create(creator_id=creator.pk, community_id=community_id, recipient_id=user_id, type='PHO', object_id=photo.pk, verb="ITE") #community_send_wall(photo.pk, creator.pk, community_id, None, "create_c_photo_wall") for user_id in list.community.get_member_for_notify_ids(): Notify.objects.create(creator_id=creator.pk, community_id=community_id, recipient_id=user_id, type='PHO', object_id=photo.pk, verb="ITE") community_send_notify(photo.pk, creator.pk, user_id, community_id, None, "create_c_photo_notify") else: from common.notify.progs import user_send_notify, user_send_wall from notify.models import Notify, Wall #Wall.objects.create(creator_id=creator.pk, type='PHO', object_id=photo.pk, verb="ITE") #user_send_wall(photo.pk, None, "create_u_photo_wall") for user_id in creator.get_user_news_notify_ids(): Notify.objects.create(creator_id=creator.pk, recipient_id=user_id, type='PHO', object_id=photo.pk, verb="ITE") user_send_notify(photo.pk, creator.pk, user_id, None, "create_u_photo_notify") else: get_photo_processing(photo, Photo.PRIVATE) return photo @classmethod def create_manager_photo(cls, creator, image, list): from common.processing import get_photo_processing from logs.model.manage_photo import PhotoManageLog from lists.models import MediaList if not list: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового элемента") photo = cls.objects.create(creator=creator, preview=image, file=image) photo.media_list.add(list) list.count += 1 list.save(update_fields=["count"]) get_photo_processing(photo, Photo.MANAGER) PhotoManageLog.objects.create(item=photo.pk, manager=creator.pk, action_type=PhotoManageLog.ITEM_CREATED) return photo def is_list_exists(self): return self.photo_list.filter(creator=self.creator).exists() def make_private(self): from notify.models import Notify, Wall self.type = Photo.PRIVATE self.save(update_fields=['type']) if Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="C") def make_publish(self): from notify.models import Notify, Wall self.type = Photo.PUBLISHED self.save(update_fields=['type']) if Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="R") def delete_photo(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Photo.DELETED elif self.type == "PRI": self.type = Photo.DELETED_PRIVATE elif self.type == "MAN": self.type = Photo.DELETED_MANAGER self.save(update_fields=['type']) if community: community.minus_photos(1) else: self.creator.minus_photos(1) if Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="C") def abort_delete_photo(self, community): from notify.models import Notify, Wall if self.type == "_DEL": self.type = Photo.PUBLISHED elif self.type == "_DELP": self.type = Photo.PRIVATE elif self.type == "_DELM": self.type = Photo.MANAGER self.save(update_fields=['type']) if community: community.plus_photos(1) else: self.creator.plus_photos(1) if Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="PHO", object_id=self.pk, verb="ITE").update(status="R") def close_item(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Photo.CLOSED elif self.type == "PRI": self.type = Photo.CLOSED_PRIVATE elif self.type == "MAN": self.type = Photo.CLOSED_MANAGER self.save(update_fields=['type']) if community: community.minus_photos(1) else: self.creator.minus_photos(1) if Notify.objects.filter(type="DOC", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="DOC", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="DOC", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="DOC", object_id=self.pk, verb="ITE").update(status="C") def abort_close_item(self, community): from notify.models import Notify, Wall if self.type == "_CLO": self.type = Photo.PUBLISHED elif self.type == "_CLOP": self.type = Photo.PRIVATE elif self.type == "_CLOM": self.type = Photo.MANAGER self.save(update_fields=['type']) if community: community.plus_photos(1) else: self.creator.plus_photos(1) if Notify.objects.filter(type="DOC", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="DOC", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="DOC", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="DOC", object_id=self.pk, verb="ITE").update(status="R") def get_type(self): return self.list.all()[0].type def is_private(self): return self.type == self.PRIVATE def is_open(self): return self.type == self.MANAGER or self.type == self.PUBLISHED def is_deleted(self): return self.type[:4] == "_DEL" def is_closed(self): return self.type[:4] == "_CLO" def is_suspended(self): return False def get_lists(self): return self.list.all()