Repository: zestedesavoir/zds-site

Issue:
Indiquer la taille des fichiers téléchargeables
[Via Jeekwiz](http://zestedesavoir.com/forums/sujet/268/indiquer-la-taille-des-fichiers-telechargeables/)

C'est qu'un détail mais ce serait bien d'afficher la taille des fichiers téléchargeables à coté du lien (PDF, HTML, EPUB, Archive).



Discussion:
Si tant est qu'on dispose de cette taille à priori, ce dont je ne suis pas
certain.

Le 12 juin 2014 15:11, Eskimon notifications@github.com a écrit :

> Via Jeekwiz
> http://zestedesavoir.com/forums/sujet/268/indiquer-la-taille-des-fichiers-telechargeables/
> 
> C'est qu'un détail mais ce serait bien d'afficher la taille des fichiers
> téléchargeables à coté du lien (PDF, HTML, EPUB, Archive).
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/zestedesavoir/zds-site/issues/872.

Google me dit : os.path.getsize(path)

Apres je sais pas si les liens sont en BDD ou pas etc... car ca pourrait etre judicieux d'ajouter un champ pour la taille du fichier pour eviter de la recalculer a chaque affichage...)

Les fichiers sont générés à la validation, donc on peut mesurer leur taille :)

Cette idée n'a pas l'air de motiver quiconque depuis plus d'un an. Je la considère donc comme abandonnée, si ça intéresse quelqu'un, il suffit de ré-ouvrir.

Raaah, c'est con, ça aurait pris 30 secondes à faire si je l'avais su ^^

@pierre-24 je peux m'occuper de ça si tu n'as pas commencé ?

Je t'en prie ;)


Resolving patch:
diff --git a/zds/tutorialv2/migrations/0010_publishedcontent_sizes.py b/zds/tutorialv2/migrations/0010_publishedcontent_sizes.py
new file mode 100644
--- /dev/null
+++ b/zds/tutorialv2/migrations/0010_publishedcontent_sizes.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tutorialv2', '0009_publishedcontent_authors'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='publishedcontent',
+            name='sizes',
+            field=models.CharField(default=b'{}', max_length=512, verbose_name=b'Tailles des fichiers t\xc3\xa9l\xc3\xa9chargeables'),
+            preserve_default=True,
+        ),
+    ]
diff --git a/zds/tutorialv2/models/models_database.py b/zds/tutorialv2/models/models_database.py
--- a/zds/tutorialv2/models/models_database.py
+++ b/zds/tutorialv2/models/models_database.py
@@ -35,6 +35,9 @@
 from zds.tutorialv2.managers import PublishedContentManager
 
 
+ALLOWED_TYPES = ['pdf', 'md', 'html', 'epub', 'zip']
+
+
 class PublishableContent(models.Model):
     """A tutorial whatever its size or an article.
 
@@ -200,6 +203,7 @@ def get_repo_path(self, relative=False):
     def in_beta(self):
         """A tutorial is not in beta if sha_beta is ``None`` or empty
 
+
         :return: ``True`` if the tutorial is in beta, ``False`` otherwise
         :rtype: bool
         """
@@ -550,6 +554,9 @@ class Meta:
     objects = PublishedContentManager()
     versioned_model = None
 
+    # sizes contain a python dict (as a string in database) with all information about file sizes
+    sizes = models.CharField('Tailles des fichiers téléchargeables', max_length=512, default='{}')
+
     def __unicode__(self):
         return _('Version publique de "{}"').format(self.content.title)
 
@@ -628,9 +635,7 @@ def have_type(self, type_):
         :rtype: bool
         """
 
-        allowed_types = ['pdf', 'md', 'html', 'epub', 'zip']
-
-        if type_ in allowed_types:
+        if type_ in ALLOWED_TYPES:
             return os.path.isfile(
                 os.path.join(self.get_extra_contents_directory(), self.content_public_slug + '.' + type_))
 
@@ -669,13 +674,75 @@ def have_epub(self):
         return self.have_type('epub')
 
     def have_zip(self):
-        """Check if the standard epub version of the content is available
+        """Check if the standard zip version of the content is available
 
         :return: ``True`` if available, ``False`` otherwise
         :rtype: bool
         """
         return self.have_type('zip')
 
+    def get_size_file_type(self, type_):
+        """
+        Get the size of a given extra content.
+        Is the size is not in database we get it and store it for next time.
+
+        :return: size of file
+        :rtype: int
+        """
+        if type_ in ALLOWED_TYPES:
+            sizes = eval(str(self.sizes))
+            try:
+                size = sizes[type_]
+            except KeyError:
+                # if size is not in database we store it
+                sizes[type_] = os.path.getsize(os.path.join(
+                    self.get_extra_contents_directory(), self.content_public_slug + '.' + type_))
+                self.sizes = sizes
+                self.save()
+                size = sizes[type_]
+            return size
+        return None
+
+    def get_size_md(self):
+        """Get the size of md
+
+        :return: size of file
+        :rtype: int
+        """
+        return self.get_size_file_type('md')
+
+    def get_size_html(self):
+        """Get the size of html
+
+        :return: size of file
+        :rtype: int
+        """
+        return self.get_size_file_type('html')
+
+    def get_size_pdf(self):
+        """Get the size of pdf
+
+        :return: size of file
+        :rtype: int
+        """
+        return self.get_size_file_type('pdf')
+
+    def get_size_epub(self):
+        """Get the size of epub
+
+        :return: size of file
+        :rtype: int
+        """
+        return self.get_size_file_type('epub')
+
+    def get_size_zip(self):
+        """Get the size of zip
+
+        :return: size of file
+        :rtype: int
+        """
+        return self.get_size_file_type('zip')
+
     def get_absolute_url_to_extra_content(self, type_):
         """Get the url that point to the extra content the user may want to download
 
@@ -685,9 +752,7 @@ def get_absolute_url_to_extra_content(self, type_):
         :rtype: str
         """
 
-        allowed_types = ['pdf', 'md', 'html', 'epub', 'zip']
-
-        if type_ in allowed_types:
+        if type_ in ALLOWED_TYPES:
             reversed_ = self.content_type.lower()
 
             return reverse(
diff --git a/zds/tutorialv2/utils.py b/zds/tutorialv2/utils.py
--- a/zds/tutorialv2/utils.py
+++ b/zds/tutorialv2/utils.py
@@ -681,6 +681,15 @@ def publish_content(db_object, versioned, is_major_update=True):
     except IOError:
         pass
 
+    # store files sizes
+    from zds.tutorialv2.models.models_database import ALLOWED_TYPES
+    sizes = {}
+    for t in ALLOWED_TYPES:
+        if public_version.have_type(t):
+            sizes[t] = public_version.get_size_file_type(t)
+    public_version.sizes = sizes
+    public_version.save()
+
     return public_version
 
 


Test patch:
diff --git a/zds/tutorialv2/tests/tests_views.py b/zds/tutorialv2/tests/tests_views.py
--- a/zds/tutorialv2/tests/tests_views.py
+++ b/zds/tutorialv2/tests/tests_views.py
@@ -19,7 +19,7 @@
 from zds.tutorialv2.factories import PublishableContentFactory, ContainerFactory, ExtractFactory, LicenceFactory, \
     SubCategoryFactory, PublishedContentFactory, tricky_text_content, BetaContentFactory
 from zds.tutorialv2.models.models_database import PublishableContent, Validation, PublishedContent, ContentReaction, \
-    ContentRead
+    ContentRead, ALLOWED_TYPES
 from zds.tutorialv2.utils import publish_content
 from zds.gallery.factories import UserGalleryFactory
 from zds.gallery.models import Image
@@ -5137,6 +5137,18 @@ def test_public_authors_versioned(self):
         self.assertNotIn(other_author.user.username, response.content)
         self.assertEqual(0, len(other_author.get_public_contents()))
 
+    def test_download_size(self):
+        """
+        Test the size of content to download.
+        """
+        sizes = self.published.sizes
+        for type_ in ALLOWED_TYPES:
+            if self.published.have_type(type_):
+                self.assertEqual(sizes[type_],
+                                 os.path.getsize(os.path.join(
+                                     self.published.get_extra_contents_directory(),
+                                     self.published.content_public_slug + '.' + type_)))
+
     def tearDown(self):
 
         if os.path.isdir(settings.ZDS_APP['content']['repo_private_path']):