Example #1
0
    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()
        }
Example #2
0
    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))
Example #3
0
    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)
Example #4
0
   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
Example #5
0
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)
Example #6
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()
Example #7
0
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
Example #9
0
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