def process_file(self, dirname, basename, **kw): """ Process a Makefile for gtk-doc information. """ is_gtk_doc = False if basename == "Makefile.am": filename = os.path.join(dirname, basename) makefile = self.scanner.get_parsed_file(parsers.Automake, filename) for line in makefile.get_lines(): if line.startswith("include $(top_srcdir)/"): if line.endswith("gtk-doc.make"): is_gtk_doc = True break if not is_gtk_doc: return branch = self.scanner.branch checkout = self.scanner.checkout bserver, bmodule, bbranch = branch.ident.split("/")[2:] doc_module = makefile["DOC_MODULE"] ident = u"/".join(["/ref", bserver, bmodule, doc_module, bbranch]) document = db.Branch.get_or_create(ident, u"Document") document.parent = branch relpath = utils.relative_path(dirname, checkout.directory) data = {} for key in ("scm_type", "scm_server", "scm_module", "scm_branch", "scm_path"): data[key] = getattr(branch, key) data["subtype"] = u"gtk-doc" data["scm_dir"] = relpath scm_file = makefile["DOC_MAIN_SGML_FILE"] if "$(DOC_MODULE)" in scm_file: scm_file = scm_file.replace("$(DOC_MODULE)", doc_module) data["scm_file"] = scm_file document.update(data) if not kw.get("no_docs", False): pulse.pulsate.docs.update_document(document, checkout=checkout, **kw) if document is not None: self.scanner.add_child(document)
def process_file (self, dirname, basename, **kw): """ Process an OAF server file for a panel applet. """ if not re.match('.*\.server(\.in)+$', basename): return filename = os.path.join (dirname, basename) branch = self.scanner.branch checkout = self.scanner.checkout bserver, bmodule, bbranch = branch.ident.split('/')[2:] rel_ch = utils.relative_path (filename, checkout.directory) rel_scm = utils.relative_path (filename, config.scm_dir) mtime = os.stat(filename).st_mtime if not kw.get('no_timestamps', False): stamp = db.Timestamp.get_timestamp (rel_scm) if mtime <= stamp: utils.log ('Skipping file %s' % rel_scm) data = {'parent' : branch} data['scm_dir'], data['scm_file'] = os.path.split (rel_ch) applets = db.Branch.select (type=u'Applet', **data) for applet in applets: self.scanner.add_child (applet) return utils.log ('Processing file %s' % rel_scm) owd = os.getcwd () try: os.chdir (checkout.directory) dom = xml.dom.minidom.parse ( os.popen ('LC_ALL=C intltool-merge -x -q -u po "' + rel_ch + '" - 2>/dev/null')) except: utils.warn ('Could not process file %s' % utils.relative_path (filename, config.scm_dir)) os.chdir (owd) return os.chdir (owd) for server in dom.getElementsByTagName ('oaf_server'): is_applet = False applet_name = {} applet_desc = {} applet_icon = None applet_iid = server.getAttribute ('iid') if applet_iid == '': continue if applet_iid.startswith ('OAFIID:'): applet_iid = applet_iid[7:] if applet_iid.startswith ('GNOME_'): applet_iid = applet_iid[6:] for oafattr in server.childNodes: if oafattr.nodeType != oafattr.ELEMENT_NODE or oafattr.tagName != 'oaf_attribute': continue if oafattr.getAttribute ('name') == 'repo_ids': for item in oafattr.childNodes: if item.nodeType != item.ELEMENT_NODE or item.tagName != 'item': continue if item.getAttribute ('value') == 'IDL:GNOME/Vertigo/PanelAppletShell:1.0': is_applet = True break if not is_applet: break if oafattr.getAttribute ('name') == 'name': lang = oafattr.getAttribute ('xml:lang') if lang == '': lang = 'C' value = oafattr.getAttribute ('value') if value != '': applet_name[lang] = value if oafattr.getAttribute ('name') == 'description': lang = oafattr.getAttribute ('xml:lang') if lang == '': lang = 'C' value = oafattr.getAttribute ('value') if value != '': applet_desc[lang] = value if oafattr.getAttribute ('name') == 'panel:icon': applet_icon = oafattr.getAttribute ('value') if applet_icon == '': applet_icon = None if not is_applet or applet_icon == None: continue ident = '/'.join(['/applet', bserver, bmodule, applet_iid, bbranch]) applet = db.Branch.get_or_create (ident, u'Applet') applet.update (name=applet_name, desc=applet_desc) if applet_icon != None: self.appleticons.append ((applet, applet_icon)) data = {} for key in ('scm_type', 'scm_server', 'scm_module', 'scm_branch', 'scm_path'): data[key] = getattr(branch, key) data['scm_dir'], data['scm_file'] = os.path.split (rel_ch) applet.update (data) self.scanner.add_child (applet) db.Timestamp.set_timestamp (rel_scm, mtime)
def process_file (self, dirname, basename, **kw): """ Process a POTFILES.in file for intltool information. """ if not basename == 'POTFILES.in': return branch = self.scanner.branch checkout = self.scanner.checkout bserver, bmodule, bbranch = branch.ident.split('/')[2:] ident = u'/'.join(['/i18n', bserver, bmodule, os.path.basename (dirname), bbranch]) domain = db.Branch.get_or_create (ident, u'Domain') domain.parent = branch scmdata = {} for key in ('scm_type', 'scm_server', 'scm_module', 'scm_branch', 'scm_path'): scmdata[key] = getattr(branch, key) scmdata['scm_dir'] = utils.relative_path (dirname, checkout.directory) domain.update (scmdata) linguas = os.path.join (dirname, 'LINGUAS') if not os.path.isfile (linguas): domain.error = u'No LINGUAS file' return else: domain.error = None rel_scm = utils.relative_path (linguas, config.scm_dir) mtime = os.stat(linguas).st_mtime langs = [] translations = [] if not kw.get('no_timestamps', False): stamp = db.Timestamp.get_timestamp (rel_scm) if mtime <= stamp: utils.log ('Skipping file %s' % rel_scm) return utils.log ('Processing file %s' % rel_scm) fd = open (linguas) for line in fd: if line.startswith ('#') or line == '\n': continue for lang in line.split(): langs.append (lang) for lang in langs: lident = u'/l10n/' + lang + domain.ident translation = db.Branch.get_or_create (lident, u'Translation') translations.append (translation) ldata = {} for key in ('scm_type', 'scm_server', 'scm_module', 'scm_branch', 'scm_path'): ldata[key] = scmdata[key] ldata['subtype'] = 'intltool' ldata['scm_dir'] = scmdata['scm_dir'] ldata['scm_file'] = lang + '.po' translation.parent = domain translation.update (ldata) if not kw.get('no_i18n', False): for po in translations: pulse.pulsate.i18n.update_translation (po, checkout=checkout, **kw) db.Timestamp.set_timestamp (rel_scm, mtime) if domain is not None: self.scanner.add_child (domain)
def get_potfile (self, **kw): """ Get a POT file for an intltool-managed translation domain. """ checkout = self.scanner.checkout domain = self.scanner.translation.parent indir = os.path.join (checkout.directory, domain.scm_dir) if self.__class__.potfiles.has_key (indir): return self.__class__.potfiles[indir] if domain.scm_dir == 'po': potname = domain.scm_module else: potname = domain.scm_dir potfile = potname + '.pot' of = pulse.db.OutputFile.select (type=u'l10n', ident=domain.ident, filename=potfile) try: of = of[0] except IndexError: of = pulse.db.OutputFile (type=u'l10n', ident=domain.ident, filename=potfile, datetime=datetime.datetime.utcnow()) potfile_abs = of.get_file_path() potfile_rel = utils.relative_path (potfile_abs, config.web_l10n_dir) if not kw.get('no_timestamps', False): dt = of.data.get ('mod_datetime') if dt != None and dt == domain.parent.mod_datetime: pulse.utils.log ('Skipping POT file %s' % potfile_rel) self.__class__.potfiles[indir] = of return of potdir = os.path.dirname (potfile_abs) if not os.path.exists (potdir): os.makedirs (potdir) cmd = 'intltool-update -p -g "%s" && mv "%s" "%s"' % (potname, potfile, potdir) owd = os.getcwd () try: os.chdir (indir) pulse.utils.log ('Creating POT file %s' % potfile_rel) (mstatus, moutput) = commands.getstatusoutput ( 'rm -f missing notexist && intltool-update -m') (status, output) = commands.getstatusoutput (cmd) finally: os.chdir (owd) missing = [] if mstatus == 0: mfile = os.path.join (indir, 'missing') if os.access (mfile, os.R_OK): missing = [line.strip() for line in open(mfile).readlines()] if status == 0: potmd5 = md5.new() # We don't start feeding potmd5 until we've hit a blank line. # This keeps inconsequential differences in the header from # affecting the MD5. blankline = False popo = parsers.Po () for line in open (potfile_abs): if blankline: potmd5.update (line) elif line.strip() == '': blankline = True popo.feed (line) popo.finish () num = popo.get_num_messages () of.datetime = datetime.datetime.utcnow() of.data['mod_datetime'] = domain.parent.mod_datetime of.data['missing'] = missing of.statistic = num of.data['md5'] = potmd5.hexdigest () self.__class__.potfiles[indir] = of domain.error = None domain.updated = of.datetime return of else: domain.error = u'Failed to create POT file' pulse.utils.warn('Failed to create POT file %s' % potfile_rel) self.__class__.potfiles[indir] = None return None
def update_translation (self, **kw): """ Update information about an intltool-managed translation. """ translation = self.scanner.translation checkout = self.scanner.checkout if translation.subtype != 'intltool': return False potfile = self.get_potfile (**kw) if potfile is None: return False filepath = os.path.join (checkout.directory, translation.scm_dir, translation.scm_file) if not os.path.exists (filepath): utils.warn('Could not locate file %s for %s' % (translation.scm_file, translation.parent.ident)) return False rel_scm = utils.relative_path (filepath, config.scm_dir) mtime = os.stat(filepath).st_mtime if not kw.get('no_timestamps', False): stamp = db.Timestamp.get_timestamp (rel_scm) if mtime <= stamp: pomd5 = translation.data.get('md5', None) potmd5 = potfile.data.get('md5', None) if pomd5 != None and pomd5 == potmd5: utils.log ('Skipping file %s' % rel_scm) return True podir = os.path.join (checkout.directory, translation.scm_dir) cmd = 'msgmerge "%s" "%s" 2>&1' % (translation.scm_file, potfile.get_file_path()) owd = os.getcwd () try: os.chdir (podir) pulse.utils.log ('Processing file ' + rel_scm) popo = parsers.Po (os.popen (cmd)) stats = popo.get_stats() total = stats[0] + stats[1] + stats[2] db.Statistic.set_statistic (translation, utils.daynum(), u'Messages', stats[0], stats[1], total) finally: os.chdir (owd) # FIXME: things like .desktop files might not be reprocessed because # they haven't changed, but translators might have updated the name # or description. Rather than trying to make those things run when # po files have been updated, let's just grab these: # po.parent.parent.select_children (...) # for Application, Capplet, Applet, and Library and see if we can # provide an updated name or description. of = db.OutputFile.select (type=u'l10n', ident=translation.parent.ident, filename=translation.scm_file) try: of = of[0] except IndexError: of = db.OutputFile (type=u'l10n', ident=translation.parent.ident, filename=translation.scm_file, datetime=datetime.datetime.utcnow()) outfile_abs = of.get_file_path() outfile_rel = pulse.utils.relative_path (outfile_abs, config.web_l10n_dir) outdir = os.path.dirname (outfile_abs) if not os.path.exists (outdir): os.makedirs (outdir) utils.log ('Copying PO file %s' % outfile_rel) shutil.copyfile (os.path.join (checkout.directory, translation.scm_dir, translation.scm_file), os.path.join (outdir, translation.scm_file)) of.datetime = datetime.datetime.utcnow() of.data['revision'] = checkout.get_revision() files = [os.path.join (translation.scm_dir, translation.scm_file)] revision = db.Revision.get_last_revision (branch=translation.parent.parent, files=files) if revision != None: translation.mod_datetime = revision.datetime translation.mod_person = revision.person translation.data['md5'] = potfile.data.get('md5', None) db.Timestamp.set_timestamp (rel_scm, mtime) return True
def process_file (self, dirname, basename, **kw): """ Process a Makefile.am file for the Evolution Quick Reference Card. """ branch = self.scanner.branch checkout = self.scanner.checkout is_quickref = False if branch.scm_server == 'http://svn.gnome.org/svn/' and branch.scm_module == 'evolution': if basename == 'Makefile.am': if os.path.join (checkout.directory, 'help/quickref') == dirname: is_quickref = True if not is_quickref: return filename = os.path.join (dirname, basename) makefile = self.scanner.get_parsed_file (parsers.Automake, filename) bserver, bmodule, bbranch = branch.ident.split('/')[2:] ident = u'/'.join(['/doc', bserver, bmodule, u'quickref', bbranch]) document = db.Branch.get_or_create (ident, u'Document') document.parent = branch relpath = utils.relative_path (dirname, checkout.directory) data = {} for key in ('scm_type', 'scm_server', 'scm_module', 'scm_branch', 'scm_path'): data[key] = getattr(branch, key) data['subtype'] = u'evolution-quickref' data['scm_dir'] = os.path.join (relpath, 'C') data['scm_file'] = u'quickref.tex' document.update (data) langs = makefile['SUBDIRS'].split () translations = [] for lang in langs: if lang == 'C': continue lident = u'/l10n/' + lang + document.ident translation = db.Branch.get_or_create (lident, u'Translation') translations.append (translation) ldata = {} for key in ('scm_type', 'scm_server', 'scm_module', 'scm_branch', 'scm_path'): ldata[key] = data[key] ldata['subtype'] = u'evolution-quickref' ldata['scm_dir'] = os.path.join ( utils.relative_path (dirname, checkout.directory), lang) ldata['scm_file'] = u'quickref.tex' translation.parent = document translation.update (ldata) document.set_children (u'Translation', translations) if not kw.get('no_i18n', False): for po in translations: pulse.pulsate.i18n.update_translation (po, checkout=checkout, **kw) if not kw.get('no_docs', False): pulse.pulsate.docs.update_document (document, checkout=checkout, **kw) if document is not None: self.scanner.add_child (document)
def update_document (self, **kw): document = self.scanner.document checkout = self.scanner.checkout if document.subtype != u'evolution-quickref': return False langs = [('C', document)] translations = db.Branch.select (type=u'Translation', parent=document) for translation in translations: langs.append ((os.path.basename (translation.scm_dir), translation)) name = {} regexp = re.compile ('\\s*\\\\textbf{\\\\Huge{(.*)}}') ofs_by_lang = {} ofs = list(db.OutputFile.select (type=u'figures', ident=document.ident)) for of in ofs: ofs_by_lang[of.filename[:-4]] = of for lang, obj in langs: texfile = os.path.join (checkout.directory, obj.scm_dir, obj.scm_file) for line in open (texfile): match = regexp.match (line) if match: name[lang] = match.group (1) break of = ofs_by_lang.get (lang, None) create_figure = False pdffile = os.path.join (obj.scm_dir, 'quickref.pdf') pdffull = os.path.join (checkout.directory, pdffile) if of is None: of = db.OutputFile (type=u'figures', ident=document.ident, filename=(lang + u'.png'), source=pdffile, datetime=datetime.datetime.utcnow()) create_figure = True else: if kw.get('no_timestamps', False): create_figure = True else: try: mtime = os.stat(pdffull).st_mtime if mtime > time.mktime(of.datetime.timetuple()): create_figure = True except: pass outfile = of.get_file_path () outfile_rel = utils.relative_path (outfile, pulse.config.web_figures_dir) if create_figure: outdir = os.path.dirname (outfile) if not os.path.exists (outdir): os.makedirs (outdir) utils.log ('Creating image %s' % outfile_rel) try: fd = os.popen ('convert "%s" png:-' % pdffull) im = Image.open (StringIO.StringIO (fd.read())) im = im.rotate (-90) im.thumbnail ((600, 600), Image.ANTIALIAS) width, height = im.size im.save (outfile) tfile = of.get_file_path ('thumbs') tdir = os.path.dirname (tfile) if not os.path.exists (tdir): os.makedirs (tdir) im.thumbnail((120, 120), Image.ANTIALIAS) twidth, theight = im.size im.save (tfile, 'PNG') of.datetime = datetime.datetime.utcnow() of.data['width'] = width of.data['height'] = height of.data['thumb_width'] = twidth of.data['thumb_height'] = theight document.data.setdefault ('screenshot', {}) document.data['screenshot'][lang] = of.id except: of.delete () else: utils.log ('Skipping image %s' % outfile_rel) document.update (name=name) document.data['files'] = [u'quickref.pdf', u'quickref.tex'] files = [os.path.join (document.scm_dir, f) for f in document.data['files']] pulse.pulsate.update_graphs (document, {'branch' : document.parent, 'files' : files}, 10, **kw) return True
def process_file (self, dirname, basename, **kw): """ Process a file to determine whether it's a pkgconfig file. """ if not re.match ('.*\.pc(\.in)+$', basename): return filename = os.path.join (dirname, basename) branch = self.scanner.branch checkout = self.scanner.checkout bserver, bmodule, bbranch = branch.ident.split('/')[2:] rootname = basename[:-6] rel_ch = utils.relative_path (filename, checkout.directory) rel_scm = utils.relative_path (filename, config.scm_dir) mtime = os.stat(filename).st_mtime # Hack for GTK+'s uninstalled pkgconfig files if '-uninstalled' in rootname: return if not kw.get('no_timestamps', False): stamp = db.Timestamp.get_timestamp (rel_scm) if mtime <= stamp: utils.log ('Skipping file %s' % rel_scm) data = {'parent' : branch} data['scm_dir'], data['scm_file'] = os.path.split (rel_ch) libs = db.Branch.select (type=u'Library', **data) try: lib = libs.one () self.scanner.add_child (lib) return except: return utils.log ('Processing file %s' % rel_scm) libname = '' libdesc = '' for line in open (filename): if line.startswith ('Name:'): libname = line[5:].strip() elif line.startswith ('Description:'): libdesc = line[12:].strip() if libname == '': return ident = u'/'.join(['/lib', bserver, bmodule, rootname, bbranch]) lib = db.Branch.get_or_create (ident, u'Library') if libname == '@PACKAGE_NAME@': libname = branch.data.get ('PACKAGE_NAME', '@PACKAGE_NAME@') lib.update (name=libname, desc=libdesc) self.libdocs.append ((lib, bserver, bmodule, rootname, bbranch)) data = {} for key in ('scm_type', 'scm_server', 'scm_module', 'scm_branch', 'scm_path'): data[key] = getattr(branch, key) data['scm_dir'], data['scm_file'] = os.path.split (rel_ch) lib.update (data) db.Timestamp.set_timestamp (rel_scm, mtime) if lib is not None: self.scanner.add_child (lib)