def rm_document(self, file_name, useID, force, doc_name=None): doc = None if not useID: relative_path = file_name.replace(self.path, '') doc = self.doc_manager.get_doc_by_prop('file_name', relative_path) title = os.path.basename(os.path.normpath(file_name)) # print("relative_path: "+relative_path) try: doc = self.doc_manager.get_doc_by_prop('file_name', relative_path) document_id = doc['id'] except TypeError: # Documents specified by name must be found in the local database to be removed. logger.warning("Document name specified for remove doesn't exist locally: {0}".format(relative_path)) return # raise exceptions.ResourceNotFound("Document name specified doesn't exist: {0}".format(document_name)) else: document_id = file_name doc = self.doc_manager.get_doc_by_prop('id', document_id) # raise exceptions.ResourceNotFound("Document name specified doesn't exist: {0}".format(document_name)) if doc: file_name = doc['file_name'] response = self.api.document_delete(document_id) #print (response) if response.status_code != 204: # raise_error(response.json(), "Failed to delete document {0}".format(document_name), True) logger.error("Failed to delete document {0} remotely".format(file_name)) else: if doc_name: logger.info("{0} ({1}) has been deleted remotely.".format(doc_name, file_name)) else: logger.info("{0} has been deleted remotely.".format(file_name)) if doc: if force: self.delete_local(file_name, document_id) self.doc_manager.remove_element(document_id)
def add_action(self, file_patterns, **kwargs): # format will be automatically detected by extension but may not be what user expects # use current working directory as root for files instead of project root matched_files = get_files(file_patterns) if not matched_files: raise exceptions.ResourceNotFound("Could not find the specified file/pattern") for file_name in matched_files: # title = os.path.basename(os.path.normpath(file_name)).split('.')[0] title = os.path.basename(os.path.normpath(file_name)) relative_path = file_name.replace(self.path, '') if not self.doc_manager.is_doc_new(relative_path): if self.doc_manager.is_doc_modified(relative_path, self.path): if 'force' in kwargs and kwargs['force']: confirm = 'Y' else: confirm = 'not confirmed' while confirm != 'y' and confirm != 'Y' and confirm != 'N' and confirm != 'n' and confirm != '': confirm = input("This document already exists. Would you like to overwrite it? [y/N]: ") # confirm if would like to overwrite existing document in Lingotek Cloud if not confirm or confirm in ['n', 'N']: continue else: logger.info('Overwriting document: {0} in Lingotek Cloud...'.format(title)) self.update_document_action(file_name, title, **kwargs) continue else: logger.error("This document has already been added: {0}".format(title)) continue # todo separate function somewhere around here maybe.. self.add_document(file_name, title, **kwargs)
def add_document(self, file_name, title, doc_metadata={}, **kwargs): ''' adds the document to Lingotek cloud and the db ''' if ltk.check_connection.check_for_connection() == False: logger.warning( "Cannot connect to network. Documents added to the watch folder will be translated after you reconnect to the network." ) while ltk.check_connection.check_for_connection() == False: time.sleep(15) if self.is_hidden_file(file_name): return try: if not 'locale' in kwargs or not kwargs['locale']: locale = self.locale else: locale = kwargs['locale'] # add document to Lingotek cloud response = self.api.add_document( locale, file_name, self.project_id, self.append_location(title, file_name), doc_metadata, **kwargs) if response.status_code == 402: raise_error(response.json(), "", True) elif response.status_code != 202: raise_error(response.json(), "Failed to add document {0}\n".format(title), True) else: title = self.append_location(title, file_name) logger.info('Added document {0} with ID {1}\n'.format( title, response.json()['properties']['id'])) relative_path = self.norm_path(file_name) # add document to the db if 'download_folder' in kwargs and kwargs['download_folder']: self._add_document( relative_path, title, response.json()['properties']['id'], response.json()['properties']['process_id'], kwargs['download_folder']) else: self._add_document( relative_path, title, response.json()['properties']['id'], response.json()['properties']['process_id']) if 'translation_locale_code' in kwargs and kwargs[ 'translation_locale_code']: self._update_document(relative_path, None, kwargs['translation_locale_code']) except KeyboardInterrupt: raise_error("", "Canceled adding document\n") except Exception as e: log_error(self.error_file_name, e) if 'string indices must be integers' in str( e) or 'Expecting value: line 1 column 1' in str(e): logger.error("Error connecting to Lingotek's TMS\n") else: logger.error("Error on adding document \n" + str(file_name) + ": " + str(e))
def delete_local_path(self, path, message=None): path = self.norm_path(path) message = '{0} has been deleted locally.'.format(path) if not message else message try: os.remove(path) logger.info(message) except OSError: logger.info('Something went wrong trying to delete the local file')
def target_action(self, document_name, locales, to_delete, due_date, workflow, document_id=None): change_db_entry = True if to_delete: expected_code = 204 failure_message = 'Failed to delete target' info_message = 'Deleted locale' else: expected_code = 201 failure_message = 'Failed to add target' info_message = 'Added target' if not document_name and not document_id: for locale in locales: response = self.api.project_add_target(self.project_id, locale, due_date) if not to_delete \ else self.api.project_delete_target(self.project_id, locale) if response.status_code != expected_code: raise_error(response.json(), '{message} {locale} for project'.format(message=failure_message, locale=locale), True) change_db_entry = False continue logger.info('{message} {locale} for project {project_name}'.format(message=info_message, locale=locale, project_name=self.project_name)) document_ids = self.doc_manager.get_doc_ids() if change_db_entry: for document_id in document_ids: self._target_action_db(to_delete, locales, document_id) else: # todo: document name or file name? since file name will be relative to root # todo: clean this code up some if not document_id: entry = self.doc_manager.get_doc_by_prop('name', document_name) try: document_id = entry['id'] except TypeError: logger.error('Document name specified for target doesn\'t exist: {0}'.format(document_name)) return # raise exceptions.ResourceNotFound("Document name specified doesn't exist: {0}".format(document_name)) if not document_name: entry = self.doc_manager.get_doc_by_prop('id', document_id) try: document_name = entry['name'] except TypeError: logger.error('Document specified for target doesn\'t exist: {0}'.format(document_id)) return for locale in locales: response = self.api.document_add_target(document_id, locale, workflow, due_date) if not to_delete \ else self.api.document_delete_target(document_id, locale) if response.status_code != expected_code: raise_error(response.json(), '{message} {locale} for document'.format(message=failure_message, locale=locale), True) change_db_entry = False continue logger.info('{message} {locale} for document {name}'.format(message=info_message, locale=locale, name=document_name)) if change_db_entry: self._target_action_db(to_delete, locales, document_id)
def update_config_file(self, option, value, conf_parser, config_file_name, log_info): try: conf_parser.set('main', option, value) with open(config_file_name, 'w') as new_file: conf_parser.write(new_file) self._initialize_self() if (len(log_info)): logger.info(log_info+"\n") except IOError as e: print(e.errno) print(e)
def add_document(self, file_name, title, **kwargs): if not 'locale' in kwargs or not kwargs['locale']: locale = self.locale else: locale = kwargs['locale'] response = self.api.add_document(locale, file_name, self.project_id, title, **kwargs) if response.status_code != 202: raise_error(response.json(), "Failed to add document {0}".format(title), True) else: logger.info('Added document {0}'.format(title)) relative_path = file_name.replace(self.path, '') # print("relative path: "+relative_path) self._add_document(relative_path, title, response.json()['properties']['id'])
def push_action(self): entries = self.doc_manager.get_all_entries() updated = False for entry in entries: if not self.doc_manager.is_doc_modified(entry['file_name'], self.path): continue #print (entry['file_name']) response = self.api.document_update(entry['id'], os.path.join(self.path, entry['file_name'])) if response.status_code != 202: raise_error(response.json(), "Failed to update document {0}".format(entry['name']), True) updated = True logger.info('Updated ' + entry['name']) self._update_document(entry['file_name']) if not updated: print('All documents up-to-date with Lingotek Cloud. ') logger.info('All documents up-to-date with Lingotek Cloud. ')
def rm(file_names, **kwargs): """ Disassociates local doc(s) from Lingotek Cloud and deletes the remote copy. If the remote copy should not be kept, please use ltk clean. """ try: action = actions.Action(os.getcwd()) init_logger(action.path) print(file_names) if not file_names and not ('all' in kwargs and kwargs['all']): logger.info("Usage: ltk rm [OPTIONS] FILE_NAMES...") return action.rm_action(file_names, **kwargs) except (UninitializedError, ResourceNotFound, RequestFailedError) as e: print_log(e) logger.error(e) return
def display_choice(display_type, info): if display_type == 'community': input_prompt = 'Which community should this project belong to? ' elif display_type == 'project': input_prompt = 'Which existing project should be used? ' else: raise exceptions.ResourceNotFound("Cannot display info asked for") mapper = choice_mapper(info) choice = 'none-chosen' while choice not in mapper: choice = input(input_prompt) try: choice = int(choice) except ValueError: print("That's not a valid option!") for v in mapper[choice]: logger.info('Selected "{0}" {1}.'.format(mapper[choice][v], display_type)) return v, mapper[choice][v]
def rm(file_names, **kwargs): """ Disassociates local doc(s) from Lingotek Cloud and removes them from the project by cancelling them. If the remote copy should be deleted, use the -r flag. """ try: action = rm_action.RmAction(os.getcwd()) init_logger(action.path) if not file_names and not (('all' in kwargs and kwargs['all']) or ('local' in kwargs and kwargs['local'])): logger.info("Usage: ltk rm [OPTIONS] FILE_NAMES...") return if len(file_names) > 0: file_names = remove_powershell_formatting(file_names) action.rm_action(file_names, **kwargs) except (UninitializedError, ResourceNotFound, RequestFailedError) as e: print_log(e) logger.error(e) return
def poll_remote(self): """ poll lingotek servers to check if MT finished """ # todo eventually: poll for other jobs (prefill, analyze, etc...) documents = self.doc_manager.get_all_entries() # todo this gets all documents, not necessarily only ones in watch folder for doc in documents: doc_id = doc['id'] if doc_id in self.watch_queue: # if doc id in queue, not imported yet continue locale_progress = self.import_locale_info(doc_id, True) try: downloaded = doc['downloaded'] except KeyError: downloaded = [] self.doc_manager.update_document('downloaded', downloaded, doc_id) for locale in locale_progress: progress = locale_progress[locale] if progress == 100 and locale not in downloaded: logger.info('Translation completed ({0} - {1})'.format(doc_id, locale)) if self.locale_delimiter: self.download_action(doc_id, locale, False, False) else: self.download_action(doc_id, locale, False)
def reinit(host, project_path, delete, reset): if is_initialized(project_path) and not reset: logger.warning('This project is already initialized!') if not delete: return False confirm = 'not confirmed' while confirm != 'y' and confirm != 'Y' and confirm != 'N' and confirm != 'n' and confirm != '': confirm = input( "Are you sure you want to delete the current project? " "This will also delete the project in your community. [y/N]: ") # confirm if would like to delete existing folder if not confirm or confirm in ['n', 'N']: return False else: # delete the corresponding project online logger.info('Deleting old project folder and creating new one...') config_file_name = os.path.join(project_path, CONF_DIR, CONF_FN) if os.path.isfile(config_file_name): old_config = configparser.ConfigParser() old_config.read(config_file_name) project_id = old_config.get('main', 'project_id') access_token = old_config.get('main', 'access_token') api = ApiCalls(host, access_token) response = api.delete_project(project_id) if response.status_code != 204 and response.status_code != 404: try: error = response.json()['messages'][0] raise exceptions.RequestFailedError(error) except (AttributeError, IndexError): raise exceptions.RequestFailedError("Failed to delete and re-initialize project") # delete existing folder to_remove = os.path.join(project_path, CONF_DIR) shutil.rmtree(to_remove) else: raise exceptions.ResourceNotFound("Cannot find config file, please re-initialize project") return access_token return True
def get_files(patterns): """ gets all files matching pattern from root pattern supports any unix shell-style wildcards (not same as RE) """ # root = os.getcwd() matched_files = [] for pattern in patterns: path = os.path.abspath(pattern) # check if pattern contains subdirectory if os.path.exists(path): if os.path.isdir(path): for root, subdirs, files in os.walk(path): split_path = root.split('/') for file in files: # print(os.path.join(root, file)) matched_files.append(os.path.join(root, file)) else: matched_files.append(path) else: logger.info("File not found: "+pattern) # subdir_pat, fn_pat = os.path.split(pattern) # if not subdir_pat: # for path, subdirs, files in os.walk(root): # for fn in fnmatch.filter(files, pattern): # matched_files.append(os.path.join(path, fn)) # else: # for path, subdirs, files in os.walk(root): # # print os.path.split(path) # # subdir = os.path.split(path)[1] # get current subdir # search_root = os.path.join(root, '') # subdir = path.replace(search_root, '') # # print subdir, subdir_pat # if fnmatch.fnmatch(subdir, subdir_pat): # for fn in fnmatch.filter(files, fn_pat): # matched_files.append(os.path.join(path, fn)) return matched_files
def delete_local_translation(self, file_name): try: if not file_name: logger.info('Please provide a valid file name') logger.info('{0} (local translation) has been deleted'.format(self.get_relative_path(file_name))) os.remove(os.path.join(self.path, file_name)) except OSError: logger.info('Something went wrong trying to download the local translation')
def clean_action(self, force, dis_all, document_name): if dis_all: # disassociate everything self.doc_manager.clear_all() return if document_name: try: entry = self.doc_manager.get_doc_by_prop('name', document_name) document_id = entry['id'] self.doc_manager.remove_element(document_id) except TypeError: logger.warning("Document name specified for clean doesn't exist: {0}".format(document_name)) return response = self.api.list_documents(self.project_id) local_ids = self.doc_manager.get_doc_ids() tms_doc_ids = [] if response.status_code == 200: tms_documents = response.json()['entities'] for entity in tms_documents: tms_doc_ids.append(entity['properties']['id']) elif response.status_code == 204: pass else: raise_error(response.json(), 'Error trying to list documents in TMS for cleaning') locals_to_delete = [x for x in local_ids if x not in tms_doc_ids] # check local files db_entries = self.doc_manager.get_all_entries() for entry in db_entries: # if local file doesn't exist, remove entry if not os.path.isfile(os.path.join(self.path, entry['file_name'])): locals_to_delete.append(entry['id']) # remove entry for local doc -- possibly delete local file too? if locals_to_delete: for curr_id in locals_to_delete: removed_doc = self.doc_manager.get_doc_by_prop('id', curr_id) if not removed_doc: continue removed_title = removed_doc['name'] # todo somehow this line^ doc is null... after delete files remotely, then delete locally if force: self.delete_local(removed_title, curr_id) self.doc_manager.remove_element(curr_id) logger.info('Removing association for document {0}'.format(removed_title)) else: logger.info('Local documents already up-to-date with Lingotek cloud') return logger.info('Cleaned up associations between local documents and Lingotek cloud')
def delete_local(self, title, document_id, message=None): # print('local delete:', title, document_id) if not title: title = document_id message = '{0} has been deleted locally.'.format(title) if not message else message try: file_name = self.doc_manager.get_doc_by_prop('id', document_id)['file_name'] except TypeError: logger.info('Document to remove not found in the local database') return try: os.remove(os.path.join(self.path, file_name)) logger.info(message) except OSError: logger.info('Something went wrong trying to delete the local file.')
def delete_local(self, title, document_id, message=None): # print('local delete:', title, document_id) if not title: title = document_id message = '{0} has been deleted locally'.format(title) if not message else message try: file_name = self.doc_manager.get_doc_by_prop('id', document_id)['file_name'] except TypeError: logger.info('Document to remove not found in the local database') return try: os.remove(os.path.join(self.path, file_name)) logger.info(message) except OSError: logger.info('Something went wrong trying to delete the local file')
def download_action(self, document_id, locale_code, auto_format, locale_ext=True): response = self.api.document_content(document_id, locale_code, auto_format) if response.status_code == 200: entry = self.doc_manager.get_doc_by_prop('id', document_id) if not entry: doc_info = self.api.get_document(document_id) try: file_title = doc_info.json()['properties']['title'] title, extension = os.path.splitext(file_title) if not extension: extension = doc_info.json()['properties']['extension'] extension = '.' + extension if extension and extension != '.none': title += extension except KeyError: raise_error(doc_info.json(), 'Something went wrong trying to download document: {0}'.format(document_id), True) return download_path = os.path.join(self.path, title) logger.info("Downloaded: {0}".format(title)) else: if not locale_code: logger.info("No target locales, downloading source instead.") locale_code = self.locale file_name = entry['file_name'] download_dir = os.path.join(self.path, os.path.dirname(file_name)) base_name = os.path.basename(os.path.normpath(file_name)) if locale_ext: name_parts = base_name.split('.') if len(name_parts) > 1: name_parts.insert(-1, locale_code) downloaded_name = '.'.join(part for part in name_parts) else: downloaded_name = name_parts[0] + '.' + locale_code else: downloaded_name = base_name download_path = os.path.join(download_dir, downloaded_name) logger.info('Downloaded: {0} ({1} - {2})'.format(downloaded_name, base_name, locale_code)) self.doc_manager.update_document('downloaded', [locale_code], document_id) if self.download_dir: title = os.path.basename(os.path.normpath(download_path)) download_path = os.path.join(self.download_dir, title) with open(download_path, 'wb') as fh: for chunk in response.iter_content(1024): fh.write(chunk) return download_path else: raise_error(response.json(), 'Failed to download content for id: {0}'.format(document_id), True)
def process(self, event): logger.info(event.event_type)
def init_logger(path): """ Initializes logger based on path """ logger.setLevel(logging.DEBUG) if not path: file_handler = logging.FileHandler(LOG_FN) else: try: file_handler = logging.FileHandler(os.path.join(path, CONF_DIR, LOG_FN)) # if on Windows system, set directory properties to hidden if os.name == 'nt': try: subprocess.call(["attrib", "+H", os.path.join(path, CONF_DIR)]) except Exception as e: logger.error("Error on init: "+str(e)) # logger.info("On Windows, make .ltk folder hidden") # # Python 2 # # ret = ctypes.windll.kernel32.SetFileAttributesW(unicode(os.path.join(path, CONF_DIR)), HIDDEN_ATTRIBUTE) # # End Python 2 # # Python 3 # ret = ctypes.windll.kernel32.SetFileAttributesW(os.path.join(path, CONF_DIR), HIDDEN_ATTRIBUTE) # # End Python 3 # if(ret != 1): # return value of 1 signifies success # pass except IOError as e: #logger.info(e) # todo error check when running init without existing conf dir try: os.mkdir(os.path.join(path, CONF_DIR)) # if on Windows system, make directory hidden if os.name == 'nt': logger.info("On Windows, make .ltk folder hidden") # Python 2 # ret = ctypes.windll.kernel32.SetFileAttributesW(unicode(os.path.join(path, CONF_DIR)), HIDDEN_ATTRIBUTE) # End Python 2 # Python 3 ret = ctypes.windll.kernel32.SetFileAttributesW(os.path.join(path, CONF_DIR), HIDDEN_ATTRIBUTE) # End Python 3 if(ret != 1): # return value of 1 signifies success pass except IOError as e: print(e.errno) print(e) file_handler = logging.FileHandler(os.path.join(path, CONF_DIR, LOG_FN)) console_handler = logging.StreamHandler(sys.stdout) file_handler.setLevel(API_LOG_LEVEL) file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s')) if quiet: console_handler.setLevel(logging.WARNING) elif verbosity: if verbosity > 1: console_handler.setLevel(API_RESPONSE_LOG_LEVEL) else: console_handler.setLevel(API_LOG_LEVEL) else: console_handler.setLevel(logging.INFO) custom_formatter = CustomFormatter() console_handler.setFormatter(custom_formatter) logger.addHandler(file_handler) logger.addHandler(console_handler)
def printResponseMessages(response): for message in response.json()['messages']: logger.info(message)
def init_action(host, access_token, project_path, folder_name, workflow_id, locale, delete, reset): # check if Lingotek directory already exists print("init_action") to_init = reinit(host, project_path, delete, reset) print("to_init: "+str(to_init)) if not to_init: return elif to_init is not True: access_token = to_init ran_oauth = False if not access_token: access_token = check_global() if not access_token or reset: from ltk.auth import run_oauth access_token = run_oauth(host) ran_oauth = True print("access_token: "+str(access_token)) if ran_oauth: # create or overwrite global file create_global(access_token) api = ApiCalls(host, access_token) # create a directory try: os.mkdir(os.path.join(project_path, CONF_DIR)) except OSError: pass logger.info('Initializing project...') config_file_name = os.path.join(project_path, CONF_DIR, CONF_FN) # create the config file and add info config_file = open(config_file_name, 'w') config_parser = configparser.ConfigParser() config_parser.add_section('main') config_parser.set('main', 'access_token', access_token) config_parser.set('main', 'host', host) # config_parser.set('main', 'root_path', project_path) config_parser.set('main', 'workflow_id', workflow_id) config_parser.set('main', 'default_locale', locale) # get community id community_info = api.get_communities_info() # print("Community INFO") # print(len(community_info)) if len(community_info) == 0: raise exceptions.ResourceNotFound('You are not part of any communities in Lingotek Cloud') if len(community_info) > 1: community_id, community_name = display_choice('community', community_info) else: for id in community_info: community_id = id #community_id = community_info.iterkeys().next() --- iterkeys() is not in python 3 config_parser.set('main', 'community_id', community_id) response = api.list_projects(community_id) if response.status_code != 200: raise_error(response.json(), 'Something went wrong trying to find projects in your community') project_info = api.get_project_info(community_id) if len(project_info) > 0: confirm = 'none' while confirm != 'y' and confirm != 'Y' and confirm != 'N' and confirm != 'n' and confirm != '': confirm = input('Would you like to use an existing Lingotek project? [y/N]:') if confirm and confirm in ['y', 'Y', 'yes', 'Yes']: project_id, project_name = display_choice('project', project_info) config_parser.set('main', 'project_id', project_id) config_parser.set('main', 'project_name', project_name) config_parser.write(config_file) config_file.close() return project_name = input("Please enter a new Lingotek project name: %s" % folder_name + chr(8) * len(folder_name)) if not project_name: project_name = folder_name response = api.add_project(project_name, community_id, workflow_id) if response.status_code != 201: raise_error(response.json(), 'Failed to add current project to Lingotek Cloud') project_id = response.json()['properties']['id'] config_parser.set('main', 'project_id', project_id) config_parser.set('main', 'project_name', project_name) config_parser.write(config_file) config_file.close()
def update_content(self, relative_path): if self.update_document_action(os.path.join(self.path, relative_path)): self.updated[relative_path] = 0 logger.info('Updating remote content: {0}'.format(relative_path))
def update_config_file(self, option, value, conf_parser, config_file_name, log_info): conf_parser.set('main', option, value) with open(config_file_name, 'w') as new_file: conf_parser.write(new_file ) # self._initialize_self() logger.info(log_info)
def poll_remote(self): """ poll lingotek servers to check if translation is finished """ documents = self.doc_manager.get_all_entries() # todo this gets all documents, not necessarily only ones in watch folder documents_downloaded = False git_commit_message = "" for doc in documents: doc_id = doc['id'] if doc_id in self.watch_queue: # if doc id in queue, not imported yet continue file_name = doc['file_name'] # Wait for Lingotek's system to no longer show translationas as completed if file_name in self.updated: if self.updated[file_name] > 3: self.updated.pop(file_name, None) else: self.updated[file_name] += self.timeout continue try: downloaded = doc['downloaded'] except KeyError: downloaded = [] self.doc_manager.update_document('downloaded', downloaded, doc_id) if file_name not in self.polled_list or self.force_poll: locale_progress = self.import_locale_info(doc_id, True) # Python 2 # for locale, progress in locale_progress.iteritems(): # End Python 2 # Python 3 for locale in locale_progress: progress = locale_progress[locale] # End Python 3 if progress == 100 and locale not in downloaded: document_added = False if (doc['name']+": ") not in git_commit_message: if documents_downloaded: git_commit_message += '; ' git_commit_message += doc['name'] + ": " document_added = True if document_added: git_commit_message += locale else: git_commit_message += ', ' + locale documents_downloaded = True logger.info('Translation completed ({0} - {1})'.format(doc_id, locale)) if self.locale_delimiter: self.download_action(doc_id, locale, False, False) else: self.download_action(doc_id, locale, False) elif progress != 100 and locale in downloaded: # print("Locale "+str(locale)+" for document "+doc['name']+" is no longer completed.") self.doc_manager.remove_element_in_prop(doc_id, 'downloaded', locale) if set(locale_progress.keys()) == set(downloaded): if all(value == 100 for value in locale_progress.values()): self.polled_list.add(file_name) config_file_name, conf_parser = self.init_config_file() git_autocommit = conf_parser.get('main', 'git_autocommit') if git_autocommit == "True" and documents_downloaded == True: username = conf_parser.get('main', 'git_username') password = conf_parser.get('main', 'git_password') self.git_auto.commit(git_commit_message) if username and username != "": if password and password != "": self.git_auto.push(username=username, password=password) else: self.git_auto.push(username=username) else: if password and password != "": self.git_auto.push(password=password) else: self.git_auto.push()
def update_content(self, relative_path): logger.info('Detected local content modified: {0}'.format(relative_path)) self.update_document_action(os.path.join(self.path, relative_path)) logger.info('Updating remote content: {0}'.format(relative_path))
def poll_remote(self): """ poll lingotek servers to check if translation is finished """ if self.auto_format_option == 'on': autoFormat = True else: autoFormat = False documents = self.doc_manager.get_all_entries( ) # todo this gets all documents, not necessarily only ones in watch folder # documents_downloaded = False git_commit_message = DEFAULT_COMMIT_MESSAGE for doc in documents: doc_id = doc['id'] if doc_id in self.watch_queue: # if doc id in queue, not imported yet continue file_name = doc['file_name'] # Wait for Lingotek's system to no longer show translation as as completed if file_name in self.updated: if self.updated[file_name] > 3: self.updated.pop(file_name, None) else: self.updated[file_name] += self.timeout continue try: downloaded = doc['downloaded'] except KeyError: downloaded = [] self.doc_manager.update_document('downloaded', downloaded, doc_id) if file_name not in self.polled_list or self.force_poll: locale_progress = self.import_locale_info(doc_id, poll=True) # Python 2 # for locale, progress in locale_progress.iteritems(): # End Python 2 # Python 3 for locale in locale_progress: progress = locale_progress[locale] # End Python 3 if progress == 100 and locale not in downloaded: # document_added = False # if (doc['name']+": ") not in git_commit_message: # if documents_downloaded: git_commit_message += '; ' # git_commit_message += doc['name'] + ": " # document_added = True # if document_added: # git_commit_message += locale # else: # git_commit_message += ', ' + locale # documents_downloaded = True logger.info( 'Translation completed ({0} - {1})\n'.format( file_name, locale)) if self.locale_delimiter: locale = locale.replace('_', '-') download_file_path = self.download.download_action( doc_id, locale, autoFormat, xliff=False, locale_ext=False) else: locale = locale.replace('_', '-') if self.clone_option == 'on': # This prevents recursion when clone option is turned on and a file in a subfolder is added/modified while watch is running download_file_path = self.download.download_action( doc_id, locale, autoFormat, xliff=False, locale_ext=False) # Making clone paths a set prevents the list of paths to become full of duplicates from files added with the same name. # Note that in the case of a file with the same name, this is only called if the file was created outside of the watch home dir first (ex. creating testing/test.txt then test.txt will trigger, creating test.txt then testing/test.txt will not) else: download_file_path = self.download.download_action( doc_id, locale, autoFormat) # This prevents recursion when clone option is off and download folder is set. self.download_file_paths.add(download_file_path) elif progress != 100 and locale in downloaded: # print("Locale "+str(locale)+" for document "+doc['name']+" is no longer completed.") self.doc_manager.remove_element_in_prop( doc_id, 'downloaded', locale) if set(locale_progress.keys()) == set(downloaded): if all(value == 100 for value in locale_progress.values()): self.polled_list.add(file_name)