class User_Profile(models.Model): Man = u'M' Woman = u'F' Other = u'O' GENDER_CHOICES = ( (Man, u'男'), (Woman, u'女'), (Other, u'其他') ) user = models.OneToOneField(User) nickname = models.CharField(max_length = 64, db_index = True, unique = True) location = models.CharField(max_length = 32, null = True, default = u'北京') city = models.CharField(max_length = 32, null = True, default = u'朝阳') gender = models.CharField(max_length = 2, choices = GENDER_CHOICES, default = Other) bio = models.CharField(max_length = 1024, null = True, blank = True) website = models.CharField(max_length = 1024, null = True, blank = True) email_verified = models.BooleanField(default = False) search = SphinxSearch( index = 'users', mode = 'SPH_MATCH_ALL', rankmode = 'SPH_RANK_NONE', ) def __unicode__(self): return self.nickname class Meta: app_label = 'base'
class WorkBidder(models.Model): title = models.CharField(_('title'), max_length=80, blank=True, null=True) poll = models.ForeignKey(Poll, related_name='workbidders') author_name = models.CharField(_('author name'), max_length=80, blank=True, null=True) photo = ImageField(upload_to=make_poll_upload_path) text = tinymce_models.HTMLField(_('text'), blank=True, null=True) #user_likes = models.ManyToManyField(User, verbose_name=_('number votes'), # blank=True, null=True) total_likes = models.PositiveIntegerField(_('number of votes'), default=0) search = SphinxSearch( index='workbidder_index', weights={ 'title': 100, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) class Meta: ordering = ['-total_likes'] verbose_name = _('work bidder') verbose_name_plural = _('work bidders') def __unicode__(self): return u'%s - %s' % (self.poll, self.title)
class Note(models.Model): entity = models.ForeignKey(Entity, related_name="notes") note = models.TextField(null = True) score = models.IntegerField(db_index = True, default = 0) figure = models.CharField(max_length = 256, null = False, default = '') creator_id = models.IntegerField(null = False, db_index = True) created_time = models.DateTimeField(auto_now_add = True, db_index = True) updated_time = models.DateTimeField(auto_now = True, db_index = True) post_time = models.DateTimeField(null = True, db_index = True) selector = models.ForeignKey(User, null = True, db_index = True, related_name = "selected_note") selected_time = models.DateTimeField(null = True) poke_count = models.IntegerField(default = 0, db_index = True) weight = models.IntegerField(default = 0, db_index = True) search = SphinxSearch( index = 'notes', mode = 'SPH_MATCH_ALL', rankmode = 'SPH_RANK_NONE', ) class Meta: ordering = ['-created_time'] unique_together = ('entity', 'creator_id') def __unicode__(self): return self.note
class Item(models.Model): title = models.CharField(max_length=255, null=False) slug = models.CharField(max_length=255, null=False) official_link = models.CharField(max_length=255, null=True, blank=True) release_date = models.DateTimeField(null=True, blank=True) retail_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True) sku = models.CharField(max_length=64, null=True, blank=True) content = models.TextField(null=True, blank=True) edition_size = models.IntegerField(null=True, blank=True) is_active = models.BooleanField() created_on = models.DateTimeField(auto_now_add=True, null=True, blank=True) updated_on = models.DateTimeField(auto_now=True, null=True, blank=True) type = models.ForeignKey(Type) isbn = models.CharField(max_length=15, null=True, blank=True) asin = models.CharField(max_length=10, null=True, blank=True) publisher = models.ForeignKey(Publisher, null=True, blank=True) binding = models.CharField(max_length=255, null=True, blank=True) image = models.CharField(max_length=255, null=True, blank=True) #denomination = models.IntegerField() denomination = models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2) year = models.SmallIntegerField(null=True, blank=True) view_count = models.SmallIntegerField(null=True, blank=True) scrape_status = models.SmallIntegerField(null=True, blank=True) disable_ebay = models.BooleanField() ebay_search_phrase = models.CharField(max_length=255, null=False, blank=True) search = SphinxSearch( index='items', weights={ # individual field weighting 'title': 100, 'content': 90, }) def __unicode__(self): return self.title def get_average_rating(self): ratings = Ratings.objects.all().filter(id=self.id) # get average return len(ratings) def first_image(self): image = Image_List.objects.all().filter( item=self.id, is_active=1).order_by('ordinal') if not image: return "" return image[0].image.src def first_image_copyright(self): image = Image_List.objects.all().filter( item=self.id, is_active=1).order_by('ordinal') return image[0].image.copyright
class Question(models.Model): author = models.ForeignKey(User) title = models.CharField(max_length=60) text = models.TextField() added = models.DateTimeField(auto_now_add=True, db_index=True) tags = models.ManyToManyField(Tag) rating = models.IntegerField(default=0, db_index=True) def __unicode__(self): return self.text[:20] search = SphinxSearch(weights={'title': 100, 'text': 70, 'ans_text': 40})
class Job(models.Model): title = models.CharField(max_length=255) description = models.TextField() tags = TagField() latitude = models.FloatField() longitude = models.FloatField() search = SphinxSearch(index='jobs_job', weights={ 'title': 100, 'description': 50, 'tags': 70, })
class Author(models.Model): name = models.CharField(max_length=NAME_LENGTH, unique=True, null=False, blank=False) #book = models.ManyToManyField(Book, null=True, blank=True)#, limit_choices_to = {'id__lte': 0}) #book = models.ManyToManyField(Book, null=True, blank=True, through='AuthorBook')#, limit_choices_to = {'id__lte': 0}) alias = models.ManyToManyField(AuthorAlias, null=True, blank=True) tag = models.ManyToManyField(Tag, null=True, blank=True) credit = models.IntegerField(default=0) #show = models.IntegerField(default=0, choices=AUTHOR_SHOW) # for more settings see 'spec/sphinx_conf/001_author_simple.tmplt' simple_search = SphinxSearch( index='authors_simple', weights={ 'name': 100, }, mode='SPH_MATCH_ANY', ) # for more settings see 'spec/sphinx_conf/002_author_soundex.tmplt' soundex_search = SphinxSearch( index='authors_soundex', weights={ 'name': 50, }, mode='SPH_MATCH_ANY', morphology='soundex', limit=1000, ) def __unicode__(self): return '[id %s] %s' % (self.id, self.name) def existed_books(self): return Author.objects.get(id=self.id).book.all()
class Search(models.Model): name = models.CharField(max_length=10) text = models.TextField() stored_string = models.CharField(max_length=100) datetime = models.DateTimeField() date = models.DateField() bool = models.BooleanField() uint = models.IntegerField() float = models.FloatField(default=1.0) excluded_field = models.CharField(max_length=10) excluded_field2 = models.CharField(max_length=10) related = models.ForeignKey(Related) m2m = models.ManyToManyField(M2M) search = SphinxSearch( options={ 'realtime': True, 'included_fields': [ 'text', 'datetime', 'bool', 'uint', ], 'excluded_fields': [ 'excluded_field2', ], 'stored_attributes': [ 'stored_string', ], 'stored_fields': [ 'excluded_field', ], 'related_fields': [ 'related', ], 'mva_fields': [ 'm2m', ] }, snippets=True, ) def __unicode__(self): return self.name
class Question(models.Model): author = models.ForeignKey(Profile) title = models.CharField(max_length=64) text = models.TextField() rating = models.IntegerField(default=0) tags = models.ManyToManyField(Tag) created = models.DateTimeField(auto_now_add=True) # answers count??? objects = QuestionManager() search = SphinxSearch(index='askga') def __str__(self): return '%s Author: %s, rating: %s' % (self.title, self.author, self.rating)
class Action(WithPublished, WithSite): STATUS_TYPE = ( (True, _('completed')), (False, _('not completed')), ) title = models.CharField(_('title'), max_length=80) slug = models.SlugField(_('title slug'), unique=True) image = models.ImageField(_('image'), upload_to="action/%Y/%m", null=True, blank=True) short_text = models.TextField(_('short text for description')) full_text = tinymce_models.HTMLField(_('full text')) is_completed = models.BooleanField(_('status'), max_length=13, choices=STATUS_TYPE, default=False) search = SphinxSearch( index='action_index', weights={ 'title': 100, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) objects = ActionManager() class Meta: ordering = ['-pub_date'] get_latest_by = 'pub_date' verbose_name = _('action') verbose_name_plural = _('actions') def __unicode__(self): return self.title def save(self, *args, **kwargs): if self.slug is None: self.slug = slugify(self.title) super(Action, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('action_detail', args=[self.slug])
class Tag(models.Model): tag = models.CharField(max_length = 128, null = False, unique = True, db_index = True) tag_hash = models.CharField(max_length = 32, unique = True, db_index = True) status = models.IntegerField(default = 0, db_index = True) creator = models.ForeignKey(User) created_time = models.DateTimeField(auto_now_add = True, db_index=True) updated_time = models.DateTimeField(auto_now = True, db_index = True) search = SphinxSearch( index = 'tags', mode = 'SPH_MATCH_ALL', rankmode = 'SPH_RANK_NONE', ) def get_absolute_url(self): return "/t/%s" % self.tag_hash class Meta: ordering = ['-created_time']
class SchoolPoint(models.Model): point_id = models.IntegerField(primary_key=True) school_id = models.IntegerField() school_name = models.CharField(max_length=100L, blank=True) specialty_category = models.CharField(max_length=100L, blank=True) area = models.CharField(max_length=100L, blank=True) type = models.CharField(max_length=100L, blank=True) year = models.CharField(max_length=100L, blank=True) point_average = models.CharField(max_length=100L, blank=True) point_height = models.CharField(max_length=100L, blank=True) point_low = models.CharField(max_length=100L, blank=True) level = models.CharField(max_length=100L, blank=True) search = SphinxSearch( index='ccard', mode='SPH_MATCH_ANY', rankmode='SPH_RANK_NONE', ) class Meta: db_table = 'school_point'
class Book(models.Model): title = models.CharField(max_length=NAME_LENGTH) lang = models.CharField(max_length=2, choices=LANG_CODE) language = models.ForeignKey(Language) book_file = models.ManyToManyField(BookFile) series = models.ManyToManyField(Series, null=True, blank=True) tag = models.ManyToManyField(Tag, null=True, blank=True) credit = models.IntegerField(default=0) author = models.ManyToManyField(Author, null=True, blank=True) # for more settings see 'spec/sphinx_conf/003_book_title.tmplt' title_search = SphinxSearch(index='book_title', weights={ 'title': 100, }, mode='SPH_MATCH_ANY') def book_authors(self): return Book.objects.get(id=self.id).author.all() # # for more settings see 'spec/sphinx_conf/004_book_title_author.tmplt' # title_author_search = SphinxSearch( # index='book_title_author', # weights={ # 'author_name': 100, # }, # mode='SPH_MATCH_ANY', # ) # # for more settings see 'spec/sphinx_conf/004_book_title_annotation.tmplt' # title_annotation_search = SphinxSearch( # index='book_title_annotation', # weights={ # 'title': 100, # } # ) def __unicode__(self): return '[id %s] %s (%s)' % (self.id, self.title, self.lang)
class Words(models.Model): word = models.CharField(max_length=WORD_LENGTH) trigrams = models.CharField(max_length=TRIGRAM_FIELD_LENGTH) length = models.IntegerField() frequency = models.IntegerField() dictionary = models.ForeignKey(Dictionary) class Meta: unique_together = ('word', 'dictionary') def __unicode__(self): string = "'%s' [freq %s] [dict %s]" % \ (self.word, self.frequency, self.dictionary.name,) return string search = SphinxSearch( index='queryspell_index', mode='SPH_MATCH_EXTENDED2', rankmode='SPH_RANK_WORDCOUNT', )
class Entity(BaseModel): entity_hash = models.CharField(max_length=32, unique=True, db_index=True) creator_id = models.IntegerField(default=None, null=True, db_index=True) category = models.ForeignKey(Category) neo_category = models.ForeignKey(Neo_Category) brand = models.CharField(max_length=256, null=False, default='') title = models.CharField(max_length=256, null=False, default='') intro = models.TextField(null=False, default='') price = models.DecimalField(max_digits=20, decimal_places=2, default=0, db_index=True) like_count = models.IntegerField(default=0, db_index=True) mark = models.IntegerField(default=0, db_index=True) chief_image = models.CharField(max_length=64, null=False) detail_images = models.CharField(max_length=1024, null=True) created_time = models.DateTimeField(auto_now_add=True, db_index=True) updated_time = models.DateTimeField(auto_now=True, db_index=True) novus_time = models.DateTimeField(db_index=True) weight = models.IntegerField(default=0, db_index=True) rank_score = models.IntegerField(default=0, db_index=True) objects = EntityManager() search = SphinxSearch( index='entities', weights={ 'title': 20, 'brand': 10, 'intro': 5, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) class Meta: ordering = ['-created_time'] def get_absolute_url(self): return "/detail/%s" % self.entity_hash def __unicode__(self): return self.title
class Poll(WithPublished): STATUS_TYPE = ( ('SOON', _('Poll will begin soon')), ('ACTIVE', _('Poll is active')), ('SUSPEND', _('Poll suspended')), ('COMPLETED', _('Poll finished')), ('NONE', _('Without poll, only work bidder')), ) FREQUENCY_TYPE = ( ('DAY', _('Once a day')), ('WEEK', _('Once a week')), ('ONCE', _('Only once')), ) CAN_VOTE = ( ('OLD', _('Only old users')), ('ALL', _('All users')), ) AS_TABLE = 'table' AS_LIST = 'list' TYPE_CHOICE = ( (AS_TABLE, _('Table')), (AS_LIST, _('List')), ) MANY_TO_CHOICE = ( ('ONE', _('One')), ('ALL', _('All')), ) action = models.ForeignKey(Action, related_name='polls', verbose_name=_('action'), blank=True, null=True) title = models.CharField(_('title'), max_length=80) start_date = models.DateField(_('start date')) end_date = models.DateField(_('end date')) status = models.CharField(_('status'), max_length=10, choices=STATUS_TYPE, default='NONE') vote_frequency = models.CharField(_('Frequency'), max_length=10, choices=FREQUENCY_TYPE, default='ONCE') can_vote = models.CharField(_('Can vote'), max_length=10, choices=CAN_VOTE, default='ALL') display_type = models.CharField(_('Type of display'), max_length=5, choices=TYPE_CHOICE) many_to_choose = models.CharField(_('Many to choice'), max_length=3, \ choices=MANY_TO_CHOICE, default='ALL') search = SphinxSearch( index='poll_index', weights={ 'title': 100, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) objects = PollManager() class Meta: ordering = ['-start_date'] verbose_name = _('poll') verbose_name_plural = _('polls') def __unicode__(self): if self.action: return u'%s: %s' % (self.action.title, self.title) else: return self.title def get_absolute_url(self): return reverse('poll_detail', args=[self.id]) @property def is_actual(self): now = datetime.date.today() return now >= self.start_date and now < self.end_date @property def status_title(self): if self.status == 'SOON': return _('Poll will begin') elif self.status == 'ACTIVE': return _('Poll will until') elif self.status == 'SUSPEND': return _('Poll suspended') elif self.status == 'COMPLETED': return _('Poll finished') else: return '' def can_add_like(self, user, work): if not self.status == 'ACTIVE': return False if self.can_vote == 'OLD' and user.date_joined.date( ) > self.start_date: return False if self.many_to_choose == 'ALL': votes = work.work_votes.filter(user=user) else: votes = WorkBidderVote.objects.filter(user=user, \ workbidder__in=(self.workbidders.all())) if not votes: return True if self.vote_frequency == 'ONCE': return False today = datetime.date.today() if self.vote_frequency == 'DAY' and today == votes[0].vote_date: return False if self.vote_frequency == 'WEEK' and today >= votes[0].vote_date \ and today <= votes[0].in_a_week: return False return True
class Place(WithSite): category = models.ManyToManyField(PlaceCategory, null=True, blank=True, verbose_name=_('category'), #related_name='places') through='RateCategories') name = models.CharField(max_length=255, verbose_name=_('company name')) tagging = models.ManyToManyField(Tag, related_name='places', null=True, blank=True, verbose_name=_('tagging')) description = models.TextField(null=True, blank=True, verbose_name=_('description')) hits = models.IntegerField(default=0, verbose_name=_('hits'),) logotype = ImageWithThumbnailsField(upload_to=gen_file_name, thumbnail={'size': (360, 170), 'quality': (100), 'subdir': '_thumb'}, null=True, blank=True, verbose_name=_('logo of company')) logotype_alt = models.CharField(blank=True, null=True, verbose_name=_('logotype_alt'), max_length=255) photo = ImageWithThumbnailsField(upload_to=gen_file_name, thumbnail={'size': (360, 170), 'options': {'crop':',10'}, 'quality': (100), 'subdir': '_thumb'}, null=True, blank=True, verbose_name=_('photo')) photo_alt = models.CharField(blank=True, null=True, verbose_name=_('photo_alt'), max_length=255) email = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('email of company')) url = models.URLField(verify_exists=False, null=True, blank=True, verbose_name=_('web site')) url_is_follow = models.BooleanField(_('follow url'), default=False) urlhits = models.IntegerField(default=0, verbose_name=_('urlhits')) promo_is_up = models.BooleanField(default=False, verbose_name=_('promo is published')) date_promo_up = models.DateField(null=True, blank=True, verbose_name=_('date of pulished promo')) date_promo_down = models.DateField(null=True, blank=True, verbose_name=_('date of unpublished promo')) is_published = models.BooleanField(default=False, verbose_name=_('company is published')) is_sponsor = models.BooleanField(default=False, verbose_name=_('company is the sponsor')) sponsor_logo = ImageWithThumbnailsField(upload_to=gen_file_name, thumbnail={'size': (200, 45), 'quality': (100), 'subdir': '_thumb'}, null=True, blank=True, verbose_name=_("sponsor's logo")) expert_choice = models.BooleanField(default=False, verbose_name=_('expert`s choice')) main_address = models.TextField(editable=False, verbose_name=_('main address'), blank=True, null=True) num_comments = models.PositiveIntegerField(_('number of comments'), default=0) date_modified = models.DateTimeField(auto_now=True, default=datetime.now, verbose_name=_('date of change')) date_mark_as_new = models.DateTimeField(default=datetime.now, verbose_name=_('date of mark as new'), blank=True, null=True) priority = models.IntegerField(default=0, verbose_name=_('priority'),) kinohod_place_id = models.IntegerField(verbose_name=_('kinohod place id'), default=0, blank=True, null=True) can_buy_tiket = models.BooleanField(default=False) manual_changed = models.BooleanField(default=True) payments = models.ManyToManyField(PaymentSystem, default=None, blank=True, null=True) flash3d = models.URLField(default=None, blank=True, null=True, verbose_name=_('panorama')) identity = models.CharField(max_length=255, default='', blank=True, null=True) last_foursquare_update = models.DateTimeField(null=True, blank=True) foursquare_show = models.BooleanField(verbose_name=_(u'show foursquare photos'), default=True) score = models.FloatField(verbose_name=_(u'Score by votes'), default=0, editable=False) search = SphinxSearch( index='place_index', weights={ 'name': 100, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) objects = PlaceManager() default_manager = models.Manager() def save(self, *args, **kwargs): self.main_address = self._main_address if 'site' in kwargs: site = kwargs.pop('site') else: site = None self.score = Vote.objects.get_score(self)['score'] super(Place, self).save(*args, **kwargs) if not self.sites.exists(): self.sites.add(site or Site.objects.get_current()) class Meta: verbose_name = _('Place') verbose_name_plural = _('Places') ordering = ['name'] def __unicode__(self): return self.name #return u"%s" % self.name @models.permalink def get_absolute_url(self): return ('place_show', [str(self.id)]) @models.permalink def get_edit_url(self): return ("control_place_edit", [str(self.pk)]) @property def _main_address(self): if self.address.count(): try: address = self.address.filter( is_main_office=True).all()[0].address except IndexError: address = self.address.all()[0].address else: address = None return address def get_main_address(self): if self.address.count(): try: return self.address.filter( is_main_office=True).all()[0] except IndexError: return self.address.all()[0] return None @property def is_taxi(self): if self.category.filter(name='Такси').exists(): return True return False @property def phone(self): phones = [ y.strip() for x in self.address.values('phone') for y in x['phone'].split(',') ] if phones: return ', '.join(phones[:2] if len(phones) > 2 else phones) return None @property def has_email(self): return bool(self.email.strip()) @property def get_url(self): url = self.url if url.endswith("/"): url = url[:-1] if "http://" in url: url = url.split('http://')[1] return url return url def dump(self): place_object = dict() for f in ['name', 'url', 'email']: place_object[f] = getattr(self, f, None) category = [{ 'id': c.id, 'name': c.__unicode__(), } for c in self.category.all().order_by('name')] place_object['category'] = category tagging = [{ 'id': c.id, 'name': c.__unicode__(), } for c in self.tagging.all().order_by('name')] place_object['tagging'] = tagging payments = [p.__unicode__() for p in self.payments.filter(name__gt='')] if payments: place_object['payments'] = list(set(payments)) place_object['payments'].sort() else: place_object['payments'] = None place_object['adr'] = list() for adr in self.address.all(): adr_object = dict() adr_object['address'] = adr.address adr_object['phone'] = adr.phone adr_object['wt_list'] = [wt.dump() for wt in adr.work_time.all()] place_object['adr'].append(adr_object) return place_object def get_fs_photos(self, fsid): url = 'https://api.foursquare.com/v2/venues/%s/photos' % fsid data = get_json(url, FS_AUTH) present_photos = self.foursquare_photo.all().values_list('photo_id', flat=True) for k in data['response']['photos']['items']: if k['id'] not in present_photos: param = { 'place': self, 'photo_id': k['id'], 'prefix': k['prefix'], 'suffix': k['suffix'], } FoursquarePhoto(**param).save()
class Article(models.Model): # Status choices STATUS_CHOICES = ( ('published', u'Publicado'), ('draft', u'Rascunho'), ('pending', u'Pendente'), ) # Article Owner user = models.ForeignKey(User, related_name=u'articles', verbose_name=u'Usuário') # Article Channel channel = models.ForeignKey(Channel, related_name=u'channels', verbose_name=u'Canal') # Article Section section = models.ForeignKey(Section, related_name=u'sections', verbose_name=u'Seção', blank=True, null=True) # Article Title title = models.CharField(u'Título fora', max_length=200, help_text=u'máximo de 70 caracteres.') # Article title in the detail page title_secondary = models.CharField(u'Título dentro', max_length=250, blank=True, null=True) # Article Slug slug = models.SlugField(max_length=255, unique=True, editable=False) # Article Headline headline = models.CharField(u'Subtítulo', max_length=40, blank=True, help_text=u'máximo de 40 caracteres') # Article Summary summary = models.CharField(u'Resumo', max_length=160, blank=True, help_text=u'máximo de 160 caracteres') # Article Content content = models.TextField(u'Conteúdo') # Article Source and Source url source = models.CharField(u'Fonte', max_length=255, blank=True) source_url = models.CharField(u'URL da Fonte', max_length=255, blank=True) # Article author author = models.CharField(u'Autor', max_length=255, blank=True) #Article picture picture = models.ImageField('Imagem', upload_to=content_file_name, max_length=300, blank=True) # picture subtitle picture_subtitle = models.CharField(u'Legenda da imagem', max_length=50, blank=True, null=True) # picture cropped for the iphone picture_cropped = models.ImageField( editable=False, upload_to='images/dynamic/articles/%Y/%m/', max_length=400, null=True, blank=True) # Status status = models.CharField(u'Status', max_length=10, choices=STATUS_CHOICES, default='draft', db_index=True) # views count views_count = models.PositiveIntegerField('Número de visitas', editable=False, default=0, db_index=True) # views count views_count_last_week = models.PositiveIntegerField( 'Número de visitas nos últimos sete dias', editable=False, default=0, db_index=True) # Publication date and hour publication_date = models.DateTimeField(u'Data da Publicação', default=datetime.now, db_index=True) # articles usermeuclick. used when the article come from an article sent by an usermeuclick usermeuclick = models.ForeignKey( UserMeuClick, verbose_name=u'Usuário vcnoclick', null=True, blank=True, help_text= u'Selecione algum valor somente se a notícia foi enviada por algum usuário.' ) # Is Urgent is_urgent = models.BooleanField(u'ativar notícia urgente', default=False, db_index=True) is_mega_manchete = models.BooleanField(u'ativar notícia mega manchete', default=False, db_index=True) # Enable comments enable_comments = models.BooleanField(u'ativar comentários', default=True) comments_count = models.PositiveIntegerField(u'Número de comentários', default=0, editable=False) # Created date and hour created_date = models.DateTimeField(u'Data da Criação', default=datetime.now, editable=False) # Id from clickpb id_migration = models.CharField(max_length=15, db_index=True, editable=False, default='0') # Video tags tags_string = TagField( u'tags', help_text= u'separar as tags por espaço. para tags com mais de uma palavra utilizar aspas duplas, exemplo: tag1 "tag2 tag2" tag3' ) # Slug slug_field_name = 'slug' slug_from = 'title' # managers objects = models.Manager() published = ArticlePublishedManager() published_detail = ArticlePublishedDetailManager() published_urgent = ArticlePublishedUrgentManager() search = SphinxSearch('articles') def __unicode__(self): return self.title class Meta: verbose_name = u'artigo' verbose_name_plural = u'artigos' ordering = ['-publication_date'] def save(self, *args, **kwargs): super(Article, self).save(*args, **kwargs) try: img = Image.open(self.picture) img.thumbnail((110, 100000000), Image.ANTIALIAS) img = crop_center(img, (103, 77)) name = add_file_termination(self.picture.name, '_crop') path = add_file_termination(self.picture.path, '_crop') self.picture_cropped = ImageFieldFile(self, self.picture_cropped, name) img.save(self.picture_cropped.path, quality=100) super(Article, self).save(*args, **kwargs) except: pass if self.usermeuclick: print "ok" def get_related_articles(self): most_similar = Article.tagged.with_all( self.tags).order_by('-publication_date')[:6] similar = Article.tagged.with_any( self.tags).order_by('-publication_date')[:11] related_articles = [] for article in most_similar: related_articles.append(article) for article in similar: if not article in related_articles: related_articles.append(article) try: related_articles.remove(self) except ValueError: pass return related_articles[:5] @models.permalink def get_absolute_url(self): return ('article_show', (), { 'channel': self.channel.slug, 'slug': self.slug })
class Question(models.Model): title = models.CharField(max_length=300) author = models.ForeignKey(User, related_name='questions') added_at = models.DateTimeField(default=datetime.datetime.now) tags = models.ManyToManyField(Tag, related_name='questions') # Status wiki = models.BooleanField(default=False) wikified_at = models.DateTimeField(null=True, blank=True) answer_accepted = models.BooleanField(default=False) closed = models.BooleanField(default=False) closed_by = models.ForeignKey(User, null=True, blank=True, related_name='closed_questions') closed_at = models.DateTimeField(null=True, blank=True) close_reason = models.SmallIntegerField(choices=CLOSE_REASONS, null=True, blank=True) deleted = models.BooleanField(default=False) deleted_at = models.DateTimeField(null=True, blank=True) deleted_by = models.ForeignKey(User, null=True, blank=True, related_name='deleted_questions') locked = models.BooleanField(default=False) locked_by = models.ForeignKey(User, null=True, blank=True, related_name='locked_questions') locked_at = models.DateTimeField(null=True, blank=True) followed_by = models.ManyToManyField(User, related_name='followed_questions') # Denormalised data score = models.IntegerField(default=0) vote_up_count = models.IntegerField(default=0) vote_down_count = models.IntegerField(default=0) answer_count = models.PositiveIntegerField(default=0) comment_count = models.PositiveIntegerField(default=0) view_count = models.PositiveIntegerField(default=0) offensive_flag_count = models.SmallIntegerField(default=0) favourite_count = models.PositiveIntegerField(default=0) last_edited_at = models.DateTimeField(null=True, blank=True) last_edited_by = models.ForeignKey(User, null=True, blank=True, related_name='last_edited_questions') last_activity_at = models.DateTimeField(default=datetime.datetime.now) last_activity_by = models.ForeignKey( User, related_name='last_active_in_questions') tagnames = models.CharField(max_length=125) summary = models.CharField(max_length=180) html = models.TextField() comments = generic.GenericRelation(Comment) votes = generic.GenericRelation(Vote) flagged_items = generic.GenericRelation(FlaggedItem) if settings.USE_SPHINX_SEARCH == True: search = SphinxSearch( index=' '.join(settings.SPHINX_SEARCH_INDICES), mode='SPH_MATCH_ALL', ) logging.debug('have sphinx search') objects = QuestionManager() def delete(self): super(Question, self).delete() try: ping_google() except Exception: logging.debug( 'problem pinging google did you register you sitemap with google?' ) def save(self, **kwargs): """ Overridden to manually manage addition of tags when the object is first saved. This is required as we're using ``tagnames`` as the sole means of adding and editing tags. """ initial_addition = (self.id is None) super(Question, self).save(**kwargs) try: ping_google() except Exception: logging.debug( 'problem pinging google did you register you sitemap with google?' ) if initial_addition: tags = Tag.objects.get_or_create_multiple(self.tagname_list(), self.author) self.tags.add(*tags) Tag.objects.update_use_counts(tags) def tagname_list(self): """Creates a list of Tag names from the ``tagnames`` attribute.""" return [name for name in self.tagnames.split(u' ')] def tagname_meta_generator(self): return u','.join([unicode(tag) for tag in self.tagname_list()]) def get_absolute_url(self): return '%s%s' % (reverse( 'question', args=[self.id]), django_urlquote(slugify(self.title))) def has_favorite_by_user(self, user): if not user.is_authenticated(): return False return FavoriteQuestion.objects.filter(question=self, user=user).count() > 0 def get_answer_count_by_user(self, user_id): query_set = Answer.objects.filter(author__id=user_id) return query_set.filter(question=self).count() def get_question_title(self): if self.closed: attr = CONST['closed'] elif self.deleted: attr = CONST['deleted'] else: attr = None if attr is not None: return u'%s %s' % (self.title, attr) else: return self.title def get_revision_url(self): return reverse('question_revisions', args=[self.id]) def get_latest_revision(self): return self.revisions.all()[0] get_comments = get_object_comments def get_last_update_info(self): when, who = post_get_last_update_info(self) answers = self.answers.all() if len(answers) > 0: for a in answers: a_when, a_who = a.get_last_update_info() if a_when > when: when = a_when who = a_who return when, who def get_update_summary(self, last_reported_at=None, recipient_email=''): edited = False if self.last_edited_at and self.last_edited_at > last_reported_at: if self.last_edited_by.email != recipient_email: edited = True comments = [] for comment in self.comments.all(): if comment.added_at > last_reported_at and comment.user.email != recipient_email: comments.append(comment) new_answers = [] answer_comments = [] modified_answers = [] commented_answers = [] import sets commented_answers = sets.Set([]) for answer in self.answers.all(): if (answer.added_at > last_reported_at and answer.author.email != recipient_email): new_answers.append(answer) if (answer.last_edited_at and answer.last_edited_at > last_reported_at and answer.last_edited_by.email != recipient_email): modified_answers.append(answer) for comment in answer.comments.all(): if comment.added_at > last_reported_at and comment.user.email != recipient_email: commented_answers.add(answer) answer_comments.append(comment) #create the report if edited or new_answers or modified_answers or answer_comments: out = [] if edited: out.append( _('%(author)s modified the question') % {'author': self.last_edited_by.username}) if new_answers: names = sets.Set(map(lambda x: x.author.username, new_answers)) people = ', '.join(names) out.append(_('%(people)s posted %(new_answer_count)s new answers') \ % {'new_answer_count':len(new_answers),'people':people}) if comments: names = sets.Set(map(lambda x: x.user.username, comments)) people = ', '.join(names) out.append( _('%(people)s commented the question') % {'people': people}) if answer_comments: names = sets.Set( map(lambda x: x.user.username, answer_comments)) people = ', '.join(names) if len(commented_answers) > 1: out.append( _('%(people)s commented answers') % {'people': people}) else: out.append( _('%(people)s commented an answer') % {'people': people}) url = settings.APP_URL + self.get_absolute_url() retval = '<a href="%s">%s</a>:<br>\n' % (url, self.title) out = map(lambda x: '<li>' + x + '</li>', out) retval += '<ul>' + '\n'.join(out) + '</ul><br>\n' return retval else: return None def __unicode__(self): return self.title class Meta: db_table = u'question'
class Post(Auditable, ExtendedAttributesManager): user = models.ForeignKey(User, related_name = '_posts', blank = True, null = True) content_type = models.ForeignKey(ContentType, blank = True, null = True) object_id = models.PositiveIntegerField(blank = True, null = True, db_index = True) in_reply_to = generic.GenericForeignKey() rating = models.IntegerField(default = 0) views_count = models.IntegerField(default = 0) replies_count = models.IntegerField(default = 0) #This should be a denorm. status = models.SmallIntegerField(default = 0) # make this an index WITH is_active versions_count = models.IntegerField(default = 0) ip = models.IPAddressField(default = '0.0.0.0') username = models.CharField(max_length = 30, blank = True, db_index = True) last_poster = models.ForeignKey(User, blank = True, null = True) last_poster_name = models.CharField(max_length = 30, blank = True, default = '') #denormalization timestamp = models.PositiveIntegerField(blank = True, default = 0, db_index=True) # reverse_timestamp = models.PositiveIntegerField(db_index = True) timeshift = models.IntegerField(default = 0) #Mostly used for bookkeeping, but might be useful later _title = models.CharField(max_length = 255, blank = True) read_only = models.BooleanField() no_replies = models.BooleanField() wiki = models.BooleanField() sticky = models.BooleanField() is_private = models.BooleanField() template_override = models.ForeignKey("Template", blank = True, null = True) _extended_attributes = generic.GenericRelation("ExtendedAttributeValue") tags = models.ManyToManyField("Tag", related_name = 'posts', through = "TagAttach") _replies = generic.GenericRelation('self') _last_reply_id = models.PositiveIntegerField(default = 0) search = SphinxSearch('a3d_post') objects = PostManager() mentions = models.ManyToManyField(User, related_name = 'mentions', blank = True, null = True, through = "Mention") def __unicode__(self): return "#%s (%s)" % (self.pk, self.title) def save(self, *args, **kwargs): #TODO: Make some kind of duplicate check parent = None pvt_recipient = False try: pvt_recipient = User.objects.get(username = re.search('^@\[(?P<username>[^]]+)\]', self.title).group('username')) self.is_private = True except AttributeError: #If the title does not start with a username-like string, we jump here. pass if not bool(self.timestamp): self.timestamp = int(time.mktime(datetime.datetime.now().timetuple())) if self.pk: #This is an update, should perhaps do something? pass elif self.object_id: #New post, update parent accordingly #TODO: Don't we want to move this to a listener? parent = self.in_reply_to parent.timestamp = max(parent.timestamp, self.timestamp) #I'd rather hit the DB than end up with the wrong numbers parent.replies_count = parent.replies.public().count() + 1 parent.last_poster_id = self.user_id #IGNORE:E1101 parent.last_poster_name = self.username try: parent.tags.all().update(timestamp = parent.timestamp) except AttributeError: #If the parent is a UserProfile there are no tags. pass tmp = super(Post, self).save(*args, **kwargs) # Call the "real" save() method. if parent: parent._last_reply_id = self.pk parent.save() if pvt_recipient: Mention.objects.attachToPost(self, pvt_recipient) return tmp @models.permalink def get_absolute_url(self): return ('board_post_view', (), { 'post_id': self.pk }) @models.permalink def get_replies_url(self): return ('board_post_view_replies', (), { 'post_id': self.pk }) @property def get_url_as_reply(self): return '%s?start=%s&inclusive#post-id-%s' % (self.parent_url, self.pk, self.pk) def get_smart_url(self): if self.replies_count or self.object_id == 0: #Not a reply, or has replies return self.get_absolute_url() else: return self.get_url_as_reply() @property def title(self): return self._title or "#%s" % self.pk @property def title_as_reply(self): #Yeah, I don't like it either but I can't think of a better way right now. if self.replies_count > 0: return self.title else: return self._title @property def last_reply(self): #TODO: Check if we want to have this return the actual object? return self._last_reply_id or self.pk @property def is_unread(self): return bool(int(getattr(self, 'read_last', 0)) < self.last_reply) @property def replies(self): return self._replies.filter(is_active = True #IGNORE:E1101 ).order_by('pk').select_related('postdata') @property def unread_replies(self): read_count = int(getattr(self, 'read_last_count', 0)) return self.replies_count - read_count @property def parent_url(self): ''' Get the url for the parent's "view": board_post_view for posts profiles_profile_detail for user profiles ''' #The following approach is the "correct" one. #Sadly, it hits the db with every single call. #I would like to find a "correct" approach using a class method, #as opposed to an instance one. # try: # return self.in_reply_to.get_absolute_url() # except AttributeError: # #Should we return self's url? # return None model = ContentType.objects.get_for_id(self.content_type_id).name if model == 'post': return urlresolvers.reverse('board_post_view', kwargs = {'post_id':self.object_id}) elif model == 'userprofile': return urlresolvers.reverse('profiles_profile_detail', kwargs = {'username':re.sub(r'/^\[\d+\]\s+/', '', self.title)}) else: return self.in_reply_to.get_absolute_url() def has_new_replies(self): read_last = getattr(self, 'read_last', False) if not read_last or read_last < self.last_reply: return True return False def _can_be_rated(self, request): if not request.user.is_authenticated(): return False if request.user.is_superuser: return True if self.user_id <> request.user.id \ and not(hasattr(self, 'timeshift_last') or hasattr(self, 'rate_last')): return True def _can_be_edited(self, request): if not request.user.is_authenticated(): return False if request.user.is_superuser: return True if self.wiki or self.user_id == request.user.id: return True def _can_be_read(self, request): if request.user.is_superuser: return True if self.is_private: return request.user.is_authenticated() and request.user.username == self.title[2:].partition(']')[0] #hackish but yields return True def with_interactions(self, request): if request.user.is_authenticated(): interactions = Interaction.objects.filter(object_id = self.pk, user = request.user).values('value', 'object_id', 'interaction_type__name') for i in interactions: try: i_val, i_count = i["value"].split(';') except ValueError: i_val, i_count = [i["value"], ''] if i_val.isdigit(): setattr(self, "%s_last" % i["interaction_type__name"], int(i_val)) else: #Trying to cater to the "post count" crowd - shouldn't harm anything else. Hopefully. setattr(self, "%s_last" % i["interaction_type__name"], i_val) if i_count.isdigit(): setattr(self, "%s_last_count" % i["interaction_type__name"], int(i_count)) elif i_count: setattr(self, "%s_last_count" % i["interaction_type__name"], i_count) setattr(self, 'can_be_rated', self._can_be_rated(request)) setattr(self, 'can_be_edited', self._can_be_edited(request)) return self class Meta: permissions = ( ("rate_post", "Can rate"), ("timeshift_post", "Can timeshift"), ("read_post", "Can read"), ) app_label = 'board'
class Advert(models.Model): title = models.CharField(verbose_name=u'Заголовок', max_length=90, blank=True) slug = models.CharField(max_length=255, blank=True) author = models.ForeignKey(UserData, blank=True, null=True) category = models.ForeignKey(Category, verbose_name=u'Рубрика') price_uah = models.IntegerField(verbose_name=u'Цена Грн', null=True) price_usd = models.IntegerField(verbose_name=u'Цена $', null=True, blank=True) price_unit = models.SmallIntegerField( verbose_name=u'Цена указана за', choices=PRICE_UNIT_CHOICES, default=1, null=True, ) # type cost exsample - 'square meter' creation_date = models.DateTimeField(default=timezone.now) date_of_update = models.DateTimeField(default=timezone.now) latitude = models.FloatField(blank=True, null=True) longitude = models.FloatField(blank=True, null=True) main_text = models.TextField(verbose_name=u'Текст объявления', max_length=1000) city = models.ForeignKey(City, verbose_name=u'Регион') metro = models.ForeignKey(Metro, verbose_name=u'Метро', blank=True, null=True) big_sublocality = models.ForeignKey(BigSublocality, blank=True, null=True) sublocality = models.ForeignKey(Sublocality, verbose_name=u'Район', blank=True, null=True) settlement = models.ForeignKey(Settlement, verbose_name=u'Населенный пункт', blank=True, null=True) contact_name = models.CharField(verbose_name=u'Контактное лицо', max_length=60, blank=True) raw_phones = models.CharField(verbose_name=u'Телефоны', max_length=100) seller = models.SmallIntegerField(verbose_name=u'Собственник / Посредник', choices=SELLER_CHOICES, blank=True, null=True) street = models.CharField(verbose_name=u'Улица', max_length=120, blank=True) is_active = models.NullBooleanField(verbose_name=u'Активное', default=True) link = models.CharField(verbose_name=u'Ссылка', max_length=2000, blank=True, null=True) site = models.CharField(verbose_name=u'Сайт', max_length=2000, blank=True, null=True) vparser = models.CharField(verbose_name=u'ID в slando', max_length=2000, blank=True, null=True) search = SphinxSearch() class Meta: ordering = ['-date_of_update'] verbose_name = u'Объявление' verbose_name_plural = u'Объявления' def __unicode__(self): return "%s - %s" % (self.title, self.creation_date) def get_absolute_url(self): if self.city_id: city_slug = self.city.slug else: city_slug = 'kharkov' return reverse('advert-detail', kwargs={ 'category': self.category.slug, 'city': city_slug, 'title': self.slug, 'pk': self.pk }) def get_phone_with_null_str(self): phones = [] for phone in self.phone_set.all().values_list('phone', flat=True): if len(str(phone)) >= 8: phones.append('0' + str(phone)) else: phones.append(str(phone)) return ', '.join(phones) def get_photo_preview(self): photo = self.photo_set.first() return photo.preview if photo else 'nopic.gif' def save(self, *args, **kwargs): """Транслитерация имени для урла""" if self.title is None or len(self.title) == 0: sub = self.sublocality if self.sublocality else "" try: rooms = u", %s-комнатная" % self.extraflat.rooms_number except: rooms = u"" self.title = u"%s %s%s" % (self.category.name if self.category else "", sub, rooms) if self.slug is None or len(self.slug) == 0: self.slug = slugify(self.title) if self.price_usd is None and self.price_uah: self.price_usd = uah_to_usd(self.price_uah) if self.price_uah is None and self.price_usd: self.price_uah = usd_to_uah(self.price_usd) # if self.author and not self.author.is_admin: if not self.author or not self.author.is_admin: for cut in CuttingWords.objects.all(): self.main_text = self.main_text.replace(cut.cut_words, '') super(Advert, self).save(*args, **kwargs) if self.raw_phones: current_phones = self.phone_set.all() current_numbers = current_phones.values_list('phone', flat=True) phones = [parse_int(x) for x in self.raw_phones.split(',')] for phone in phones: if phone not in current_numbers: phone, c = Phone.objects.get_or_create(phone=phone) self.phone_set.add(phone) for current_phone in current_phones: if current_phone.phone not in phones: self.phone_set.remove(current_phone) super(Advert, self).save(*args, **kwargs) def price(self): if self.price_uah: return u"%s грн" % self.price_uah else: return "" def phones(self): return ", ".join([ "0%s" % x if len(str(x.phone)) > 5 else "" for x in self.phone_set.all() ]) #return ", ".join(["0%s" % x for x in self.phone_set.all()]) def get_raw_phones(self): return self.raw_phones.replace(" ", "").split(',') def rooms_number(self): try: return self.extraflat.rooms_number except Exception, e: logger.error(e) return 0
class Photo(models.Model): photoreport = models.ForeignKey(PhotoReport, related_name='photos', verbose_name=_('Photo report'), null=True, blank=True) title = models.CharField(_('title'), max_length=100) slug = models.SlugField( _('slug'), unique=True, help_text=('A "slug" is a unique URL-friendly title for an object.')) caption = models.TextField(_('caption'), blank=True) date_added = models.DateTimeField(_('date added'), auto_now_add=True, editable=False) image = ImageField(upload_to=make_upload_path) search = SphinxSearch( index='photo_index', weights={ 'title': 100, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) class Meta: ordering = ['date_added', 'id'] get_latest_by = 'date_added' verbose_name = _('Photo') verbose_name_plural = _('Photos') @property def prev_photo(self): """Return the previous photo""" prev_photo = self.get_previous_by_date_added() if prev_photo in self.photoreport.photos.all(): return prev_photo @property def next_photo(self): """Return the next photo""" next_photo = self.get_next_by_date_added() if next_photo in self.photoreport.photos.all(): return next_photo @property def get_image(self): """Returns no_image.gif if image is blank""" return self.image if self.image else 'i/no_image.gif' def __unicode__(self): if self.photoreport: return u'%s: %s' % (self.photoreport.title, self.title) else: return self.title def save(self, *args, **kwargs): if self.slug is None: self.slug = slugify(self.title) super(Photo, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('photo_detail', args=[self.photoreport.slug, self.id])
class PhotoReport(WithPublished, WithSite): ON_MAIN_PAGE_CHOICES = ( (True, _('On main page')), (False, _('Not on main page')), ) event = models.ForeignKey(Event, related_name='photoreports', blank=True, null=True) place = models.ForeignKey(Place, related_name='photoreports', blank=True, null=True) tags = models.ManyToManyField(Tag, related_name='photoreports', verbose_name=_('tagging'), blank=True, null=True) title = models.CharField(_('title'), max_length=100) slug = models.SlugField(_('title slug'), unique=True, help_text=_('A "slug" is a unique URL-\ friendly title for an object.')) description = models.TextField(_('description'), blank=True) date_event = models.DateField(_('date event')) num_photos = models.PositiveIntegerField(_('number of photos'), default=0) on_mainpage = models.BooleanField(_('On mainpage'), choices=ON_MAIN_PAGE_CHOICES, default=False) search = SphinxSearch( index='photoreport_index', weights={ 'title': 100, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) objects = PhotoReportManager() default_manager = models.Manager() class Meta: ordering = ['-date_event'] get_latest_by = 'date_added' verbose_name = _('Photo report') verbose_name_plural = _('Photo reports') def __unicode__(self): return self.title def save(self, *args, **kwargs): if self.slug is None: self.slug = slugify(self.title) self.num_photos = self.get_num_photos() super(PhotoReport, self).save(*args, **kwargs) @property def place_event(self): if self.event: places = self.event.place.all() if places: return places[0] return None def get_absolute_url(self): return reverse('photoreport_detail', args=[self.slug]) def get_preview(self): if self.photos.exists(): return self.photos.order_by('?')[0] return None def get_num_photos(self): return self.photos.all().count()
class Event(models.Model): """ Event model Contains all the basics about events, """ author = models.ForeignKey(User, blank=True, null=True, related_name="created_events") title = models.CharField(max_length=140, verbose_name=_('Title'), blank=False) slug = models.SlugField(max_length=140, verbose_name=_('slug'), help_text=_( 'Letters, numbers, underscore and hyphen.' ' Do not use reserved words \'create\',' ' \'history\' and \'edit\'.'), blank=True) created_at = models.DateTimeField(_('created at'), default=datetime.now) modified_on = models.DateTimeField(_('modified on'), default=datetime.now) is_active = models.BooleanField(default=True) users = models.ManyToManyField(User, related_name="events", through='Calendar') start = models.DateTimeField(_("start")) end = models.DateTimeField( _("end"), blank=True, null=True, help_text=_("The end time must be later than the start time.")) allDay = models.BooleanField(default=False) category = models.CharField(max_length=1, choices=EVENT_CATEGORY) priority = models.CharField(max_length=1, choices=EVENT_PRIORITY) recursion = models.ForeignKey(Recursion, null=True, blank=True, verbose_name=_("recursion")) end_recurring_period = models.DateTimeField( _("end recurring period"), null=True, blank=True, help_text=_("This date is ignored for one time only events.")) active = ActiveManager() objects = models.Manager() if SphinxSearch: search_events = SphinxSearch( index='event event_delta', weights={ 'title': 100, 'slug': 100, }, ) class Meta: verbose_name = _('Event') verbose_name_plural = _('Events') app_label = 'calendars' def __unicode__(self): return self.title def get_indiv_cal(self): return '<a href= "%s" data-analytic="profile" data-tooltip="user"> \ %s %s </a>:\ <h3><a class="cal_title" href= "%s" > %s </a></h3>' % ( reverse('profiles_profile_detail', args=[self.author.username]), self.author.first_name, self.author.last_name, self.get_absolute_url(), self.title, ) def attachments(self): return AttachmentEvent.objects.filter(event__exact=self) def attachment_profile(self): attachments = AttachmentEvent.objects.filter( event__exact=self).order_by('-uploaded_on') if attachments.count() > 0: return attachments[0].thumbnail.url else: return False def get_url(self): """Return the cal URL for an article""" return self.slug @models.permalink def get_absolute_url(self): url = 'event_view' return (url, [self.get_url()]) @models.permalink def get_edit_url(self): url = 'event_edit' return (url, [self.get_url()]) @models.permalink def get_upload_photo_url(self): url = 'event_upload_photo' return (url, [self.get_url()]) @models.permalink def get_cancel_url(self): url = 'event_cancel' return (url, [self.get_url()]) @models.permalink def get_reactivate_url(self): url = 'event_reactivate' return (url, [self.get_url()]) def get_occurrences(self, start, end): """ >>> recursion = Recursion(frequency = "MONTHLY", name = "Monthly") >>> recursion.save() >>> event = Event(recursion=recursion, start=datetime.datetime(2008,1,1), end=datetime.datetime(2008,1,2)) >>> event.recursion <recursion: Monthly> >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2)) >>> ["%s to %s" %(o.start, o.end) for o in occurrences] ['2008-02-01 00:00:00 to 2008-02-02 00:00:00', '2008-03-01 00:00:00 to 2008-03-02 00:00:00'] Ensure that if an event has no recursion, that it appears only once. >>> event = Event(start=datetime.datetime(2008,1,1,8,0), end=datetime.datetime(2008,1,1,9,0)) >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2)) >>> ["%s to %s" %(o.start, o.end) for o in occurrences] [] """ persisted_occurrences = self.occurrence_set.all() occ_replacer = OccurrenceReplacer(persisted_occurrences) occurrences = self._get_occurrence_list(start, end) final_occurrences = [] for occ in occurrences: # replace occurrences with their persisted counterparts if occ_replacer.has_occurrence(occ): p_occ = occ_replacer.get_occurrence(occ) # ...but only if they are within this period if p_occ.start < end and p_occ.end >= start: final_occurrences.append(p_occ) else: final_occurrences.append(occ) # then add persisted occurrences which originated outside of this period but now # fall within it final_occurrences += occ_replacer.get_additional_occurrences( start, end) return final_occurrences def get_rrule_object(self): if self.recursion is not None: params = self.recursion.get_params() frequency = 'rrule.%s' % self.recursion.frequency return rrule.rrule(eval(frequency), dtstart=self.start, **params) def _create_occurrence(self, start, end=None): if end is None: end = start + (self.end - self.start) return Occurrence(event=self, start=start, end=end, original_start=start, original_end=end) def get_occurrence(self, date): rule = self.get_rrule_object() if rule: next_occurrence = rule.after(date, inc=True) else: next_occurrence = self.start if next_occurrence == date: try: return Occurrence.objects.get(event=self, original_start=date) except Occurrence.DoesNotExist: return self._create_occurrence(next_occurrence) def has_occurrence(self, date): try: return Occurrence.objects.get(event=self, original_start=date) except Occurrence.DoesNotExist: return None def _get_occurrence_list(self, start, end): """ returns a list of occurrences for this event from start to end. """ difference = (self.end - self.start) if self.recursion is not None: occurrences = [] if self.end_recurring_period and self.end_recurring_period < end: end = self.end_recurring_period rule = self.get_rrule_object() o_starts = rule.between(start - difference, end, inc=True) # #check if the first occurrence doesn't much the original event, if so append the original # if not self.start in o_starts: # # check if event is in the period # if self.start < end and self.end >= start: # return [self._create_occurrence(self.start)] #continue with normal occurrences for o_start in o_starts: o_end = o_start + difference occurrences.append(self._create_occurrence(o_start, o_end)) return occurrences else: # check if event is in the period if self.start < end and self.end >= start: return [self._create_occurrence(self.start)] else: return [] def _occurrences_after_generator(self, after=None): """ returns a generator that produces unpresisted occurrences after the datetime ``after``. """ if after is None: after = datetime.now() rule = self.get_rrule_object() if rule is None: if self.end > after: yield self._create_occurrence(self.start, self.end) raise StopIteration date_iter = iter(rule) difference = self.end - self.start while True: o_start = date_iter.next() if o_start > self.end_recurring_period: raise StopIteration o_end = o_start + difference if o_end > after: yield self._create_occurrence(o_start, o_end) def occurrences_after(self, after=None): """ returns a generator that produces occurrences after the datetime ``after``. Includes all of the persisted Occurrences. """ occ_replacer = OccurrenceReplacer(self.occurrence_set.all()) generator = self._occurrences_after_generator(after) while True: next = generator.next() yield occ_replacer.get_occurrence(next)
from forum.models import Question from django.conf import settings from djangosphinx.models import SphinxSearch Question.add_to_class('search', SphinxSearch( index=' '.join(settings.SPHINX_SEARCH_INDICES), mode='SPH_MATCH_BOOLEAN', ) )
retval = '<a href="%s">%s</a>:<br>\n' % (url, self.title) out = map(lambda x: '<li>' + x + '</li>', out) retval += '<ul>' + '\n'.join(out) + '</ul><br>\n' return retval else: return None def __unicode__(self): return self.title if getattr(settings, 'USE_SPHINX_SEARCH', False): from djangosphinx.models import SphinxSearch Question.add_to_class( 'sphinx_search', SphinxSearch(index=settings.ASKBOT_SPHINX_SEARCH_INDEX, mode='SPH_MATCH_ALL')) class QuestionView(models.Model): question = models.ForeignKey(Question, related_name='viewed') who = models.ForeignKey(User, related_name='question_views') when = models.DateTimeField() class Meta: app_label = 'askbot' class FavoriteQuestion(models.Model): """A favorite Question of a User.""" question = models.ForeignKey(Question) user = models.ForeignKey(User, related_name='user_favorite_questions')
class Event(WithPublished, WithSite): title = models.CharField(_('title'), max_length=300) original_title = models.CharField(_('origin title'), max_length=300, null=True, blank=True) category = models.ForeignKey(EventCategory, related_name='events', verbose_name=_('category')) image = models.ImageField(_('image'), upload_to=make_upload_path, null=True, blank=True) genre = TaggableManager(blank=True, verbose_name=_('genres')) place = models.ManyToManyField(Place, through='Occurrence', related_name='events', verbose_name=_('place')) description = tinymce_models.HTMLField(_('description'), default='') additional = models.TextField(_('Additional Field'), blank=True, null=True) intro = models.TextField(_('intro'), blank=True, null=True) trailer = models.URLField(_('video URL'), help_text=_( 'Put the URL of the YouTube video. Example: ' 'http://www.youtube.com/watch?v=wuzgCwKElm4 ' 'or http://vimeo.com/3465465'), blank=True, null=True) rate = models.FloatField(max_length=10, default=1, editable=False) num_votes = models.PositiveIntegerField(_('number of votes'), default=0, editable=False) members = models.ManyToManyField(User, related_name='events', blank=True, null=True) num_comments = models.PositiveIntegerField(_('number of comments'), default=0) publish_on_main = models.BooleanField(_('event publish on the main page'), default=True) start_date = models.DateField(_('start date for displaying'), default=None, blank=True, null=True) start_time = models.TimeField(_('start time for displaying'), default=None, blank=True, null=True) kinohod_id = models.IntegerField(_('Kinohod id movie'), default=0) search = SphinxSearch( index='event_index', weights={ 'title': 100, }, mode='SPH_MATCH_ALL', rankmode='SPH_RANK_NONE', ) objects = EventManager() default_manager = models.Manager() class Meta: ordering = ['title', 'category', 'id'] verbose_name = _('event') verbose_name_plural = _('events') def save(self, *args, **kwargs): super(Event, self).save(*args, **kwargs) if not self.sites.exists(): self.sites.add(Site.objects.get_current()) self.start_date = self.get_start_date() self.save_base() super(Event, self).save(*args, **kwargs) def __unicode__(self): return self.title @property def get_video_id(self): if not self.trailer: return None match = re.match(VIDEO_URL_PATTERN, self.trailer) # print self.trailer if match: if 'vimeo' in match.groups()[1]: return 'www.' + match.groups( )[1] + '/moogaloop.swf?clip_id=' + match.groups()[3] if 'youtube' in match.groups()[1]: # print 'www.' + match.groups()[1] + '/v/' + match.groups()[3] + '&fs=1' return 'www.' + match.groups()[1] + '/v/' + match.groups()[3] return None def get_thumbnail_url(self): return 'http://i.ytimg.com/vi/%s/default.jpg' % self.get_video_id() def get_start_date(self): periods = self.periods.all() if periods: return periods[0].start_date return None @property def get_embed_video_object(self): video_id = self.get_video_id if video_id: return EMBED_VIDEO_OBJECT % ('100%', '100%', video_id) else: return None @property def is_movie(self): if self.category.id == 14: return True else: return False @property def has_movie(self): if self.is_movie and self.trailer: return True return False @property def is_exposure(self): return self.category.id == 25 @property def is_sport(self): return self.category.id in (23, 24, 26, 27, 28) @property def has_passed(self): today = datetime.date.today() date = self.periods.aggregate(end=models.Max('end_date')) if date['end'] < today: return True return False @property def is_soon(self): today = datetime.date.today() try: if self.soon_flag: return True except SoonEvent.DoesNotExist: pass try: start_date = self.periods.all().order_by('start_date')[0] if start_date.start_date > today: return True except IndexError: pass return False def get_absolute_url(self): return reverse('event_detail', args=[self.category.slug, self.id]) def has_recurring_occurrences(self): return self.periods.exclude(repeat_on=0).exists() def has_several_occurrences(self): return self.periods.all().count( ) > 1 or self.has_recurring_occurrences() def is_today(self): return any( (period.has_repeat_on_day() for period in self.periods.active())) def shedule(self, today=None): today = today or self.is_today() try: if today: period = self.periods.daily_occurrences()[0] else: period = self.periods.soon()[0] except IndexError: try: period = self.periods.order_by('-end_date')[0] except IndexError: period = self.periods.none() return (period, today)