0ccdb5da3876cd7192fbbfea35f065ab8913b85e
[wolnelektury.git] / apps / wolnelektury_core / management / commands / localepack.py
1
2 from optparse import make_option
3 from django.conf import settings
4 from django.core.management.base import BaseCommand
5 from django.core.management import call_command
6 from modeltranslation.management.commands.translation2po import get_languages
7
8 import os
9 import shutil
10 import tempfile
11 import sys
12
13 import allauth
14
15 ROOT = os.path.dirname(settings.PROJECT_DIR)
16
17
18 def is_our_app(mod):
19     return mod.__path__[0].startswith(ROOT)
20
21
22 class Locale(object):
23     def save(self, output_directory, languages):
24         pass
25
26     def generate(self, languages):
27         pass
28
29
30 class AppLocale(Locale):
31     def __init__(self, appmod):
32         self.app = appmod
33         if not os.path.exists(os.path.join(self.path, 'locale')):
34             raise LookupError('No locale for app %s' % appmod)
35
36     @property
37     def path(self):
38         return self.app.__path__[0]
39
40     @property
41     def name(self):
42         return self.app.__name__
43
44     def save(self, output_directory, languages):
45         for lc in languages:
46             lc = lc[0]
47             if os.path.exists(os.path.join(self.path, 'locale', lc)):
48                 shutil.copy2(os.path.join(self.path, 'locale', lc, 'LC_MESSAGES', 'django.po'),
49                          os.path.join(output_directory, lc, self.name + '.po'))
50
51     def load(self, input_directory, languages):
52         for lc in zip(*languages)[0]:
53             shutil.copy2(os.path.join(input_directory, lc, self.name + '.po'),
54                          os.path.join(self.path, 'locale', lc, 'LC_MESSAGES', 'django.po'))
55
56     def generate(self, languages):
57         wd = os.getcwd()
58         os.chdir(self.path)
59         try:
60             call_command('makemessages', all=True)
61         except:
62             pass
63         finally:
64             os.chdir(wd)
65
66
67 class ModelTranslation(Locale):
68     def __init__(self, appname):
69         self.appname = appname
70
71     def save(self, output_directory, languages):
72         call_command('translation2po', self.appname, directory=output_directory)
73
74     def load(self, input_directory, languages):
75         call_command('translation2po', self.appname, directory=input_directory, load=True, lang=','.join(zip(*languages)[0]))
76
77
78 class CustomLocale(Locale):
79     def __init__(self, app_dir,
80                  config=os.path.join(ROOT, "babel.cfg"),
81                  out_file=os.path.join(ROOT, 'wolnelektury/locale-contrib/django.pot'),
82                  name=None):
83         self.app_dir = app_dir
84         self.config = config
85         self.out_file = out_file
86         self.name = name
87
88     def generate(self, languages):
89         os.system('pybabel extract -F "%s" -o "%s" "%s"' % (self.config, self.out_file, self.app_dir))
90         os.system('pybabel update -D django -i %s -d %s' % (self.out_file, os.path.dirname(self.out_file)))
91
92     def po_file(self, language):
93         d = os.path.dirname(self.out_file)
94         n = os.path.basename(self.out_file).split('.')[0]
95         return os.path.join(d, language, 'LC_MESSAGES', n + '.po')
96
97     def save(self, output_directory, languages):
98         for lc in zip(*languages)[0]:
99             if os.path.exists(self.po_file(lc)):
100                 shutil.copy2(self.po_file(lc),
101                              os.path.join(output_directory, lc, self.name + '.po'))
102
103     def load(self, input_directory, languages):
104         for lc in zip(*languages)[0]:
105             shutil.copy2(os.path.join(input_directory, lc, self.name + '.po'),
106                          self.po_file(lc))
107         os.system('pybabel compile -D django -d %s' % os.dirname(self.out_file))
108
109
110 SOURCES = []
111
112 for appn in settings.INSTALLED_APPS:
113     app = __import__(appn)
114     if is_our_app(app):
115         try:
116             SOURCES.append(AppLocale(app))
117         except LookupError, e:
118             print "no locales in %s" % app.__name__
119
120 SOURCES.append(ModelTranslation('infopages'))
121 SOURCES.append(CustomLocale(os.path.dirname(allauth.__file__), name='contrib'))
122
123
124 class Command(BaseCommand):
125     option_list = BaseCommand.option_list + (
126         make_option('-l', '--load', help='load locales back to source', action='store_true', dest='load', default=False),
127         make_option('-L', '--lang', help='load just one language', dest='lang', default=None),
128         make_option('-d', '--directory', help='load from this directory', dest='directory', default=None),
129         make_option('-o', '--outfile', help='Resulting zip file', dest='outfile', default='./wl-locale.zip'),
130         make_option('-m', '--merge', help='Use git to merge. Please use with clean working directory.', dest='merge', default=False),
131         )
132     help = 'Make a locale pack'
133     args = ''
134
135     def save(self, options):
136         tmp_dir = tempfile.mkdtemp('-wl-locale')
137         out_dir = os.path.join(tmp_dir, 'wl-locale')
138         os.mkdir(out_dir)
139
140         try:
141             for lang in settings.LANGUAGES:
142                 os.mkdir(os.path.join(out_dir, lang[0]))
143
144             for src in SOURCES:
145                 src.generate(settings.LANGUAGES)
146                 src.save(out_dir, settings.LANGUAGES)
147                 #                src.save(settings.LANGUAGES)
148
149             # write out revision
150             rev = os.popen('git rev-parse HEAD').read()
151             rf = open(os.path.join(out_dir, '.revision'), 'w')
152             rf.write(rev)
153             rf.close()
154
155             packname = options.get('outfile')
156             packname_b = os.path.basename(packname).split('.')[0]
157             fmt = '.'.join(os.path.basename(packname).split('.')[1:])
158             shutil.make_archive(packname_b, fmt, root_dir=os.path.dirname(out_dir), base_dir=os.path.basename(out_dir))
159         finally:
160             shutil.rmtree(tmp_dir, ignore_errors=True)
161
162     def load(self, options):
163         if not options['directory'] or not os.path.exists(options['directory']):
164             print "Directory not provided or does not exist, please use -d"
165             sys.exit(1)
166
167         langs = get_languages(options['lang'])
168
169         for src in SOURCES:
170             src.load(options['directory'], langs)
171
172     def handle(self, *a, **options):
173         if options['load']:
174             self.load(options)
175         else:
176             self.save(options)