def read_project_config(self, filename): log = Logger() if os.path.getsize(filename) == 0: log.info('The project config file is empty, need command line options') return project_config xmldoc = minidom.parse(filename) # Read the project url if xmldoc.getElementsByTagName("url"): node = xmldoc.getElementsByTagName("url")[0] project_config['url'] = getCombinedTextChildren(node) # Read the project id if xmldoc.getElementsByTagName("project"): node = xmldoc.getElementsByTagName("project")[0] project_config['project_id'] = getCombinedTextChildren(node) # Read the project-version if xmldoc.getElementsByTagName("project-version"): node = xmldoc.getElementsByTagName("project-version")[0] project_config['project_version'] = getCombinedTextChildren(node) # Read the project-type if xmldoc.getElementsByTagName("project-type"): node = xmldoc.getElementsByTagName("project-type")[0] project_config['project_type'] = getCombinedTextChildren(node) # Read the locale map if xmldoc.getElementsByTagName("locales"): locales = xmldoc.getElementsByTagName("locales")[0] localelist = locales.getElementsByTagName("locale") project_config['locale_map'] = {} for locale in localelist: for node in locale.childNodes: if node.nodeType == node.TEXT_NODE: if locale.getAttribute("map-from"): locale_map = {str(locale.getAttribute("map-from")): str(node.data)} else: locale_map = {str(node.data): str(node.data)} project_config['locale_map'].update(locale_map) # Read <src-dir> and <trans-dir> if xmldoc.getElementsByTagName("src-dir"): node = xmldoc.getElementsByTagName("src-dir")[0] project_config['srcdir'] = getCombinedTextChildren(node) if xmldoc.getElementsByTagName("trans-dir"): node = xmldoc.getElementsByTagName("trans-dir")[0] project_config['transdir'] = getCombinedTextChildren(node) return dict((node, value.strip() if isinstance(value, str) else value) for node, value in project_config.items() if value)
def read_project_config(self, filename): log = Logger() if os.path.getsize(filename) == 0: log.info( 'The project config file is empty, need command line options') return project_config xmldoc = minidom.parse(filename) # Read the project url if xmldoc.getElementsByTagName("url"): node = xmldoc.getElementsByTagName("url")[0] project_config['project_url'] = getCombinedTextChildren(node) # Read the project id if xmldoc.getElementsByTagName("project"): node = xmldoc.getElementsByTagName("project")[0] project_config['project_id'] = getCombinedTextChildren(node) # Read the project-version if xmldoc.getElementsByTagName("project-version"): node = xmldoc.getElementsByTagName("project-version")[0] project_config['project_version'] = getCombinedTextChildren(node) # Read the project-type if xmldoc.getElementsByTagName("project-type"): node = xmldoc.getElementsByTagName("project-type")[0] project_config['project_type'] = getCombinedTextChildren(node) # Read the locale map if xmldoc.getElementsByTagName("locales"): locales = xmldoc.getElementsByTagName("locales")[0] localelist = locales.getElementsByTagName("locale") for locale in localelist: for node in locale.childNodes: if node.nodeType == node.TEXT_NODE: if locale.getAttribute("map-from"): locale_map = { str(locale.getAttribute("map-from")): str(node.data) } else: locale_map = {str(node.data): str(node.data)} project_config['locale_map'].update(locale_map) return project_config
class ZanataCommand: def __init__(self): self.log = Logger() ############################################## ## ## Commands for interaction with zanata server ## ############################################## def check_project(self, zanataclient, command_options, project_config): project_id = '' iteration_id = '' if command_options.has_key('project_id'): project_id = command_options['project_id'][0]['value'] else: if project_config.has_key('project_id'): project_id = project_config['project_id'] if command_options.has_key('project_version'): iteration_id = command_options['project_version'][0]['value'] else: if project_config.has_key('project_version'): iteration_id = project_config['project_version'] if not project_id: self.log.error("Please specify a valid project id in zanata.xml or with '--project-id' option") sys.exit(1) if not iteration_id: self.log.error("Please specify a valid version id in zanata.xml or with '--project-version' option") sys.exit(1) self.log.info("Project: %s"%project_id) self.log.info("Version: %s"%iteration_id) try: zanataclient.projects.get(project_id) except NoSuchProjectException, e: self.log.error(e.msg) sys.exit(1) try: zanataclient.projects.iterations.get(project_id, iteration_id) return project_id, iteration_id except NoSuchProjectException, e: self.log.error(e.msg) sys.exit(1)
def read_project_config(self, filename): log = Logger() if os.path.getsize(filename) == 0: log.info('The project config file is empty, need command line options') return project_config xmldoc = minidom.parse(filename) # Read the project url if xmldoc.getElementsByTagName("url"): node = xmldoc.getElementsByTagName("url")[0] project_config['project_url'] = getCombinedTextChildren(node) # Read the project id if xmldoc.getElementsByTagName("project"): node = xmldoc.getElementsByTagName("project")[0] project_config['project_id'] = getCombinedTextChildren(node) # Read the project-version if xmldoc.getElementsByTagName("project-version"): node = xmldoc.getElementsByTagName("project-version")[0] project_config['project_version'] = getCombinedTextChildren(node) # Read the project-type if xmldoc.getElementsByTagName("project-type"): node = xmldoc.getElementsByTagName("project-type")[0] project_config['project_type'] = getCombinedTextChildren(node) # Read the locale map if xmldoc.getElementsByTagName("locales"): locales = xmldoc.getElementsByTagName("locales")[0] localelist = locales.getElementsByTagName("locale") for locale in localelist: for node in locale.childNodes: if node.nodeType == node.TEXT_NODE: if locale.getAttribute("map-from"): locale_map = {str(locale.getAttribute("map-from")): str(node.data)} else: locale_map = {str(node.data): str(node.data)} project_config['locale_map'].update(locale_map) return project_config
#Read the user-config file config.set_userconfig(path) try: server = config.get_server(url) if server: user_name = config.get_config_value("username", "servers", server) apikey = config.get_config_value("key", "servers", server) except Exception, e: log.info("Processing user-config file:%s" % str(e)) break break if not (user_name, apikey): log.info("Can not find user-config file in home folder, current path or path in 'user-config' option") log.info("zanata server: %s" % url) #The value in commandline options will overwrite the value in user-config file if command_options.has_key('user_name'): user_name = command_options['user_name'][0]['value'] if command_options.has_key('key'): apikey = command_options['key'][0]['value'] return (user_name, apikey) def get_version(url): #Retrieve the version of client version_number = ""
sys.exit(1) else: #get all the pot files from the template folder publicanutil = PublicanUtility() filelist = publicanutil.get_file_list(tmlfolder, ".pot") if not filelist: log.error("The template folder is empty") sys.exit(1) deletefiles = True if command_options.has_key('force'): force = True if project_type == 'podir': log.info("POT directory (originals):%s" % tmlfolder) folder = None elif project_type == 'gettext': log.info("PO directory (originals):%s" % tmlfolder) folder = tmlfolder if pushtrans is None: pushtrans = self.get_pushtrans(command_options) if deletefiles: zanatacmd.del_server_content(tmlfolder, project_id, version_id, filelist, force, project_type) if pushtrans: log.info("Send local translation: True") import_param = self.get_importparam(project_type, command_options, project_config, folder) zanatacmd.push_command(filelist, tmlfolder, project_id, version_id, copytrans, plural_support, import_param)
class OptionsUtil: def __init__(self, options): self.command_options = options self.project_config = {} self.log = Logger() self.config = ZanataConfig() def apply_configfiles(self): url = self.apply_project_config() username, apikey = self.apply_user_config(url) # The value in commandline options will overwrite the value in user-config file if self.command_options.has_key("user_name"): username = self.command_options["user_name"][0]["value"] if self.command_options.has_key("key"): apikey = self.command_options["key"][0]["value"] self.log.info("zanata server: %s" % url) return url, username, apikey def apply_project_config(self): # Read the project configuration file using --project-config option config_file = [os.path.join(os.getcwd(), filename) for filename in ["zanata.xml", "flies.xml"]] if self.command_options.has_key("project_config"): config_file.append(self.command_options["project_config"][0]["value"]) for path in config_file: if os.path.exists(path): self.log.info("Loading zanata project config from: %s" % path) self.project_config = self.config.read_project_config(path) break if not self.project_config: self.log.info("Can not find zanata.xml, please specify the path of zanata.xml") # process the url of server if self.project_config.has_key("project_url"): url = self.project_config["project_url"] # The value in options will override the value in project-config file if self.command_options.has_key("url"): self.log.info("Overriding url of server with command line option") url = self.command_options["url"][0]["value"] if not url or url.isspace(): self.log.error("Please specify valid server url in zanata.xml or with '--url' option") sys.exit(1) url = self.trim_url(url) return url def trim_url(self, url): if " " in url or "\n" in url: self.log.info("Warning, the url which contains '\\n' or whitespace is not valid, please check zanata.xml") url = url.strip() if url[-1] == "/": url = url[:-1] return url def get_localemap(self): if self.project_config and self.project_config.has_key("locale_map"): locale_map = self.project_config["locale_map"] return locale_map def apply_user_config(self, url): user_name = "" apikey = "" # Try to read user-config file user_config = [ os.path.join(os.path.expanduser("~") + "/.config", filename) for filename in ["zanata.ini", "flies.ini"] ] if self.command_options.has_key("user_config"): user_config.append(self.command_options["user_config"][0]["value"]) for path in user_config: if os.path.exists(path): self.log.info("Loading zanata user config from: %s" % path) # Read the user-config file self.config.set_userconfig(path) try: server = self.config.get_server(url) if server: user_name = self.config.get_config_value("username", "servers", server) apikey = self.config.get_config_value("key", "servers", server) except Exception, e: self.log.info("Processing user-config file:%s" % str(e)) break break if not (user_name, apikey): self.log.info("Can not find user-config file in home folder, current path or path in 'user-config' option") return (user_name, apikey)
log.info("Loading zanata user config from: %s" % path) #Read the user-config file config.set_userconfig(path) try: server = config.get_server(url) if server: user_name = config.get_config_value("username", "servers", server) apikey = config.get_config_value("key", "servers", server) except Exception, e: log.info("Processing user-config file:%s" % str(e)) break break if not (user_name, apikey): log.info("Can not find user-config file in home folder, current path or path in 'user-config' option") log.info("zanata server: %s" % url) #The value in commandline options will overwrite the value in user-config file if command_options.has_key('user_name'): user_name = command_options['user_name'][0]['value'] if command_options.has_key('key'): apikey = command_options['key'][0]['value'] return (user_name, apikey) def get_version(url, command_options,headers=None): #Retrieve the version of client version_number = ""
# Read the user-config file config.set_userconfig(path) try: server = config.get_server(url) if server: user_name = config.get_config_value("username", "servers", server) apikey = config.get_config_value("key", "servers", server) except Exception, e: log.info("Processing user-config file:%s" % str(e)) break break if not (user_name, apikey): log.info("Can not find user-config file in home folder, current path or path in 'user-config' option") # The value in commandline options will overwrite the value in user-config file if command_options.has_key("user_name"): user_name = command_options["user_name"][0]["value"] if command_options.has_key("key"): apikey = command_options["key"][0]["value"] return (user_name, apikey) def get_client_version(self, command_options): # Retrieve the version of client version_number = "" path = os.path.dirname(os.path.realpath(__file__)) version_file = os.path.join(path, "VERSION-FILE")
config.set_userconfig(path) try: server = config.get_server(url) if server: user_name = config.get_config_value( "username", "servers", server) apikey = config.get_config_value("key", "servers", server) except Exception, e: log.info("Processing user-config file:%s" % str(e)) break break if not (user_name, apikey): log.info( "Can not find user-config file in home folder, current path or path in 'user-config' option" ) log.info("zanata server: %s" % url) #The value in commandline options will overwrite the value in user-config file if command_options.has_key('user_name'): user_name = command_options['user_name'][0]['value'] if command_options.has_key('key'): apikey = command_options['key'][0]['value'] return (user_name, apikey) def get_version(url, command_options, headers=None):
try: server = config.get_server(url) if server: user_name = config.get_config_value( "username", "servers", server) apikey = config.get_config_value( "key", "servers", server) except Exception, e: log.info("Processing user-config file:%s" % str(e)) break break if not (user_name, apikey): log.info( "Can not find user-config file in home folder, current path or path in 'user-config' option" ) #The value in commandline options will overwrite the value in user-config file if command_options.has_key('user_name'): user_name = command_options['user_name'][0]['value'] if command_options.has_key('key'): apikey = command_options['key'][0]['value'] return (user_name, apikey) def get_client_version(self, command_options): #Retrieve the version of client version_number = "" path = os.path.dirname(os.path.realpath(__file__))
class OptionsUtil: def __init__(self, options): self.command_options = options self.project_config = {} self.log = Logger() self.config = ZanataConfig() def apply_configfiles(self): url = self.apply_project_config() username, apikey = self.apply_user_config(url) # The value in commandline options will overwrite the value in user-config file if self.command_options.has_key('user_name'): username = self.command_options['user_name'][0]['value'] if self.command_options.has_key('key'): apikey = self.command_options['key'][0]['value'] self.log.info("zanata server: %s" % url) return url, username, apikey def apply_project_config(self): url = "" # Read the project configuration file using --project-config option config_file = [os.path.join(os.getcwd(), filename) for filename in ['zanata.xml', 'flies.xml']] if self.command_options.has_key('project_config'): config_file.append(self.command_options['project_config'][0]['value']) for path in config_file: if os.path.exists(path): self.log.info("Loading zanata project config from: %s" % path) self.project_config = self.config.read_project_config(path) break if not self.project_config: self.log.info("Can not find zanata.xml, please specify the path of zanata.xml") # process the url of server if self.project_config.has_key('project_url'): url = self.project_config['project_url'] # The value in options will override the value in project-config file if self.command_options.has_key('url'): self.log.info("Overriding url of server with command line option") url = self.command_options['url'][0]['value'] if not url or url.isspace(): self.log.error("Please specify valid server url in zanata.xml or with '--url' option") sys.exit(1) url = self.trim_url(url) return url def trim_url(self, url): if ' ' in url or '\n' in url: self.log.info("Warning, the url which contains '\\n' or whitespace is not valid, please check zanata.xml") url = url.strip() if url[-1] == "/": url = url[:-1] return url def get_localemap(self): if self.project_config and self.project_config.has_key('locale_map'): locale_map = self.project_config['locale_map'] return locale_map def apply_user_config(self, url): user_name = "" apikey = "" # Try to read user-config file user_config = [os.path.join(os.path.expanduser("~") + '/.config', filename) for filename in ['zanata.ini', 'flies.ini']] if self.command_options.has_key('user_config'): user_config.append(self.command_options['user_config'][0]['value']) for path in user_config: if os.path.exists(path): self.log.info("Loading zanata user config from: %s" % path) # Read the user-config file self.config.set_userconfig(path) try: server = self.config.get_server(url) if server: user_name = self.config.get_config_value("username", "servers", server) apikey = self.config.get_config_value("key", "servers", server) except Exception, e: self.log.info("Processing user-config file:%s" % str(e)) break break if not (user_name, apikey): self.log.info("Can not find user-config file in home folder, current path or path in 'user-config' option") return (user_name, apikey)
def read_project_config(self, filename): log = Logger() if os.path.getsize(filename) == 0: log.info('The project config file is empty, need command line options') return project_config xmldoc = minidom.parse(filename) #Read the project url if xmldoc.getElementsByTagName("url"): node = xmldoc.getElementsByTagName("url")[0] rc = "" for node in node.childNodes: if node.nodeType in ( node.TEXT_NODE, node.CDATA_SECTION_NODE): rc = rc + node.data project_config['project_url'] = rc #Read the project id if xmldoc.getElementsByTagName("project"): node = xmldoc.getElementsByTagName("project")[0] rc = "" for node in node.childNodes: if node.nodeType in ( node.TEXT_NODE, node.CDATA_SECTION_NODE): rc = rc + node.data project_config['project_id'] = rc #Read the project-version if xmldoc.getElementsByTagName("project-version"): node = xmldoc.getElementsByTagName("project-version")[0] rc = "" for node in node.childNodes: if node.nodeType in ( node.TEXT_NODE, node.CDATA_SECTION_NODE): rc = rc + node.data project_config['project_version'] = rc if xmldoc.getElementsByTagName("python-client"): python_config = xmldoc.getElementsByTagName("python-client")[0] srcdir = python_config.getElementsByTagName("dir") rc = "" for folder in srcdir: for node in folder.childNodes: if node.nodeType in ( node.TEXT_NODE, node.CDATA_SECTION_NODE): rc = rc + node.data project_config['project_srcdir'] = rc #Read the locale map if xmldoc.getElementsByTagName("locales"): locales = xmldoc.getElementsByTagName("locales")[0] localelist = locales.getElementsByTagName("locale") for locale in localelist: for node in locale.childNodes: if node.nodeType == node.TEXT_NODE: if locale.getAttribute("map-from"): locale_map = {locale.getAttribute("map-from"):node.data} project_config['locale_map'].update(locale_map) else: locale_map = {node.data:node.data} project_config['locale_map'].update(locale_map) return project_config
class PublicanUtility: def __init__(self): self.log = Logger() def create_txtflow(self, pofile): """ Convert the content of the pot file to a list of text flow. @return: the dictionary object of textflow """ textflows = [] for entry in pofile: reflist = [] if entry.msgctxt: self.log.warn("encountered msgctxt; not currently supported") m = hashlib.md5() m.update(entry.msgid.encode('utf-8')) textflowId = m.hexdigest() """ "extensions":[{"object-type":"pot-entry-header","context":"context", "references":["fff"],"extractedComment":"extractedComment", "flags":["java-format"]}] """ extracted_comment = entry.comment references = entry.occurrences for ref in references: node = ref[0]+":"+ref[1] reflist.append(node) flags = entry.flags #extensions_single_comment = [{'object-type':'comment','value':'test','space':'preserve'}] #extensions_pot_entry_header = [{"object-type":"pot-entry-header","context":"context","references":["fff"],"extractedComment":"extractedComment","flags":["java-format"]}] extensions=[{'object-type':'comment','value':extracted_comment,'space':'preserve'}, {"object-type":"pot-entry-header","context":"","references":reflist,"extractedComment":'',"flags":flags}] textflow = {'id': textflowId, 'lang':'en-US', 'content':entry.msgid, 'extensions':extensions, 'revision':1} textflows.append(textflow) return textflows def create_txtflowtarget(self, pofile): """ Convert the content of the po file to a list of textflowtarget. @return: the dictionary object of textflow """ obs_list=pofile.obsolete_entries() textflowtargets = [] for entry in pofile: if entry in obs_list: continue m = hashlib.md5() m.update(entry.msgid.encode('utf-8')) textflowId = m.hexdigest() comment = entry.comment if entry.msgstr: state = "Approved" else: state = "New" #need judge for fuzzy state #create extensions extensions = [{"object-type":"comment","value":comment,"space":"preserve"}] # {"resId":"782f49c4e93c32403ba0b51821b38b90","state":"Approved","translator":{"email":"id","name":"name"},"content":"title: # ttff","extensions":[{"object-type":"comment","value":"testcomment","space":"preserve"}]} # Diable the translator to avoid issues on server side textflowtarget = {'resId': textflowId, 'state': state, 'content':entry.msgstr,'extensions':extensions} #Temporary fill in the admin info for translator to pass the validation, waiting for server side change textflowtargets.append(textflowtarget) return textflowtargets def create_extensions(self, pofile, object_type): """ "extensions":[{"object-type":"po-header","comment":"comment_value", "entries":[{"key":"h1","value":"v1"}]}] "extensions":[{"object-type":"po-target-header", "comment":"comment_value", "entries":[{"key":"ht","value":"vt1"}]}] """ entries = [] metadatas = pofile.ordered_metadata() for item in metadatas: entry = {"key":item[0], "value":item[1]} entries.append(entry) extensions = [{"object-type":object_type,"comment":pofile.header, "entries":entries}] return extensions def create_pofile(self, path): """ Convert the po file to a pofile object in polib. @return: pofile object """ try: po = polib.pofile(path) except Exception: self.log.error("Can not processing the po file") sys.exit() return po def get_file_list(self, path, file_type): final_file_list = [] root_list = os.listdir(path) for item in root_list: if item == '.svn': continue full_path = os.path.join(path, item) if full_path.endswith(file_type): final_file_list.append(full_path) if os.path.isdir(full_path): final_file_list+=self.get_file_list(full_path, file_type) return final_file_list def hash_match(self, message, msgid): m = hashlib.md5() m.update(message.msgid.encode('utf-8')) if m.hexdigest() == msgid: return True else: return False def strip_path(self, full_path, root_path): if root_path[-1] != "/": root_path = root_path+'/' filename = full_path.split(root_path)[1] if '.' in filename: # Strip the file name filename = filename.split('.')[0] return filename def potfile_to_json(self, filepath, root_path): """ Parse the pot file, create the request body @param filepath: the path of the pot file """ filename = self.strip_path(filepath, root_path) pofile = self.create_pofile(filepath) textflows = self.create_txtflow(pofile) extensions = self.create_extensions(pofile, "po-header") items = {'name':filename, 'contentType':'application/x-gettext', 'lang':'en-US', 'extensions':extensions, 'textFlows':textflows} return json.dumps(items), filename def pofile_to_json(self, filepath): """ Parse the po file, create the request body @param filepath: the path of the po file """ pofile = self.create_pofile(filepath) textflowtargets = self.create_txtflowtarget(pofile) #the function for extensions have not implemented yet extensions = self.create_extensions(pofile, "po-target-header") items = {'links':[],'extensions':extensions, 'textFlowTargets':textflowtargets} return json.dumps(items) def save_to_pofile(self, path, translations, pot): """ Save PO file to path, based on json objects of pot and translations @param translations: the json object of the content retrieved from server @param path: the po folder for output @param pot: the json object of the pot retrieved from server """ po = polib.POFile(fpath=path) potcontent = json.loads(pot) # pylint: disable-msg=E1103 textflows = potcontent.get('textFlows') if potcontent.get('extensions'): extensions = potcontent.get('extensions')[0] po.header = extensions.get('comment') for item in extensions.get('entries'): po.metadata[item['key']]=item['value'] else: raise InvalidPOTFileException("Error", "the extensions of Resource is empty") for textflow in textflows: if textflow.get('extensions'): poentry = polib.POEntry(occurrences=None) entry_list = textflow.get('extensions') for entry in entry_list: if entry.get('object-type') == 'pot-entry-header': #PotEntryHeader #Check the references is not empty if entry.get('references')!=[u'']: for item in entry.get('references'): #in some cases, entry contains more than one reference if ' ' in item: reference = item.split(' ') ref_list = [] for i in reference: ref = tuple(i.split(':')) ref_list.append(ref) poentry.occurrences= ref_list else: poentry.occurrences = [tuple(item.split(':'))] else: poentry.occurrences = None #print poentry.occurrences poentry.flags = entry.get('flags') if entry.get('object-type') == 'comment': #SimpleComment poentry.comment = entry.get('value') poentry.msgid = textflow.get('content') po.append(poentry) else: raise InvalidPOTFileException("Error", "the extensions of TextFlow is empty") #If the translation is exist, read the content of the po file if translations: content = json.loads(translations) """ "extensions":[{"object-type":"po-target-header", "comment":"comment_value", "entries":[{"key":"ht","value":"vt1"}]}] """ if content.get('extensions'): ext = content.get('extensions')[0] header_comment = ext.get('comment') if header_comment: po.header = header_comment for item in ext.get('entries'): po.metadata[item['key']]=item['value'] targets = content.get('textFlowTargets') """ "extensions":[{"object-type":"comment","value":"testcomment","space":"preserve"}] """ # copy any other stuff you need to transfer for message in po: for translation in targets: if translation.get('extensions'): extensions=translation.get('extensions')[0] #if extensions: # ext_type = extensions.get('object-type') # comment = extensions.get('comment') # entries = extensions.get('value') if self.hash_match(message, translation.get('resId')): message.msgstr = translation.get('content') # finally save resulting po to outpath as lang/myfile.po po.save() # pylint: disable-msg=E1103 self.log.info("Writing po file to %s"%(path))