|
@@ -51,6 +51,7 @@ def graph(data=[]):
|
|
|
# Concept art:
|
|
|
|
|
|
# 2021-11-15 --------------------------------------> 2021-12-30
|
|
|
+ #0 2 4 6 8 10 13 16 19 22 25 28 31 34 37 40 43 46 49 .... 100 104
|
|
|
#
|
|
|
# #
|
|
|
# #
|
|
@@ -63,16 +64,16 @@ def graph(data=[]):
|
|
|
|
|
|
if not data:
|
|
|
center("No Data!", "bdrd")
|
|
|
- return
|
|
|
+ return {0:[]}
|
|
|
if len(data) == 1:
|
|
|
center("Only one entry! Cannot draw graph!", "bdrd")
|
|
|
- return
|
|
|
+ return {0:data}
|
|
|
|
|
|
w, h = tsize()
|
|
|
|
|
|
- height = h - 5
|
|
|
+ height = h - 7
|
|
|
width = w - 16
|
|
|
-
|
|
|
+
|
|
|
times = []
|
|
|
values = []
|
|
|
|
|
@@ -92,6 +93,8 @@ def graph(data=[]):
|
|
|
|
|
|
center(startdate+" "+("-"*(width-(len(startdate)+len(enddate))-6))+"> "+enddate)
|
|
|
|
|
|
+
|
|
|
+ # Times minus the amount of the first entry
|
|
|
ctimes = []
|
|
|
for i in times:
|
|
|
ctimes.append(i-min(times))
|
|
@@ -106,11 +109,15 @@ def graph(data=[]):
|
|
|
p.append(pix)
|
|
|
|
|
|
ap = []
|
|
|
+ ret_data = {}
|
|
|
for i in range(width):
|
|
|
count = 0
|
|
|
for n, d in enumerate(p):
|
|
|
if d == i:
|
|
|
count = count + values[n]
|
|
|
+ if d not in ret_data:
|
|
|
+ ret_data[d] = []
|
|
|
+ ret_data[d].append(data[n])
|
|
|
ap.append(count)
|
|
|
|
|
|
choice = " ░▒▓█"
|
|
@@ -121,7 +128,7 @@ def graph(data=[]):
|
|
|
|
|
|
va = max(ap) * ((i+1)/(height-1))
|
|
|
|
|
|
- s = clr["bdma"]+" "+wdth(va, 5)+" "
|
|
|
+ s = clr["bdma"]+" "+clr["tbwh"]+wdth(va, 5)+" "
|
|
|
|
|
|
|
|
|
for b in ap:
|
|
@@ -130,14 +137,242 @@ def graph(data=[]):
|
|
|
c = max(min(round((x - i)*4), 4), 0)
|
|
|
|
|
|
y = choice[c]
|
|
|
- s = s + clr["bdbu"]+clr["tdcy"]+y
|
|
|
+ s = s + clr["bdbu"]+clr["tbwh"]+y
|
|
|
|
|
|
|
|
|
print(" "+s+clr["bdma"]+" "+clr["norm"])
|
|
|
|
|
|
center(" ")
|
|
|
+ # Here I want to print a sideways ruler
|
|
|
+ ruler_sideways(width-1, 6)
|
|
|
+ center(" ")
|
|
|
+
|
|
|
+ return ret_data
|
|
|
+
|
|
|
+def graph_loop(items):
|
|
|
+
|
|
|
+ to_make = True
|
|
|
+ while True:
|
|
|
+ # parts of the graph's data indexed to the column on the graph
|
|
|
+ parts = graph(items)
|
|
|
+
|
|
|
+ # commands
|
|
|
+ c = input(typing_dots("Type 'help' for graph commands.", to_make))
|
|
|
+ to_make = False
|
|
|
+
|
|
|
+ if not c:
|
|
|
+ break
|
|
|
+
|
|
|
+ # Showing minimum data ( similar to raw, but with a lot less stuff )
|
|
|
+ elif c == "numbers":
|
|
|
+ data_print = {"categories": ["Time", "Amount"],
|
|
|
+ "size":[2,1],
|
|
|
+ "data":[]}
|
|
|
+ for i in parts:
|
|
|
+ for b in parts[i]:
|
|
|
+ try:
|
|
|
+ amount = b["amount"]
|
|
|
+ except:
|
|
|
+ amount = "[NO AMOUNT]"
|
|
|
+ try:
|
|
|
+ import time
|
|
|
+ timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(b["timestamp"]) )
|
|
|
+ except:
|
|
|
+ timestamp = "[NO TIME DATA]"
|
|
|
+ data_print["data"].append([timestamp, amount])
|
|
|
|
|
|
+ print()
|
|
|
+ table(data_print, False)
|
|
|
+ center("")
|
|
|
+ input()
|
|
|
+ print()
|
|
|
+
|
|
|
+ # Zooming in the Graph
|
|
|
+ elif c.startswith("zoom"):
|
|
|
+ try:
|
|
|
+ if " " in c:
|
|
|
+ n = c[c.find(" ")+1:]
|
|
|
+ else:
|
|
|
+ n = input(typing_dots("Number if a range?"))
|
|
|
+
|
|
|
+ # if it's a range
|
|
|
+ if " " in n:
|
|
|
+ nr = n.split()
|
|
|
+ nrange = []
|
|
|
+
|
|
|
+ for i in nr:
|
|
|
+ nrange.append(int(i))
|
|
|
+
|
|
|
+ zoom_data = []
|
|
|
+ for i in range(nrange[0], nrange[-1]+1):
|
|
|
+ if i in parts:
|
|
|
+ for d in parts[i]:
|
|
|
+ zoom_data.append(d)
|
|
|
+
|
|
|
+ graph_loop(zoom_data)
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ graph_loop(parts[int(n)])
|
|
|
+ except:
|
|
|
+ graph_loop([])
|
|
|
+ except Exception as e:
|
|
|
+ center("Error: "+str(e), "bdrd")
|
|
|
+
|
|
|
+ # Printing the Raw data into the terminal
|
|
|
+ elif c == "raw":
|
|
|
+
|
|
|
+ size = [1,4]
|
|
|
+ for i in range(len(parts[0][0].keys())-2):
|
|
|
+ size.append(2)
|
|
|
|
|
|
+ categories = list(parts[0][0].keys())
|
|
|
+
|
|
|
+ data_print = {"categories": categories,
|
|
|
+ "size":size,
|
|
|
+ "data":[]}
|
|
|
+ for i in parts:
|
|
|
+ for b in parts[i]:
|
|
|
+ if list(b.keys()) != categories:
|
|
|
+
|
|
|
+ print()
|
|
|
+ table(data_print, False)
|
|
|
+ center("")
|
|
|
+
|
|
|
+ categories = list(b.keys())
|
|
|
+ size = [1,4]
|
|
|
+ for i in range(len(b.keys())-2):
|
|
|
+ size.append(2)
|
|
|
+ data_print = {"categories": categories,
|
|
|
+ "size":size,
|
|
|
+ "data":[]}
|
|
|
+
|
|
|
+ ap = list(b.values())
|
|
|
+ if len(ap) < len(size):
|
|
|
+ for dif in range(len(size) - len(ap)):
|
|
|
+ ap.append(None)
|
|
|
+ data_print["data"].append(ap)
|
|
|
+ print()
|
|
|
+ table(data_print, False)
|
|
|
+ center("")
|
|
|
+ input()
|
|
|
+ print()
|
|
|
+
|
|
|
+ # Output a CSV file.
|
|
|
+ elif c == "csv":
|
|
|
+
|
|
|
+ def to_csv_string(data):
|
|
|
+ ret = ""
|
|
|
+ for n, i in enumerate(data):
|
|
|
+ if n == 0:
|
|
|
+ comma = ""
|
|
|
+ else:
|
|
|
+ comma = ","
|
|
|
+ if type(i) in [int,float,bool,str]:
|
|
|
+ ret = ret + comma + '"'+str(i).replace('"', '""')+'"'
|
|
|
+ else:
|
|
|
+ ret = ret + comma + '"[COMPLEX DATA]"'
|
|
|
+ return ret
|
|
|
+
|
|
|
+ text = to_csv_string(parts[0][0].keys())
|
|
|
+ keys = text
|
|
|
+ for i in parts:
|
|
|
+ for b in parts[i]:
|
|
|
+ if to_csv_string(b.keys()) != keys:
|
|
|
+ keys = to_csv_string(b.keys())
|
|
|
+ text = text + "\n\n"+ keys
|
|
|
+ text = text + "\n" + to_csv_string(b.values())
|
|
|
+
|
|
|
+ saving = open("/tmp/fast_lbry_csv_tempfile.csv", 'w')
|
|
|
+ saving.write(text)
|
|
|
+ saving.close()
|
|
|
+ Popen(["xdg-open",
|
|
|
+ "/tmp/fast_lbry_csv_tempfile.csv"],
|
|
|
+ stdout=DEVNULL,
|
|
|
+ stderr=STDOUT)
|
|
|
+ # Saving graph
|
|
|
+ elif c == "save":
|
|
|
+ itemsjson = []
|
|
|
+ for i in parts:
|
|
|
+ for b in parts[i]:
|
|
|
+ itemsjson.append(b)
|
|
|
+ filename = settings.get_settings_folder(flbry="flbry/graphs")
|
|
|
+ from datetime import datetime
|
|
|
+ now = datetime.now()
|
|
|
+ filename = filename + "/" + str(now.strftime("%Y-%m-%d_%H:%M:%S")) + ".json"
|
|
|
+
|
|
|
+ note = input(typing_dots("Note?"))
|
|
|
+ savedata = {"note":note, "items":itemsjson}
|
|
|
+
|
|
|
+ with open(filename, 'w') as f:
|
|
|
+ json.dump(savedata, f, indent=4)
|
|
|
+
|
|
|
+ center("Saved to :"+ filename)
|
|
|
+ input()
|
|
|
+
|
|
|
+
|
|
|
+ elif c == "help":
|
|
|
+
|
|
|
+ markdown.draw("help/graph.md", "Graph Help")
|
|
|
+
|
|
|
+def get_data(claim_id="", total=0, mode="sales"):
|
|
|
+
|
|
|
+ # This function will actually load data from
|
|
|
+ # a given claim_id
|
|
|
+
|
|
|
+ if not total:
|
|
|
+ command = [lbrynet_binary["b"],
|
|
|
+ "txo", "list",
|
|
|
+ "--exclude_internal_transfers",
|
|
|
+ "--is_not_my_input",
|
|
|
+ "--page_size=1"]
|
|
|
+ if mode == "sales":
|
|
|
+ command.append("--type=purchase")
|
|
|
+ if claim_id:
|
|
|
+ command.append("--claim_id="+claim_id)
|
|
|
+ txo = check_output(command)
|
|
|
+ try:
|
|
|
+ txo = json.loads(txo)
|
|
|
+ except:
|
|
|
+ center("Connect to LBRY first.")
|
|
|
+ return
|
|
|
+ total = txo["total_items"]
|
|
|
+
|
|
|
+ cpage = 1
|
|
|
+ items = []
|
|
|
+ total_total = total
|
|
|
+ print()
|
|
|
+ while total > 0:
|
|
|
+
|
|
|
+ progress_bar(total_total-total, total_total, "Getting "+mode+" data...")
|
|
|
+
|
|
|
+
|
|
|
+ command = [lbrynet_binary["b"],
|
|
|
+ "txo", "list",
|
|
|
+ "--page_size=50",
|
|
|
+ "--exclude_internal_transfers",
|
|
|
+ "--is_not_my_input",
|
|
|
+ "--page="+str(cpage)]
|
|
|
+ if mode == "sales":
|
|
|
+ command.append("--type=purchase")
|
|
|
+ if claim_id:
|
|
|
+ command.append("--claim_id="+claim_id)
|
|
|
+ txo = check_output(command)
|
|
|
+ try:
|
|
|
+ txo = json.loads(txo)
|
|
|
+ except:
|
|
|
+ center("Connect to LBRY first.")
|
|
|
+ return
|
|
|
+ cpage = cpage + 1
|
|
|
+ for i in txo["items"]:
|
|
|
+ items.append(i)
|
|
|
+ total = total - 50
|
|
|
+
|
|
|
+ progress_bar(total_total, total_total, "Done.")
|
|
|
+
|
|
|
+ print()
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
def sales(mode="sales"):
|
|
|
|
|
|
# This function will show sales of non-gratis publications.
|
|
@@ -219,6 +454,8 @@ def sales(mode="sales"):
|
|
|
command = [lbrynet_binary["b"],
|
|
|
"txo", "list",
|
|
|
"--claim_id="+i["claim_id"],
|
|
|
+ "--exclude_internal_transfers",
|
|
|
+ "--is_not_my_input",
|
|
|
"--page_size=1"]
|
|
|
if mode == "sales":
|
|
|
command.append("--type=purchase")
|
|
@@ -260,30 +497,61 @@ def sales(mode="sales"):
|
|
|
c = int(c)
|
|
|
total = data_print["data"][c][-1]
|
|
|
i = list_of_publications["items"][c]
|
|
|
- cpage = 1
|
|
|
- items = []
|
|
|
- while total > 0:
|
|
|
- command = [lbrynet_binary["b"],
|
|
|
- "txo", "list",
|
|
|
- "--claim_id="+i["claim_id"],
|
|
|
- "--page_size=50",
|
|
|
- "--page="+str(cpage)]
|
|
|
- if mode == "sales":
|
|
|
- command.append("--type=purchase")
|
|
|
- txo = check_output(command)
|
|
|
- try:
|
|
|
- txo = json.loads(txo)
|
|
|
- except:
|
|
|
- center("Connect to LBRY first.")
|
|
|
- return
|
|
|
- cpage = cpage + 1
|
|
|
- for i in txo["items"]:
|
|
|
- items.append(i)
|
|
|
- total = total - 50
|
|
|
-
|
|
|
- graph(items)
|
|
|
- input()
|
|
|
- print()
|
|
|
+ try:
|
|
|
+
|
|
|
+ items = get_data(i["claim_id"], total, mode)
|
|
|
+ graph_loop(items)
|
|
|
+ except Exception as e:
|
|
|
+ print(e)
|
|
|
|
|
|
+ print()
|
|
|
+
|
|
|
except:
|
|
|
pass
|
|
|
+
|
|
|
+def load_graph_from_file():
|
|
|
+
|
|
|
+ # This function will load cached graphs back into the terminal.
|
|
|
+
|
|
|
+ folder = settings.get_settings_folder(flbry="flbry/graphs")
|
|
|
+ while True:
|
|
|
+ data_print = {"categories": ["Note", "Size", "Saving Time"],
|
|
|
+ "size":[4,1,2],
|
|
|
+ "data":[]}
|
|
|
+ graphs = []
|
|
|
+ for graph in os.listdir(folder):
|
|
|
+ if graph.endswith(".json"):
|
|
|
+ date = graph.replace(".json", "").replace("_", " ")
|
|
|
+
|
|
|
+ with open(folder+"/"+graph) as f:
|
|
|
+ json_data= json.load(f)
|
|
|
+
|
|
|
+ try:
|
|
|
+ note = json_data["note"]
|
|
|
+ except:
|
|
|
+ note = ""
|
|
|
+
|
|
|
+ try:
|
|
|
+ items = json_data["items"]
|
|
|
+ except:
|
|
|
+ items = []
|
|
|
+ graphs.append(items)
|
|
|
+ data_print["data"].append([note,len(items), date])
|
|
|
+
|
|
|
+ print()
|
|
|
+ table(data_print)
|
|
|
+ center("")
|
|
|
+ print()
|
|
|
+
|
|
|
+ c = input(typing_dots("Select graph number."))
|
|
|
+
|
|
|
+ if not c:
|
|
|
+ break
|
|
|
+
|
|
|
+ try:
|
|
|
+ graph_loop(graphs[int(c)])
|
|
|
+ except:
|
|
|
+ center("Something's wrong!", "bdrd")
|
|
|
+
|
|
|
+
|
|
|
+
|