# HG changeset patch # User dellsystem # Date 1350790130 14400 # Node ID 86129d185ddbe5014e6a35d4cc13c99aaeb625a6 # Parent c042d26e693631fdc387c230cd8cf8a100239049 Add versioning to bundles Some other bundle-related changes were made, including: * Editing the snippetform CSS and HTML to allow bundle/form.djhtml to be reused for editing * Changing {% block title %} to {% block section %} in the base template for bundles to allow for more flexibility when creating breadcrumbs * Saved common URL patterns in variables in bundle/urls.py * Renamed explore.html to explore.djhtml for consistency You should now be able to upload new versions as well as view the files (or a particular file) for a bundle at a specific version. Coming soon: the ability to add a timestamp and a comment for each new uploaded version (if this feature is desirable). diff -r c042d26e6936 -r 86129d185ddb apps/bundle/forms.py --- a/apps/bundle/forms.py Sat Oct 20 19:24:09 2012 -0400 +++ b/apps/bundle/forms.py Sat Oct 20 23:28:50 2012 -0400 @@ -6,7 +6,21 @@ class BundleForm(forms.ModelForm): class Meta: model = Bundle - fields = ('uploader', 'name', 'description', 'free_license') + fields = ('name', 'description', 'free_license') file = forms.FileField(help_text=("Upload a plain text file or an \ archive file.")) + + +class BundleEditForm(forms.ModelForm): + """ + Like BundleForm, but for editing bundles. A new form is needed because + the name field should not be editable after creation, and because the + file field shouldn't be required in this case + """ + class Meta: + model = Bundle + fields = ('description', 'free_license') + + file = forms.FileField(help_text=("Upload a plain text file or an \ + archive file to update the version."), required=False) diff -r c042d26e6936 -r 86129d185ddb apps/bundle/models.py --- a/apps/bundle/models.py Sat Oct 20 19:24:09 2012 -0400 +++ b/apps/bundle/models.py Sat Oct 20 23:28:50 2012 -0400 @@ -28,6 +28,7 @@ mod_date = models.DateTimeField('date last modified', auto_now=True) done_uploading = models.BooleanField(default=False) file_name = models.CharField(max_length=256) # the uploaded file + latest_version = models.IntegerField(default=1) def __unicode__(self): return self.name @@ -37,11 +38,16 @@ return ('bundle_details', [self.uploader.username, self.name]) def get_temp_path(self): - return os.path.join('tmp', 'bundles', '%s' % self.id) + """ + Returns the path to where the file is initially uploaded + """ + return os.path.join('tmp', 'bundles', + "%d_%d" % (self.id, self.latest_version)) class BundleFile(MPTTModel): bundle = models.ForeignKey(Bundle) + version = models.IntegerField() parent = TreeForeignKey('self', null=True, blank=True, related_name='children') name = models.CharField(max_length=256) @@ -86,5 +92,6 @@ return ('bundlefile_details', [ self.bundle.uploader.username, self.bundle.name, + self.version, self.get_path() ]) diff -r c042d26e6936 -r 86129d185ddb apps/bundle/tasks.py --- a/apps/bundle/tasks.py Sat Oct 20 19:24:09 2012 -0400 +++ b/apps/bundle/tasks.py Sat Oct 20 23:28:50 2012 -0400 @@ -30,7 +30,8 @@ filename = os.path.basename(file_path) full_path = file_path[len(bundle.get_temp_path()) + 1:] bundle_file = BundleFile(bundle=bundle, name=filename, - parent=parent_dir, full_path=full_path) + parent=parent_dir, full_path=full_path, + version=bundle.latest_version) if file_path in files: bundle_file.is_dir = False @@ -79,7 +80,8 @@ elif mime_type.startswith('text/'): # Should be a plain text file - create a CodeFile for it bundle_file = BundleFile(bundle=bundle, name=bundle.file_name, - full_path=bundle.file_name, file_size=os.path.getsize(file)) + full_path=bundle.file_name, file_size=os.path.getsize(file), + version=bundle.latest_version) bundle_file.save_file_contents(open(file, 'rt'), original_filename=bundle.file_name) diff -r c042d26e6936 -r 86129d185ddb apps/bundle/urls.py --- a/apps/bundle/urls.py Sat Oct 20 19:24:09 2012 -0400 +++ b/apps/bundle/urls.py Sat Oct 20 23:28:50 2012 -0400 @@ -1,10 +1,17 @@ from django.conf.urls.defaults import * +BUNDLE_PATTERN = r'^(?P[^/]*)/(?P[^/]+)' +VERSION_PATTERN = '(?P\d+)' + + urlpatterns = patterns('apps.bundle.views', - url(r'^(?P[^/]+)/(?P[^/]+)/(?P.+)/$', 'file_detail', - name='bundlefile_details'), - url(r'^(?P.*)/(?P.*)/$', 'detail', name='bundle_details'), + url(BUNDLE_PATTERN + '/?$', 'detail', name='bundle_details'), + url(BUNDLE_PATTERN + '/' + VERSION_PATTERN + '/?$', 'detail', + name='bundle_version'), + url(BUNDLE_PATTERN + '/edit', 'edit', name='bundle_edit'), + url(BUNDLE_PATTERN + '/' + VERSION_PATTERN + '/(?P.+)/?$', + 'file_detail', name='bundlefile_details'), url(r'^$', 'index', name='bundle_new'), url(r'^explore$', 'explore', name='bundle_explore'), ) diff -r c042d26e6936 -r 86129d185ddb apps/bundle/views.py --- a/apps/bundle/views.py Sat Oct 20 19:24:09 2012 -0400 +++ b/apps/bundle/views.py Sat Oct 20 23:28:50 2012 -0400 @@ -7,14 +7,16 @@ from django.http import HttpResponse from apps.bundle.models import Bundle, BundleFile -from apps.bundle.forms import BundleForm +from apps.bundle.forms import BundleForm, BundleEditForm from apps.bundle.tasks import handle_bundle_upload from apps.pygments_style.models import PygmentsStyle -def detail(request, user, bundle, file=None): +def detail(request, user, bundle, file=None, version=0): bundle = get_object_or_404(Bundle, uploader__username=user, name=bundle) - files = bundle.bundlefile_set.all() + # If the version is not set, use the latest version + version = int(version) or bundle.latest_version + files = bundle.bundlefile_set.filter(version=version) if request.user.is_authenticated(): pygments_style = request.user.get_profile().pygments_style @@ -27,28 +29,31 @@ 'bundle': bundle, 'files': files, 'file': file, + 'previous_versions': xrange(1, bundle.latest_version + 1), + 'this_version': version, } return render(request, 'bundle/bundle.djhtml', context) -def file_detail(request, user, bundle, path): +def file_detail(request, user, bundle, version, path): + print version bundle_file = get_object_or_404(BundleFile, bundle__uploader__username=user, - bundle__name=bundle, full_path=path, is_dir=False) + bundle__name=bundle, full_path=path, is_dir=False, version=version) - return detail(request, user, bundle, file=bundle_file) + return detail(request, user, bundle, file=bundle_file, version=version) + @login_required def index(request): if request.method == 'POST': post_data = request.POST.copy() - post_data['uploader'] = request.user.id - form = BundleForm(post_data, - request.FILES) + bundle = Bundle(uploader=request.user) + form = BundleForm(post_data, request.FILES, instance=bundle) if form.is_valid(): file = request.FILES.get('file') - bundle = form.save() + form.save() bundle.file_name = file.name bundle.save() @@ -76,4 +81,45 @@ 'recent_bundles': Bundle.objects.all()[:20] } - return render(request, "bundle/explore.html", context) + return render(request, "bundle/explore.djhtml", context) + + +@login_required +def edit(request, user, bundle): + bundle = get_object_or_404(Bundle, name=bundle, + uploader__username=request.user.username) + + # If the username specified in the URL is someone else's, show that page + if user != request.user.username: + # The bundle must exist, otherwise it would 404 + return redirect(bundle) + + if request.method == 'POST': + form = BundleEditForm(request.POST, instance=bundle) + + if form.is_valid(): + form.save() + + file = request.FILES.get('file') + if file is not None: + bundle.done_uploading = False + bundle.file_name = file.name + bundle.latest_version += 1 + bundle.save() + bundle_path = bundle.get_temp_path() + + with open(bundle_path, 'wb+') as destination: + for chunk in request.FILES.get('file', []): + destination.write(chunk) + + handle_bundle_upload.delay(bundle.id) + return redirect(bundle) + else: + form = BundleEditForm(instance=bundle) + + context = { + 'bundle': bundle, + 'form': form, + } + + return render(request, "bundle/edit.djhtml", context) diff -r c042d26e6936 -r 86129d185ddb static/css/agora.less --- a/static/css/agora.less Sat Oct 20 19:24:09 2012 -0400 +++ b/static/css/agora.less Sat Oct 20 23:28:50 2012 -0400 @@ -190,6 +190,7 @@ .snippetform { input[type=text], textarea { + display: block; width: @nonSidebarWidth - @inputPadding * 2 - 2; padding: 5px; margin: 10px 0; @@ -415,3 +416,7 @@ margin-left: 0; padding-left: 18px; } + +.form-field { + margin-bottom: 10px; +} diff -r c042d26e6936 -r 86129d185ddb templates/bundle/base.djhtml --- a/templates/bundle/base.djhtml Sat Oct 20 19:24:09 2012 -0400 +++ b/templates/bundle/base.djhtml Sat Oct 20 23:28:50 2012 -0400 @@ -1,5 +1,5 @@ {% extends "base.djhtml" %} {% block breadcrumbs %} -Bundles » {% block title %}{% endblock %} +Bundles » {% block section %}{% endblock %} {% endblock %} diff -r c042d26e6936 -r 86129d185ddb templates/bundle/bundle.djhtml --- a/templates/bundle/bundle.djhtml Sat Oct 20 19:24:09 2012 -0400 +++ b/templates/bundle/bundle.djhtml Sat Oct 20 23:28:50 2012 -0400 @@ -5,16 +5,33 @@ {% load sizefieldtags %} +{% block section %} +{{ bundle }} +by {{ bundle.uploader }} +(version {{ this_version }}) +{% if file %} +» +{{ file }} +{% endif %} +{% endblock %} + {% block title %} -{{ bundle.name }} by {{ bundle.uploader }} -{% endblock title %} +{% if file %} +{{ file }} in +{% endif %} +{{ bundle }} by {{ bundle.uploader }} +{% endblock %} {% block content %} +

{{ bundle.name }} by {{ bundle.uploader }} +(version {{ this_version }})

{% if not bundle.done_uploading %} @@ -57,6 +74,21 @@ {% else %}

Description: {{ bundle.description|default:"N/A" }}

License: {{ bundle.free_license }}

+

Latest version number: {{ bundle.latest_version }}

+ {% if previous_versions %} +

Versions

+ + {% endif %} {% endif %} {% else %} diff -r c042d26e6936 -r 86129d185ddb templates/bundle/edit.djhtml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/bundle/edit.djhtml Sat Oct 20 23:28:50 2012 -0400 @@ -0,0 +1,23 @@ +{% extends "bundle/base.djhtml" %} + + +{% block title %} +Editing {{ bundle }} +{% endblock %} + +{% block section %} +{{ bundle }} +» +Edit +{% endblock %} + +{% block content %} +

Editing {{ bundle }}

+ +

+You can't change a bundle's name after creating it. If you need to change +the name, simply create a new bundle using the desired name. +

+ +{% include "bundle/form.djhtml" %} +{% endblock %} diff -r c042d26e6936 -r 86129d185ddb templates/bundle/explore.djhtml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/bundle/explore.djhtml Sat Oct 20 23:28:50 2012 -0400 @@ -0,0 +1,41 @@ +{% extends "bundle/base.djhtml" %} + + +{% load i18n %} + + +{% block title %} +{% trans "Explore" %} +{% endblock %} + + +{% block content %} +

{% trans "Recent bundles" %}

+ +{% if recent_bundles %} + + + + + + + + + + {% for bundle in recent_bundles %} + + + + + + {% endfor %} + +
{% trans "Bundle name" %}{% trans "Created on" %}{% trans "User" %}
{{ bundle }}{{ bundle.pub_date }} + + {{ bundle.uploader }} + +
+{% else %} +

{% trans "No bundles have been created yet!" %}

+{% endif %} +{% endblock %} diff -r c042d26e6936 -r 86129d185ddb templates/bundle/explore.html --- a/templates/bundle/explore.html Sat Oct 20 19:24:09 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -{% extends "bundle/base.djhtml" %} - - -{% load i18n %} - - -{% block title %} -{% trans "Explore" %} -{% endblock %} - - -{% block content %} -

{% trans "Recent bundles" %}

- -{% if recent_bundles %} - - - - - - - - - - {% for bundle in recent_bundles %} - - - - - - {% endfor %} - -
{% trans "Bundle name" %}{% trans "Created on" %}{% trans "User" %}
{{ bundle }}{{ bundle.pub_date }} - - {{ bundle.uploader }} - -
-{% else %} -

{% trans "No bundles have been created yet!" %}

-{% endif %} -{% endblock %} diff -r c042d26e6936 -r 86129d185ddb templates/bundle/form.djhtml --- a/templates/bundle/form.djhtml Sat Oct 20 19:24:09 2012 -0400 +++ b/templates/bundle/form.djhtml Sat Oct 20 23:28:50 2012 -0400 @@ -10,23 +10,9 @@ {% csrf_token %} - {% with field=form.name %} - {% include "simple_field.djhtml" %} - {% endwith %} - - {% with field=form.description %} + {% for field in form %} {% include "simple_field.djhtml" %} - {% endwith %} - - {% with field=form.free_license %} - {% include "simple_field.djhtml" %} - {% endwith %} - -

- - {% with field=form.file %} - {% include "simple_field.djhtml" %} - {% endwith %} + {% endfor %}
diff -r c042d26e6936 -r 86129d185ddb templates/bundle/index.djhtml --- a/templates/bundle/index.djhtml Sat Oct 20 19:24:09 2012 -0400 +++ b/templates/bundle/index.djhtml Sat Oct 20 23:28:50 2012 -0400 @@ -5,6 +5,10 @@ New bundle {% endblock title %} +{% block section %} +New bundle +{% endblock %} + {% block content %}

{% trans "Upload a new bundle" %}

diff -r c042d26e6936 -r 86129d185ddb templates/simple_field.djhtml --- a/templates/simple_field.djhtml Sat Oct 20 19:24:09 2012 -0400 +++ b/templates/simple_field.djhtml Sat Oct 20 23:28:50 2012 -0400 @@ -1,10 +1,13 @@ -{{ field.label_tag }} -{{ field }} +
+ {{ field.label_tag }} + + {% if field.errors %} +
{{ field.errors }}
+ {% endif %} -{% if field.errors %} -
{{ field.errors }}
-{% endif %} + {{ field }} -{% if field.help_text %} -

{{ field.help_text }}

-{% endif %} + {% if field.help_text %} +

{{ field.help_text }}

+ {% endif %} +