Skip to content

Commit 256a77b

Browse files
Normalize CLI options
Fix doc strings Fix command parameters processing
1 parent 8b19a47 commit 256a77b

File tree

14 files changed

+155
-54
lines changed

14 files changed

+155
-54
lines changed

cloudinary_cli/cli.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python3
2+
import platform
23
import shutil
34
import sys
45

@@ -13,11 +14,17 @@
1314
from cloudinary_cli.utils.config_utils import initialize, load_config, refresh_cloudinary_config, \
1415
is_valid_cloudinary_config
1516
from cloudinary_cli.utils.utils import log_exception, ConfigurationError
17+
from cloudinary_cli.version import __version__ as cli_version
1618

1719
CONTEXT_SETTINGS = dict(max_content_width=shutil.get_terminal_size()[0], terminal_width=shutil.get_terminal_size()[0])
1820

1921

2022
@click.group(context_settings=CONTEXT_SETTINGS)
23+
@click.help_option()
24+
@click.version_option(cli_version, prog_name="Cloudinary CLI",
25+
message=f"%(prog)s, version %(version)s\n"
26+
f"Cloudinary SDK, version {cloudinary.VERSION}\n"
27+
f"Python, version {platform.python_version()}")
2128
@click.option("-c", "--config",
2229
help="""Tell the CLI which account to run the command on by specifying an account environment variable."""
2330
)

cloudinary_cli/core/search.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
from webbrowser import open as open_url
2-
31
import cloudinary
4-
from click import command, argument, option
2+
from click import command, argument, option, launch
53

64
from cloudinary_cli.defaults import logger
75
from cloudinary_cli.utils.json_utils import write_json_to_file, print_json
@@ -35,7 +33,7 @@
3533
def search(query, with_field, sort_by, aggregate, max_results, next_cursor,
3634
auto_paginate, force, filter_fields, json, csv, doc):
3735
if doc:
38-
return open_url("https://cloudinary.com/documentation/search_api")
36+
return launch("https://cloudinary.com/documentation/search_api")
3937

4038
fields_to_keep = []
4139
if filter_fields:

cloudinary_cli/core/uploader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
\b
1414
Run any methods that can be called through the upload API.
1515
Format: cld <cli options> uploader <command options> <method> <method parameters>
16-
\te.g. cld uploader upload http://res.cloudinary.com/demo/image/upload/sample public_id=flowers invalidate=True
16+
\te.g. cld uploader upload https://res.cloudinary.com/demo/image/upload/sample public_id=flowers invalidate=True
1717
\b
1818
\te.g. cld uploader rename flowers secret_flowers to_type=private
1919
\t OR

cloudinary_cli/core/utils.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
from webbrowser import open as open_url
2-
3-
from click import command, argument, option, Choice, echo
1+
from click import command, argument, option, Choice, echo, launch
42
from cloudinary import utils as cld_utils
53

64
from cloudinary_cli.core.overrides import cloudinary_url
75
from cloudinary_cli.utils.api_utils import handle_command
8-
from cloudinary_cli.utils.utils import print_help
6+
from cloudinary_cli.utils.utils import print_api_help
97

108
cld_utils.cloudinary_url = cloudinary_url
119

@@ -22,7 +20,7 @@
2220
@option("-ls", "--ls", is_flag=True, help="List all available utility methods.")
2321
def utils(params, optional_parameter, optional_parameter_parsed, ls):
2422
if ls or len(params) < 1:
25-
return print_help(cld_utils, allow_list=utils_list)
23+
return print_api_help(cld_utils, allow_list=utils_list)
2624

2725
echo(handle_command(params, optional_parameter, optional_parameter_parsed, cld_utils, "Utils"))
2826

@@ -47,4 +45,4 @@ def url(public_id, transformation, resource_type, delivery_type, open_in_browser
4745
echo(res)
4846

4947
if open_in_browser:
50-
open_url(res)
48+
launch(res)

cloudinary_cli/modules/make.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,55 @@
1-
from click import command, argument, echo
1+
import os
22

3-
from cloudinary_cli.defaults import TEMPLATE_EXTS
4-
from cloudinary_cli.utils.utils import load_template
3+
from click import command, argument, echo, option
4+
5+
from cloudinary_cli.defaults import TEMPLATE_EXTS, TEMPLATE_FOLDER
6+
from cloudinary_cli.utils.utils import load_template, print_help_and_exit
57

68

79
@command("make", short_help="Return template code for implementing the specified Cloudinary widget.",
810
help="""\b
911
Return template code for implementing the specified Cloudinary widget.
10-
e.g. cld make product_gallery
12+
e.g. cld make media library widget
13+
cld make python find all empty folders
1114
""")
1215
@argument("template", nargs=-1)
13-
def make(template):
14-
language = "html"
16+
@option("-ll", "--list-languages", is_flag=True, help="List available languages.")
17+
@option("-lt", "--list-templates", is_flag=True, help="List available templates.")
18+
def make(template, list_languages, list_templates):
19+
if not any([template, list_languages, list_templates]):
20+
print_help_and_exit()
21+
22+
if list_languages:
23+
echo("Available languages")
24+
with os.scandir(TEMPLATE_FOLDER) as languages:
25+
for tpl_language in languages:
26+
if tpl_language.is_dir():
27+
echo(tpl_language.name)
28+
return True
29+
30+
language, template = _handle_language_and_template(template)
31+
32+
if list_templates:
33+
echo(f"Available templates for language: {language}")
34+
with os.scandir(os.path.join(TEMPLATE_FOLDER, language)) as templates:
35+
for template_file in templates:
36+
if template_file.is_file():
37+
echo(template_file.name.replace("_", " "))
38+
return True
39+
40+
echo(load_template(language, '_'.join(template)))
41+
42+
43+
def _handle_language_and_template(language_and_template):
44+
language = "html" # default language, in case not specified
45+
46+
if not language_and_template:
47+
return language, language_and_template
48+
49+
template = list(language_and_template)
1550
if template[-1] in TEMPLATE_EXTS.keys():
16-
language = template[-1]
17-
template = template[:-1]
51+
language = template.pop()
1852
elif template[0] in TEMPLATE_EXTS.keys():
19-
language = template[0]
20-
template = template[1:]
53+
language = template.pop(0)
2154

22-
echo(load_template(language, '_'.join(template)))
55+
return language, template

cloudinary_cli/modules/sync.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ def __init__(self, local_dir, remote_dir, include_hidden, concurrent_workers, fo
7979
Cloudinary is a very permissive service. When uploading files that contain invalid characters,
8080
unicode characters, etc, Cloudinary does the best effort to store those files.
8181
82-
Usually Cloudinary sanitizes those file names and strips invalid characters. Although it is good best effort for
83-
a general use case, when syncing local folder with Cloudinary, it is not the best option, since directories will
84-
be always out-of-sync.
82+
Usually Cloudinary sanitizes those file names and strips invalid characters. Although it is a good best effort
83+
for a general use case, when syncing local folder with Cloudinary, it is not the best option, since directories
84+
will be always out-of-sync.
8585
8686
To overcome this limitation, cloudinary-cli keeps .cld-sync hidden file in the sync directory that contains a
87-
mapping of the diverse file names. This file keeps tracking on the files and allows syncing in both directions.
87+
mapping of the diverse file names. This file keeps tracking of the files and allows syncing in both directions.
8888
"""
8989
diverse_file_names = read_json_from_file(self.sync_meta_file, does_not_exist_ok=True)
9090
self.diverse_file_names = dict(

cloudinary_cli/modules/upload_dir.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"You can specify a whole path, for example folder1/folder2/folder3. "
2222
"Any folders that do not exist are automatically created.")
2323
@option("-p", "--preset", help="The upload preset to use.")
24-
@option("-w", "--concurrent_workers", type=int, default=30, help="Specify number of concurrent network threads.")
24+
@option("-w", "--concurrent_workers", type=int, default=30, help="Specify the number of concurrent network threads.")
2525
def upload_dir(directory, optional_parameter, optional_parameter_parsed, transformation, folder, preset,
2626
concurrent_workers):
2727
items, skipped = {}, {}

cloudinary_cli/samples/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
from webbrowser import open as open_url
2-
31
import cloudinary
4-
from click import command, argument, option
2+
from click import command, argument, option, launch
53
from cloudinary.utils import cloudinary_url
64

75

@@ -31,7 +29,7 @@ def _handle_sample_command(source, transformation=None, open_in_browser=False, r
3129
res = cloudinary_url(source, raw_transformation=transformation, resource_type=resource_type)
3230
print(res)
3331
if open_in_browser:
34-
open_url(res)
32+
launch(res)
3533

3634

3735
commands = [

cloudinary_cli/templates/python/explicit

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
{% block content %}
44
from cloudinary import uploader
55

6-
res = uploader.explcit("sample", **{
6+
res = uploader.explicit("sample", **{
77
"eager": "w_2000"
88
})
99

1010
print(res)
11-
{% endblock %}
11+
{% endblock %}

cloudinary_cli/utils/api_utils.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import logging
22
from os import path, makedirs
3-
from webbrowser import open as open_url
43

5-
import cloudinary
64
import requests
7-
from click import style
5+
from click import style, launch
86
from cloudinary import Search, uploader
97
from cloudinary.utils import cloudinary_url
108

119
from cloudinary_cli.defaults import logger
10+
from cloudinary_cli.utils.config_utils import is_valid_cloudinary_config
1211
from cloudinary_cli.utils.file_utils import normalize_file_extension, posix_rel_path
1312
from cloudinary_cli.utils.json_utils import print_json, write_json_to_file
14-
from cloudinary_cli.utils.utils import print_help, log_exception, confirm_action, \
15-
get_command_params, merge_responses, normalize_list_params, ConfigurationError
16-
from cloudinary_cli.utils.config_utils import is_valid_cloudinary_config
13+
from cloudinary_cli.utils.utils import log_exception, confirm_action, get_command_params, merge_responses, \
14+
normalize_list_params, ConfigurationError, print_api_help
1715

1816
PAGINATION_MAX_RESULTS = 500
1917

@@ -154,10 +152,10 @@ def handle_api_command(
154152
Used by Admin and Upload API commands
155153
"""
156154
if doc:
157-
return open_url(doc_url)
155+
return launch(doc_url)
158156

159157
if ls or len(params) < 1:
160-
return print_help(api_instance)
158+
return print_api_help(api_instance)
161159

162160
func, args, kwargs = get_command_params(
163161
params,

0 commit comments

Comments
 (0)