def backup(self, alias, multipart=False): """Set up proper backup environment. @param string alias @param boolean multipart (optional) @return dict """ try: # self.logger.set_source(alias) self.logger = self.init_logger(alias) if not multipart: self.logger.info('Starting...') # Get config handle self.config = ConfigHelper(alias) # Check if config exists if not self.config.exists(): raise Exception('Alias {} does not exist'.format(alias)) self.alias = alias self.multipart = multipart # Read config self.config = ConfigHelper(alias) # Validate config self.validate_config() # Determine backup path if multipart or (self.config.exists('versions') and self.config.get('versions') > 1 and not self.config.get('archive')): self.backup_path = os.path.join( self.config.get('backup_path'), self.alias + '_' + util.startup_time) else: self.backup_path = self.config.get('backup_path') # Make sure backup path exists util.create_folder(self.backup_path) # Start the actual backup self.start_backup() # Tear down backup environment self.teardown() except KeyboardInterrupt: self.logger.warn('Interrupted') except Exception as err: self.logger.error(err) traceback.print_exc() return { 'errors': self.get_error_count(), 'warnings': self.get_warning_count() }
def __init__(self, **kwargs): c = ConfigHelper().config if 'wunderground_api_key' not in c.keys() or \ 'weather_state' not in c.keys() or \ 'weather_city' not in c.keys(): logging.warning('Config file missing wunderground_api_key, ' + 'weather_state, or weather_city') return self.api_key = kwargs.get('ApiKey', c["wunderground_api_key"]) self.state = kwargs.get('State', c["weather_state"]) self.city = kwargs.get('City', c["weather_city"]) logging.info('Weather state={}, city={}'.format(self.state, self.city))
def add(self, override={}): """ Add WordPress strategy. @param dict override (optional) """ alias = self.server.add({'archive': True, 'type': self.TYPE}) server_config = ConfigHelper(alias) override = { 'alias': alias, 'versions': server_config.get('versions'), 'exclude': [] } self.mysql.add(override)
def translate_content_item(content_item, source, target): translated_result = {} # Handle KC default language as most translation libraries won't recognize "default" as a valid culture code if source == "default": source = ConfigHelper.get_env_value("KC_DEFAULT_LANG") for key, value in content_item.items(): text = TranslatorService(value, source, target) translated_result[key] = text.translate_string() return translated_result
def teach(no_audio, voice_id): try: c = ConfigHelper().config cache_manager = CacheManager(BucketName='pollexy-media', CacheName='chimes') cache_manager.sync_remote_folder() chime = c['teach_chime'] speech = random.choice(c['teach_phrases']) speaker = Speaker(NoAudio=no_audio) logging.info('Teach phrase={}'.format(speech)) speaker.generate_audio(Message=speech, TextType='text', VoiceId=voice_id) speaker.speak(IncludeChime=True, Chime=chime) speaker.cleanup() except Exception as exc: exc_type, exc_value, exc_traceback = sys.exc_info() print repr(traceback.format_exception(exc_type, exc_value, exc_traceback)) click.echo("Error: %s" % str(exc)) exit(2)
def add(self, override={}): """Use strategy schema to provice default add prompts. @param dict override @return string """ alias = override['alias'] if 'alias' in override else input('Alias: ') self.config = ConfigHelper() if 'alias' not in override: # Check if alias exists while self.config.exists(alias): print('This alias already exists') alias = input('Alias: ') try: # Get config handle self.config = ConfigHelper(alias, False) # Load schema schema = self.load_schema() if 'alias' not in override: # Set backup path backup_path_default = os.path.join(util.get_project_path(), 'backups', alias) backup_path = input('Backup path [{}]: '.format( backup_path_default)) or backup_path_default self.config.set('backup_path', backup_path) # Set type the_type = override['type'] if 'type' in override else self.TYPE self.config.set('type', the_type) # Read parameters for param in schema: if param['key'] in override: # Use value override self.config.set(param['key'], override[param['key']]) continue if 'prompt' not in param: # Value is not supposed to be read here continue default_str = self.build_default_string(param) value = input('{}{}: '.format(param['prompt'], default_str)) # Try setting default value if no value given if value == '' and 'default' in param: value = param['default'] # Ensure right format if 'type' not in param: pass elif param['type'] == 'int': value = int(value) elif param['type'] == 'bool': value = value.lower() in ['y', 'yes'] elif param['type'] == 'list': value = value if value else [] # Write to config self.config.set(param['key'], value) # Flush config to file self.config.write() # Enable config write through self.config.set_write_through(True) return alias except KeyboardInterrupt: self.logger.info('Aborted') except Exception: traceback.print_exc()
class Strategy: """Super class for all strategies to provide common basic functionalities.""" NAME = None TYPE = None logger = None config = None alias = None multipart = False backup_path = '' common_fields = ['backup_path', 'type'] def __init__(self): self.msg_counter_handler = LogCounterHandler() self.logger = self.init_logger() def init_logger(self, alias=None): """Initialize the logger. @param string alias (optional) """ alias = alias or self.__class__.__name__ # Load logger config with open(os.path.join('config', 'logger.yaml'), 'r') as f: config = yaml.safe_load(f.read()) logging.config.dictConfig(config) logger = logging.getLogger(alias) logger.addHandler(self.msg_counter_handler) return logger def set_logger(self, logger): """Explicitly set logger (used for multipart). @param Logger logger @return self For chaining """ self.logger = logger return self def get_error_count(self): """Get error count from logger handler.""" if 'ERROR' in self.msg_counter_handler.level_to_count: return self.msg_counter_handler.level_to_count['ERROR'] else: return 0 def get_warning_count(self): """Get warnings count from logger handler.""" if 'WARN' in self.msg_counter_handler.level_to_count: return self.msg_counter_handler.level_to_count['WARN'] else: return 0 def add(self, override={}): """Use strategy schema to provice default add prompts. @param dict override @return string """ alias = override['alias'] if 'alias' in override else input('Alias: ') self.config = ConfigHelper() if 'alias' not in override: # Check if alias exists while self.config.exists(alias): print('This alias already exists') alias = input('Alias: ') try: # Get config handle self.config = ConfigHelper(alias, False) # Load schema schema = self.load_schema() if 'alias' not in override: # Set backup path backup_path_default = os.path.join(util.get_project_path(), 'backups', alias) backup_path = input('Backup path [{}]: '.format( backup_path_default)) or backup_path_default self.config.set('backup_path', backup_path) # Set type the_type = override['type'] if 'type' in override else self.TYPE self.config.set('type', the_type) # Read parameters for param in schema: if param['key'] in override: # Use value override self.config.set(param['key'], override[param['key']]) continue if 'prompt' not in param: # Value is not supposed to be read here continue default_str = self.build_default_string(param) value = input('{}{}: '.format(param['prompt'], default_str)) # Try setting default value if no value given if value == '' and 'default' in param: value = param['default'] # Ensure right format if 'type' not in param: pass elif param['type'] == 'int': value = int(value) elif param['type'] == 'bool': value = value.lower() in ['y', 'yes'] elif param['type'] == 'list': value = value if value else [] # Write to config self.config.set(param['key'], value) # Flush config to file self.config.write() # Enable config write through self.config.set_write_through(True) return alias except KeyboardInterrupt: self.logger.info('Aborted') except Exception: traceback.print_exc() def backup(self, alias, multipart=False): """Set up proper backup environment. @param string alias @param boolean multipart (optional) @return dict """ try: # self.logger.set_source(alias) self.logger = self.init_logger(alias) if not multipart: self.logger.info('Starting...') # Get config handle self.config = ConfigHelper(alias) # Check if config exists if not self.config.exists(): raise Exception('Alias {} does not exist'.format(alias)) self.alias = alias self.multipart = multipart # Read config self.config = ConfigHelper(alias) # Validate config self.validate_config() # Determine backup path if multipart or (self.config.exists('versions') and self.config.get('versions') > 1 and not self.config.get('archive')): self.backup_path = os.path.join( self.config.get('backup_path'), self.alias + '_' + util.startup_time) else: self.backup_path = self.config.get('backup_path') # Make sure backup path exists util.create_folder(self.backup_path) # Start the actual backup self.start_backup() # Tear down backup environment self.teardown() except KeyboardInterrupt: self.logger.warn('Interrupted') except Exception as err: self.logger.error(err) traceback.print_exc() return { 'errors': self.get_error_count(), 'warnings': self.get_warning_count() } def start_backup(self): """Placeholder for method only to be called on child classes.""" raise NotImplementedError("Must override start_backup") def teardown(self): """Clean up backup environment.""" if self.multipart: return if self.config.get('versions'): # Remove old versions util.cleanup_versions(self.config.get('backup_path'), self.config.get('versions'), self.alias) # Done self.logger.info('Done') def build_default_string(self, param): """Build default value string to be displayed in add prompt. @param string param @return string """ if 'default' in param: if not 'type' in param or param['type'] in ['int']: return ' [{}]'.format(param['default']) elif param['type'] == 'bool': return ' [Y/n]' if param['default'] else ' [y/N]' else: if 'type' in param and param['type'] == 'bool': return ' [y/N]' return '' def load_schema(self): """Load strategy schema. @return list """ # Determine config location location = os.path.join(util.get_project_path(), 'config', 'schemas', self.TYPE + '.json') if not os.path.exists(location): return [] with open(location, 'r') as f: return json.load(f) def validate_config(self): """Check config for missing required values. @raises Exception """ # Load schema schema = self.load_schema() # Determine all required fields required_fields = self.common_fields +\ list(map(lambda x: x['key'], filter( lambda x: 'required' not in x or x['required'], schema))) # Check if we have all necessary information for field in required_fields: if self.config.get(field, '') == '': raise Exception( 'Config corrupted: "{}" is missing'.format(field))
def post(self): # Parse the body of the request data = self.parser.parse_args() lang_param = request.args.get("lang") default_config = ConfigHelper.get_env_value("KC_DEFAULT_LANG") # Only execute on publish events if data["message"]["operation"] == "publish": project_id = ConfigHelper.get_env_value("KC_PROJECT_ID") # Ensure that the culture code is present and valid for the translation service if lang_param: try: valid_language = ValidationHelper.check_valid_culture( lang_param) except: return { "message": "invalid language parameter. Set ?lang= to a supported culture." }, 400 else: return { "message": "API requires ?lang parameter to be set to the target language." }, 400 if valid_language: # Due to Linked content, there can be multiple content items in webhook's "items" array for content_item in data["data"]["items"]: # One way translation: only translate the default language into other languages if content_item["language"] != "default" and content_item[ "language"] != default_config: continue item = ItemRepo(content_item["codename"], content_item["language"]) json_data = item.get_content_item(project_id) if json_data: # Convert the JSON to a Python dictionary object that we can pass to the translator elements, non_translateable_elements = item.convert_json_to_dict( json_data) # Ensure that the element string length is valid for the translation service limits try: valid_length = ValidationHelper.check_valid_length( elements) except: return { "message": "Maximum string length exceeded." }, 400 if valid_length is True: # Pass the Python dictionary to the translation service that uses the Google library translated_item = TranslatorService.translate_content_item( elements, item.language, lang_param) # Add arrays (assets, taxonomies, multiple choice, etc.) to the item translated_item.update(non_translateable_elements) # Import the dictionary as JSON into Kentico Cloud using the Content Management API item.import_content_item(translated_item, project_id, item.codename, lang_param) continue return { "message": "Source content item {} doesn't exist.".format( content_item["codename"]) }, 400 return { "message": "Translation script completed without error." }, 200 return { "message": "Not a publish event. No translation required." }, 200
from strategies.mysql import MySQL from strategies.server import Server from strategies.mongodb import MongoDB from strategies.postgresql import PostgreSQL from helpers import util from helpers import mail from helpers.argumentparser import ArgumentParser from helpers.config import ConfigHelper strategies = [ Github, Gist, GooglePhotos, GoogleDrive, Wordpress, Dropbox, MySQL, Server, MongoDB, PostgreSQL ] config = ConfigHelper('') def type_to_strategy(strategy_type): """Get backup module by type. @param string type @return misc """ for strategy in strategies: if strategy.TYPE == strategy_type: return strategy return None