Repository: django-cms/django-cms

Issue:
.pyc included in tarball
I'm working on packaging django-cms for Debian and I've stumbled across the minor issue that there are lots of .pyc files shipped in the source tarball. Maybe this can be fixed in a future release.



Discussion:
Any pointers _how_ we can fix that?

```
find . -name '*.pyc' -delete
```

Before making source tarball?

I'd do a `git checkout-index -a -f --prefix=/destination/path/` to get a clean copy the the tree and then run `python setup.py sdist upload` from there.


Resolving patch:
diff --git a/cms/utils/reversion_hacks.py b/cms/utils/reversion_hacks.py
--- a/cms/utils/reversion_hacks.py
+++ b/cms/utils/reversion_hacks.py
@@ -1,35 +1,34 @@
 # -*- coding: utf-8 -*-
+from django.db import models
 import reversion
 from reversion.revisions import RegistrationError, RegistrationInfo
-from reversion.storage import VersionFileStorageWrapper
-from django.db import models
 
 def register_draft_only(model_class, fields, follow, format):
     """
-    version of the reversion register function that only 
-    registers drafts and ignores public models
+    version of the reversion register function that only registers drafts and
+    ignores public models
     """
     revision_manager = reversion.revision
     if revision_manager.is_registered(model_class):
-        raise RegistrationError, "%r has already been registered with Reversion." % model_class
+        raise RegistrationError(
+            "%r has already been registered with Reversion." % model_class)
+
     # Ensure the parent model of proxy models is registered.
-    if model_class._meta.proxy and not revision_manager.is_registered(model_class._meta.parents.keys()[0]):
-        raise RegistrationError, "%r is a proxy model, and its parent has not been registered with Reversion." % model_class
+    if (model_class._meta.proxy and
+        not revision_manager.is_registered(model_class._meta.parents.keys()[0])):
+        raise RegistrationError(
+            '%r is a proxy model, and its parent has not been registered with'
+            'Reversion.' % model_class)
+
     # Calculate serializable model fields.
     opts = model_class._meta
     local_fields = opts.local_fields + opts.local_many_to_many
     if fields is None:
         fields = [field.name for field in local_fields]
     fields = tuple(fields)
-    # Calculate serializable model file fields.
-    file_fields = []
-    for field in local_fields:
-        if isinstance(field, models.FileField) and field.name in fields:
-            field.storage = VersionFileStorageWrapper(field.storage)
-            file_fields.append(field)
-    file_fields = tuple(file_fields)
+
     # Register the generated registration information.
     follow = tuple(follow)
-    registration_info = RegistrationInfo(fields, file_fields, follow, format)
+    registration_info = RegistrationInfo(fields, follow, format)
     revision_manager._registry[model_class] = registration_info
     # Do not connect to the post save signal of the model.
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -46,7 +46,7 @@
     platforms=['OS Independent'],
     classifiers=CLASSIFIERS,
     install_requires=[
-        'Django>=1.2',
+        'Django>=1.2.5',
         'django-classy-tags>=0.3.3',
         'south>=0.7.2',
         'django-mptt>=0.4.2',


Test patch:
diff --git a/cms/tests/__init__.py b/cms/tests/__init__.py
--- a/cms/tests/__init__.py
+++ b/cms/tests/__init__.py
@@ -22,7 +22,7 @@
 from cms.tests.po import PoTest
 from cms.tests.publisher import PublisherTestCase
 from cms.tests.rendering import RenderingTestCase
-from cms.tests.reversion_tests import ReversionTestCase
+from cms.tests.reversion_tests import ReversionTestCase, ReversionFileFieldTests
 from cms.tests.security import SecurityTests
 from cms.tests.settings import SettingsTests
 from cms.tests.site import SiteTestCase
diff --git a/cms/tests/reversion_tests.py b/cms/tests/reversion_tests.py
--- a/cms/tests/reversion_tests.py
+++ b/cms/tests/reversion_tests.py
@@ -3,25 +3,32 @@
 from cms.models import Page
 from cms.models.pluginmodel import CMSPlugin
 from cms.plugins.text.models import Text
-from cms.test_utils.testcases import (CMSTestCase, URL_CMS_PAGE, 
-    URL_CMS_PAGE_CHANGE, URL_CMS_PAGE_ADD, URL_CMS_PLUGIN_ADD, URL_CMS_PLUGIN_EDIT)
+from cms.test_utils.testcases import (CMSTestCase, URL_CMS_PAGE,
+    URL_CMS_PAGE_CHANGE, URL_CMS_PAGE_ADD, URL_CMS_PLUGIN_ADD,
+    URL_CMS_PLUGIN_EDIT)
 from django.conf import settings
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
+from django.core.files.uploadedfile import SimpleUploadedFile
+from os.path import join
+from project.fileapp.models import FileModel
 from reversion.models import Revision, Version
-
+from reversion import revision as revision_manager
+import shutil
 
 class ReversionTestCase(CMSTestCase):
     def setUp(self):
-        u = User(username="test", is_staff = True, is_active = True, is_superuser = True)
+        u = User(username="test", is_staff=True, is_active=True,
+            is_superuser=True)
         u.set_password("test")
         u.save()
-        
+
         with self.login_user_context(u):
             # add a new text plugin
             self.page_data = self.get_new_page_data()
             response = self.client.post(URL_CMS_PAGE_ADD, self.page_data)
             self.assertRedirects(response, URL_CMS_PAGE)
+
             page = Page.objects.all()[0]
             placeholderpk = page.placeholders.get(slot="body").pk
             plugin_data = {
@@ -32,7 +39,9 @@ def setUp(self):
             }
             response = self.client.post(URL_CMS_PLUGIN_ADD, plugin_data)
             self.assertEquals(response.status_code, 200)
-            self.assertEquals(int(response.content), CMSPlugin.objects.all()[0].pk)
+            self.assertEquals(int(response.content),
+                CMSPlugin.objects.all()[0].pk)
+
             # now edit the plugin
             edit_url = URL_CMS_PLUGIN_EDIT + response.content + "/"
             response = self.client.get(edit_url)
@@ -41,6 +50,7 @@ def setUp(self):
             self.assertEquals(response.status_code, 200)
             txt = Text.objects.all()[0]
             self.assertEquals("Hello World", txt.body)
+
             # change the content
             response = self.client.post(edit_url, {"body":"Bye Bye World"})
             self.assertEquals(response.status_code, 200)
@@ -59,25 +69,32 @@ def test_revert(self):
             self.assertEquals(Page.objects.all().count(), 2)
             self.assertEquals(CMSPlugin.objects.all().count(), 2)
             self.assertEquals(Revision.objects.all().count(), 5)
+
             ctype = ContentType.objects.get_for_model(Page)
             revision = Revision.objects.all()[2]
             version = Version.objects.get(content_type=ctype, revision=revision)
             page = Page.objects.all()[0]
+
             history_url = URL_CMS_PAGE_CHANGE % (page.pk) + "history/"
             response = self.client.get(history_url)
             self.assertEquals(response.status_code, 200)
+
             revert_url = history_url + "%s/" % version.pk
             response = self.client.get(revert_url)
             self.assertEquals(response.status_code, 200)
+
             response = self.client.post(revert_url, self.page_data)
             self.assertRedirects(response, URL_CMS_PAGE_CHANGE % page.pk)
-            # test for publisher_is_draft, published is set for both draft and published page
+
+            # test for publisher_is_draft, published is set for both draft and
+            # published page
             self.assertEquals(Page.objects.all()[0].publisher_is_draft, True)
             self.assertEquals(CMSPlugin.objects.all().count(), 2)
+
             # test that CMSPlugin subclasses are reverted
             self.assertEquals(Text.objects.all().count(), 2)
             self.assertEquals(Revision.objects.all().count(), 6)
-        
+
     def test_recover(self):
         """
         Test that you can recover a page
@@ -87,22 +104,23 @@ def test_recover(self):
             ctype = ContentType.objects.get_for_model(Page)
             revision = Revision.objects.all()[4]
             version = Version.objects.get(content_type=ctype, revision=revision)
-            
+
             self.assertEquals(Page.objects.all().count(), 2)
             self.assertEquals(CMSPlugin.objects.all().count(), 2)
             self.assertEquals(Text.objects.all().count(), 2)
-            
+
             page = Page.objects.all()[0]
             page_pk = page.pk
             page.delete_with_public()
-            
+
             self.assertEquals(Page.objects.all().count(), 0)
             self.assertEquals(CMSPlugin.objects.all().count(), 0)
             self.assertEquals(Text.objects.all().count(), 0)
-                    
+
             recover_url = URL_CMS_PAGE + "recover/"
             response = self.client.get(recover_url)
             self.assertEquals(response.status_code, 200)
+
             recover_url += "%s/" % version.pk
             response = self.client.get(recover_url)
             self.assertEquals(response.status_code, 200)
@@ -110,5 +128,34 @@ def test_recover(self):
             self.assertRedirects(response, URL_CMS_PAGE_CHANGE % page_pk)
             self.assertEquals(Page.objects.all().count(), 1)
             self.assertEquals(CMSPlugin.objects.all().count(), 1)
+
             # test that CMSPlugin subclasses are recovered
             self.assertEquals(Text.objects.all().count(), 1)
+
+class ReversionFileFieldTests(CMSTestCase):
+    def tearDown(self):
+        shutil.rmtree(join(settings.MEDIA_ROOT, 'fileapp'))
+
+    def test_file_persistence(self):
+        with revision_manager:
+            # add a file instance
+            file1 = FileModel()
+            file1.test_file.save('file1.txt',
+                SimpleUploadedFile('file1.txt', 'content1'), False)
+            file1.save()
+            # manually add a revision because we use the explicit way
+            # django-cms uses too.
+            revision_manager.add(file1)
+
+        # reload the instance from db
+        file2 = FileModel.objects.all()[0]
+        # delete the instance.
+        file2.delete()
+
+        # revert the old version
+        file_version = Version.objects.get_for_object(file1)[0]
+        file_version.revert()
+
+        # reload the reverted instance and check for its content
+        file1 = FileModel.objects.all()[0]
+        self.assertEqual(file1.test_file.file.read(), 'content1')
diff --git a/tests/buildout.cfg b/tests/buildout.cfg
--- a/tests/buildout.cfg
+++ b/tests/buildout.cfg
@@ -34,5 +34,5 @@ eggs = ${buildout:eggs}
 [versions]
 coverage = 3.4
 unittest-xml-reporting = 1.0.3
-django-reversion = 1.3.3
+django-reversion = 1.4
 djangorecipe = 0.23.1
diff --git a/tests/django-124.cfg b/tests/django-124.cfg
new file mode 100644
--- /dev/null
+++ b/tests/django-124.cfg
@@ -0,0 +1,9 @@
+[buildout]
+extends = buildout.cfg
+
+[django]
+recipe = djangorecipe
+version = 1.2.4
+project = project
+settings = settings
+eggs = ${buildout:eggs}
diff --git a/tests/project/fileapp/__init__.py b/tests/project/fileapp/__init__.py
new file mode 100644
diff --git a/tests/project/fileapp/models.py b/tests/project/fileapp/models.py
new file mode 100644
--- /dev/null
+++ b/tests/project/fileapp/models.py
@@ -0,0 +1,7 @@
+from cms.utils.helpers import reversion_register
+from django.db import models
+
+class FileModel(models.Model):
+    test_file = models.FileField(upload_to='fileapp/', blank=True, null=True)
+
+reversion_register(FileModel)
diff --git a/tests/project/settings.py b/tests/project/settings.py
--- a/tests/project/settings.py
+++ b/tests/project/settings.py
@@ -104,6 +104,7 @@
     'project.pluginapp',
     'project.pluginapp.plugins.manytomany_rel',
     'project.fakemlng',
+    'project.fileapp',
     'south',
     'reversion',
     'sekizai',