Пример #1
0
def make_request(method, host, url, username, password, fields=None):
    if host.lower().startswith('https://'):
        connection = urllib3.connection_from_url(host,
                                                 cert_reqs=ssl.CERT_REQUIRED,
                                                 ca_certs=certs_file())
    else:
        connection = urllib3.connection_from_url(host)
    headers = urllib3.util.make_headers(basic_auth='{0}:{1}'.format(
        username, password),
                                        accept_encoding=True,
                                        user_agent=user_agent_identifier(),
                                        keep_alive=True)
    r = None
    try:
        r = connection.request(method, url, headers=headers, fields=fields)
        data = r.data
        charset = determine_charset(r)
        if isinstance(data, bytes):
            data = data.decode(charset)
        if r.status < 200 or r.status >= 400:
            if r.status == 404:
                raise HttpNotFound(data)
            else:
                raise Exception(data)
        return data, charset
    except SSLError:
        logger.error("Invalid SSL certificate")
        raise
    finally:
        if not r is None:
            r.close()
Пример #2
0
 def _delete_resource(self, project_details, resource, stats, *args):
     """Delete a resource from Transifex."""
     project_slug, resource_slug = resource.split('.')
     project_resource_slugs = [
         r['slug'] for r in project_details['resources']
     ]
     logger.info("Deleting resource %s:" % resource)
     if resource_slug not in project_resource_slugs:
         if not self.skip:
             msg = "Skipping: %s : Resource does not exist."
             logger.info(msg % resource)
         return
     if not self.force:
         slang = self.get_resource_option(resource, 'source_lang')
         for language in stats:
             if language == slang:
                 continue
             if int(stats[language]['translated_entities']) > 0:
                 msg = (
                     "Skipping: %s : Unable to delete resource because it "
                     "has a not empty %s translation.\nPlease use -f or "
                     "--force option to delete this resource.")
                 logger.info(msg % (resource, language))
                 return
     try:
         self.do_url_request('delete_resource', method="DELETE")
         self.config.remove_section(resource)
         self.save()
         msg = "Deleted resource %s of project %s."
         logger.info(msg % (resource_slug, project_slug))
     except Exception, e:
         msg = "Unable to delete resource %s of project %s."
         logger.error(msg % (resource_slug, project_slug))
         if not self.skip:
             raise
Пример #3
0
def get_details(api_call, username, password, *args, **kwargs):
    """
    Get the tx project info through the API.

    This function can also be used to check the existence of a project.
    """
    url = (API_URLS[api_call] % (kwargs)).encode('UTF-8')
    conn = urllib3.connection_from_url(kwargs['hostname'])
    headers = urllib3.util.make_headers(
        basic_auth='{0}:{1}'.format(username, password),
        accept_encoding=True,
        user_agent=user_agent_identifier(),
    )
    try:
        r = conn.request('GET', url, headers=headers)
        if r.status < 200 or r.status >= 400:
            raise Exception(r.data)
        remote_project = parse_json(r.data)
        return remote_project
    except ssl.SSLError:
        logger.error("Invalid SSL certificate")
        raise
    except Exception, e:
        logger.debug(unicode(e))
        raise
Пример #4
0
    def _init(self, path_to_tx=None):
        instructions = "Run 'tx init' to initialize your project first!"
        try:
            self.root = self._get_tx_dir_path(path_to_tx)
            self.config_file = self._get_config_file_path(self.root)
            self.config = self._read_config_file(self.config_file)

            local_txrc_file = self._get_transifex_file(os.getcwd())
            if os.path.exists(local_txrc_file):
                self.txrc_file = local_txrc_file
            else:
                self.txrc_file = self._get_transifex_file()
            self.txrc = self._get_transifex_config([
                self.txrc_file,
            ])
        except ProjectNotInit as e:
            logger.error('\n'.join([six.u(str(e)), instructions]))
            raise
        host = self.config.get('main', 'host')
        if host.lower().startswith('https://'):
            self.conn = urllib3.connection_from_url(host,
                                                    cert_reqs=CERT_REQUIRED,
                                                    ca_certs=web.certs_file())
        else:
            self.conn = urllib3.connection_from_url(host)
Пример #5
0
 def _delete_translation(self, project_details, resource, stats, language):
     """Delete a specific translation from the specified resource."""
     project_slug, resource_slug = resource.split('.')
     if language not in stats:
         if not self.skip:
             msg = "Skipping %s: Translation does not exist."
             logger.warning(msg % (language))
         return
     if not self.force:
         teams = project_details['teams']
         if language in teams:
             msg = (
                 "Skipping %s: Unable to delete translation because it is "
                 "associated with a team.\nPlease use -f or --force option "
                 "to delete this translation.")
             logger.warning(msg % language)
             return
         if int(stats[language]['translated_entities']) > 0:
             msg = (
                 "Skipping %s: Unable to delete translation because it "
                 "is not empty.\nPlease use -f or --force option to delete "
                 "this translation.")
             logger.warning(msg % language)
             return
     try:
         self.do_url_request('delete_translation',
                             language=language,
                             method="DELETE")
         msg = "Deleted language %s from resource %s of project %s."
         logger.info(msg % (language, resource_slug, project_slug))
     except Exception, e:
         msg = "Unable to delete translation %s"
         logger.error(msg % language)
         if not self.skip:
             raise
Пример #6
0
    def _init(self, path_to_tx=None):
        instructions = "Run 'tx init' to initialize your project first!"
        try:
            self.root = self._get_tx_dir_path(path_to_tx)
            self.config_file = self._get_config_file_path(self.root)
            self.config = self._read_config_file(self.config_file)

            local_txrc_file = self._get_transifex_file(os.getcwd())
            if os.path.exists(local_txrc_file):
                self.txrc_file = local_txrc_file
            else:
                self.txrc_file = self._get_transifex_file()
            self.txrc = self._get_transifex_config([self.txrc_file, ])
        except ProjectNotInit as e:
            logger.error('\n'.join([six.u(str(e)), instructions]))
            raise
        host = self.config.get('main', 'host')
        if host.lower().startswith('https://'):
            self.conn = urllib3.connection_from_url(
                host,
                cert_reqs=ssl.CERT_REQUIRED,
                ca_certs=certs_file()
            )
        else:
            self.conn = urllib3.connection_from_url(host)
Пример #7
0
def make_request(method, host, url, username, password, fields=None):
    if host.lower().startswith('https://'):
        connection = urllib3.connection_from_url(
            host,
            cert_reqs=ssl.CERT_REQUIRED,
            ca_certs=certs_file()
        )
    else:
        connection = urllib3.connection_from_url(host)
    headers = urllib3.util.make_headers(
        basic_auth='{0}:{1}'.format(username, password),
        accept_encoding=True,
        user_agent=user_agent_identifier(),
        keep_alive=True
    )
    r = None
    try:
        r = connection.request(method, url, headers=headers, fields=fields)
        data = r.data
        charset = determine_charset(r)
        if isinstance(data, bytes):
            data = data.decode(charset)
        if r.status < 200 or r.status >= 400:
            if r.status == 404:
                raise HttpNotFound(data)
            else:
                raise Exception(data)
        return data, charset
    except SSLError:
        logger.error("Invalid SSL certificate")
        raise
    finally:
        if not r is None:
            r.close()
Пример #8
0
    def _create_resource(self, resource, pslug, fileinfo, filename, **kwargs):
        """Create a resource.

        Args:
            resource: The full resource name.
            pslug: The slug of the project.
            fileinfo: The information of the resource.
            filename: The name of the file.
        Raises:
            URLError, in case of a problem.
        """
        multipart = True
        method = "POST"
        api_call = 'create_resource'

        host = self.url_info['host']
        try:
            username = self.txrc.get(host, 'username')
            passwd = self.txrc.get(host, 'password')
            token = self.txrc.get(host, 'token')
            hostname = self.txrc.get(host, 'hostname')
        except ConfigParser.NoSectionError:
            raise Exception("No user credentials found for host %s. Edit"
                " ~/.transifexrc and add the appropriate info in there." %
                host)

        # Create the Url
        kwargs['hostname'] = hostname
        kwargs.update(self.url_info)
        kwargs['project'] = pslug
        url = (API_URLS[api_call] % kwargs).encode('UTF-8')

        headers = None

        i18n_type = self._get_option(resource, 'type')
        if i18n_type is None:
            logger.error(
                "Please define the resource type in .tx/config (eg. type = PO)."
                " More info: http://bit.ly/txcl-rt"
            )

        headers = urllib3.util.make_headers(
            basic_auth='{0}:{1}'.format(username, passwd),
            accept_encoding=True,
            user_agent=user_agent_identifier(),
            keep_alive=True
        )
        data = {
            "slug": fileinfo.split(';')[0],
            "name": fileinfo.split(';')[0],
            "uploaded_file": (filename, open(filename, 'rb').read()),
            "i18n_type": i18n_type
        }
        try:
            r = self.conn.request(method, url, fields=data, headers=headers)
        except ssl.SSLError:
            logger.error("Invalid SSL certificate")
        r.close()
        return r.data
Пример #9
0
 def _extension_for(self, i18n_type):
     """Return the extension used for the specified type."""
     try:
         res = parse_json(self.do_url_request('formats'))
         return res[i18n_type]['file-extensions'].split(',')[0]
     except Exception,e:
         logger.error(e)
         return ''
Пример #10
0
 def _extension_for(self, i18n_type):
     """Return the extension used for the specified type."""
     try:
         res = parse_json(self.do_url_request('formats'))
         return res[i18n_type]['file-extensions'].split(',')[0]
     except Exception, e:
         logger.error(e)
         return ''
Пример #11
0
    def get_projects_for_org(self, organization):
        try:
            projects = self.api.get('projects', organization=organization)
        except Exception as e:
            logger.error(e)
            raise

        # return project list sorted by name
        return sorted([p for p in projects if not p['archived']],
                      key=lambda x: x['name'])
Пример #12
0
    def get_organizations(self):
        try:
            organizations = self.api.get('organizations')
        except Exception as e:
            logger.error(e)
            raise

        # return org list sorted by name
        return sorted([(o['slug'], o['name']) for o in organizations],
                      key=lambda x: x[1])
Пример #13
0
 def _init(self, path_to_tx=None):
     instructions = "Run 'tx init' to initialize your project first!"
     try:
         self.root = self._get_tx_dir_path(path_to_tx)
         self.config_file = self._get_config_file_path(self.root)
         self.config = self._read_config_file(self.config_file)
         self.txrc_file = self._get_transifex_file()
         self.txrc = self._get_transifex_config(self.txrc_file)
     except ProjectNotInit, e:
         logger.error('\n'.join([unicode(e), instructions]))
         raise
Пример #14
0
 def _init(self, path_to_tx=None):
     instructions = "Run 'tx init' to initialize your project first!"
     try:
         self.root = self._get_tx_dir_path(path_to_tx)
         self.config_file = self._get_config_file_path(self.root)
         self.config = self._read_config_file(self.config_file)
         self.txrc_file = self._get_transifex_file()
         self.txrc = self._get_transifex_config(self.txrc_file)
     except ProjectNotInit, e:
         logger.error('\n'.join([unicode(e), instructions]))
         raise
Пример #15
0
    def get_organizations(self):
        try:
            organizations = self.api.get('organizations')
        except Exception as e:
            logger.error(e)
            raise

        # return org list sorted by name
        return sorted(
            [(o['slug'], o['name']) for o in organizations],
            key=lambda x: x[1]
        )
Пример #16
0
    def get_projects_for_org(self, organization):
        try:
            projects = self.api.get('projects', organization=organization)
        except Exception as e:
            logger.error(e)
            raise

        # return project list sorted by name
        return sorted(
            [p for p in projects if not p['archived']],
            key=lambda x: x['name']
        )
Пример #17
0
 def _get_stats_for_resource(self):
     """Get the statistics information for a resource."""
     try:
         r = self.do_url_request('resource_stats')
         logger.debug("Statistics response is %s" % r)
         stats = parse_json(r)
     except ssl.SSLError:
         logger.error("Invalid SSL certificate")
         raise
     except Exception, e:
         logger.debug(unicode(e))
         raise
Пример #18
0
 def __init__(self, token=None, username=None, password=None,
              path_to_tx=None, host=None):
     self.hostnames = self.map_paths_to_hostnames(path_to_tx, host)
     if token:
         self.token = token
         self.username = self.USERNAME
     elif username and password:
         self.token = password
         self.username = username
     else:
         logger.error("Authorization credentials are missing. Make sure "
                      "that you have run `tx init` to setup your "
                      "credentials.")
Пример #19
0
 def __init__(self, token=None, username=None, password=None,
              path_to_tx=None, host=None):
     self.hostnames = self.map_paths_to_hostnames(path_to_tx, host)
     if token:
         self.token = token
         self.username = self.USERNAME
     elif username and password:
         self.token = password
         self.username = username
     else:
         logger.error("Authorization credentials are missing. Make sure "
                      "that you have run `tx init` to setup your "
                      "credentials.")
Пример #20
0
    def get_formats(self, filename):
        _, extension = os.path.splitext(filename)
        try:
            formats = self.api.get('formats')
        except Exception as e:
            logger.error(e)
            raise

        def display_format(v):
            return '{} - {}'.format(v['description'], v['file-extensions'])

        formats = [(k, display_format(v)) for k, v in formats.items()
                   if extension in v['file-extensions']]
        return sorted(formats, key=lambda x: x[0])
Пример #21
0
    def get_formats(self, filename):
        _, extension = os.path.splitext(filename)
        try:
            formats = self.api.get('formats')
        except Exception as e:
            logger.error(e)
            raise

        def display_format(v):
            return '{} - {}'.format(v['description'], v['file-extensions'])

        formats = [(k, display_format(v)) for k, v in formats.items()
                   if extension in v['file-extensions']]
        if not formats:
            raise Exception(messages.TEXTS['formats']['empty'])
        return sorted(formats, key=lambda x: x[0])
Пример #22
0
def get_branch_from_options(options, project_root):
    """ Returns the branch name that needs to be used in command
    based on parser options.

    options: optparse parser options as returned from `parse()`
    project_root: project root directory
    """
    if not options.branch:
        return

    if options.branch != '-1':
        return options.branch

    branch = utils.get_current_branch(project_root)
    if not branch:
        logger.error("You specified the --branch option but current "
                     "directory does not seem to belong in any git repo.")
        sys.exit(1)
    return branch
Пример #23
0
def perform_single_request(method,
                           url,
                           headers,
                           fields,
                           manager,
                           skip_decode,
                           callback=None,
                           callback_args=None):
    callback_args = callback_args or {}
    response = None

    try:
        encoded_request = encode_args(manager.request)
        response = encoded_request(method, url, headers=headers, fields=fields)
        r_value = parse_tx_response(response, skip_decode)
    except SSLError:
        logger.error("Invalid SSL certificate")
        raise
    except HTTPError:
        logger.error("HTTP error")
        raise
    except Exception as e:
        logger.error(str(e))
        if isinstance(current_thread(), _MainThread):
            raise
        return
    finally:
        if response is not None:
            response.close()

    if callback is not None:
        callback_args.update({"data": r_value[0], "charset": r_value[1]})
        callback(**callback_args)

    return r_value
Пример #24
0
def main(argv=None):
    """
    Here we parse the flags (short, long) and we instantiate the classes.
    """
    parser = tx_main_parser()
    options, rest = parser.parse_known_args()
    if not options.command:
        parser.print_help()
        sys.exit(1)

    utils.DISABLE_COLORS = options.color_disable

    # set log level
    if options.quiet:
        set_log_level('WARNING')
    elif options.debug:
        set_log_level('DEBUG')

    web.cacerts_file = options.cacert

    # find .tx
    path_to_tx = options.root_dir or utils.find_dot_tx()

    cmd = options.command
    try:
        utils.exec_command(cmd, rest, path_to_tx)
    except SSLError as e:
        logger.error("SSL error %s" % e)
    except utils.UnknownCommandError:
        logger.error("Command %s not found" % cmd)
    except AuthenticationError:
        authentication_failed_message = """
Error: Authentication failed. Please make sure your credentials are valid.
For more information, visit:
https://docs.transifex.com/client/client-configuration#-transifexrc.
"""
        logger.error(authentication_failed_message)
    except Exception as e:
        import traceback
        if options.trace:
            traceback.print_exc()
        else:
            msg = "Unknown error" if not str(e) else str(e)
            logger.error(msg)
    # The else statement will be executed only if the command raised no
    # exceptions. If an exception was raised, we want to return a non-zero exit
    # code
    else:
        return
    sys.exit(1)
Пример #25
0
def main(argv=None):
    """
    Here we parse the flags (short, long) and we instantiate the classes.
    """
    parser = tx_main_parser()
    options, rest = parser.parse_known_args()
    if not options.command:
        parser.print_help()
        sys.exit(1)

    utils.DISABLE_COLORS = options.color_disable

    # set log level
    if options.quiet:
        set_log_level('WARNING')
    elif options.debug:
        set_log_level('DEBUG')

    # find .tx
    path_to_tx = options.root_dir or utils.find_dot_tx()

    cmd = options.command
    try:
        utils.exec_command(cmd, rest, path_to_tx)
    except SSLError as e:
        logger.error("SSL error %s" % e)
    except utils.UnknownCommandError:
        logger.error("Command %s not found" % cmd)
    except AuthenticationError:
        authentication_failed_message = """
Error: Authentication failed. Please make sure your credentials are valid.
For more information, visit:
https://docs.transifex.com/client/client-configuration#-transifexrc.
"""
        logger.error(authentication_failed_message)
    except Exception as e:
        import traceback
        if options.trace:
            traceback.print_exc()
        else:
            msg = "Unknown error" if not str(e) else str(e)
            logger.error(msg)
    # The else statement will be executed only if the command raised no
    # exceptions. If an exception was raised, we want to return a non-zero exit
    # code
    else:
        return
    sys.exit(1)
Пример #26
0
 def _delete_translation(self, project_details, resource, stats, language):
     """Delete a specific translation from the specified resource."""
     project_slug, resource_slug = resource.split('.', 1)
     if language not in stats:
         if not self.skip:
             msg = "Skipping %s: Translation does not exist."
             logger.warning(msg % (language))
         return
     if not self.force:
         teams = project_details['teams']
         if language in teams:
             msg = (
                 "Skipping %s: Unable to delete translation because it is "
                 "associated with a team.\nPlease use -f or --force option "
                 "to delete this translation."
             )
             logger.warning(msg % language)
             return
         if int(stats[language]['translated_entities']) > 0:
             msg = (
                 "Skipping %s: Unable to delete translation because it "
                 "is not empty.\nPlease use -f or --force option to delete "
                 "this translation."
             )
             logger.warning(msg % language)
             return
     try:
         self.do_url_request(
             'delete_translation', language=language, method="DELETE"
         )
         msg = "Deleted language %s from resource %s of project %s."
         logger.info(msg % (language, resource_slug, project_slug))
     except Exception as e:
         msg = "Unable to delete translation %s"
         logger.error(msg % language)
         if isinstance(e, SSLError) or not self.skip:
             raise
Пример #27
0
 def _delete_resource(self, project_details, resource, stats, *args):
     """Delete a resource from Transifex."""
     project_slug, resource_slug = resource.split('.', 1)
     project_resource_slugs = [
         r['slug'] for r in project_details['resources']
     ]
     logger.info("Deleting resource %s:" % resource)
     if resource_slug not in project_resource_slugs:
         if not self.skip:
             msg = "Skipping: %s : Resource does not exist."
             logger.info(msg % resource)
         return
     if not self.force:
         slang = self.get_resource_option(resource, 'source_lang')
         for language in stats:
             if language == slang:
                 continue
             if int(stats[language]['translated_entities']) > 0:
                 msg = (
                     "Skipping: %s : Unable to delete resource because it "
                     "has a not empty %s translation.\nPlease use -f or "
                     "--force option to delete this resource."
                 )
                 logger.info(msg % (resource, language))
                 return
     try:
         self.do_url_request('delete_resource', method="DELETE")
         self.config.remove_section(resource)
         self.save()
         msg = "Deleted resource %s of project %s."
         logger.info(msg % (resource_slug, project_slug))
     except Exception as e:
         msg = "Unable to delete resource %s of project %s."
         logger.error(msg % (resource_slug, project_slug))
         if isinstance(e, SSLError) or not self.skip:
             raise
Пример #28
0
    def push(self, source=False, translations=False, force=False, resources=[], languages=[],
        skip=False, no_interactive=False):
        """
        Push all the resources
        """
        resource_list = self.get_chosen_resources(resources)
        self.skip = skip
        self.force = force
        for resource in resource_list:
            push_languages = []
            project_slug, resource_slug = resource.split('.', 1)
            files = self.get_resource_files(resource)
            slang = self.get_resource_option(resource, 'source_lang')
            sfile = self.get_source_file(resource)
            lang_map = self.get_resource_lang_mapping(resource)
            host = self.get_resource_host(resource)
            logger.debug("Language mapping is: %s" % lang_map)
            logger.debug("Using host %s" % host)
            self.url_info = {
                'host': host,
                'project': project_slug,
                'resource': resource_slug
            }

            logger.info("Pushing translations for resource %s:" % resource)

            stats = self._get_stats_for_resource()

            if force and not no_interactive:
                answer = input("Warning: By using --force, the uploaded"
                    " files will overwrite remote translations, even if they"
                    " are newer than your uploaded files.\nAre you sure you"
                    " want to continue? [y/N] ")

                if not answer in ["", 'Y', 'y', "yes", 'YES']:
                    return

            if source:
                if sfile is None:
                    logger.error("You don't seem to have a proper source file"
                        " mapping for resource %s. Try without the --source"
                        " option or set a source file first and then try again." %
                        resource)
                    continue
                # Push source file
                try:
                    logger.warning("Pushing source file (%s)" % sfile)
                    if not self._resource_exists(stats):
                        logger.info("Resource does not exist.  Creating...")
                        fileinfo = "%s;%s" % (resource_slug, slang)
                        filename = self.get_full_path(sfile)
                        self._create_resource(resource, project_slug, fileinfo, filename)
                    self.do_url_request(
                        'push_source', multipart=True, method="PUT",
                        files=[(
                                "%s;%s" % (resource_slug, slang)
                                , self.get_full_path(sfile)
                        )],
                    )
                except Exception as e:
                    if isinstance(e, SSLError) or not skip:
                        raise
                    else:
                        logger.error(e)
            else:
                try:
                    self.do_url_request('resource_details')
                except Exception as e:
                    if isinstance(e, SSLError):
                        raise
                    code = getattr(e, 'code', None)
                    if code == 404:
                        msg = "Resource %s doesn't exist on the server."
                        logger.error(msg % resource)
                        continue

            if translations:
                # Check if given language codes exist
                if not languages:
                    push_languages = list(files.keys())
                else:
                    push_languages = []
                    f_langs = list(files.keys())
                    for l in languages:
                        if l in list(lang_map.keys()):
                            l = lang_map[l]
                        push_languages.append(l)
                        if l not in f_langs:
                            msg = "Warning: No mapping found for language code '%s'."
                            logger.error(msg % color_text(l,"RED"))
                logger.debug("Languages to push are %s" % push_languages)

                # Push translation files one by one
                for lang in push_languages:
                    local_lang = lang
                    if lang in list(lang_map.values()):
                        remote_lang = lang_map.flip[lang]
                    else:
                        remote_lang = lang

                    local_file = files[local_lang]

                    kwargs = {
                        'lang': remote_lang,
                        'stats': stats,
                        'local_file': local_file,
                        'force': force,
                    }
                    if not self._should_push_translation(**kwargs):
                        msg = "Skipping '%s' translation (file: %s)."
                        logger.info(msg % (color_text(lang, "RED"), local_file))
                        continue

                    msg = "Pushing '%s' translations (file: %s)"
                    logger.warning(
                         msg % (color_text(remote_lang, "RED"), local_file)
                    )
                    try:
                        self.do_url_request(
                            'push_translation', multipart=True, method='PUT',
                            files=[(
                                    "%s;%s" % (resource_slug, remote_lang),
                                    self.get_full_path(local_file)
                            )], language=remote_lang
                        )
                        logger.debug("Translation %s pushed." % remote_lang)
                    except HttpNotFound:
                        if not source:
                            logger.error("Resource hasn't been created. Try pushing source file.")
                    except Exception as e:
                        if isinstance(e, SSLError) or not skip:
                            raise
                        else:
                            logger.error(e)
Пример #29
0
    def pull(self, languages=[], resources=[], overwrite=True, fetchall=False,
        fetchsource=False, force=False, skip=False, minimum_perc=0, mode=None,
        pseudo=False):
        """Pull all translations file from transifex server."""
        self.minimum_perc = minimum_perc
        resource_list = self.get_chosen_resources(resources)

        if mode == 'reviewed':
            url = 'pull_reviewed_file'
        elif mode == 'translator':
            url = 'pull_translator_file'
        elif mode == 'developer':
            url = 'pull_developer_file'
        else:
            url = 'pull_file'

        for resource in resource_list:
            logger.debug("Handling resource %s" % resource)
            self.resource = resource
            project_slug, resource_slug = resource.split('.', 1)
            files = self.get_resource_files(resource)
            slang = self.get_resource_option(resource, 'source_lang')
            sfile = self.get_source_file(resource)
            lang_map = self.get_resource_lang_mapping(resource)
            host = self.get_resource_host(resource)
            logger.debug("Language mapping is: %s" % lang_map)
            if mode is None:
                mode = self._get_option(resource, 'mode')
            self.url_info = {
                'host': host,
                'project': project_slug,
                'resource': resource_slug
            }
            logger.debug("URL data are: %s" % self.url_info)

            stats = self._get_stats_for_resource()

            try:
                file_filter = self.config.get(resource, 'file_filter')
            except configparser.NoOptionError:
                file_filter = None

            # Pull source file
            pull_languages = set([])
            new_translations = set([])

            if pseudo:
                pseudo_file = self._get_pseudo_file(
                    slang, resource, file_filter
                )
                if self._should_download(slang, stats, local_file=pseudo_file):
                    logger.info("Pulling pseudo file for resource %s (%s)." % (
                        resource,
                        color_text(pseudo_file, "RED")
                    ))
                    self._download_pseudo(
                        project_slug, resource_slug, pseudo_file
                    )
                if not languages:
                    continue

            if fetchall:
                new_translations = self._new_translations_to_add(
                    files, slang, lang_map, stats, force
                )
                if new_translations:
                    msg = "New translations found for the following languages: %s"
                    logger.info(msg % ', '.join(new_translations))

            existing, new = self._languages_to_pull(
                languages, files, lang_map, stats, force
            )
            pull_languages |= existing
            new_translations |= new
            logger.debug("Adding to new translations: %s" % new)

            if fetchsource:
                if sfile and slang not in pull_languages:
                    pull_languages.add(slang)
                elif slang not in new_translations:
                    new_translations.add(slang)

            if pull_languages:
                logger.debug("Pulling languages for: %s" % pull_languages)
                msg = "Pulling translations for resource %s (source: %s)"
                logger.info(msg % (resource, sfile))

            for lang in pull_languages:
                local_lang = lang
                if lang in list(lang_map.values()):
                    remote_lang = lang_map.flip[lang]
                else:
                    remote_lang = lang
                if languages and lang not in pull_languages:
                    logger.debug("Skipping language %s" % lang)
                    continue
                if lang != slang:
                    local_file = files.get(lang, None) or files[lang_map[lang]]
                else:
                    local_file = sfile
                logger.debug("Using file %s" % local_file)

                kwargs = {
                    'lang': remote_lang,
                    'stats': stats,
                    'local_file': local_file,
                    'force': force,
                    'mode': mode,
                }
                if not self._should_update_translation(**kwargs):
                    msg = "Skipping '%s' translation (file: %s)."
                    logger.info(
                        msg % (color_text(remote_lang, "RED"), local_file)
                    )
                    continue

                if not overwrite:
                    local_file = ("%s.new" % local_file)
                logger.warning(
                    " -> %s: %s" % (color_text(remote_lang, "RED"), local_file)
                )
                try:
                    r, charset = self.do_url_request(url, language=remote_lang)
                except Exception as e:
                    if isinstance(e, SSLError) or not skip:
                        raise
                    else:
                        logger.error(e)
                        continue
                base_dir = os.path.split(local_file)[0]
                mkdir_p(base_dir)
                fd = open(local_file, 'wb')
                fd.write(r.encode(charset))
                fd.close()

            if new_translations:
                msg = "Pulling new translations for resource %s (source: %s)"
                logger.info(msg % (resource, sfile))
                for lang in new_translations:
                    if lang in list(lang_map.keys()):
                        local_lang = lang_map[lang]
                    else:
                        local_lang = lang
                    remote_lang = lang
                    if file_filter:
                        local_file = os.path.relpath(
                            os.path.join(
                                self.root, native_path(
                                    file_filter.replace('<lang>', local_lang)
                                )
                            ), os.curdir
                        )
                    else:
                        trans_dir = os.path.join(self.root, ".tx", resource)
                        if not os.path.exists(trans_dir):
                            os.mkdir(trans_dir)
                        local_file = os.path.relpath(os.path.join(trans_dir, '%s_translation' %
                            local_lang, os.curdir))

                    if lang != slang:
                        satisfies_min = self._satisfies_min_translated(
                            stats[remote_lang], mode
                        )
                        if not satisfies_min:
                            msg = "Skipping language %s due to used options."
                            logger.info(msg % lang)
                            continue
                    logger.warning(
                        " -> %s: %s" % (color_text(remote_lang, "RED"), local_file)
                    )

                    r, charset = self.do_url_request(url, language=remote_lang)
                    base_dir = os.path.split(local_file)[0]
                    mkdir_p(base_dir)
                    fd = open(local_file, 'wb')
                    fd.write(r.encode(charset))
                    fd.close()
Пример #30
0
def ERRMSG(msg, verbosity=1):
    """
    STDERR logging function
    """
    logger.error('%s' % msg)
Пример #31
0
def make_request(method,
                 host,
                 url,
                 username,
                 password,
                 fields=None,
                 skip_decode=False,
                 get_params={}):

    # Initialize http and https pool managers
    num_pools = 1
    managers = {}

    if host.lower().startswith("http://"):
        scheme = "http"
        if "http_proxy" in os.environ:
            proxy_url = urllib3.util.url.parse_url(os.environ["http_proxy"])
            managers["http"] = urllib3.ProxyManager(
                proxy_url=proxy_url.url,
                proxy_headers=urllib3.util.make_headers(
                    user_agent=user_agent_identifier(),
                    proxy_basic_auth=proxy_url.auth),
                num_pools=num_pools)
        else:
            managers["http"] = urllib3.PoolManager(num_pools=num_pools)
    elif host.lower().startswith("https://"):
        scheme = "https"
        if "https_proxy" in os.environ:
            proxy_url = urllib3.util.url.parse_url(os.environ["https_proxy"])
            managers["https"] = urllib3.ProxyManager(
                proxy_url=proxy_url.url,
                proxy_headers=urllib3.util.make_headers(
                    user_agent=user_agent_identifier(),
                    proxy_basic_auth=proxy_url.auth),
                num_pools=num_pools,
                cert_reqs=CERT_REQUIRED,
                ca_certs=certs_file())
        else:
            managers["https"] = urllib3.PoolManager(num_pools=num_pools,
                                                    cert_reqs=CERT_REQUIRED,
                                                    ca_certs=certs_file())
    else:
        raise Exception("Unknown scheme")

    charset = None
    headers = urllib3.util.make_headers(basic_auth='{0}:{1}'.format(
        username, password),
                                        accept_encoding=True,
                                        user_agent=user_agent_identifier(),
                                        keep_alive=True)

    response = None
    try:
        manager = managers[scheme]
        # All arguments must be bytes, not unicode
        encoded_request = encode_args(manager.request)
        response = encoded_request(method,
                                   urljoin(host, url),
                                   headers=dict(headers),
                                   fields=fields)
        data = response.data
        if not skip_decode:
            charset = determine_charset(response)
            if isinstance(data, bytes):
                data = data.decode(charset)
        if response.status < 200 or response.status >= 400:
            if response.status == 401:
                raise AuthenticationError(data)
            elif response.status == 403:
                raise HttpNotAuthorized(data)
            elif response.status == 404:
                raise HttpNotFound(data)
            elif response.status >= 500:
                msg = "Failed to connect. Server responded with HTTP code {}"
                raise TXConnectionError(msg.format(response.status),
                                        code=response.status)
            else:
                raise Exception("Error received from server: {}".format(data))
        return data, charset
    except SSLError:
        logger.error("Invalid SSL certificate")
        raise
    finally:
        if response is not None:
            response.close()
Пример #32
0
    def pull(self,
             languages=[],
             resources=[],
             overwrite=True,
             fetchall=False,
             fetchsource=False,
             force=False,
             skip=False,
             minimum_perc=0,
             mode=None):
        """Pull all translations file from transifex server."""
        self.minimum_perc = minimum_perc
        resource_list = self.get_chosen_resources(resources)

        if mode == 'reviewed':
            url = 'pull_reviewed_file'
        elif mode == 'translator':
            url = 'pull_translator_file'
        elif mode == 'developer':
            url = 'pull_developer_file'
        else:
            url = 'pull_file'

        for resource in resource_list:
            logger.debug("Handling resource %s" % resource)
            self.resource = resource
            project_slug, resource_slug = resource.split('.')
            files = self.get_resource_files(resource)
            slang = self.get_resource_option(resource, 'source_lang')
            sfile = self.get_source_file(resource)
            lang_map = self.get_resource_lang_mapping(resource)
            host = self.get_resource_host(resource)
            verify_ssl(host)
            logger.debug("Language mapping is: %s" % lang_map)
            if mode is None:
                mode = self._get_option(resource, 'mode')
            self.url_info = {
                'host': host,
                'project': project_slug,
                'resource': resource_slug
            }
            logger.debug("URL data are: %s" % self.url_info)

            stats = self._get_stats_for_resource()

            try:
                file_filter = self.config.get(resource, 'file_filter')
            except ConfigParser.NoOptionError:
                file_filter = None

            # Pull source file
            pull_languages = set([])
            new_translations = set([])

            if fetchall:
                new_translations = self._new_translations_to_add(
                    files, slang, lang_map, stats, force)
                if new_translations:
                    msg = "New translations found for the following languages: %s"
                    logger.info(msg % ', '.join(new_translations))

            existing, new = self._languages_to_pull(languages, files, lang_map,
                                                    stats, force)
            pull_languages |= existing
            new_translations |= new
            logger.debug("Adding to new translations: %s" % new)

            if fetchsource:
                if sfile and slang not in pull_languages:
                    pull_languages.add(slang)
                elif slang not in new_translations:
                    new_translations.add(slang)

            if pull_languages:
                logger.debug("Pulling languages for: %s" % pull_languages)
                msg = "Pulling translations for resource %s (source: %s)"
                logger.info(msg % (resource, sfile))

            for lang in pull_languages:
                local_lang = lang
                if lang in lang_map.values():
                    remote_lang = lang_map.flip[lang]
                else:
                    remote_lang = lang
                if languages and lang not in pull_languages:
                    logger.debug("Skipping language %s" % lang)
                    continue
                if lang != slang:
                    local_file = files.get(lang, None) or files[lang_map[lang]]
                else:
                    local_file = sfile
                logger.debug("Using file %s" % local_file)

                kwargs = {
                    'lang': remote_lang,
                    'stats': stats,
                    'local_file': local_file,
                    'force': force,
                    'mode': mode,
                }
                if not self._should_update_translation(**kwargs):
                    msg = "Skipping '%s' translation (file: %s)."
                    logger.info(msg %
                                (color_text(remote_lang, "RED"), local_file))
                    continue

                if not overwrite:
                    local_file = ("%s.new" % local_file)
                logger.warning(" -> %s: %s" %
                               (color_text(remote_lang, "RED"), local_file))
                try:
                    r = self.do_url_request(url, language=remote_lang)
                except Exception, e:
                    if not skip:
                        raise e
                    else:
                        logger.error(e)
                        continue
                base_dir = os.path.split(local_file)[0]
                mkdir_p(base_dir)
                fd = open(local_file, 'wb')
                fd.write(r)
                fd.close()

            if new_translations:
                msg = "Pulling new translations for resource %s (source: %s)"
                logger.info(msg % (resource, sfile))
                for lang in new_translations:
                    if lang in lang_map.keys():
                        local_lang = lang_map[lang]
                    else:
                        local_lang = lang
                    remote_lang = lang
                    if file_filter:
                        local_file = os.path.relpath(
                            os.path.join(
                                self.root,
                                native_path(
                                    file_filter.replace('<lang>',
                                                        local_lang))),
                            os.curdir.decode('utf-8'))
                    else:
                        trans_dir = os.path.join(self.root, ".tx", resource)
                        if not os.path.exists(trans_dir):
                            os.mkdir(trans_dir)
                        local_file = os.path.relpath(
                            os.path.join(trans_dir,
                                         '%s_translation' % local_lang,
                                         os.curdir))

                    if lang != slang:
                        satisfies_min = self._satisfies_min_translated(
                            stats[remote_lang], mode)
                        if not satisfies_min:
                            msg = "Skipping language %s due to used options."
                            logger.info(msg % lang)
                            continue
                    logger.warning(
                        " -> %s: %s" %
                        (color_text(remote_lang, "RED"), local_file))
                    r = self.do_url_request(url, language=remote_lang)

                    base_dir = os.path.split(local_file)[0]
                    mkdir_p(base_dir)
                    fd = open(local_file, 'wb')
                    fd.write(r)
                    fd.close()
Пример #33
0
def ERRMSG(msg, verbosity=1):
    """
    STDERR logging function
    """
    logger.error('%s' % msg)
Пример #34
0
    def _create_resource(self, resource, pslug, fileinfo, filename, **kwargs):
        """Create a resource.

        Args:
            resource: The full resource name.
            pslug: The slug of the project.
            fileinfo: The information of the resource.
            filename: The name of the file.
        Raises:
            URLError, in case of a problem.
        """
        multipart = True
        method = "POST"
        api_call = 'create_resource'

        host = self.url_info['host']
        try:
            username = self.txrc.get(host, 'username')
            passwd = self.txrc.get(host, 'password')
            token = self.txrc.get(host, 'token')
            hostname = self.txrc.get(host, 'hostname')
        except ConfigParser.NoSectionError:
            raise Exception("No user credentials found for host %s. Edit"
                " ~/.transifexrc and add the appropriate info in there." %
                host)

        # Create the Url
        kwargs['hostname'] = hostname
        kwargs.update(self.url_info)
        kwargs['project'] = pslug
        url = (API_URLS[api_call] % kwargs).encode('UTF-8')

        opener = None
        headers = None
        req = None

        i18n_type = self._get_option(resource, 'type')
        if i18n_type is None:
            logger.error(
                "Please define the resource type in .tx/config (eg. type = PO)."
                " More info: http://bit.ly/txcl-rt"
            )

        opener = urllib2.build_opener(MultipartPostHandler)
        data = {
            "slug": fileinfo.split(';')[0],
            "name": fileinfo.split(';')[0],
            "uploaded_file":  open(filename,'rb'),
            "i18n_type": i18n_type
        }
        urllib2.install_opener(opener)
        req = RequestWithMethod(url=url, data=data, method=method)

        base64string = base64.encodestring('%s:%s' % (username, passwd))[:-1]
        authheader = "Basic %s" % base64string
        req.add_header("Authorization", authheader)

        try:
            fh = urllib2.urlopen(req)
        except urllib2.HTTPError, e:
            if e.code in [401, 403, 404]:
                raise e
            else:
                # For other requests, we should print the message as well
                raise Exception("Remote server replied: %s" % e.read())
Пример #35
0
def make_request(method,
                 host,
                 url,
                 username,
                 password,
                 fields=None,
                 skip_decode=False):

    # Initialize http and https pool managers
    num_pools = 1
    managers = {}

    if host.lower().startswith("http://"):
        scheme = "http"
        if "http_proxy" in os.environ:
            proxy_url = os.environ["http_proxy"]
            managers["http"] = urllib3.ProxyManager(
                proxy_url=proxy_url,
                proxy_headers={"User-Agent": user_agent_identifier()},
                num_pools=num_pools)
        else:
            managers["http"] = urllib3.PoolManager(num_pools=num_pools)
    elif host.lower().startswith("https://"):
        scheme = "https"
        if "https_proxy" in os.environ:
            proxy_url = os.environ["https_proxy"]
            managers["https"] = urllib3.ProxyManager(
                proxy_url=proxy_url,
                proxy_headers={"User-Agent": user_agent_identifier()},
                num_pools=num_pools,
                cert_reqs=CERT_REQUIRED,
                ca_certs=certs_file())
        else:
            managers["https"] = urllib3.PoolManager(num_pools=num_pools,
                                                    cert_reqs=CERT_REQUIRED,
                                                    ca_certs=certs_file())
    else:
        raise Exception("Unknown scheme")

    charset = None
    headers = urllib3.util.make_headers(basic_auth='{0}:{1}'.format(
        username, password),
                                        accept_encoding=True,
                                        user_agent=user_agent_identifier(),
                                        keep_alive=True)

    response = None
    try:
        manager = managers[scheme]
        response = manager.request(method,
                                   host + url,
                                   headers=dict(headers),
                                   fields=fields)
        data = response.data
        if not skip_decode:
            charset = determine_charset(response)
            if isinstance(data, bytes):
                data = data.decode(charset)
        if response.status < 200 or response.status >= 400:
            if response.status == 401:
                raise HttpNotAuthorized(data)
            elif response.status == 404:
                raise HttpNotFound(data)
            else:
                raise Exception(data)
        return data, charset
    except SSLError:
        logger.error("Invalid SSL certificate")
        raise
    finally:
        if response is not None:
            response.close()
Пример #36
0
                        continue

            if translations:
                # Check if given language codes exist
                if not languages:
                    push_languages = files.keys()
                else:
                    push_languages = []
                    f_langs = files.keys()
                    for l in languages:
                        if l in lang_map.keys():
                            l = lang_map[l]
                        push_languages.append(l)
                        if l not in f_langs:
                            msg = "Warning: No mapping found for language code '%s'."
                            logger.error(msg % color_text(l,"RED"))
                logger.debug("Languages to push are %s" % push_languages)

                # Push translation files one by one
                for lang in push_languages:
                    local_lang = lang
                    if lang in lang_map.values():
                        remote_lang = lang_map.flip[lang]
                    else:
                        remote_lang = lang

                    local_file = files[local_lang]

                    kwargs = {
                        'lang': remote_lang,
                        'stats': stats,
Пример #37
0
def make_request(method, host, url, username, password, fields=None,
                 skip_decode=False):

    # Initialize http and https pool managers
    num_pools = 1
    managers = {}

    if host.lower().startswith("http://"):
        scheme = "http"
        if "http_proxy" in os.environ:
            proxy_url = os.environ["http_proxy"]
            managers["http"] = urllib3.ProxyManager(
                proxy_url=proxy_url,
                proxy_headers={"User-Agent": user_agent_identifier()},
                num_pools=num_pools
            )
        else:
            managers["http"] = urllib3.PoolManager(num_pools=num_pools)
    elif host.lower().startswith("https://"):
        scheme = "https"
        if "https_proxy" in os.environ:
            proxy_url = os.environ["https_proxy"]
            managers["https"] = urllib3.ProxyManager(
                proxy_url=proxy_url,
                proxy_headers={"User-Agent": user_agent_identifier()},
                num_pools=num_pools,
                cert_reqs=CERT_REQUIRED,
                ca_certs=certs_file()
            )
        else:
            managers["https"] = urllib3.PoolManager(
                num_pools=num_pools,
                cert_reqs=CERT_REQUIRED,
                ca_certs=certs_file()
            )
    else:
        raise Exception("Unknown scheme")

    charset = None
    headers = urllib3.util.make_headers(
        basic_auth='{0}:{1}'.format(username, password),
        accept_encoding=True,
        user_agent=user_agent_identifier(),
        keep_alive=True
    )

    response = None
    try:
        manager = managers[scheme]
        # All arguments must be bytes, not unicode
        encoded_request = encode_args(manager.request)
        response = encoded_request(
            method,
            host + url,
            headers=dict(headers),
            fields=fields
        )
        data = response.data
        if not skip_decode:
            charset = determine_charset(response)
            if isinstance(data, bytes):
                data = data.decode(charset)
        if response.status < 200 or response.status >= 400:
            if response.status == 401:
                raise HttpNotAuthorized(data)
            elif response.status == 404:
                raise HttpNotFound(data)
            else:
                raise Exception(data)
        return data, charset
    except SSLError:
        logger.error("Invalid SSL certificate")
        raise
    finally:
        if response is not None:
            response.close()
Пример #38
0
                        continue

            if translations:
                # Check if given language codes exist
                if not languages:
                    push_languages = files.keys()
                else:
                    push_languages = []
                    f_langs = files.keys()
                    for l in languages:
                        if l in lang_map.keys():
                            l = lang_map[l]
                        push_languages.append(l)
                        if l not in f_langs:
                            msg = "Warning: No mapping found for language code '%s'."
                            logger.error(msg % color_text(l, "RED"))
                logger.debug("Languages to push are %s" % push_languages)

                # Push translation files one by one
                for lang in push_languages:
                    local_lang = lang
                    if lang in lang_map.values():
                        remote_lang = lang_map.flip[lang]
                    else:
                        remote_lang = lang

                    local_file = files[local_lang]

                    kwargs = {
                        'lang': remote_lang,
                        'stats': stats,
Пример #39
0
    def _create_resource(self, resource, pslug, fileinfo, filename, **kwargs):
        """Create a resource.

        Args:
            resource: The full resource name.
            pslug: The slug of the project.
            fileinfo: The information of the resource.
            filename: The name of the file.
        Raises:
            URLError, in case of a problem.
        """
        multipart = True
        method = "POST"
        api_call = 'create_resource'

        host = self.url_info['host']
        try:
            username = self.txrc.get(host, 'username')
            passwd = self.txrc.get(host, 'password')
            token = self.txrc.get(host, 'token')
            hostname = self.txrc.get(host, 'hostname')
        except ConfigParser.NoSectionError:
            raise Exception(
                "No user credentials found for host %s. Edit"
                " ~/.transifexrc and add the appropriate info in there." %
                host)

        # Create the Url
        kwargs['hostname'] = hostname
        kwargs.update(self.url_info)
        kwargs['project'] = pslug
        url = (API_URLS[api_call] % kwargs).encode('UTF-8')

        opener = None
        headers = None
        req = None

        i18n_type = self._get_option(resource, 'type')
        if i18n_type is None:
            logger.error(
                "Please define the resource type in .tx/config (eg. type = PO)."
                " More info: http://bit.ly/txcl-rt")

        opener = urllib2.build_opener(MultipartPostHandler)
        data = {
            "slug": fileinfo.split(';')[0],
            "name": fileinfo.split(';')[0],
            "uploaded_file": open(filename, 'rb'),
            "i18n_type": i18n_type
        }
        urllib2.install_opener(opener)
        req = RequestWithMethod(url=url, data=data, method=method)

        base64string = base64.encodestring('%s:%s' % (username, passwd))[:-1]
        authheader = "Basic %s" % base64string
        req.add_header("Authorization", authheader)

        try:
            fh = urllib2.urlopen(req)
        except urllib2.HTTPError, e:
            if e.code in [401, 403, 404]:
                raise e
            else:
                # For other requests, we should print the message as well
                raise Exception("Remote server replied: %s" % e.read())
Пример #40
0
    def pull(self,
             languages=[],
             resources=[],
             overwrite=True,
             fetchall=False,
             fetchsource=False,
             force=False,
             skip=False,
             minimum_perc=0,
             mode=None,
             pseudo=False):
        """Pull all translations file from transifex server."""
        self.minimum_perc = minimum_perc
        resource_list = self.get_chosen_resources(resources)
        skip_decode = False

        if mode == 'reviewed':
            url = 'pull_reviewed_file'
        elif mode == 'translator':
            url = 'pull_translator_file'
        elif mode == 'developer':
            url = 'pull_developer_file'
        elif mode == 'onlytranslated':
            url = 'pull_onlytranslated_file'
        elif mode == 'onlyreviewed':
            url = 'pull_onlyreviewed_file'
        else:
            url = 'pull_file'

        for resource in resource_list:
            logger.debug("Handling resource %s" % resource)
            self.resource = resource
            project_slug, resource_slug = resource.split('.', 1)
            files = self.get_resource_files(resource)
            slang = self.get_resource_option(resource, 'source_lang')
            sfile = self.get_source_file(resource)
            lang_map = self.get_resource_lang_mapping(resource)
            host = self.get_resource_host(resource)
            logger.debug("Language mapping is: %s" % lang_map)
            if mode is None:
                mode = self._get_option(resource, 'mode')
            self.url_info = {
                'host': host,
                'project': project_slug,
                'resource': resource_slug
            }
            logger.debug("URL data are: %s" % self.url_info)

            stats = self._get_stats_for_resource()
            details_response, _ = self.do_url_request('resource_details')
            details = utils.parse_json(details_response)
            if details['i18n_type'] in self.SKIP_DECODE_I18N_TYPES:
                skip_decode = True
            try:
                file_filter = self.config.get(resource, 'file_filter')
            except configparser.NoOptionError:
                file_filter = None

            # Pull source file
            pull_languages = set([])
            new_translations = set([])

            if pseudo:
                pseudo_file = self._get_pseudo_file(slang, resource,
                                                    file_filter)
                if self._should_download(slang, stats, local_file=pseudo_file):
                    logger.info(
                        "Pulling pseudo file for resource %s (%s)." %
                        (resource, utils.color_text(pseudo_file, "RED")))
                    self._download_pseudo(project_slug, resource_slug,
                                          pseudo_file)
                if not languages:
                    continue

            if fetchall:
                new_translations = self._new_translations_to_add(
                    files, slang, lang_map, stats, force)
                if new_translations:
                    msg = ("New translations found "
                           "for the following languages:%s")
                    logger.info(msg % ', '.join(new_translations))

            existing, new = self._languages_to_pull(languages, files, lang_map,
                                                    stats, force)
            pull_languages |= existing
            new_translations |= new
            logger.debug("Adding to new translations: %s" % new)

            if fetchsource:
                if sfile and slang not in pull_languages:
                    pull_languages.add(slang)
                elif slang not in new_translations:
                    new_translations.add(slang)

            if pull_languages:
                logger.debug("Pulling languages for: %s" % pull_languages)
                msg = "Pulling translations for resource %s (source: %s)"
                logger.info(msg % (resource, sfile))

            for lang in pull_languages:
                local_lang = lang
                if lang in list(lang_map.values()):
                    remote_lang = lang_map.flip[lang]
                else:
                    remote_lang = lang
                if languages and lang not in pull_languages:
                    logger.debug("Skipping language %s" % lang)
                    continue
                if lang != slang:
                    local_file = files.get(lang, None) or files[lang_map[lang]]
                else:
                    local_file = sfile
                logger.debug("Using file %s" % local_file)

                kwargs = {
                    'lang': remote_lang,
                    'stats': stats,
                    'local_file': local_file,
                    'force': force,
                    'mode': mode,
                }
                if not self._should_update_translation(**kwargs):
                    msg = "Skipping '%s' translation (file: %s)."
                    logger.info(
                        msg %
                        (utils.color_text(remote_lang, "RED"), local_file))
                    continue

                if not overwrite:
                    local_file = ("%s.new" % local_file)
                logger.warning(
                    " -> %s: %s" %
                    (utils.color_text(remote_lang, "RED"), local_file))
                try:
                    r, charset = self.do_url_request(url,
                                                     language=remote_lang,
                                                     skip_decode=skip_decode)
                except Exception as e:
                    if isinstance(e, SSLError) or not skip:
                        raise
                    else:
                        logger.error(e)
                        continue
                self._save_file(local_file, charset, r)

            if new_translations:
                msg = "Pulling new translations for resource %s (source: %s)"
                logger.info(msg % (resource, sfile))
                for lang in new_translations:
                    if lang in list(lang_map.keys()):
                        local_lang = lang_map[lang]
                    else:
                        local_lang = lang
                    remote_lang = lang
                    if file_filter:
                        local_file = os.path.relpath(
                            os.path.join(
                                self.root,
                                native_path(
                                    file_filter.replace('<lang>',
                                                        local_lang))),
                            os.curdir)
                    else:
                        trans_dir = os.path.join(self.root, ".tx", resource)
                        if not os.path.exists(trans_dir):
                            os.mkdir(trans_dir)
                        local_file = os.path.relpath(
                            os.path.join(trans_dir,
                                         '%s_translation' % local_lang,
                                         os.curdir))

                    if lang != slang:
                        satisfies_min = self._satisfies_min_translated(
                            stats[remote_lang], mode)
                        if not satisfies_min:
                            msg = "Skipping language %s due to used options."
                            logger.info(msg % lang)
                            continue
                    logger.warning(
                        " -> %s: %s" %
                        (utils.color_text(remote_lang, "RED"), local_file))

                    r, charset = self.do_url_request(url,
                                                     language=remote_lang,
                                                     skip_decode=skip_decode)
                    self._save_file(local_file, charset, r)
Пример #41
0
    def push(self,
             source=False,
             translations=False,
             force=False,
             resources=[],
             languages=[],
             skip=False,
             no_interactive=False):
        """
        Push all the resources
        """
        resource_list = self.get_chosen_resources(resources)
        self.skip = skip
        self.force = force
        for resource in resource_list:
            push_languages = []
            project_slug, resource_slug = resource.split('.', 1)
            files = self.get_resource_files(resource)
            slang = self.get_resource_option(resource, 'source_lang')
            sfile = self.get_source_file(resource)
            lang_map = self.get_resource_lang_mapping(resource)
            host = self.get_resource_host(resource)
            logger.debug("Language mapping is: %s" % lang_map)
            logger.debug("Using host %s" % host)
            self.url_info = {
                'host': host,
                'project': project_slug,
                'resource': resource_slug
            }

            logger.info("Pushing translations for resource %s:" % resource)

            stats = self._get_stats_for_resource()

            if force and not no_interactive:
                answer = input(
                    "Warning: By using --force, the uploaded"
                    " files will overwrite remote translations, even if they"
                    " are newer than your uploaded files.\nAre you sure you"
                    " want to continue? [y/N] ")

                if not answer in ["", 'Y', 'y', "yes", 'YES']:
                    return

            if source:
                if sfile is None:
                    logger.error(
                        "You don't seem to have a proper source file"
                        " mapping for resource %s. Try without the --source"
                        " option or set a source file first and then try again."
                        % resource)
                    continue
                # Push source file
                try:
                    logger.warning("Pushing source file (%s)" % sfile)
                    if not self._resource_exists(stats):
                        logger.info("Resource does not exist.  Creating...")
                        fileinfo = "%s;%s" % (resource_slug, slang)
                        filename = self.get_full_path(sfile)
                        self._create_resource(resource, project_slug, fileinfo,
                                              filename)
                    self.do_url_request(
                        'push_source',
                        multipart=True,
                        method="PUT",
                        files=[("%s;%s" % (resource_slug, slang),
                                self.get_full_path(sfile))],
                    )
                except Exception as e:
                    if isinstance(e, SSLError) or not skip:
                        raise
                    else:
                        logger.error(e)
            else:
                try:
                    self.do_url_request('resource_details')
                except Exception as e:
                    if isinstance(e, SSLError):
                        raise
                    code = getattr(e, 'code', None)
                    if code == 404:
                        msg = "Resource %s doesn't exist on the server."
                        logger.error(msg % resource)
                        continue

            if translations:
                # Check if given language codes exist
                if not languages:
                    push_languages = list(files.keys())
                else:
                    push_languages = []
                    f_langs = list(files.keys())
                    for l in languages:
                        if l in list(lang_map.keys()):
                            l = lang_map[l]
                        push_languages.append(l)
                        if l not in f_langs:
                            msg = "Warning: No mapping found for language code '%s'."
                            logger.error(msg % color_text(l, "RED"))
                logger.debug("Languages to push are %s" % push_languages)

                # Push translation files one by one
                for lang in push_languages:
                    local_lang = lang
                    if lang in list(lang_map.values()):
                        remote_lang = lang_map.flip[lang]
                    else:
                        remote_lang = lang

                    local_file = files[local_lang]

                    kwargs = {
                        'lang': remote_lang,
                        'stats': stats,
                        'local_file': local_file,
                        'force': force,
                    }
                    if not self._should_push_translation(**kwargs):
                        msg = "Skipping '%s' translation (file: %s)."
                        logger.info(msg %
                                    (color_text(lang, "RED"), local_file))
                        continue

                    msg = "Pushing '%s' translations (file: %s)"
                    logger.warning(
                        msg % (color_text(remote_lang, "RED"), local_file))
                    try:
                        self.do_url_request(
                            'push_translation',
                            multipart=True,
                            method='PUT',
                            files=[("%s;%s" % (resource_slug, remote_lang),
                                    self.get_full_path(local_file))],
                            language=remote_lang)
                        logger.debug("Translation %s pushed." % remote_lang)
                    except HttpNotFound:
                        if not source:
                            logger.error(
                                "Resource hasn't been created. Try pushing source file."
                            )
                    except Exception as e:
                        if isinstance(e, SSLError) or not skip:
                            raise
                        else:
                            logger.error(e)
Пример #42
0
def main(argv=None):
    """
    Here we parse the flags (short, long) and we instantiate the classes.
    """
    if argv is None:
        argv = sys.argv[1:]
    usage = "usage: %prog [options] command [cmd_options]"
    description = "This is the Transifex command line client which"\
                  " allows you to manage your translations locally and sync"\
                  " them with the master Transifex server.\nIf you'd like to"\
                  " check the available commands issue `%prog help` or if you"\
                  " just want help with a specific command issue `%prog help"\
                  " command`"

    parser = OptionParser(usage=usage,
                          version=txclib.__version__,
                          description=description)
    parser.disable_interspersed_args()
    parser.add_option("-d",
                      "--debug",
                      action="store_true",
                      dest="debug",
                      default=False,
                      help=("enable debug messages"))
    parser.add_option("-q",
                      "--quiet",
                      action="store_true",
                      dest="quiet",
                      default=False,
                      help="don't print status messages to stdout")
    parser.add_option("-r",
                      "--root",
                      action="store",
                      dest="root_dir",
                      type="string",
                      default=None,
                      help="change root directory (default is cwd)")
    parser.add_option("--traceback",
                      action="store_true",
                      dest="trace",
                      default=False,
                      help="print full traceback on exceptions")
    parser.add_option("--disable-colors",
                      action="store_true",
                      dest="color_disable",
                      default=(os.name == 'nt' or not sys.stdout.isatty()),
                      help="disable colors in the output of commands")
    (options, args) = parser.parse_args()

    if len(args) < 1:
        parser.error("No command was given")

    utils.DISABLE_COLORS = options.color_disable

    # set log level
    if options.quiet:
        set_log_level('WARNING')
    elif options.debug:
        set_log_level('DEBUG')

    # find .tx
    path_to_tx = options.root_dir or utils.find_dot_tx()

    cmd = args[0]
    try:
        utils.exec_command(cmd, args[1:], path_to_tx)
    except SSLError as e:
        logger.error("SSl error %s" % e)
        sys.exit(1)
    except utils.UnknownCommandError:
        logger.error("tx: Command %s not found" % cmd)
    except SystemExit:
        sys.exit()
    except:
        import traceback
        if options.trace:
            traceback.print_exc()
        else:
            formatted_lines = traceback.format_exc().splitlines()
            logger.error(formatted_lines[-1])
        sys.exit(1)
Пример #43
0
    def push(self, source=False, translations=False, force=False, resources=[], languages=[],
        skip=False, no_interactive=False):
        """
        Push all the resources
        """
        resource_list = self.get_chosen_resources(resources)
        self.skip = skip
        self.force = force
        for resource in resource_list:
            push_languages = []
            project_slug, resource_slug = resource.split('.')
            files = self.get_resource_files(resource)
            slang = self.get_resource_option(resource, 'source_lang')
            sfile = self.get_resource_option(resource, 'source_file')
            lang_map = self.get_resource_lang_mapping(resource)
            host = self.get_resource_host(resource)
            logger.debug("Language mapping is: %s" % lang_map)
            logger.debug("Using host %s" % host)
            self.url_info = {
                'host': host,
                'project': project_slug,
                'resource': resource_slug
            }

            logger.info("Pushing translations for resource %s:" % resource)

            stats = self._get_stats_for_resource()

            if force and not no_interactive:
                answer = raw_input("Warning: By using --force, the uploaded"
                    " files will overwrite remote translations, even if they"
                    " are newer than your uploaded files.\nAre you sure you"
                    " want to continue? [y/N] ")

                if not answer in ["", 'Y', 'y', "yes", 'YES']:
                    return

            if source:
                if sfile == None:
                    logger.error("You don't seem to have a proper source file"
                        " mapping for resource %s. Try without the --source"
                        " option or set a source file first and then try again." %
                        resource)
                    continue
                # Push source file
                try:
                    logger.warning("Pushing source file (%s)" % sfile)
                    if not self._resource_exists(stats):
                        logger.info("Resource does not exist.  Creating...")
                        fileinfo = "%s;%s" % (resource_slug, slang)
                        filename = self.get_full_path(sfile)
                        self._create_resource(resource, project_slug, fileinfo, filename)
                    self.do_url_request(
                        'push_source', multipart=True, method="PUT",
                        files=[(
                                "%s;%s" % (resource_slug, slang)
                                , self.get_full_path(sfile)
                        )],
                    )
                except Exception, e:
                    if not skip:
                        raise e
                    else:
                        logger.error(e)
            else:
                try:
                    self.do_url_request('resource_details')
                except Exception, e:
                    code = getattr(e, 'code', None)
                    if code == 404:
                        msg = "Resource %s doesn't exist on the server."
                        logger.error(msg % resource)
                        continue
Пример #44
0
def main():
    """
    Here we parse the flags (short, long) and we instantiate the classes.
    """
    usage = "usage: %prog [options] command [cmd_options]"
    description = "This is the Transifex command line client which"\
                  " allows you to manage your translations locally and sync"\
                  " them with the master Transifex server.\nIf you'd like to"\
                  " check the available commands issue `%prog help` or if you"\
                  " just want help with a specific command issue `%prog help"\
                  " command`"
    argv = sys.argv[1:]
    parser = OptionParser(
        usage=usage, version=get_version(), description=description
    )
    parser.disable_interspersed_args()
    parser.add_option(
        "-d", "--debug", action="store_true", dest="debug",
        default=False, help=("enable debug messages")
    )
    parser.add_option(
        "-q", "--quiet", action="store_true", dest="quiet",
        default=False, help="don't print status messages to stdout"
    )
    parser.add_option(
        "-r", "--root", action="store", dest="root_dir", type="string",
        default=None, help="change root directory (default is cwd)"
    )
    parser.add_option(
        "--traceback", action="store_true", dest="trace", default=False,
        help="print full traceback on exceptions"
    )
    parser.add_option(
        "--disable-colors", action="store_true", dest="color_disable",
        default=(os.name == 'nt' or not sys.stdout.isatty()),
        help="disable colors in the output of commands"
    )
    (options, args) = parser.parse_args()

    if len(args) < 1:
        parser.error("No command was given")

    utils.DISABLE_COLORS = options.color_disable

    # set log level
    if options.quiet:
        set_log_level('WARNING')
    elif options.debug:
        set_log_level('DEBUG')

    # find .tx
    path_to_tx = options.root_dir or utils.find_dot_tx()


    cmd = args[0]
    try:
        utils.exec_command(cmd, args[1:], path_to_tx)
    except utils.UnknownCommandError:
        logger.error("tx: Command %s not found" % cmd)
    except SystemExit:
        sys.exit()
    except:
        import traceback
        if options.trace:
            traceback.print_exc()
        else:
            formatted_lines = traceback.format_exc().splitlines()
            logger.error(formatted_lines[-1])
        sys.exit(1)
Пример #45
0
    def push(self,
             source=False,
             translations=False,
             force=False,
             resources=[],
             languages=[],
             skip=False,
             no_interactive=False):
        """
        Push all the resources
        """
        resource_list = self.get_chosen_resources(resources)
        self.skip = skip
        self.force = force
        for resource in resource_list:
            push_languages = []
            project_slug, resource_slug = resource.split('.')
            files = self.get_resource_files(resource)
            slang = self.get_resource_option(resource, 'source_lang')
            sfile = self.get_source_file(resource)
            lang_map = self.get_resource_lang_mapping(resource)
            host = self.get_resource_host(resource)
            verify_ssl(host)
            logger.debug("Language mapping is: %s" % lang_map)
            logger.debug("Using host %s" % host)
            self.url_info = {
                'host': host,
                'project': project_slug,
                'resource': resource_slug
            }

            logger.info("Pushing translations for resource %s:" % resource)

            stats = self._get_stats_for_resource()

            if force and not no_interactive:
                answer = raw_input(
                    "Warning: By using --force, the uploaded"
                    " files will overwrite remote translations, even if they"
                    " are newer than your uploaded files.\nAre you sure you"
                    " want to continue? [y/N] ")

                if not answer in ["", 'Y', 'y', "yes", 'YES']:
                    return

            if source:
                if sfile is None:
                    logger.error(
                        "You don't seem to have a proper source file"
                        " mapping for resource %s. Try without the --source"
                        " option or set a source file first and then try again."
                        % resource)
                    continue
                # Push source file
                try:
                    logger.warning("Pushing source file (%s)" % sfile)
                    if not self._resource_exists(stats):
                        logger.info("Resource does not exist.  Creating...")
                        fileinfo = "%s;%s" % (resource_slug, slang)
                        filename = self.get_full_path(sfile)
                        self._create_resource(resource, project_slug, fileinfo,
                                              filename)
                    self.do_url_request(
                        'push_source',
                        multipart=True,
                        method="PUT",
                        files=[("%s;%s" % (resource_slug, slang),
                                self.get_full_path(sfile))],
                    )
                except Exception, e:
                    if not skip:
                        raise
                    else:
                        logger.error(e)
            else:
                try:
                    self.do_url_request('resource_details')
                except Exception, e:
                    code = getattr(e, 'code', None)
                    if code == 404:
                        msg = "Resource %s doesn't exist on the server."
                        logger.error(msg % resource)
                        continue