Question

I have a csv with all the values to be translated...I want to read the csv file and produce a .pot file but when i load and try calling print _(value) no .pot is produced. Not sure why you can't produce a .pot file with dynamic content from a csv.

Here's a snippet of my code:

import csv
import gettext

t = gettext.translation('api_trans', '/path/to/locale/', fallback=True)
_ = t.ugettext

string_list = []
with open('/path/to/csv/file') as csvfile:
  reader = csv.reader(csvfile, delimiter=',', quotechar='"')
  for row in reader:
    if row:
        if row[0] != '':
            print _(%row[0])

When I run this script, I see all the values listed however no .pot file is produced if i run:

xgettext -d api_trans -o api_trans.pot api_trans.py 

Specifying an actual string versus a variable with a string value (eg. print _('hello')) does work...any help would be greatly appreciated.

Was it helpful?

Solution

The reason this is happening is because xgettext does not actually execute your Python file, but reads as plain text and tries to identify strings which have to be translated. As you are adding a _(varaible) and not _("literal string that xgettext understands"), it will not recognize it as text that should be translated.

For that to happen, the most direct way I can think of is generating a dummy file that you will feed to xgettext, which will contain all the actual values. Now considering your csv file is not really big, you could try to generate a file which will contain a line similar to print _("the value of the thing you want to translate") and that will be understood by xgettext. Now of course that would not be the optimal way, but its the most straight-forward without having to worry about parsing.

import csv
import gettext

t = gettext.translation('api_trans', '/path/to/locale/', fallback=True)
_ = t.ugettext

string_list = []
with open('/path/to/csv/file') as csvfile:
  with open('/path/to/some/other/file', 'w') as out:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    for row in reader:
      if row:
          if row[0] != '':
              out.write("print _(%s)\n" % (repr(row[0],))

Then you'd execute xgettext -d api_trans -o api_trans.pot /path/to/that/file.

Again, this is sub optimal. You might want to look into Babel, and come up with a more effective solution, I'll look into that too.

That's what I got from using Babel:

def extract_csv(fileobj, keywords, comment_tags, options):
    """Extract messages from XXX files.
    :param fileobj: the file-like object the messages should be extracted
                    from
    :param keywords: a list of keywords (i.e. function names) that should
                     be recognized as translation functions
    :param comment_tags: a list of translator tags to search for and
                         include in the results
    :param options: a dictionary of additional options (optional)
    :return: an iterator over ``(lineno, funcname, message, comments)``
             tuples
    :rtype: ``iterator``
    """
    import csv

    reader = csv.reader(fileobj, delimiter=',', quotechar='"')
    for row in reader:
        if row and row[0] != '':
            yield (lineno, ',', row[0], 'No comment')

Then you would need to include it as an extraction method. The simplest way is to have it in a package in the PYTHONPATH and use it as follows:

# Some custom extraction method
[extractors]
csv = mypackage.module:extract_csv
[csv: **.ctm]
some_option = foo

I'm not entirely sure about that last bit, you can see here for more details :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top