class Houseplant(TimeStampedModel): common_name = models.CharField(max_length=100) latin_name = models.CharField(max_length=200, blank=True, null=True) slug = AutoSlugField(populate_from=['common_name'], unique=True) avatar = models.ImageField(upload_to=image_upload_to, blank=True, null=True) description = models.TextField(blank=True, null=True) care_notes = models.TextField(blank=True, null=True) temperature = models.CharField(max_length=30, choices=TEMPERATURE_CHOICES) moisture = models.CharField(max_length=30, choices=MOISTURE_CHOICES) difficulty = models.CharField(max_length=30, choices=DIFFICULTY_CHOICES) light_high = models.BooleanField(default=True) light_low = models.BooleanField(default=True) edible = models.BooleanField(default=False) flowering = models.BooleanField(default=False) poisonous = models.BooleanField(default=False) tags = TaggableManager(blank=True) def __str__(self): return self.common_name def get_absolute_url(self): return 'plants/' + self.slug
class Team(TimeStampedModel): name = models.CharField(max_length=60, ) slug = AutoSlugField(populate_from=['name'], ) location = models.TextField() def __str__(self): return self.name
class Team(TimeStampedModel): name = models.CharField(max_length=100, ) slug = AutoSlugField(populate_from=["name"], ) location = models.TextField() def __str__(self): return f"{self.name} ({self.location})"
class Idea(Model): name = CharField(max_length=100, verbose_name=_('Name')) slug = AutoSlugField(populate_from='name', verbose_name=_('Slug')) created_at = CreationDateTimeField(verbose_name=_('Date Created')) modified_at = ModificationDateTimeField( verbose_name=_('Date Modified')) description = TextField(max_length=300, verbose_name=_('Description')) is_public = BooleanField(default=False, verbose_name=_('Is Public')) is_published = BooleanField(default=False, verbose_name=_('Pusblish Now')) views = PositiveIntegerField(default=0, verbose_name=_('Amount of Views')) # relations # license = ForeignKey(to=License, related_name='ideas', verbose_name=_('Licenses')) # patent = ForeignKey(to=Patent, related_name='ideas', verbose_name=_('Patents')) user = ForeignKey(to=User, related_name='ideas', verbose_name=_('Author')) categories = ManyToManyField(to=Category, related_name='ideas', verbose_name=_('Category')) class Meta: db_table = 'idea' verbose_name = _('Idea') verbose_name_plural = _('Ideas') def __unicode__(self): return u"%s" % self.name
class League(TimeStampedModel): name = models.CharField(max_length=100, ) slug = AutoSlugField(populate_from=["name"], ) owner = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.PROTECT, ) def __str__(self): return f"{self.name}"
class Season(TimeStampedModel): league = models.ForeignKey( 'league.League', on_delete=models.CASCADE, ) name = models.CharField(max_length=60, ) slug = AutoSlugField(populate_from=['name'], ) def __str__(self): return self.name
class Season(TimeStampedModel): league = models.ForeignKey( "league.League", on_delete=models.CASCADE, ) name = models.CharField(max_length=100, ) slug = AutoSlugField(populate_from=["name"], ) def __str__(self): return f"{self.name} ({self.league})"
class Player(TimeStampedModel): first_name = models.CharField(max_length=100, ) last_name = models.CharField(max_length=100, ) slug = AutoSlugField(populate_from=["first_name", "last_name"], ) height = models.FloatField(help_text="In cm", ) weight = models.FloatField(help_text="In kg", ) date_of_birth = models.DateField() def __str__(self): return f"{self.first_name} {self.middle_name} {self.last_name}"
class Contact(models.Model): first_name = models.CharField(max_length=56) last_name = models.CharField(max_length=256) contact_user_obj = models.ManyToManyField(User) slug = AutoSlugField(populate_from=['first_name', 'last_name']) def __str__(self): return '{} {}'.format(self.first_name, self.last_name) def get_queryset(self): return User.objects.get(id=self.id)
class Section(SoftDeleteObject, TimeStampedModel): project = models.ForeignKey("projects.Project", on_delete=models.CASCADE, related_name="sections") name = models.CharField(max_length=constants.SECTION_NAME_MAX_LENGTH) slug = AutoSlugField(populate_from="name", allow_duplicates=True) created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True) is_public = models.BooleanField(default=True) is_rss_content = models.BooleanField(default=False) objects = managers.SectionManager() class Meta: constraints = [ models.UniqueConstraint( fields=["project", "name"], name="unique_section_name", condition=models.Q(deleted_at=None), ) ] def __str__(self): return f"{self.name}" def natural_key(self): return self.project.title, self.name natural_key.dependencies = ["projects.project"] @functional.cached_property def project_info(self): return self.project.project_info @functional.cached_property def pages_count(self): return self.pages.count() def set_main_page(self, page_id): self.pages.filter(is_main_page=True, is_draft=True).update(is_main_page=False) main_page = self.pages.get(id=page_id) main_page.is_main_page = True main_page.save() def get_main_page(self): try: main_page = Page.only_pages.get(section=self, is_main_page=True, is_draft=True) return main_page except Page.DoesNotExist: return None
class Category(Model): name = CharField(max_length=100, verbose_name=_('Name')) slug = AutoSlugField(populate_from='name', max_length=200) class Meta: db_table = 'category' verbose_name = _('Category') verbose_name_plural = _('Categories') def __unicode__(self): return u"%s" % self.name
class Player(TimeStampedModel): first_name = models.CharField(max_length=60, ) middle_name = models.CharField( max_length=60, blank=True, ) last_name = models.CharField(max_length=60, ) slug = AutoSlugField(populate_from=['first_name', 'last_name'], ) height = models.FloatField(help_text='In cm', ) weight = models.FloatField(help_text='In kg', ) date_of_birth = models.DateField() def __str__(self): return f'{self.first_name} {self.last_name}'
class TeamSeason(TimeStampedModel): season = models.ForeignKey( "league.Season", on_delete=models.CASCADE, ) team = models.ForeignKey( "league.Team", #"Team" on_delete=models.CASCADE, ) name = models.CharField(max_length=100, ) slug = AutoSlugField(populate_from=["name"], ) def __str__(self): return f"{self.name} ({self.team} {self.season})"
class Menu(ClusterableModel): title = models.CharField(max_length=100) slug = AutoSlugField( populate_from="title", editable=True, ) panels = [ FieldPanel("title"), FieldPanel("slug"), InlinePanel("menu_items", label="Single Menu Item") ] def __str__(self): return self.title
class Category(TimestampedModel): name = models.CharField(db_index=True, max_length=150, unique=True) # Unique slug field to enforce that categories are the same as lone categories or subcategory # A concatenation of the supercategory(if specified) and its name slug = AutoSlugField(populate_from=['supercategory', 'name'], unique=True) # A one-to-many relation where a category can belong to another category(supercategory) as a subcategory supercategory = models.ForeignKey('self', related_name='subcategories', blank=True, null=True, on_delete=models.CASCADE) class Meta: # unique_together = ('name', 'supercategory') verbose_name_plural = 'categories' def __str__(self): return self.name
class Light(TimeStampedModel): """Database model representing a light bulb.""" OFF_STATUS, ON_STATUS = range(2) STATUS_CHOICES = ( (OFF_STATUS, _('Off')), (ON_STATUS, _('On')), ) name = models.CharField(_('Name'), max_length=255) slug = AutoSlugField(_('Slug'), populate_from='name') status = models.IntegerField(_('Status'), choices=STATUS_CHOICES, default=OFF_STATUS) class Meta: ordering = ('-created', ) def __str__(self): return self.name def send_status_update(self): """ Sends a status updates to subscribed channels. """ command = { "light_id": self.id, "status": self.status, "created": self.created.strftime("%a %d %b %Y %H:%M"), } Group('lights').send({ # WebSocket text frame, with JSON content "text": json.dumps(command), }) def save(self, *args, **kwargs): """ Hooking send_notification into the save of the object as I'm not the biggest fan of signals. """ result = super().save(*args, **kwargs) self.send_status_update() return result
class Page(Content): section = models.ForeignKey("Section", on_delete=models.CASCADE, null=True, blank=True, related_name="pages") template = models.ForeignKey("Page", on_delete=models.SET_NULL, null=True, blank=True) display_name = models.CharField( max_length=constants.PAGE_DISPLAY_NAME_MAX_LENGTH, blank=True, default="") description = models.TextField(blank=True, default="") keywords = models.TextField(blank=True, default="") slug = AutoSlugField(populate_from="name", allow_duplicates=True) is_public = models.BooleanField(default=True) allow_edit = models.BooleanField(default=False) is_template = models.BooleanField(default=True) is_draft = models.BooleanField(default=True, editable=False, db_index=True) published_version = models.OneToOneField( "self", on_delete=models.SET_NULL, related_name="draft_version", null=True, editable=False, ) publish_date = models.DateTimeField(null=True, blank=True) state = FSMField(choices=constants.PAGE_STATE_CHOICES, default=constants.PageState.DRAFT) link = models.URLField(blank=True, default="") is_main_page = models.BooleanField(default=False) objects = managers.PageManager() only_pages = managers.PageOnlyManager() templates = managers.PageOnlyTemplateManager() _clone_many_to_one_or_one_to_many_fields = ["tags"] class Meta: ordering = ("-created", ) def natural_key(self): return self.project.title, self.name, self.is_template, self.is_draft natural_key.dependencies = [ "projects.project", "pages.section", "pages.blocktemplate" ] @property def is_published(self): published_states = [ constants.PageState.PUBLISHED, constants.PageState.WAITING_TO_REPUBLISH ] if self.is_draft: return self.published_version.state in published_states else: return self.state in published_states def create_or_update_block(self, block): return PageBlock.objects.update_or_create(id=block.get("id", None), defaults={ "page": self, **block }) def delete_blocks(self, blocks: list = None): if not blocks: self.page_blocks.all().delete() self.page_blocks.all_with_deleted().delete() else: self.page_blocks.filter(id__in=blocks).delete() self.page_blocks.all_with_deleted().filter(id__in=blocks).delete() def add_tags(self, tags_list): self.tags.all().delete() self.tags.all().delete() for tag in tags_list: PageTag.objects.create(page=self, category_id=tag["category"], value=tag["value"]) @transition(field=state, source="*", target=constants.PageState.PUBLISHED) def publish(self): draft: Page = self.draft_version now = timezone.now() self.name = draft.name self.section = draft.section self.template = draft.template self.display_name = draft.display_name self.description = draft.description self.keywords = draft.keywords self.slug = draft.slug self.is_public = draft.is_public self.allow_edit = draft.allow_edit self.link = draft.link self.publish_date = now self.delete_blocks() self.tags.all().delete() self.tags.all().delete() for block in draft.page_blocks.all(): c_block = block.make_clone(attrs={"page": self}) for element in block.elements.all(): element.clone(c_block) for tag in draft.tags.all(): tag.make_clone(attrs={"page": self}) draft.publish_date = now @transition(field=state, source=constants.PageState.PUBLISHED, target=constants.PageState.WAITING_TO_REPUBLISH) def wait_to_republish(self): pass @transaction.atomic() def copy_page(self, attrs: dict = None): copy_time = timezone.now().strftime("%Y-%m-%d, %H:%M:%S.%f") if not attrs: attrs = {"name": f"Page ID #{self.id} copy({copy_time})"} new_page = self.make_clone(attrs=attrs) for block in self.page_blocks.all(): c_block = block.make_clone(attrs={"page": new_page}) for element in block.elements.all(): element.clone(c_block) return new_page @transaction.atomic() def copy_template(self): copy_time = timezone.now().strftime("%Y-%m-%d, %H:%M:%S.%f") new_page = self.make_clone( attrs={"name": f"Page Template ID #{self.id} copy({copy_time})"}) for block in self.page_blocks.all(): block.make_clone(attrs={"page": new_page}) return new_page def create_xml_item(self): item = etree.Element("item") etree.SubElement(item, "title").text = self.name etree.SubElement(item, "link").text = self.link etree.SubElement(item, "description").text = self.description ctime = self.publish_date.ctime() pub_date = f"{ctime[0:3]}, {self.publish_date.day:02d} {ctime[4:7]}" + self.publish_date.strftime( " %Y %H:%M:%S %z") etree.SubElement(item, "pubDate").text = pub_date return item
class PodcastChannel(TimeStampedModel): url = models.URLField(unique=True) title = models.CharField(max_length=255, blank=True) slug = AutoSlugField(populate_from='title', overwrite=True) description = models.TextField(blank=True) website = models.URLField(blank=True) copyright = models.CharField(max_length=255, blank=True) cover_url = models.URLField(blank=True) download_new = models.BooleanField(default=False) def __unicode__(self): return u'%s' % (self.title or self.url) @classmethod def subscribe(cls, url): channel = cls(url=url) channel.update_channel() return channel def update_channel(self, download=False): logger.info('Updating Channel: %s' % self) req = requests.get(self.url) if req.ok: tree = etree.fromstring(req.content) channel = tree.find('channel') self.title = getattr(channel.find('title'), 'text', None) or '' self.description = getattr( channel.find('description'), 'text', None) or '' self.website = getattr( channel.find('link'), 'text', None or '') self.copyright = getattr( channel.find('copyright'), 'text', None) or '' self.cover_url = self.parse_cover_url(channel) self.save() self.update_items(channel, download=download) else: logger.error('Failed to retrieve feed. Status %s' % req.reason) def parse_cover_url(self, tree): image_url = getattr( tree.find('image/url'), 'text', None) or '' if not image_url and 'media' in tree.nsmap: image_url = getattr( tree.find('media:thumbnail', tree.nsmap), 'attrib', {}).get('url', '') if not image_url and 'itunes' in tree.nsmap: image_url = getattr( tree.find('itunes:image', tree.nsmap), 'attrib', {}).get('href', '') return image_url def update_items(self, channel, download=False): new_items = [] for item in channel.findall('item'): guid = getattr(item.find('guid'), 'text', None) or '' pod_item, created = self.podcast_items.get_or_create(guid=guid) if created: pod_item.title = getattr( item.find('title'), 'text', None) or '' pod_item.description = getattr( item.find('description'), 'text', None) or '' pod_item.author = getattr( item.find('author'), 'text', None)or '' pod_item.link = getattr(item.find('link'), 'text', None) or '' pub_date = getattr(item.find('pubDate'), 'text', None) or '' if pub_date: pod_item.publish_date = dateutil.parser.parse(pub_date) enclosure = getattr( item.find('enclosure'), 'attrib', None) or '' if enclosure: pod_item.url = enclosure.get('url', '') pod_item.file_type = enclosure.get('type', '') pod_item.cover_url = self.parse_cover_url(item) pod_item.save() new_items.append(pod_item) logger.info('Found %d new items' % len(new_items)) if self.download_new or download: for item in new_items: item.download_file() def has_unlistened(self): return self.podcast_items.filter(listened=False).exists()
class PodcastItem(models.Model): guid = models.CharField(max_length=255, db_index=True) channel = models.ForeignKey(PodcastChannel, related_name='podcast_items') url = models.URLField() title = models.CharField(max_length=255, blank=True) slug = AutoSlugField(populate_from=('channel', 'title'), overwrite=True) description = models.TextField(blank=True) author = models.CharField(max_length=255, blank=True) link = models.URLField(blank=True) publish_date = models.DateTimeField(blank=True, null=True) file_type = models.CharField(max_length=20, blank=True) file = models.FileField(upload_to=settings.PODCAST_DIRECTORY, blank=True, null=True) listened = models.BooleanField(default=False) cover_url = models.URLField(blank=True) AUDIO_FORMATS = ('audio/mpeg', 'audio/mp4', 'audio/ogg', 'audio/vorbis', 'audio/webm', 'audio/vnd.wave') VIDEO_FORMATS = ('video/mpeg', 'video/mp4', 'video/ogg', 'video/webm', 'video/quicktime', 'video/x-flv', 'video/x-ms-wmv', 'video/x-m4v') class Meta: get_latest_by = 'publish_date' ordering = ('-publish_date',) def __unicode__(self): return u'%s - %s' % (self.channel, self.title) def download_file(self): logger.info('Downloading - %s' % self.title) req = requests.get(self.url, stream=True) if req.ok: # some downloads are too big to keep in memory filename = urlparse(self.url).path.split('/')[-1] file_path = '%s/%s' % (settings.PODCAST_DIRECTORY, filename) path = '%s/%s' % (settings.MEDIA_ROOT, file_path) with open(path, 'wb') as f: for block in req.iter_content(1024): if not block: break f.write(block) self.file = file_path self.save() else: logger.error('Failed to retrieve file. Status %s' % req.reason) def delete_file(self): if self.file: self.file.delete() @property def media_type(self): if self.file_type in self.AUDIO_FORMATS: media_type = 'audio' elif self.file_type in self.VIDEO_FORMATS: media_type = 'video' elif self.file_type: media_type = 'unknown' else: media_type = 'none' return media_type