def test_video_can_be_uploaded(self): file_name = get_random_name() video = File( open(os.path.join('tests', 'dummy-files', 'dummy-video.mp4'), 'rb')) model = TestVideoModel(name='name') model.video.save(file_name, video) model.full_clean() file_name = model.video.name storage = VideoMediaCloudinaryStorage() try: self.assertTrue(storage.exists(file_name)) finally: storage.delete(file_name)
class Audio(models.Model): name = models.CharField(max_length=100) mp3 = models.FileField(upload_to='audios/', blank=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) image = models.ImageField(upload_to='images/', blank=True) def delete(self, *args, **kwargs): # object is being removed from db, remove the file from storage first self.remove_audio( ) # Calling a custom delete method before remove this object from the database. self.mp3.delete() return super(Audio, self).delete(*args, **kwargs) def remove_audio(self): title = self.name path = os.listdir(DEFAULT_FILE_STORAGE) # Updating the title to compare it with the mp4 file that exist for it in this folder... title = special_characters(title) # Loop through the path to save the files to the database. for mp3_file in path: if mp3_file.endswith('mp3') and mp3_file.__contains__(title): os.remove(mp3_file) break def __str__(self): return f'{self.name}'
class Video(models.Model): name = models.CharField(max_length=100) mp4 = models.FileField(upload_to='videos/', blank=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) image = models.ImageField(upload_to='images/', blank=True)
class Flag(models.Model): ''' profile class to define FlagRecord objects ''' STATUS = [('Under Investigation', 'Under Investigation'), ('rejected', 'rejected'), ('resolved', 'resolved')] title = models.CharField(max_length=100) description = models.TextField() created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) latitude = models.DecimalField(max_digits=9, decimal_places=6, default='') longitude = models.DecimalField(max_digits=9, decimal_places=6, default='') tags = models.ManyToManyField(Tag) image = models.ImageField(upload_to='images/flagimages/', blank=True, storage=MediaCloudinaryStorage()) videos = models.FileField(upload_to='videos/', blank=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) user = models.ForeignKey(User, on_delete=models.CASCADE) def __str__(self): return self.title class Meta: verbose_name_plural = "Flags" ordering = ["-pk"]
class Video(models.Model): name = models.CharField(max_length=255, null=True, blank=True) mp4 = models.FileField(upload_to='videos/', null=True, blank=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) def __str__(self): return f'{self.name}'
class Audio(models.Model): name = models.CharField(max_length=255, null=True, blank=True) api = models.CharField(max_length=50, null=True, blank=True) mp3 = models.FileField(upload_to='audios/', null=True, blank=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) downloaded_on = models.DateTimeField(default=timezone.now) def __str__(self): return f'{self.name}' class Meta: ordering = ['name', '-downloaded_on']
class VideoPost(models.Model): caption = models.CharField(max_length=100) video = models.FileField(upload_to='videos/%y/', storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) thumbnail = models.ImageField(null=True, blank=True, default='defaults/kobyDrillsDotKom.png', upload_to='videos/%y/thumbnails') body = RichTextUploadingField() author = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True) category = models.ManyToManyField(Category) date = models.DateTimeField(auto_now_add=True, blank=True, null=True) slug = models.SlugField(blank=True, null=True) def __str__(self): return self.caption def save(self, *args, **kwargs): if self.slug == None: slug = slugify(self.caption) count = 0 slug_exist = VideoPost.objects.filter(slug=slug).exists() while slug_exist: slug = slugify(self.caption) + '-' + count count += 1 slug_exist = VideoPost.objects.filter(slug=slug).exists() self.slug = slug super().save(*args, **kwargs) @property def get_body_length(self): length = len(self.body) return length
class InterventionRecord(models.Model): ''' profile class to define InterventionRecord objects ''' STATUS = (('Under Investigation', 'Under Investigation'), ('rejected', 'rejected'), ('resolved', 'resolved')) title = models.CharField(max_length=50, blank=False) description = models.TextField(blank=True, null=True) time_of_creation = models.DateTimeField(auto_now_add=True) time_last_edit = models.DateTimeField(auto_now=True) status = models.CharField(max_length=20, choices=STATUS, blank=True, null=True, default="waiting") latitude = models.CharField(max_length=200, blank=True, null=True) longitude = models.CharField(max_length=200, blank=True, null=True) image = models.ImageField( upload_to='images/interventionimages/', blank=True, null=True, storage=MediaCloudinaryStorage(), max_length=100000, default="media/images/intervention_default_ozvizh.jpg") videos = models.FileField(upload_to='videos/', blank=True, null=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) user = models.ForeignKey(User, on_delete=models.CASCADE) tags = models.ManyToManyField(Tag, blank=True) def __str__(self): return self.title class Meta: ordering = ["-pk"]
class Article(CoreModel): """ A model for representing each article for the blog. Attributes: author (ForeignKey): one-to-one relation to set user to object tags (ManyToManyField): many-to-many relation to set tags to object video (FileField): field for video files. saved to cloudinary cover (ImageField): field for image files. saved to cloudinary title (CharField): field for article title. max length to 255. this field needs to be unique slug (SlugField): field for article slug. used for routing description (TextField): field for article description. content (MartorField): field for article content. uses martor's MartorField for markdown. related_article (ManyToManyField): many-to-many relation to set self as related articles keywords (CharField): field for article keyword. this is used for SEO. publish_at (DateTimeField) field for article publish datetime. objects (ArticleManager): set custom Manager to model Note: because ImageField and DateTimeField saves string in the database, null=True is not necessary. """ author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) tags = models.ManyToManyField(Tag, blank=True) video = models.FileField(upload_to=upload_video_to, blank=True, null=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) cover = models.ImageField(upload_to=upload_image_to, blank=True, null=True, storage=MediaCloudinaryStorage()) title = models.CharField(max_length=255, unique=True) slug = models.SlugField(unique=True) description = models.TextField() content = MartorField() related_articles = models.ManyToManyField('self', verbose_name='related articles', blank=True) keywords = models.CharField('記事のキーワード', max_length=255, default='プログラミング') publish_at = models.DateTimeField(auto_now=False, auto_now_add=False, blank=True, null=True) objects = ArticleManager() class Meta: """ Attributes: ordering (List): use to determine the ordering of model objects when listed """ ordering = [ '-publish_at', '-timestamp', '-updated', ] def __str__(self): """ determine which field of the model should be representing the model object. mainly used in admin site. Returns: str: returns title field. """ return self.title def get_absolute_url(self): """ determine to absolute url of the model. mainly used to route to detail view. """ return reverse("articles:article_detail", kwargs={"slug": self.slug}) def get_markdown(self): """ return a cleaned html. in case there is a markdown we use markdown package to convert them to html. Returns: str: string of safe html """ content = self.content markdown_content = markdownify(content) return mark_safe(markdown_content) def get_description(self): """ return description. if the description str length is greater then 50 it truncates the str. Returns: str: truncated string """ if len(self.description) > 50: return f"{self.description[:50]}..." return self.description def get_text_count(self): """ count strings in html. using BeautifulSoup4 to sanitize html tags. Returns: int: length of the string after sanitized by BeautifulSoup4 """ content = self.content markdown_content = markdownify(content) souped = BeautifulSoup(markdown_content, features="html.parser").findAll(text=True) stripted_text = "".join(souped).replace(" ", "") return len(stripted_text) def get_img_count(self): """ count img tags in html. using BeautifulSoup4 search through html. Returns: int: length of the images after filtering through using BeautifulSoup4 """ content = self.content markdown_content = markdownify(content) img_tags = BeautifulSoup(markdown_content, features="html.parser").find_all("img") return len(img_tags) @property def is_series_summary(self): return 'Series' in [tag.name for tag in self.tags.all()] @property def is_published(self): if self.publish_at is None: return False return timezone.now() > self.publish_at
class TestVideoModel(models.Model): name = models.CharField(max_length=100) video = models.FileField(upload_to='tests-videos/', blank=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video])
class TestModelWithVideoAndImage(models.Model): name = models.CharField(max_length=100) video = models.ImageField(upload_to='videos/', blank=True, storage=VideoMediaCloudinaryStorage(), validators=[validate_video]) image = models.ImageField(upload_to='images/', blank=True) # no need to set storage, field will use the default one