示例#1
0
def push_command(curdir, config, update, version=None, files=()):
    api = ProjectAPI(config)
    project = api.get_project()
    remote_content_type_codes = project['content_type_codes']
    init_language_storage(api)
    add_project_file_formats(get_project_file_formats(config))

    if not files:
        pattern_list = get_push_pattern(config)
        if pattern_list is None:
            log.info("No push pattern found in config. Taking files from current directory")
            pass

    if files:
        pattern_list = []
        for file_ in files:
            pattern_list.append(file_)

    for pattern in pattern_list:
        assert len(pattern_list) != 0
        if pattern[-2:] == '/*':
            pattern_extension = pattern.split('/')[-1]
            directory_list = find_directories(pattern)
            for dir_ in directory_list:
                dir_ = dir_ + '/' + pattern_extension
                final_push(project, curdir, dir_, api,  update, version, remote_content_type_codes)
        else:
            final_push(project, curdir, pattern, api, update, version, remote_content_type_codes)
示例#2
0
def status_command_json(config):
    """
    as the other status command is a generator, no other returns are allowed. This def is created instead.
        """
    api = ProjectAPI(config)
    report = api.get_report_progress()['languages']
    return report
示例#3
0
def ls_command(config):
    api = ProjectAPI(config)
    project = api.get_project()

    lang = next(get_destination_languages(project))

    for page in api.page_search(lang.id):
        if page.get('deleted', False):
            continue
        if page.get('version_tag', None):
            page_name = '{} [{}]'.format(page['url'], page['version_tag'])
        else:
            page_name = page['url']
        yield ResultRow(page['page_id'], page_name, page['segment_count'],
                        datetime.fromtimestamp(page['update'] / 1e3),
                        get_status(page))
示例#4
0
def push_command(curdir,
                 config,
                 update,
                 file_path=False,
                 version=None,
                 files=()):
    api = ProjectAPI(config)
    project = api.get_project()
    remote_content_type_codes = project['content_type_codes']
    init_language_storage(api)
    add_project_file_formats(get_project_file_formats(config))

    if not files:
        pattern_list = get_push_pattern(config)
        if pattern_list is None:
            log.info(
                "No push pattern found in config. Taking files from current directory"
            )
            files = os.listdir(curdir)
            files = [
                file for file in files
                if os.path.isfile(file) and not str(file).startswith(".")
                and not str(file).startswith("__")
            ]

    if files:
        pattern_list = []
        for file_ in files:
            pattern_list.append(file_)

    for pattern in pattern_list:
        assert len(pattern_list) != 0
        if pattern[-2:] == slash + '*':
            pattern_extension = pattern.split(slash)[-1]
            directory_list = find_directories(pattern, slash)
            for dir_ in directory_list:
                if dir_.endswith(slash):
                    dir_ = dir_ + pattern_extension
                else:
                    dir_ = dir_ + slash + pattern_extension
                final_push(project, curdir, dir_, api, update, version,
                           remote_content_type_codes, file_path)
        else:
            final_push(project, curdir, pattern, api, update, version,
                       remote_content_type_codes, file_path)
示例#5
0
def filelist(curdir, config, file_name):
    api = ProjectAPI(config)
    project = api.get_project()

    lang = next(get_destination_languages(project))
    remote_file_pages = list(
        api.page_search(language_id=lang.id, search_string=file_name))
    list_of_remote_files = list()

    for remote_file in remote_file_pages:
        file_name_ = remote_file.get('url', None)
        version_tag = remote_file.get('version_tag', None)
        page_id = remote_file.get('page_id', None)

        list_of_remote_files.append([file_name_, version_tag, page_id])

    from tabulate import tabulate
    log.info(
        tabulate(list_of_remote_files,
                 headers=['filename', 'version', 'page_id']))
示例#6
0
def addkey_command(curdir, config, key, value, file_id):
    api = ProjectAPI(config)
    status_response = api.status_single_key(file_id, key)
    if not status_response['success']:
        if status_response['error'] == "Key  is pointing to an existing node.":
            log.info("Key already exists.")
        else:
            log.info(
                "You may not be formatting your key correctly for use with Qordoba."
            )
            log.info(
                "Please see https://dev.qordoba.com/docs/key-reference for key syntax."
                .format(key))
        log.info("The key could not be added.".format(key))
    else:
        if status_response['success']:
            log.info("Key has been added successfully")
        if not status_response['success']:
            log.info("Key upload failed")

        api.upload_single_key(file_id, key, value)
示例#7
0
def delete_command(curdir, config, file_name, force=False):
    api = ProjectAPI(config)
    project = api.get_project()
    lang = next(get_destination_languages(project))

    page_id = None
    try:
        page_id = int(file_name)
    except ValueError:
        pass

    if not page_id:
        for page in api.page_search(lang.id, search_string=file_name):
            if page['url'] == file_name:
                page_id = page['page_id']
                break

    if page_id:
        if not force:
            if not ask_bool(
                    'Are you sure you want to delete `{}` and all translations for this resource?'
                    .format(file_name)):
                return

        api.delete_page(page_id)

    else:
        log.info('Resource `{}` not found.'.format(file_name))
示例#8
0
def find_new_command(curdir, config, files=()):
    api = ProjectAPI(config)
    init_language_storage(api)

    project = api.get_project()
    source_lang = get_source_language(project)
    pattern = get_push_pattern(config)

    if not files:
        files = list(find_files_by_pattern(curdir, pattern, source_lang))

        if not files:
            raise FilesNotFound(
                'Files not found by pattern `{}`'.format(pattern))

    for file_name in files:
        blob = curdir + '/' + ''.join(
            pattern.split('/')[:-1]) + '/' + str(file_name)
        if not vendored_or_documented(blob) and not not_valid(blob):
            language = [strategy.find(blob) for strategy in STRATEGIES]
            RESULTS.append(language)
        print(RESULTS)
示例#9
0
def init_command(curpath,
                 access_token,
                 project_id,
                 organization_id=None,
                 force=False):
    try:
        config, loaded = load_settings(access_token=access_token,
                                       project_id=project_id,
                                       organization_id=organization_id)
    except SettingsValidationError:
        raise
    else:
        if loaded and force is False:
            raise SettingsError('Config file already exists.')

    api = ProjectAPI(config)

    log.info('Checking organization and project...')

    project = api.get_project()

    save_settings(config)
示例#10
0
def status_command(config):
    """
    """
    api = ProjectAPI(config)
    report = api.get_report_progress()['languages']

    header = None

    for lang in report:
        names, percentage = prepare_milestones(lang['milestones'])
        if header is None:
            header = list(DEFAULT_HEADERS)
            header.extend(names)
            yield header

        row = [
            lang['code'],
            lang['total_words'],
            lang['segments'],
        ]
        row.extend(percentage)

        yield row
示例#11
0
def pull_command(curdir,
                 config,
                 files=(),
                 force=False,
                 bulk=False,
                 workflow=False,
                 workflow_all=None,
                 version=None,
                 distinct=False,
                 languages=(),
                 in_progress=False,
                 update_action=None,
                 custom=False,
                 **kwargs):
    api = ProjectAPI(config)
    init_language_storage(api)
    project = api.get_project()
    dest_languages = list(get_destination_languages(project))
    if languages:
        languages = validate_languges_input(languages, dest_languages)
    else:
        languages = dest_languages

    # prepare variables for pull_bulk command
    src_language = get_source_language(project)
    src_language_code = src_language.code
    src_language_id = src_language.id
    dest_languages_page_ids = []
    dest_languages_ids = [src_language_id]
    src_to_dest_paths = []

    pattern_list = get_pull_pattern(config, default=None)
    if pattern_list is None:
        pattern_list = [None]

    # based on the configuration in .qordoba.yml the destination for the pulled files will be set. Default path is '.qordoba-cli/qordoba/'
    for pattern in pattern_list:
        for language in languages:
            status_filter = [
                PageStatus.enabled,
            ]

            # generally only completed files will be pulled
            if in_progress is False:
                log.debug('Pull only completed translations.')
                status_filter = [
                    PageStatus.completed,
                ]

            is_started = False
            pages_completed = api.page_search(language.id,
                                              status=status_filter)
            pages_all = [
                pages_completed,
            ]

            # if workflow flag exists, enabled files will be pulled too
            if workflow or workflow_all:
                pages_enabled = api.page_search(language.id,
                                                status=[
                                                    PageStatus.enabled,
                                                ])
                pages_all = [pages_completed, pages_enabled]

            milestone_all = None
            for pages in pages_all:
                for page in pages:
                    is_started = True
                    page_status = api.get_page_details(
                        language.id,
                        page['page_id'],
                    )
                    dest_languages_page_ids.append(page['page_id'])
                    dest_languages_ids.append(language.id)
                    milestone = page_status['status']['id']
                    version_tag = page_status['version_tag']
                    filename = page['url']

                    if str(version_tag) != str(
                            version) and version is not None:
                        print("dismissing file `{}` with wrong version {}".
                              format(filename, version_tag))
                        continue

                    if distinct:
                        source_name = page_status['name']
                        tag = page_status['version_tag']
                        try:
                            pattern_name = pattern.split('/')[-1]
                        except AttributeError:
                            pattern_name = files[0]

                        if tag:
                            real_filename = tag + '_' + source_name
                        else:
                            real_filename = source_name

                        if real_filename != pattern_name:
                            continue

                    # when '--workflow' parameter is set, user can pick of which workflow files should be downloaded
                    if workflow or workflow_all:
                        milestones_resp = api.get_milestone(
                            language.id, page_status['assignees'][0]['id'])
                        milestone_dict = dict()
                        for i in milestones_resp:
                            milestone_dict[i['name']] = i['id']
                        if workflow:
                            log.info(
                                'For file {} and language {} pick workflow step'
                                .format(format_file_name(page), language))
                            # takes the milestone answer from stdin
                            pick = ask_select(
                                MilestoneOptions().all(milestone_dict),
                                prompt='Pick a milestone: ')
                            milestone = milestone_dict[pick]

                        if workflow_all:
                            if milestone_dict[workflow_all]:
                                milestone = milestone_dict[workflow_all]
                            else:
                                log.info(
                                    "The given Milestone `{}` does not exists in your project"
                                    .format(workflow_all))

                    if in_progress:
                        log.debug('Selected status for page `{}` - {}'.format(
                            page_status['id'], page_status['status']['name']))

                    dest_path = create_target_path_by_pattern(
                        curdir,
                        language,
                        pattern=pattern,
                        distinct=distinct,
                        version_tag=page_status['version_tag'],
                        source_name=page_status['name'],
                        content_type_code=page_status['content_type_code'],
                    )

                    if pattern is not None:
                        stripped_dest_path = ((dest_path.native_path).rsplit(
                            '/', 1))[0]
                        src_to_dest_paths.append(
                            tuple((language.code, stripped_dest_path)))
                    src_to_dest_paths.append(
                        tuple((language.code, language.code)))

                    # adding the src langauge to the dest_path_of_src_language pattern
                    dest_path_of_src_language = create_target_path_by_pattern(
                        curdir,
                        src_language,
                        pattern=pattern,
                        distinct=distinct,
                        version_tag=page_status['version_tag'],
                        source_name=page_status['name'],
                        content_type_code=page_status['content_type_code'],
                    )

                    if pattern is not None:
                        stripped_dest_path_of_src_language = ((
                            dest_path_of_src_language.native_path).rsplit(
                                '/', 1))[0]
                        src_to_dest_paths.append(
                            tuple((src_language_code,
                                   stripped_dest_path_of_src_language)))
                    src_to_dest_paths.append(
                        tuple((src_language_code, src_language_code)))

                    if not bulk:
                        """
                        Checking if file extension in config file matches downloaded file.
                        If not, continue e.g. *.resx should only download resx files from Qordoba
                        """
                        valid_extension = pattern.split(
                            '.')[-1] if pattern else None
                        file_extension = page['url'].split('.')[-1]

                        if not custom and pattern and valid_extension != "<extension>" and valid_extension != file_extension:
                            continue

                        log.info(
                            'Starting Download of translation file(s) for src `{}`, language `{}` and pattern {}'
                            .format(format_file_name(page), language.code,
                                    pattern))

                        if os.path.exists(dest_path.native_path) and not force:
                            log.warning(
                                'Translation file already exists. `{}`'.format(
                                    dest_path.native_path))
                            answer = FileUpdateOptions.get_action(
                                update_action) or ask_select(
                                    FileUpdateOptions.all, prompt='Choice: ')

                            if answer == FileUpdateOptions.skip:
                                log.info(
                                    'Download translation file `{}` was skipped.'
                                    .format(dest_path.native_path))
                                continue
                            elif answer == FileUpdateOptions.new_name:
                                while os.path.exists(dest_path.native_path):
                                    dest_path = ask_question(
                                        'Set new filename: ',
                                        answer_type=dest_path.replace)
                                    # pass to replace file

                        if workflow:
                            log.info(
                                '- note: pulls only from workflowstep  `{}` '.
                                format(pick))
                        if workflow_all:
                            assert milestone_dict[workflow_all] == milestone
                            log.info(
                                '- note: pulls only from workflowstep  `{}` '.
                                format(workflow_all))

                        res = api.download_file(page_status['id'],
                                                language.id,
                                                milestone=milestone)
                        res.raw.decode_content = True  # required to decompress content

                        if not os.path.exists(
                                os.path.dirname(dest_path.native_path)):
                            try:
                                os.makedirs(
                                    os.path.dirname(dest_path.native_path))
                                log.info("Creating folder path {}".format(
                                    dest_path.native_path))
                            except OSError as exc:  # Guard against race condition
                                if exc.errno != errno.EEXIST:
                                    pass

                        with open(dest_path.native_path, 'wb') as f:
                            shutil.copyfileobj(res.raw, f)

                        log.info(
                            'Downloaded translation file `{}` for src `{}` and language `{}`'
                            .format(dest_path.native_path,
                                    format_file_name(page), language.code))
            if not is_started and not bulk:
                log.info(
                    'Nothing to download for language `{}`. Check if your file translation status is `completed`.'
                    .format(language.code))

        if bulk:
            pull_bulk(api,
                      src_to_dest_paths,
                      dest_languages_page_ids,
                      dest_languages_ids,
                      pattern=pattern)
示例#12
0
def pull_command(curdir, config, force=False, bulk=False, languages=(), in_progress=False, update_action=None,
                 files=(), **kwargs):
    api = ProjectAPI(config)
    init_language_storage(api)
    project = api.get_project()
    dest_languages = list(get_destination_languages(project))
    if languages:
        languages = validate_languges_input(languages, dest_languages)
    else:
        languages = dest_languages

    '''prepare variables for pull_bulk command'''
    src_language = get_source_language(project)
    src_language_code = src_language.code
    src_language_id = src_language.id
    dest_languages_page_ids = []
    dest_languages_ids = [src_language_id]
    src_to_dest_paths = []

    pattern = get_pull_pattern(config, default=None)
    status_filter = [PageStatus.enabled, ]

    if in_progress is False:
        log.debug('Pull only completed translations.')
        status_filter = [PageStatus.completed, ]


    for language in languages:

        is_started = False
        current_page_path = None

        if not files:
            pages = api.page_search(language.id, status=status_filter)
        else:
            pages = []
            for search_term in files:
                result = api.page_search(language.id, status=status_filter, search_string=search_term)
                pages = itertools.chain(pages, result)

        for page in pages:
            is_started = True
            page_status = api.get_page_details(language.id, page['page_id'], )

            """
            If searching for specific files, skip those that don't match the search criteria.
            """
            if files:
                needle = None
                for file_name in files:
                    remote_file_name = page_status['url'].partition('_')[2]
                    if file_name in remote_file_name:
                        needle = page_status['url']
                if needle is None:
                    continue
                else:
                    log.info('Found matching translation file src `{}` language `{}`'.format(
                        format_file_name(page),
                        language.code,
                    ))

            dest_languages_page_ids.append(page['page_id'])
            dest_languages_ids.append(language.id)

            milestone = None
            if in_progress:
                milestone = page_status['status']['id']
                log.debug('Selected status for page `{}` - {}'.format(page_status['id'], page_status['status']['name']))

            dest_path = create_target_path_by_pattern(curdir, language, pattern=pattern,
                                                      source_name=page_status['name'],
                                                      content_type_code=page_status['content_type_code'])
            if pattern is not None:
                stripped_dest_path = ((dest_path.native_path).rsplit('/', 1))[0]
                src_to_dest_paths.append(tuple((language.code, stripped_dest_path)))
            src_to_dest_paths.append(tuple((language.code, language.code)))

            '''adding the src langauge to the dest_path_of_src_language pattern'''
            dest_path_of_src_language = create_target_path_by_pattern(curdir, src_language, pattern=pattern, source_name=page_status['name'], content_type_code=page_status['content_type_code'])

            if pattern is not None:
                stripped_dest_path_of_src_language = ((dest_path_of_src_language.native_path).rsplit('/', 1))[0]
                src_to_dest_paths.append(tuple((src_language_code, stripped_dest_path_of_src_language)))
            src_to_dest_paths.append(tuple((src_language_code, src_language_code)))


            if not bulk:
                '''checking if file extension wanted in config file matches downloaded file. If not, continue'''
                valid_extension = pattern.split('.')[-1] if pattern else None
                file_extension = page['url'].split('.')[-1]
                if valid_extension != "<extension>" and valid_extension != file_extension:
                        log.info('{} is not a valid file extension'.format(file_extension))
                        continue
            
                log.info('Starting Download of translation file(s) for src `{}` and language `{}`'.format(format_file_name(page), language.code))
                if os.path.exists(dest_path.native_path) and not force:

                    log.warning('Translation file already exists. `{}`'.format(dest_path.native_path))
                    answer = FileUpdateOptions.get_action(update_action) or ask_select(FileUpdateOptions.all, prompt='Choice: ')

                    if answer == FileUpdateOptions.skip:
                        log.info('Download translation file `{}` was skipped.'.format(dest_path.native_path))
                        continue

                    elif answer == FileUpdateOptions.new_name:
                        while os.path.exists(dest_path.native_path):
                            dest_path = ask_question('Set new filename: ', answer_type=dest_path.replace)
                            # pass to replace file

                res = api.download_file(page_status['id'], language.id, milestone=milestone)
                res.raw.decode_content = True  # required to decompress content

                if not os.path.exists(os.path.dirname(dest_path.native_path)):
                    try:
                        os.makedirs(os.path.dirname(dest_path.native_path))
                        log.info("Creating folder path {}".format(dest_path.native_path))
                    except OSError as exc:  # Guard against race condition
                        if exc.errno != errno.EEXIST:
                            pass

                with open(dest_path.native_path, 'wb') as f:
                    shutil.copyfileobj(res.raw, f)

                log.info('Downloaded translation file `{}` for src `{}` and language `{}`'.format(dest_path.native_path, format_file_name(page), language.code))

        if not is_started:
            log.info('Nothing to download for language `{}`'.format(language.code))

    if bulk:
        pull_bulk(api, src_to_dest_paths, dest_languages_page_ids, dest_languages_ids, pattern=pattern)