Commits

Dimitris Glezos  committed 4615d52 Merge

merge

  • Participants
  • Parent commits 32a4103, 94d51d8

Comments (0)

Files changed (24)

File docs/releases/relprocess.txt

 Prepare the code
 ----------------
 
-1. Get changesets into mainline branch::
+1. Sync your repo with the mainline branch::
 
-    cd ../b-mainline
-    hg pull txo
-    hg pull ../b-0.3    
-    hg push txo
+    hg -R ../b-mainline pull default
+    hg pull ../b-mainline
+    hg push ../b-mainline
 
 2. Write the release notes for this release::
 
     date +%c
     hg log -r 0.3:tip \
         --template "{author|person}\t{author|email}\t{desc|firstline}\n" | \
-        python devel-docs/hg-shortlog.py | grep -v trivial > NEWS.new
+        python docs/hg-shortlog.py | grep -v trivial > NEWS.new
     vi NEWS.new docs/releases/0.4.txt
     rm NEWS.new
 
 4. Update packaging files with version bump. If there are new translations,
    include them in ``setup.py``::
 
-    vim setup.py transifex.spec
+    vim setup.py transifex.spec txcommon/__init__.py
 
 5. Commit changes::
 

File projects/handlers/types/intltool.py

         using intltool-update.    .
         """
 
-        # Deleting all stats for the component
         logger.debug("Setting stats for %s" % self.component)
-        self.tm.delete_stats_for_object(self.component)
 
         isIntltooled = self.tm.intltool_update()
         if not isIntltooled:

File projects/handlers/types/pot.py

     def set_stats(self):
         """Calculate stats for all translations of the component."""
 
-        # Deleting all stats for the component
-        self.clear_stats()
         logger.debug("Setting stats for %s" % self.component)
 
         # Copying the source file to the static dir
 
     def msgfmt_check(self, po_contents):
         """Check a POT/PO file with msgfmt -c."""
-        return self.tm.msgfmt_check(po_contents)
+        return self.tm.msgfmt_check(po_contents)

File projects/models.py

         choices=settings.TRANS_CHOICES.items(),
         help_text=_("The code's type of i18n support (%s)" %
                     ', '.join(settings.TRANS_CHOICES.keys())))
-    file_filter = models.CharField(max_length=50, blank=True, null=True,
+    file_filter = models.CharField(max_length=50,
         help_text=_("A regex to filter the exposed files. Eg: 'po/.*'"))
 
     allows_submission = models.BooleanField(default=False,

File repowatch/update.py

                 continue
         # ...and notify by user
         if changes:
-            changes.sort(operator.itemgetter(0)
+            changes.sort(operator.itemgetter(0))
             for usergroup in itertool.groupby(changes,
                 key=operator.itemgetter(0)):
                 repowatch.send_email(Site.objects.get_current(), comp,

File site_media/css/base.css

 table.definition th { text-align: left; color: #666; }
 table.definition td {
   padding: 0.2em 0.5em;
+  margin: 0.5em 0;
 }
 
 table.definition tr.empty th,

File site_media/css/icons.css

 .i16.action { background-image: url('../images/icons/lightning.png'); }
 .i16.admin { background-image: url('../images/icons/award_star_gold_1.png'); }
 .i16.add { background-image: url('../images/icons/add.png'); }
+.i16.allow_file { background-image: url('../images/icons/database_edit.png'); }
 .i16.bell { background-image: url('../images/icons/bell.png'); }
 .i16.branch { background-image: url('../images/icons/arrow_branch.png'); }
 .i16.collection { background-image: url('../images/icons/basket.png'); }
 .i16.component { background-image: url('../images/icons/brick.png'); }
 .i16.delete { background-image: url('../images/icons/cross.png'); }
+.i16.delete_circle { background-image: url('../images/icons/cancel.png'); }
 .i16.edit { background-image: url('../images/icons/pencil.png'); }
 .i16.cache { background-image: url('../images/icons/lorry.png'); }
 .i16.cache_empty { background-image: url('../images/icons/lorry_flatbed.png'); }
 .i16.source_code { background-image: url('../images/icons/database_gear.png'); }
 .i16.stats { background-image: url('../images/icons/chart_bar.png'); }
 .i16.stats_edit { background-image: url('../images/icons/chart_bar_edit.png'); }
+.i16.stop { background-image: url('../images/icons/delete.png'); }
 .i16.submit { background-image: url('../images/icons/tick.png'); }
 .i16.submit_file { background-image: url('../images/icons/page_white_edit.png'); }
 .i16.tag { background-image: url('../images/icons/tag_blue.png'); }
 .i16.tick { background-image: url('../images/icons/tick.png'); }
+.i16.tick_circle { background-image: url('../images/icons/accept.png'); }
 .i16.tip { background-image: url('../images/icons/lightbulb.png'); }
 .i16.user { background-image: url('../images/icons/user.png'); }
-.i16.view { background-image: url('../images/icons/page_magnify.png'); }
+.i16.view { background-image: url('../images/icons/page_magnify.png'); }

File site_media/css/stats.css

 table.stats_comp {
   font-size: 100%;
   border-collapse: collapse;
-  margin-bottom: 1.5em;
+  margin: 1em 0;
 }
 
 .stats_comp a {
 input.nodecoration_icon:hover { /* Not sure why this is needed. */
   margin-left: 0;
   padding-left: 16px !important;
-}
+}

File site_media/images/icons/accept.png

Added
New image

File site_media/images/icons/cancel.png

Added
New image

File site_media/images/icons/database_edit.png

Added
New image

File site_media/images/icons/delete.png

Added
New image

File site_media/images/icons/page_white_key.png

Added
New image

File site_media/js/file_submit.js

     if ( $(this).next("form.submit_form").is(':hidden') ) { 
       $("form.submit_form").hide("slide");
     }
+    // Temporary "if" for warning users about locked files
+    if ( $(this).prev().attr("nodeName") == "SPAN" && $(this).prev().text() != "(you)" ) {
+        lastChild = $(this).next("form.submit_form").children().attr('lastChild');
+        if (lastChild["nodeName"] != "P")
+            $(this).next("form.submit_form").children().append("<p style=\"margin: 0px; color: red;\">This file is locked by someone else. Are you sure that you want to do it?</p>");
+    }
+
     $(this).next("form.submit_form").toggle("medium");
    })
 });

File templates/languages/language_detail.html

 
 {% block breadcrumb %}{{ block.super }} &raquo; {{ language.name }}{% endblock %}
 
-
 {% block content_title %}<h2 class="pagetitle">{{ language.name }} <sup class="entry_metalink">{{ language.code }}</sup></h2>{% endblock %}
 
 {% block body_main %}
 
  {% endfor %}
 
-{% endblock %}
+{% endblock %}

File templates/projects/component_detail.html

       <td>{{ component.unit.branch }}</td>
     </tr>
     <tr>
-      <th class="i16 filter">{% trans "Filter:" %}</th>
+      <th class="i16 filter">{% trans "File filter:" %}</th>
       <td>{{ component.file_filter }}</td>
     </tr>
-    {% if component.trans.get_source_stats %}
-    <tr>
-      <th class="i16 source_code">{% trans "Source file:" %}</th>
-      <td>
-      {% with component.trans.get_source_stats as source_stats %}
-      {% url component_raw_file component.project.slug component.slug source_stats.filename as source_raw_url %}
-      {% url component_view_file component.project.slug component.slug source_stats.filename as source_view_url %}
-        <code style="margin-right: 0.7em;">{{ source_stats.filename }} ({{ source_stats.total }} {% trans "entries" %})</code>
-        <a class="i16 view nodecoration_icon" title="{% trans "View " %}{{ source_stats.filename }}" href="{{ source_view_url }}"></a>
-        <a class="i16 get_file nodecoration_icon" title="{% trans "Download " %}{{ source_stats.filename }}" href="{{ source_raw_url }}"></a>
-      {% endwith %}
-      </td>
-    </tr>
-    {% endif %}
     {% with component.releases.all as releases %}
     {% if releases %}
     <tr>
     {% endif %}
     {% endwith %}
     <tr>
-      <th class="i16 cache">{% trans "Local cache:" %}</th>
-      <td>
-        {% if component.unit.last_checkout %}
-        {% trans "The local checked-out copy of this component was last updated " %} <strong>{{component.unit.last_checkout|timesince}}</strong> {% trans "ago" %}.
-        {% else %}
-        {% trans "Component not yet pulled from source repository." %}
-        {% endif %}
-      </td>
-    </tr>
-    <tr>
     {% if request.user.is_authenticated %}<tr>
       <th class="i16 maintainer">{% trans "Maintainer actions:" %}</th>
       <td>
     </tr>{% endif %}
   </table>
 </div>
-{% endif %}  
+{% endif %}
+
+<h3>{% trans "Translation files" %}</h3>
+
+{% if component.trans.get_source_stats %}
+<table class="definition">
+<tr>
+  <th class="link i16">{% trans "Source file:" %}</th>
+  <td>
+  {% with component.trans.get_source_stats as source_stats %}
+  {% url component_raw_file component.project.slug component.slug source_stats.filename as source_raw_url %}
+  {% url component_view_file component.project.slug component.slug source_stats.filename as source_view_url %}
+    <code style="margin-right: 0.7em;">{{ source_stats.filename }} ({{ source_stats.total }} {% trans "entries" %})</code>
+    <a class="i16 view nodecoration_icon" title="{% trans "View " %}{{ source_stats.filename }}" href="{{ source_view_url }}"></a>
+    <a class="i16 link nodecoration_icon" title="{% trans "Download " %}{{ source_stats.filename }}" href="{{ source_raw_url }}"></a>
+  {% endwith %}
+  </td>
+</tr>
+    <tr>
+      <th class="i16 cache">{% trans "Statistics last updated:" %}</th>
+      <td>
+        {% if component.unit.last_checkout %}<strong>{{component.unit.last_checkout|timesince}}</strong> {% trans "ago" %}.
+        {% else %}{% trans "Component not yet pulled from source repository." %}{% endif %}
+      </td>
+    </tr>
+</table>
+{% endif %}
 
 {% comp_stats_table component.trans.get_stats %}
 

File templates/txcollections/release_detail.html

 
 <div id="projects" class="projects">
 
+<h3>{% trans "Translation statistics" %} </h3>
 {% release_stats_table pofile_list collection release %}
 
 {% if not pofile_list %}
 {% endif %}
 
 </div>
+</div>
 {% endblock %}{# body_main #}
 
-{% block content_footer %}
-  <div id="content_footer_center">
-    {% if request.user.is_authenticated and perms.txcollections.delete_collectionrelease %}
-    <div class="deletelink">
-      <a class="i16 delete buttonized" href="{% url collection_delete slug=collection.slug %}">{% trans "Delete collection" %}</a>
-    </div>
-    {% endif %}
-  </div>
-{% endblock %}

File translations/lib/types/pot.py

         Raises a ValueError in case the file has errors.
         """
         try:
-            p = run_command('msgfmt -c -', _input=po_contents)
+            p = run_command('msgfmt -o /dev/null -c -', _input=po_contents)
         except CommandError:
             # TODO: Figure out why gettext is not working here
             raise ValueError, "Your file does not" \

File translations/models.py

         Yield a POFile for every language in a release containing the language
         total statistics
         """
-        postats = self.by_release(release).filter(is_pot=True).values('total')
-        pot_total = sum(postat['total'] for postat in postats)
+        postats = self.by_release(release).filter(is_pot=True).values_list(
+            'total', flat=True)
+        pot_total = sum(postats)
 
         postats = self.by_release(release).filter(is_pot=False,
                                                   language__isnull=False)

File translations/templates/comp_stats_table.html

 {% load statistics %}
 {% load locks %}
 {% if stats %}
-<h3>{% trans "Translation statistics" %} </h3>
 <table class="stats_comp">
    <thead>
     <tr>

File translations/templates/release_stats_table.html

 {% load i18n %}
 {% load statistics %}
 {% if stats %}
-<h3>{% trans "Translation statistics" %} </h3>
 <table class="stats_comp">
    <thead>
     <tr>

File translations/templatetags/statistics.py

 from django import template
 import os
 from translations.models import Language
+from txcommon.templatetags.txcommontags import key_sort
 
 register = template.Library()
 
     languages for a component.
     """
 
-    context['stats'] = key_sort(stats, ('sort_id', '-trans_perc',))
+    context['stats'] = key_sort(stats, 'sort_id', '-trans_perc')
     return context
 
 @register.inclusion_tag("project_stats_table.html")
     for a specific language.
     """
 
-    context['stats'] = key_sort(stats, ('object.project.name', '-trans_perc'))
+    context['stats'] = key_sort(stats, 'object.project.name', '-trans_perc')
     return context
 
 @register.inclusion_tag("release_stats_table.html")
     Create a HTML table to presents the statistics of all languages 
     for a specific release.
     """
-    return {'stats': key_sort(stats, ('language.name', '-trans_perc')),
+    return {'stats': key_sort(stats, 'language.name', '-trans_perc'),
             'collection': collection,
             'release': release}
 
     return {'stat': stat,
             'pos': pos_from_stat(stat),}
 
-@register.filter
-def sort(value, arg):
-    keys = [k.strip() for k in arg.split(',')]
-    return key_sort(value, keys)
-
-def key_sort(l, keys):
-    """
-    Sort an iterable given an arbitary number of keys relative to it
-    and return the result as a list. When a key starts with '-' the
-    sorting is reversed.
-    
-    Example: key_sort(people, ('lastname','-age'))
-    """
-    l = list(l)
-    for key in keys:
-        #Find out if we want a reversed ordering
-        if key.startswith('-'):
-            reverse = True
-            key = key[1:]
-        else:
-            reverse = False
-            
-        attrs = key.split('.')
-        def fun(x):
-            # Calculate x.attr1.attr2...
-            for attr in attrs:
-                x = getattr(x, attr)
-            # If the key attribute is a string we lowercase it
-            if isinstance(x, basestring):
-                x = x.lower()
-            return x
-        l.sort(key=fun, reverse=reverse)
-    return l
 
 @register.filter  
 def truncate_chars(value, max_length):

File txcommon/__init__.py

-version_info = (0, 5, 0, 'alpha', 0)
+version_info = (0, 5, 0, 'rc1', 0)
 
 _verpart = ''
 if version_info[3] != 'final':

File txcommon/templatetags/txcommontags.py

     return mark_safe(result)
 
 mungify.needs_autoescape = True
+
+@register.filter
+def sort(value, arg):
+    keys = [k.strip() for k in arg.split(',')]
+    return key_sort(value, *keys)
+
+def key_sort(l, *keys):
+    """
+    Sort an iterable given an arbitary number of keys relative to it
+    and return the result as a list. When a key starts with '-' the
+    sorting is reversed.
+    
+    Example: key_sort(people, 'lastname', '-age')
+    """
+    l = list(l)
+    for key in keys:
+        #Find out if we want a reversed ordering
+        if key.startswith('-'):
+            reverse = True
+            key = key[1:]
+        else:
+            reverse = False
+            
+        attrs = key.split('.')
+        def fun(x):
+            # Calculate x.attr1.attr2...
+            for attr in attrs:
+                x = getattr(x, attr)
+            # If the key attribute is a string we lowercase it
+            if isinstance(x, basestring):
+                x = x.lower()
+            return x
+        l.sort(key=fun, reverse=reverse)
+    return l