Skip to content

Commit

Permalink
Daemon.jsonrpc_file_summary: new method to print a summary of claims
Browse files Browse the repository at this point in the history
This allows printing a list of all claim streams that were downloaded
to the system.
The list is printed to the terminal or to a specific file.

It accepts some parameters to control the information that is printed.
```
lbrynet file summary --blobs --show_channel --title --stream_type --path
lbrynet file summary --show=incomplete --start=10 --end=40
lbrynet file summary --sort=claim_name --reverse --sep=' ;.;'
```

The `--file` option writes the list of claims to a file
which then can be shared with other users of LBRY in order
to download the same claims and contribute to seeding that content.
```
lbrynet file summary --channel=@somechannel --file=summary.txt --fdate
```

By default it will print the date of the claim which is based on the `'claim_height'`,
when the claim was registered in the blockchain, the `'claim_id'`, the `'claim_name'`,
and whether the media is present or not in the download directory.
```
 1/42; 20200610_10:23:37-0500; b231714456ee832daeba4b8356803e7591126dff; "07-S"; no-media
 2/42; 20200610_10:27:06-0500; 31700ff11f900429d742f2f137ba25393bdb3b0a; "09-S"; media
 3/42; 20200609_23:14:47-0500; 70dfefa510ca6eee7023a2a927e34d385b5a18bd; "04-S"; no-media
```
  • Loading branch information
belikor committed Sep 14, 2021
1 parent 561566e commit 736be1f
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 0 deletions.
90 changes: 90 additions & 0 deletions lbry/extras/daemon/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
from lbry.schema.claim import Claim
from lbry.schema.url import URL, normalize_name
from lbry.wallet.server.db.elasticsearch.constants import RANGE_FIELDS, REPLACEMENTS
import lbry.extras.daemon.files as files
MY_RANGE_FIELDS = RANGE_FIELDS - {"limit_claims_per_channel"}

if typing.TYPE_CHECKING:
Expand Down Expand Up @@ -2214,6 +2215,95 @@ async def jsonrpc_file_save(self, file_name=None, download_directory=None, **kwa
await stream.save_file(file_name, download_directory)
return stream

@requires(FILE_MANAGER_COMPONENT)
def _sort_items(self, sort=None, reverse=False, comparison=None,
channel_name=None, wallet_id=None, **kwargs):
"""Get all items downloaded, and ordered."""
if not sort or sort in "release_time":
sort = "claim_height"
comparison = comparison or 'eq'

if channel_name:
items = self.file_manager.get_filtered(sort, reverse, comparison,
channel_name=channel_name, **kwargs)
else:
items = self.file_manager.get_filtered(sort, reverse, comparison,
**kwargs)
n_items = len(items)

if n_items < 1:
return False, False

print(f"Number of items: {n_items}")

sorted_items = items

release_times = []
for it, item in enumerate(sorted_items, start=1):
_time = self.ledger.headers.estimated_timestamp(item.claim_height)
release_times.append(_time)

return sorted_items, release_times

@requires(FILE_MANAGER_COMPONENT)
async def jsonrpc_file_summary(self, show=None,
blobs=None, show_channel=None,
title=None, stream_type=None, path=None,
start=1, end=0, channel=None,
file=None, fdate=None, sep=";",
sort=None, reverse=False, comparison=None, wallet_id=None,
**kwargs):
"""
Print summary of all downloaded claims.
Usage:
file_summary [--show=<show>] [--blobs] [--show_channel] [--title] [--stream_type] [--path]
[--start=<start>] [--end=<end>]
[--channel=<channel>] [--file=<file>] [--fdate] [--sep=<sep>]
[--sort=<sort_by>] [--reverse] [--comparison=<comparison>] [--wallet_id=<wallet_id>]
Options:
--show=<show> : (str) what to show, it may be 'all' (default), 'incomplete', 'full', or 'media'
--blobs : (bool) show the number of blobs in the stream
--show_channel : (bool) show the channel that published the stream
--title : (bool) show the title of the claim
--stream_type : (bool) show the type of stream (video, audio, document, etc.)
--path : (bool) show the full path of the downloaded media file if it exists
--start=<start> : (int) show claims starting from this index (default 1)
--end=<end> : (int) show claims until and including this index (default 0);
if it is 0, it is the same as the last index
--channel=<channel> : (str) show only the claims by this channel
--file=<file> : (str) name of the output file where the summary will be placed,
if it is omitted it will show the summary in the terminal
--fdate : (bool) add the current date to the summary file
--sep=<sep> : (str) string used as separator for fields (default ;)
--sort=<sort_by> : (str) sort by one of the filter fields;
by default it uses 'claim_height', that is, time.
Other fields are those available for the 'file_list' command
such as 'claim_name' and 'claim_id'.
--reverse : (bool) reverse the order of the list
--comparison=<comparison> : (str) logical comparison, (eq | ne | g | ge | l | le | in)
"""
if show is None or show not in ("all", "incomplete", "full", "media", "missing"):
show = "all"

items, release_times = self._sort_items(sort=sort, reverse=reverse, comparison=comparison,
channel_name=channel, wallet_id=wallet_id,
**kwargs)
if not items or len(items) < 1:
error = {"error": "No downloaded claims"}
if file:
error["error"] += f'; no file written "{file}"'
return error

n_out, file_out = files.print_items(items=items, release_times=release_times,
show=show, title=title, typ=stream_type, path=path,
cid=True, blobs=blobs, ch=show_channel,
name=True, start=start, end=end,
file=file, fdate=fdate, sep=sep)
return {"total_items": n_out,
"file": file_out}

PURCHASE_DOC = """
List and make purchases of claims.
"""
Expand Down
118 changes: 118 additions & 0 deletions lbry/extras/daemon/files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env python3
"""
Print various types of information regarding the claims.
"""
import os
import time


def print_items(items=None, release_times=None, show="all",
title=False, typ=False, path=False,
cid=True, blobs=True, ch=False,
name=True, start=1, end=0,
file=None, fdate=None, sep=";"):
"""Print items provided by file_list."""
if not items:
error = "No claims"
if file:
error += f'; no file written "{file}"'
print(error)
return False, False

n_items = len(items)

fd = 0

if file:
dirn = os.path.dirname(file)
base = os.path.basename(file)

if fdate:
fdate = time.strftime("%Y%m%d_%H%M", time.localtime()) + "_"
else:
fdate = ""

file = os.path.join(dirn, fdate + base)

try:
fd = open(file, "w")
except (FileNotFoundError, PermissionError) as err:
print(f"Cannot open file for writing; {err}")

out_list = []

for it, pair in enumerate(zip(items, release_times), start=1):
if it < start:
continue
if end != 0 and it > end:
break

item = pair[0]
release_time = pair[1]

_path = item.download_path
_blobs = item.blobs_completed
_blobs_in_stream = item.blobs_in_stream

if show in "media" and not _path:
continue
elif show in "missing" and _path:
continue
elif show in "incomplete" and _blobs == _blobs_in_stream:
continue
elif show in "full" and _blobs < _blobs_in_stream:
continue

if "release_time" not in item.metadata:
_time = release_time
else:
_time = int(item.metadata["release_time"])
_time = time.localtime(_time)
_time = time.strftime("%Y%m%d_%H:%M:%S%z", _time)

_claim_id = item.claim_id
_claim_ch = item.channel_name
_claim_name = item.claim_name
_title = item.metadata["title"]
_type = item.metadata["stream_type"]

out = "{:4d}/{:4d}".format(it, n_items) + sep + f" {_time}" + f"{sep} "

if cid:
out += f"{_claim_id}" + f"{sep} "
if blobs:
out += "{:3d}/{:3d}".format(_blobs, _blobs_in_stream) + f"{sep} "
if ch:
if _claim_ch:
out += f"{_claim_ch}" + f"{sep} "
else:
out += f"_Unknown_" + f"{sep} "
if name:
out += f'"{_claim_name}"' + f"{sep} "

if title:
out += f'"{_title}"' + f"{sep} "
if typ:
out += f"{_type}" + f"{sep} "
if path:
out += f'"{_path}"' + f"{sep} "

if _path:
out += "media"
else:
out += "no-media"

out_list.append(out)

print(f"Number of shown items: {len(out_list)}")

if file and fd:
for line in out_list:
print(line, file=fd)

fd.close()
print(f'Summary written: "{file}"')
else:
print("\n".join(out_list))

return len(out_list), file

0 comments on commit 736be1f

Please sign in to comment.