diff --git a/CHANGELOG.md b/CHANGELOG.md index 9193240..b2a7f66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ *Applanga CLI Documentation:* *** -### Version 1.0.33 (26 Jun 2018) +### Version 1.0.34 (3 Jul 2018) #### Fixed - do not download empty strings #### Added diff --git a/README.md b/README.md index 776fc66..080f41f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Applanga Localization Command Line Interface (CLI) *** -*Version:* 1.0.33 +*Version:* 1.0.34 *Website:* -*Changelog:* +*Changelog:* *** ## Table of Contents @@ -15,7 +15,7 @@ 3. [Usage](#push-pull-translations) 4. [Configuration](#configuration) - + ## Installation ##### Manual @@ -161,3 +161,10 @@ Name of tag to use. If defined in the "source" block it will apply the tag to al The language of the file. Is only needed if there is no placeholder `` defined in "path" e.g. for your base **"./values/"** or **"./Base.lproj/"** folder. *Example: "en"* + + +##### exclude_languages (optional) + +Excludes languages from being pushed or pulled. + +*Example: ["en", "de-AT"]* diff --git a/applanga.py b/applanga.py index 7606daf..3b62fc9 100755 --- a/applanga.py +++ b/applanga.py @@ -5,7 +5,7 @@ import commands @click.group() -@click.version_option('1.0.33') +@click.version_option('1.0.34') @click.option('--debug/--no-debug', default=False) @click.pass_context def cli(ctx, debug): diff --git a/commands/pull.py b/commands/pull.py index a9e5ac5..646ab63 100644 --- a/commands/pull.py +++ b/commands/pull.py @@ -41,8 +41,8 @@ def pull(ctx): # Language is defined in config request_languages = [ target['language'] ] elif '' in target['path']: - # Language laceholder is defined in path so download all languages - request_languages = all_app_languages + # Language placeholder is defined in path so download all languages + request_languages = all_app_languages[:] else: # No language defined so error click.echo('\nDownload : %s\nLanguage : %s' % (target['path'], 'missing')) @@ -51,6 +51,13 @@ def pull(ctx): click.secho('No language defined. It either has to be set as property or as placeholder in path.\n', err=True, fg='red') continue + # Remove all the languages on the exclude list + exclude_languages = [] + if 'exclude_languages' in target: + exclude_languages = target['exclude_languages'] + + request_languages = [x for x in request_languages if x not in exclude_languages] + # Go through all the languages that should be downloaded for language in request_languages: target['language'] = language diff --git a/commands/push.py b/commands/push.py index fcec48e..530d66c 100644 --- a/commands/push.py +++ b/commands/push.py @@ -16,27 +16,26 @@ def push(ctx, force): click.secho('There was a problem with the config file:\n%s\n' % str(e), err=True, fg='red') return - for source in config_file_data['app']['push']['source']: - try: - file_responses = api.uploadFiles(source, force=force, debug=ctx.obj['DEBUG']) - except api.ApplangaRequestException as e: - click.secho('There was a problem with importing file:\n%s\n' % str(e), err=True, fg='red') - return + try: + file_responses = api.uploadFiles(config_file_data['app']['push']['source'], force=force, debug=ctx.obj['DEBUG']) + except api.ApplangaRequestException as e: + click.secho('There was a problem with pushing files:\n%s\n' % str(e), err=True, fg='red') + return - if len(file_responses) == 0: - click.secho('No file to upload got found.', err=True, fg='red') + if len(file_responses) == 0: + click.secho('No file to upload got found.', err=True, fg='red') - for upload_data in file_responses: - language = upload_data['language'] if 'language' in upload_data else 'language missing' - click.echo('\nUpload : %s\nLanguage : %s' % (upload_data['path'], language)) - click.echo('=' * 60) + for upload_data in file_responses: + language = upload_data['language'] if 'language' in upload_data else 'language missing' + click.echo('\nUpload : %s\nLanguage : %s' % (upload_data['path'], language)) + click.echo('=' * 60) - if 'error' in upload_data: - # There was a problem with the import - click.echo('Result: "Error"') - click.secho('There was a problem with importing file:\n%s\n' % upload_data['error'], err=True, fg='red') - continue + if 'error' in upload_data: + # There was a problem with the import + click.echo('Result: "Error"') + click.secho('There was a problem with importing file:\n%s\n' % upload_data['error'], err=True, fg='red') + continue - # Import was successful - response_json = upload_data['response'].json() - click.echo('Result: "Success"\n\n - Entries in file: %d\n - Added: %d\n - Updated: %d\n - Tag updates: %d\n' % (response_json['total'], response_json['added'], response_json['updated'], response_json['tagUpdates'])) + # Import was successful + response_json = upload_data['response'].json() + click.echo('Result: "Success"\n\n - Entries in file: %d\n - Added: %d\n - Updated: %d\n - Tag updates: %d\n' % (response_json['total'], response_json['added'], response_json['updated'], response_json['tagUpdates'])) diff --git a/lib/api.py b/lib/api.py index edcb106..8fc6c4e 100644 --- a/lib/api.py +++ b/lib/api.py @@ -65,7 +65,7 @@ def downloadFile(file_data, debug=False): -def uploadFiles(file_data, force=False, debug=False): +def uploadFiles(upload_files, force=False, debug=False): """Uploads multiple files to Applanga. Args: @@ -77,36 +77,69 @@ def uploadFiles(file_data, force=False, debug=False): """ - # Make sure it contains all the data that is needed - if 'file_format' not in file_data: - raise ApplangaRequestException('Request is incomplete. The file_format is missing.') - if 'path' not in file_data: - raise ApplangaRequestException('Request is incomplete. The path is missing.') - if 'tag' not in file_data: - file_data['tag'] = None - - try: - language_files = files.getFiles(file_data) - except files.ApplangaTranslationsException as e: - raise ApplangaRequestException('Could not download file "%s": %s' % (file_data['path'], str(e))) + placeholder_files = {} return_data = [] - for file_path in language_files['skipped']: - return_data.append( - { - 'path': file_path, - 'error': 'No language defined' - } - ) - for language in language_files['found']: + files_to_upload = []; + + for source in upload_files: + # Check if we have the data we need for sure + if 'path' not in source: + return_data.append( + { + 'path': 'unknown', + 'error': 'No path defined' + } + ) + continue + if 'file_format' not in source: + return_data.append( + { + 'path': source['path'], + 'error': 'No file-format defined' + } + ) + continue + + + language_files = files.getFiles(source) + + files_to_upload.append(language_files['found']) + + if language_files['uses_placeholder'] == True: + placeholder_files.update() + + # Upload all the files + for files_data in files_to_upload: + + for file_path in files_data: + file_data = files_data[file_path] + + # Make sure it contains all the data that is needed + if 'file_format' not in file_data: + return_data.append( + { + 'language': file_data['language'], + 'path': file_path, + 'error': 'Request is incomplete. The file_format is missing.' + } + ) - for file_path in language_files['found'][language]: try: - response = uploadFile({'file_format': file_data['file_format'], 'language': language, 'tag': file_data['tag'], 'path': file_path}, force=force, debug=debug) + send_data = { + 'file_format': file_data['file_format'], + 'language': file_data['language'], + 'path': file_path + } + + if 'tag' in file_data: + send_data['tag'] = file_data['tag'] + + response = uploadFile(send_data, force=force, debug=debug) return_data.append( { - 'language': language, + 'language': file_data['language'], 'path': file_path, 'response': response } @@ -114,7 +147,7 @@ def uploadFiles(file_data, force=False, debug=False): except ApplangaRequestException as e: return_data.append( { - 'language': language, + 'language': file_data['language'], 'path': file_path, 'error': str(e) } @@ -234,13 +267,21 @@ def makeRequest(data={}, api_path=None, access_token=None, upload_file=None, met click.secho(' Data: %s' % (data), fg=constants.DEBUG_TEXT_COLOR) if method == 'GET': - response = requests.get(url, params=data, headers=headers) + try: + response = requests.get(url, params=data, headers=headers) + except requests.exceptions.ConnectionError as e: + raise ApplangaRequestException('Problem connecting to server. Please check your internet connection.') else: if upload_file: try: with open(upload_file, 'rb') as upload_file_content: - response = requests.post(url, params=data, headers=headers, files={upload_file: upload_file_content}) - except IOError: + try: + response = requests.post(url, params=data, headers=headers, files={upload_file: upload_file_content}) + except requests.exceptions.ConnectionError as e: + raise ApplangaRequestException('Problem connecting to server. Please check your internet connection.') + + except IOError as e: + click.echo(e) raise ApplangaRequestException('Problem with accessing file to upload. The file does probably not exist or there are problems with the access rights.') else: diff --git a/lib/files.py b/lib/files.py index 5f4e9bd..c2f79d1 100644 --- a/lib/files.py +++ b/lib/files.py @@ -38,10 +38,23 @@ def convertLanguageName(language_name): if len(split_name) != 2: # It has to have exactly two parts else it is not valid return None - return split_name[0].lower() + '-' + split_name[1].upper() + + second_part = split_name[1].lower(); + + if len(second_part) == 2: + # Normally the most have only two letters so return + return split_name[0].lower() + '-' + split_name[1].upper() + elif len(second_part) == 4: + # Two special cases of 4 letter ones that are supported + if second_part == 'hant': + return split_name[0].lower() + '-Hant' + elif second_part == 'hans': + return split_name[0].lower() + '-Hans' + else: return language_name.lower() + return None def getFiles(source): @@ -63,6 +76,7 @@ def getFiles(source): source_language = None language_regex_path = None search_path = path + uses_placeholder = False if 'language' in source: # Language is given as parameter @@ -70,7 +84,8 @@ def getFiles(source): else: # Language is in path search_path = path.replace('', '*') - language_regex_path = re.escape(path).replace('\*', '.*').replace('\', '([a-zA-Z]{2}(\-[a-zA-Z]{2})?)') + language_regex_path = re.escape(path).replace('\*', '.*').replace('\', '([a-zA-Z]{2}(\-[a-zA-Z]{2,4})?)') + uses_placeholder = True files = glob2.glob(search_path) @@ -95,13 +110,26 @@ def getFiles(source): # Make sure the language name is in the correct format file_language = convertLanguageName(file_language) - if file_language not in return_files: - return_files[file_language] = [] - return_files[file_language].append(file) - else: - skipped_files.append(file) + if file_language == None: + skipped_files.append(file) + continue + + # Remove all the languages on the exclude list + if 'exclude_languages' in source: + if file_language in source['exclude_languages']: + continue + + return_files[file] = {'language': file_language} + + # Add other properties which got defined for file + if 'tag' in source: + return_files[file]['tag'] = source['tag'] + if 'file_format' in source: + return_files[file]['file_format'] = source['file_format'] + return { 'skipped': skipped_files, - 'found': return_files + 'found': return_files, + 'uses_placeholder': uses_placeholder }