[damned-lies] Add support for custom linguas location (or no linguas)



commit 0e7ea6f8dfaeaaf1a473c20e6b356f0e1602dccb
Author: Claude Paroz <claude 2xlibre net>
Date:   Sat Sep 5 15:45:27 2009 +0200

    Add support for custom linguas location (or no linguas)

 docs/DataModel.odg     |  Bin 26657 -> 26709 bytes
 docs/notes-upgrade.txt |    3 ++
 stats/admin.py         |    8 +++--
 stats/models.py        |   38 ++++++++++++++++++++----
 stats/utils.py         |   75 +++++++++++++++++++++++++-----------------------
 5 files changed, 79 insertions(+), 45 deletions(-)
---
diff --git a/docs/DataModel.odg b/docs/DataModel.odg
index 8dc4946..da9f4d5 100644
Binary files a/docs/DataModel.odg and b/docs/DataModel.odg differ
diff --git a/docs/notes-upgrade.txt b/docs/notes-upgrade.txt
index 0009566..249cf29 100644
--- a/docs/notes-upgrade.txt
+++ b/docs/notes-upgrade.txt
@@ -89,3 +89,6 @@ ALTER SEQUENCE archived_statistics_id_seq RENAME TO statistics_archived_id_seq;
 
 ## Add language plural forms
 ALTER TABLE language ADD plurals VARCHAR(200);
+
+# Add new linguas_location field
+ALTER TABLE domain ADD linguas_location VARCHAR(50);
diff --git a/stats/admin.py b/stats/admin.py
index 4601252..0a134d1 100644
--- a/stats/admin.py
+++ b/stats/admin.py
@@ -19,6 +19,7 @@
 # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 from django.contrib import admin
+from django import forms
 from stats.models import Statistics, Information, Module, Branch, Domain, Category, Release
 
 class BranchInline(admin.TabularInline):
@@ -27,10 +28,11 @@ class BranchInline(admin.TabularInline):
 class DomainInline(admin.TabularInline):
     model = Domain
     def formfield_for_dbfield(self, db_field, **kwargs):
-        field = super(DomainInline, self).formfield_for_dbfield(db_field, **kwargs)
         if db_field.name == 'description':
-            field.widget.attrs['rows'] = '1'
-        return field
+            kwargs['widget'] = forms.Textarea(attrs={'rows':'1', 'cols':'20'})
+        if db_field.name in ('name', 'directory'):
+            kwargs['widget'] = forms.TextInput(attrs={'size':'20'})
+        return super(DomainInline, self).formfield_for_dbfield(db_field, **kwargs)
 
 class ModuleAdmin(admin.ModelAdmin):
     fieldsets = (
diff --git a/stats/models.py b/stats/models.py
index 790b653..6425e2f 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -312,7 +312,6 @@ class Branch(models.Model):
             # ****************************
             if dom.dtype == 'ui':
                 potfile, errs = dom.generate_pot_file(self)
-                linguas = utils.get_ui_linguas(self.co_path(), domain_path)
             elif dom.dtype == 'doc':
                 if dom.pot_method:
                     potfile, errs = dom.generate_pot_file(self)
@@ -322,12 +321,12 @@ class Branch(models.Model):
                 if not potfile:
                     print >> sys.stderr, "\n".join([e[1] for e in errs])
                     continue
-                linguas = utils.get_doc_linguas(self.co_path(), domain_path)
             else:
                 print >> sys.stderr, "Unknown domain type '%s', ignoring domain '%s'" % (dom.dtype, dom.name)
                 continue
             errors.extend(errs)
-            if linguas['langs'] is None:
+            linguas = dom.get_linguas(self.co_path())
+            if linguas['langs'] is None and linguas['error']:
                 errors.append(("warn", linguas['error']))
 
             # Prepare statistics object
@@ -636,9 +635,12 @@ class Domain(models.Model):
     dtype = models.CharField(max_length=5, choices=DOMAIN_TYPE_CHOICES, default='ui')
     directory = models.CharField(max_length=50)
     # The pot_method is a command who should produce a potfile in the po directory of
-    # the domain, named <potbase()>.pot (e.g. /po/gnucash.pot). If blank, method is
-    # intltool for UI and gnome-doc-utils for DOC
-    pot_method = models.CharField(max_length=50, null=True, blank=True)
+    # the domain, named <potbase()>.pot (e.g. /po/gnucash.pot).
+    pot_method = models.CharField(max_length=50, null=True, blank=True,
+        help_text="Leave blank for standard method (intltool for UI and gnome-doc-utils for DOC)")
+    linguas_location = models.CharField(max_length=50, null=True, blank=True,
+        help_text="""Use 'no' for no LINGUAS check, or path/to/file#variable for a non-standard location.
+            Leave blank for standard location (ALL_LINGUAS in LINGUAS/configure.ac/.in for UI and DOC_LINGUAS in Makefile.am for DOC)""")
 
     class Meta:
         db_table = 'domain'
@@ -697,6 +699,30 @@ class Domain(models.Model):
         else:
             return potfile, ()
 
+    def get_linguas(self, base_path):
+        """ Return a linguas dict like this: {'langs':['lang1', lang2], 'error':"Error"} """
+        if self.linguas_location:
+            # Custom (or no) linguas location
+            if self.linguas_location == 'no':
+                return {'langs':None, 'error':''}
+            else:
+                variable = "ALL_LINGUAS"
+                if "#" in self.linguas_location:
+                    file_path, variable = self.linguas_location.split("#")
+                else:
+                    file_path = self.linguas_location
+                langs = utils.search_variable_in_file(os.path.join(base_path, file_path), variable)
+                return {'langs': langs,
+                        'error': ugettext_noop("Entry for this language is not present in %(var)s variable in %(file)s file." % {
+                            'var': variable, 'file': file_path})}
+        # Standard linguas location
+        if self.dtype == 'ui':
+            return utils.get_ui_linguas(base_path, os.path.join(base_path, self.directory))
+        elif self.dtype == 'doc':
+            return utils.get_doc_linguas(base_path, os.path.join(base_path, self.directory))
+        else:
+            raise ValueError("Domain dtype should be one of 'ui', 'doc'")
+
 RELEASE_STATUS_CHOICES = (
     ('official', 'Official'),
     ('unofficial', 'Unofficial'),
diff --git a/stats/utils.py b/stats/utils.py
index 2358f5f..f18cdc8 100644
--- a/stats/utils.py
+++ b/stats/utils.py
@@ -113,7 +113,7 @@ def generate_doc_pot_file(vcs_path, potbase, moduleid, verbose):
 
         pages = read_makefile_variable([vcs_path], "DOC_PAGES")
         if pages:
-            for f in pages.split(" "):
+            for f in pages.split():
                 if f.strip() != "":
                     files += " %s" % (os.path.join("C", f.strip()))
 
@@ -157,27 +157,46 @@ def generate_doc_pot_file(vcs_path, potbase, moduleid, verbose):
 def read_makefile_variable(vcs_paths, variable):
     """ vcs_paths is a list of potential path where Makefile.am could be found """
     makefiles = [os.path.join(path, "Makefile.am") for path in vcs_paths]
+    good_makefile = None
     for makefile in makefiles:
-        try:
-            fin = open(makefile, "r")
+        if os.access(makefile, os.R_OK):
+            good_makefile = makefile
             break
-        except IOError:
-            # probably file not found or unreadable
-            fin = None
-    if not fin:
+    if not good_makefile:
         return None # no file found
 
-    fullline = ""
-    for line in fin:
-        fullline += " " + line.strip()
-        if len(line)>2 and fullline[-1] == "\\":
-            fullline = fullline[:-1]
+    return search_variable_in_file(good_makefile, variable)
+
+def search_variable_in_file(file_path, variable):
+    """ Search for a variable value in a file, and return content if found
+        Return None if variable not found in file (or file does not exist)
+    """
+    try:
+        file = open(file_path, "r")
+    except IOError:
+        return None
+
+    non_terminated_content = ""
+    found = None
+    for line in file:
+        line = line.strip()
+        if non_terminated_content:
+            line = non_terminated_content + " " + line
+        # Test if line is non terminated (end with \ or even quote count)
+        if (len(line)>2 and line[-1] == "\\") or line.count('"') % 2 == 1:
+            if line[-1] == "\\":
+                # Remove trailing backslash
+                line = line[:-1]
+            non_terminated_content = line
         else:
-            match = re.match(variable + r"\s*=\s*([^=]*)", fullline.strip())
+            non_terminated_content = ""
+            # Search for variable
+            match = re.search('%s\s*[=,]\s*"?([^"=]*)"?' % variable, line)
             if match:
-                return match.group(1)
-            fullline = ""
-    return None
+                found = match.group(1)
+                break
+    file.close()
+    return found
 
 def pot_diff_status(pota, potb):
     (status, output, errs) = run_shell_command("diff %s %s|wc -l" % (pota, potb))
@@ -290,26 +309,10 @@ def get_ui_linguas(module_path, po_path):
                     'error': ugettext_noop("Entry for this language is not present in LINGUAS file.") }
 
     for configure in [configureac, configurein]:
-        if os.access(configure, os.R_OK):
-            cfile = open(configure, "r")
-            lines = []
-            prev = ""
-            for line in cfile:
-                line = prev + line.strip()
-                if line.count('"') % 2 == 1:
-                    prev = line
-                else:
-                    lines.append(line)
-                    prev = ""
-
-            for line in lines:
-                line = line.strip()
-                match = re.search('ALL_LINGUAS\s*[=,]\s*"([^"]*)"', line)
-                if match:
-                    langs = match.groups(1)[0].split()
-                    cfile.close()
-                    return {'langs':langs,
-                            'error': ugettext_noop("Entry for this language is not present in ALL_LINGUAS in configure file.") }
+        found = search_variable_in_file(configure, 'ALL_LINGUAS')
+        if found is not None:
+            return {'langs': found.split(),
+                    'error': ugettext_noop("Entry for this language is not present in ALL_LINGUAS in configure file.") }
     return {'langs':None,
             'error': ugettext_noop("Don't know where to look for the LINGUAS variable, ask the module maintainer.") }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]