Skip to content

Commit f106959

Browse files
Move listing functions of the obj plugin to its own files (#587)
1 parent fc013da commit f106959

File tree

4 files changed

+189
-180
lines changed

4 files changed

+189
-180
lines changed

linodecli/plugins/obj/__init__.py

Lines changed: 2 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,22 @@
33
CLI Plugin for handling OBJ
44
"""
55
import getpass
6-
import glob
7-
import math
86
import os
9-
import platform
107
import socket
118
import sys
129
import time
1310
from argparse import ArgumentParser
1411
from contextlib import suppress
1512
from datetime import datetime
1613
from math import ceil
17-
from typing import Iterable, List
14+
from typing import List
1815

1916
from rich import print as rprint
2017
from rich.table import Table
2118

2219
from linodecli.cli import CLI
2320
from linodecli.configuration import _do_get_request
2421
from linodecli.configuration.helpers import _default_thing_input
25-
from linodecli.helpers import expand_globs, pagination_args_shared
2622
from linodecli.plugins import PluginContext, inherit_plugin_args
2723
from linodecli.plugins.obj.buckets import create_bucket, delete_bucket
2824
from linodecli.plugins.obj.config import (
@@ -42,12 +38,10 @@
4238
from linodecli.plugins.obj.helpers import (
4339
ProgressPercentage,
4440
_borderless_table,
45-
_convert_datetime,
4641
_denominate,
4742
_pad_to,
48-
_progress,
49-
restricted_int_arg_type,
5043
)
44+
from linodecli.plugins.obj.list import list_all_objects, list_objects_or_buckets
5145
from linodecli.plugins.obj.objects import (
5246
delete_object,
5347
get_object,
@@ -61,22 +55,12 @@
6155

6256
try:
6357
import boto3
64-
from boto3.exceptions import S3UploadFailedError
65-
from boto3.s3.transfer import MB, TransferConfig
6658
from botocore.exceptions import ClientError
6759

6860
HAS_BOTO = True
6961
except ImportError:
7062
HAS_BOTO = False
7163

72-
TRUNCATED_MSG = (
73-
"Notice: Not all results were shown. If your would "
74-
"like to get more results, you can add the '--all-row' "
75-
"flag to the command or use the built-in pagination flags."
76-
)
77-
78-
INVALID_PAGE_MSG = "No result to show in this page."
79-
8064

8165
def get_available_cluster(cli: CLI):
8266
"""Get list of possible clusters for the account"""
@@ -90,117 +74,6 @@ def get_available_cluster(cli: CLI):
9074
]
9175

9276

93-
def flip_to_page(iterable: Iterable, page: int = 1):
94-
"""Given a iterable object and return a specific iteration (page)"""
95-
iterable = iter(iterable)
96-
for _ in range(page - 1):
97-
try:
98-
next(iterable)
99-
except StopIteration:
100-
print(INVALID_PAGE_MSG)
101-
sys.exit(2)
102-
103-
return next(iterable)
104-
105-
106-
def list_objects_or_buckets(
107-
get_client, args, **kwargs
108-
): # pylint: disable=too-many-locals,unused-argument,too-many-branches
109-
"""
110-
Lists buckets or objects
111-
"""
112-
parser = inherit_plugin_args(ArgumentParser(PLUGIN_BASE + " ls"))
113-
pagination_args_shared(parser)
114-
115-
parser.add_argument(
116-
"bucket",
117-
metavar="NAME",
118-
type=str,
119-
nargs="?",
120-
help=(
121-
"Optional. If not given, lists all buckets. If given, "
122-
"lists the contents of the given bucket. May contain a "
123-
"/ followed by a directory path to show the contents of "
124-
"a directory within the named bucket."
125-
),
126-
)
127-
128-
parsed = parser.parse_args(args)
129-
client = get_client()
130-
131-
if parsed.bucket:
132-
# list objects
133-
if "/" in parsed.bucket:
134-
bucket_name, prefix = parsed.bucket.split("/", 1)
135-
if not prefix.endswith("/"):
136-
prefix += "/"
137-
else:
138-
bucket_name = parsed.bucket
139-
prefix = ""
140-
141-
data = []
142-
objects = []
143-
sub_directories = []
144-
pages = client.get_paginator("list_objects_v2").paginate(
145-
Prefix=prefix,
146-
Bucket=bucket_name,
147-
Delimiter="/",
148-
PaginationConfig={"PageSize": parsed.page_size},
149-
)
150-
try:
151-
if parsed.all_rows:
152-
results = pages
153-
else:
154-
page = flip_to_page(pages, parsed.page)
155-
if page.get("IsTruncated", False):
156-
print(TRUNCATED_MSG)
157-
158-
results = [page]
159-
except client.exceptions.NoSuchBucket:
160-
print("No bucket named " + bucket_name)
161-
sys.exit(2)
162-
163-
for item in results:
164-
objects.extend(item.get("Contents", []))
165-
sub_directories.extend(item.get("CommonPrefixes", []))
166-
167-
for d in sub_directories:
168-
data.append((" " * 16, "DIR", d.get("Prefix")))
169-
for obj in objects:
170-
key = obj.get("Key")
171-
172-
# This is to remove the dir itself from the results
173-
# when the the files list inside a directory (prefix) are desired.
174-
if key == prefix:
175-
continue
176-
177-
data.append(
178-
(
179-
_convert_datetime(obj.get("LastModified")),
180-
obj.get("Size"),
181-
key,
182-
)
183-
)
184-
185-
if data:
186-
tab = _borderless_table(data)
187-
rprint(tab)
188-
189-
sys.exit(0)
190-
else:
191-
# list buckets
192-
buckets = client.list_buckets().get("Buckets", [])
193-
data = [
194-
[_convert_datetime(b.get("CreationDate")), b.get("Name")]
195-
for b in buckets
196-
]
197-
198-
tab = _borderless_table(data)
199-
rprint(tab)
200-
201-
sys.exit(0)
202-
203-
20477
def generate_url(get_client, args, **kwargs): # pylint: disable=unused-argument
20578
"""
20679
Generates a URL to an object
@@ -368,52 +241,6 @@ def show_usage(get_client, args, **kwargs): # pylint: disable=unused-argument
368241
sys.exit(0)
369242

370243

371-
def list_all_objects(
372-
get_client, args, **kwargs
373-
): # pylint: disable=unused-argument
374-
"""
375-
Lists all objects in all buckets
376-
"""
377-
# this is for printing help when --help is in the args
378-
parser = inherit_plugin_args(ArgumentParser(PLUGIN_BASE + " la"))
379-
pagination_args_shared(parser)
380-
381-
parsed = parser.parse_args(args)
382-
383-
client = get_client()
384-
385-
buckets = [b["Name"] for b in client.list_buckets().get("Buckets", [])]
386-
387-
for b in buckets:
388-
print()
389-
objects = []
390-
pages = client.get_paginator("list_objects_v2").paginate(
391-
Bucket=b, PaginationConfig={"PageSize": parsed.page_size}
392-
)
393-
if parsed.all_rows:
394-
results = pages
395-
else:
396-
page = flip_to_page(pages, parsed.page)
397-
if page.get("IsTruncated", False):
398-
print(TRUNCATED_MSG)
399-
400-
results = [page]
401-
402-
for page in results:
403-
objects.extend(page.get("Contents", []))
404-
405-
for obj in objects:
406-
size = obj.get("Size", 0)
407-
408-
print(
409-
f"{_convert_datetime(obj['LastModified'])} "
410-
f"{_pad_to(size, 9, right_align=True)} "
411-
f"{b}/{obj['Key']}"
412-
)
413-
414-
sys.exit(0)
415-
416-
417244
COMMAND_MAP = {
418245
"mb": create_bucket,
419246
"rb": delete_bucket,

linodecli/plugins/obj/helpers.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
The helper functions for the object storage plugin.
33
"""
44

5+
import sys
56
from argparse import ArgumentTypeError
7+
from collections.abc import Iterable
68
from datetime import datetime
79

810
from rich.table import Table
911
from rich.text import Text
1012

1113
from linodecli.plugins.obj.config import DATE_FORMAT
1214

15+
INVALID_PAGE_MSG = "No result to show in this page."
16+
1317

1418
class ProgressPercentage: # pylint: disable=too-few-public-methods
1519
"""
@@ -126,3 +130,16 @@ def _borderless_table(data):
126130
tab.add_row(*row)
127131

128132
return tab
133+
134+
135+
def flip_to_page(iterable: Iterable, page: int = 1):
136+
"""Given a iterable object and return a specific iteration (page)"""
137+
iterable = iter(iterable)
138+
for _ in range(page - 1):
139+
try:
140+
next(iterable)
141+
except StopIteration:
142+
print(INVALID_PAGE_MSG)
143+
sys.exit(2)
144+
145+
return next(iterable)

0 commit comments

Comments
 (0)