analytics.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #####################################################################
  2. # #
  3. # THIS IS A SOURCE CODE FILE FROM A PROGRAM TO INTERACT WITH THE #
  4. # LBRY PROTOCOL ( lbry.com ). IT WILL USE THE LBRY SDK ( lbrynet ) #
  5. # FROM THEIR REPOSITORY ( https://github.com/lbryio/lbry-sdk ) #
  6. # WHICH I GONNA PRESENT TO YOU AS A BINARY. SINCE I DID NOT DEVELOP #
  7. # IT AND I'M LAZY TO INTEGRATE IN A MORE SMART WAY. THE SOURCE CODE #
  8. # OF THE SDK IS AVAILABLE IN THE REPOSITORY MENTIONED ABOVE. #
  9. # #
  10. # ALL THE CODE IN THIS REPOSITORY INCLUDING THIS FILE IS #
  11. # (C) J.Y.Amihud and Other Contributors 2021. EXCEPT THE LBRY SDK. #
  12. # YOU CAN USE THIS FILE AND ANY OTHER FILE IN THIS REPOSITORY UNDER #
  13. # THE TERMS OF GNU GENERAL PUBLIC LICENSE VERSION 3 OR ANY LATER #
  14. # VERSION. TO FIND THE FULL TEXT OF THE LICENSE GO TO THE GNU.ORG #
  15. # WEBSITE AT ( https://www.gnu.org/licenses/gpl-3.0.html ). #
  16. # #
  17. # THE LBRY SDK IS UNFORTUNATELY UNDER THE MIT LICENSE. IF YOU ARE #
  18. # NOT INTENDING TO USE MY CODE AND JUST THE SDK. YOU CAN FIND IT ON #
  19. # THEIR OFFICIAL REPOSITORY ABOVE. THEIR LICENSE CHOICE DOES NOT #
  20. # SPREAD ONTO THIS PROJECT. DON'T GET A FALSE ASSUMPTION THAT SINCE #
  21. # THEY USE A PUSH-OVER LICENSE, I GONNA DO THE SAME. I'M NOT. #
  22. # #
  23. # THE LICENSE CHOSEN FOR THIS PROJECT WILL PROTECT THE 4 ESSENTIAL #
  24. # FREEDOMS OF THE USER FURTHER, BY NOT ALLOWING ANY WHO TO CHANGE #
  25. # THE LICENSE AT WILL. SO NO PROPRIETARY SOFTWARE DEVELOPER COULD #
  26. # TAKE THIS CODE AND MAKE THEIR USER-SUBJUGATING SOFTWARE FROM IT. #
  27. # #
  28. #####################################################################
  29. # This file with handle various analytics. Currently in LBRY Desktop
  30. # or Odysee.com, the analytics are very basic, while they have a very
  31. # rich SDK that allows to get all kinds of information about transactions.
  32. # This transaction data is useful to get various Analytics.
  33. from subprocess import *
  34. import json
  35. import time
  36. from flbry import url
  37. from flbry import settings
  38. from flbry import markdown
  39. from flbry import channel
  40. from flbry.variables import *
  41. def graph(data=[]):
  42. # This function will draw a graph. I wanted originally to make it a
  43. # part of variables.py, but I'm afraid it will be a huge function.
  44. # And it makes a lot of sense to put it here (in Analytics).
  45. # Concept art:
  46. # 2021-11-15 --------------------------------------> 2021-12-30
  47. #
  48. # #
  49. # #
  50. # # # # # #
  51. # # ### # ## # # # # #
  52. # # ## ###### # ####### # ## ### ## # #
  53. # # # ### ########### ### # ######### ### ##### ### ####
  54. # #################################################### ###########
  55. # ################################################################
  56. if not data:
  57. center("No Data!", "bdrd")
  58. return
  59. if len(data) == 1:
  60. center("Only one entry! Cannot draw graph!", "bdrd")
  61. return
  62. w, h = tsize()
  63. height = h - 5
  64. width = w - 16
  65. times = []
  66. values = []
  67. for i in data:
  68. times.append(i["timestamp"])
  69. try:
  70. values.append(float(i["amount"]))
  71. except:
  72. values.append(0)
  73. #for i in times:
  74. # print(i)
  75. # Finding times
  76. import time
  77. startdate = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime( min(times)) )
  78. enddate = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime( max(times)))
  79. center(startdate+" "+("-"*(width-(len(startdate)+len(enddate))-6))+"> "+enddate)
  80. ctimes = []
  81. for i in times:
  82. ctimes.append(i-min(times))
  83. # LET'S START DRAWING
  84. p = []
  85. for i in ctimes:
  86. pix = round((width-1)/max(ctimes)*i)
  87. p.append(pix)
  88. ap = []
  89. for i in range(width):
  90. count = 0
  91. for n, d in enumerate(p):
  92. if d == i:
  93. count = count + values[n]
  94. ap.append(count)
  95. choice = " ░▒▓█"
  96. if settings.get("graph_force_ASCII"):
  97. choice = " .~8#"
  98. for i in reversed(range(height)):
  99. va = max(ap) * ((i+1)/(height-1))
  100. s = clr["bdma"]+" "+wdth(va, 5)+" "
  101. for b in ap:
  102. x = ((height-1)/max(ap)*b)
  103. c = max(min(round((x - i)*4), 4), 0)
  104. y = choice[c]
  105. s = s + clr["bdbu"]+clr["tdcy"]+y
  106. print(" "+s+clr["bdma"]+" "+clr["norm"])
  107. center(" ")
  108. def sales(mode="sales"):
  109. # This function will show sales of non-gratis publications.
  110. # First let's get the list of our channels
  111. out = check_output([lbrynet_binary["b"],
  112. "channel", "list"])
  113. try:
  114. out = json.loads(out)
  115. except:
  116. center("Connect to LBRY first.")
  117. return
  118. channels = []
  119. for i in out["items"]:
  120. channels.append(i["claim_id"])
  121. page = 1
  122. cached = 0 # Page that was loaded last
  123. while True:
  124. w, h = tsize()
  125. page_size = h - 5
  126. command = [lbrynet_binary["b"],
  127. "claim", "search",
  128. "--remove_duplicates",
  129. '--order_by=release_time',
  130. '--page='+str(page),
  131. '--page_size='+str(page_size)]
  132. if mode == "sales":
  133. command.append('--fee_amount=>0')
  134. for i in channels:
  135. command.append("--channel_ids="+i)
  136. if page != cached:
  137. list_of_publications = check_output(command)
  138. try:
  139. list_of_publications = json.loads(list_of_publications)
  140. except:
  141. center("Connect to LBRY first.")
  142. return
  143. if mode == "sales":
  144. data_print = {"categories":["Publication", "Price", "Sold Copies"],
  145. "size":[5,1,1],
  146. "data":[]}
  147. else:
  148. data_print = {"categories":["Publication", "Supported Times"],
  149. "size":[5,2],
  150. "data":[]}
  151. print()
  152. for n, i in enumerate(list_of_publications["items"]):
  153. name = i["name"]
  154. try:
  155. name = i["value"]["title"]
  156. except:
  157. pass
  158. #print( name )
  159. price = 0
  160. try:
  161. price = i["value"]["fee"]["amount"]
  162. except:
  163. pass
  164. #print(price)
  165. progress_bar(n+1, len(list_of_publications["items"]), "Fetching: "+name)
  166. # Now lets get the amount of entries in txo
  167. command = [lbrynet_binary["b"],
  168. "txo", "list",
  169. "--claim_id="+i["claim_id"],
  170. "--page_size=1"]
  171. if mode == "sales":
  172. command.append("--type=purchase")
  173. txo = check_output(command)
  174. try:
  175. txo = json.loads(txo)
  176. except:
  177. center("Connect to LBRY first.")
  178. return
  179. sold = 0
  180. try:
  181. sold = txo["total_items"]
  182. except:
  183. pass
  184. #print(sold)
  185. if mode == "sales":
  186. data_print["data"].append([name, price, sold])
  187. else:
  188. data_print["data"].append([name, sold])
  189. print()
  190. table(data_print)
  191. cached = page
  192. center("---type 'more' to load more---")
  193. # Now the 'more' and such.
  194. c = input(typing_dots())
  195. if not c:
  196. break
  197. # TODO: Please test that this even works.
  198. if c == "more":
  199. page = page + 1
  200. else:
  201. try:
  202. c = int(c)
  203. total = data_print["data"][c][-1]
  204. i = list_of_publications["items"][c]
  205. cpage = 1
  206. items = []
  207. while total > 0:
  208. command = [lbrynet_binary["b"],
  209. "txo", "list",
  210. "--claim_id="+i["claim_id"],
  211. "--page_size=50",
  212. "--page="+str(cpage)]
  213. if mode == "sales":
  214. command.append("--type=purchase")
  215. txo = check_output(command)
  216. try:
  217. txo = json.loads(txo)
  218. except:
  219. center("Connect to LBRY first.")
  220. return
  221. cpage = cpage + 1
  222. for i in txo["items"]:
  223. items.append(i)
  224. total = total - 50
  225. graph(items)
  226. input()
  227. print()
  228. except:
  229. pass