variables.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  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 is a set of variables used by different files. It's needed
  30. # so I will not need to hard code the values each time. Stuff like
  31. # basic translations of the LBRY data into human language. And a more
  32. # complex functions like translating size in bytes into something more
  33. # readable.
  34. import os
  35. import json
  36. import inspect
  37. # Colors are used to make the
  38. clr = {
  39. "norm":"\033[00m", # Reset to normal
  40. "bold":"\033[01m", # Bold Text
  41. "ital":"\033[03m", # Italic Text
  42. "undr":"\033[04m", # Underlined
  43. "blnk":"\033[05m", # Blinking
  44. # Text
  45. "tdbl":"\033[30m", # Dark Black
  46. "tdrd":"\033[31m", # Dark Red
  47. "tdgr":"\033[32m", # Dark Green
  48. "tdyl":"\033[33m", # Dark Yellow
  49. "tdbu":"\033[34m", # Dark Blue
  50. "tdma":"\033[35m", # Dark Magenta
  51. "tdcy":"\033[36m", # Dark Cyan
  52. "tdwh":"\033[37m", # Dark White
  53. "tbbl":"\033[90m", # Bright Black
  54. "tbrd":"\033[91m", # Bright Red
  55. "tbgr":"\033[92m", # Bright Green
  56. "tbyl":"\033[93m", # Bright Yellow
  57. "tbbu":"\033[94m", # Bright Blue
  58. "tbma":"\033[95m", # Bright Magenta
  59. "tbcy":"\033[96m", # Bright Cyan
  60. "tbwh":"\033[97m", # Bright White
  61. # Background
  62. "bdbl":"\033[40m", # Dark Black
  63. "bdrd":"\033[41m", # Dark Red
  64. "bdgr":"\033[42m", # Dark Green
  65. "bdyl":"\033[43m", # Dark Yellow
  66. "bdbu":"\033[44m", # Dark Blue
  67. "bdma":"\033[45m", # Dark Magenta
  68. "bdcy":"\033[46m", # Dark Cyan
  69. "bdwh":"\033[47m", # Dark White
  70. "bbbl":"\033[100m", # Bright Black
  71. "bbrd":"\033[101m", # Bright Red
  72. "bbgr":"\033[102m", # Bright Green
  73. "bbyl":"\033[103m", # Bright Yellow
  74. "bbbu":"\033[104m", # Bright Blue
  75. "bbma":"\033[105m", # Bright Magenta
  76. "bbcy":"\033[106m", # Bright Cyan
  77. "bbwh":"\033[108m" # Bright White
  78. }
  79. # A function that turns emogi into emocons
  80. def emote(text, ASCII=True):
  81. # TODO: Add more emogis to the lists.
  82. # Odysee.com just added a bunch of weird ass
  83. # stickers with codes for each one. They need
  84. # to work in FastLBRY.
  85. emojis = {
  86. ":smile:" :"โ˜บ๏ธ",
  87. ":grin:" :"๐Ÿ˜ƒ",
  88. ":frowning_face:" :"โ˜น๏ธ",
  89. ":sob:" :"๐Ÿ˜ญ",
  90. ":open_mouth:" :"๐Ÿ˜ฎ",
  91. ":kissing:" :"๐Ÿ˜—",
  92. ":wink:" :"๐Ÿ˜‰",
  93. ":stuck_out_tongue:":"๐Ÿ˜›",
  94. ":confused:" :"๐Ÿ˜•",
  95. ":neutral_face:" :"๐Ÿ˜",
  96. ":expressionless:" :"๐Ÿ˜‘",
  97. }
  98. emocons = {
  99. "โ˜บ๏ธ":":)",
  100. "๐Ÿ˜ƒ":":D",
  101. "โ˜น๏ธ":":(",
  102. "๐Ÿ˜ญ":":,(",
  103. "๐Ÿ˜ฎ":":o",
  104. "๐Ÿ˜—":":*",
  105. "๐Ÿ˜‰":";)",
  106. "๐Ÿ˜›":":p",
  107. "๐Ÿ˜•":":/",
  108. "๐Ÿ˜":":|",
  109. "๐Ÿ˜‘":"(-_-)"
  110. }
  111. # The actual function lol
  112. for i in emojis:
  113. text = text.replace(i, emojis[i])
  114. if ASCII:
  115. for i in emocons:
  116. text = text.replace(i, emocons[i])
  117. return text
  118. # A function that insures a specific width of the printed part
  119. def wdth(x, n):
  120. # Convert Data to String
  121. mode = "normal"
  122. if type(x) == bool and x == True:
  123. x = "V"
  124. mode = "bdgr"
  125. elif type(x) == bool and x == False:
  126. x = "X"
  127. mode = "bdrd"
  128. else:
  129. x = str(x)
  130. # Turn emogis
  131. x = emote(x)
  132. # Some characters are too wide. They do not obey the
  133. # monospace of the terminal, thus making it not pretty.
  134. # This is the string of characters which are checked to
  135. good = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'โ€™()*+,-./:;<=>?@[\]^_`{|}~ ะนั†ัƒะบะตะฝะณัˆั‰ะทั…ัŠั„ั‹ะฒะฐะฟั€ะพะปะดะถััั‡ัะผะธั‚ัŒะฑัŽะ™ะฆะฃะšะ•ะะ“ะจะฉะ—ะฅะชะคะซะ’ะะŸะ ะžะ›ะ”ะ–ะญะฏะงะกะœะ˜ะขะฌะ‘ะฎั‘ะ"
  136. # let's filter the string
  137. y = x
  138. from flbry import settings
  139. if not settings.get("ignore_width_forcing"):
  140. x = ""
  141. for i in y:
  142. if i in good:
  143. x = x + i
  144. else:
  145. x = x + "โ–“"
  146. # Now let's print what we've got.
  147. if len(y) < n:
  148. fac = n-len(y)
  149. fac1 = int(round(fac/2))
  150. fac2 = fac1
  151. while fac1 + fac2 > fac:
  152. fac2 -=1
  153. while fac1 + fac2 < fac:
  154. fac2 +=1
  155. x = (" "*fac1)+x+(" "*fac2)
  156. elif len(y) > n:
  157. if n > 10:
  158. x = x[:n-3]+"..."
  159. else:
  160. x = x[:n]
  161. if mode == "normal":
  162. return x
  163. else:
  164. return clr[mode]+clr["bold"]+x+clr["norm"]
  165. # A dictionary for translations of things from the SDK into
  166. # readable thing
  167. what = {
  168. "stream":"FILE",
  169. "repost":"SHARED",
  170. "channel": "CHANNEL",
  171. "collection": "PLAYLIST",
  172. "video":"VIDEO",
  173. "audio":"SOUND",
  174. "document":"TEXT",
  175. "binary":"FILE",
  176. "image":"PICTURE"
  177. }
  178. # This function will take a list and present in a pretty
  179. # way.
  180. def tgz(x):
  181. # Just in case
  182. if type(x) != list:
  183. x = x.split()
  184. y = ""
  185. for i in x:
  186. y = y + i + ", "
  187. return y[:-2]
  188. # This function will convert bites into readable data making sense
  189. def csize(x):
  190. x = float(x)
  191. l = ["B","KB", "MB", "GB", "TB"]
  192. for i in range(5):
  193. if x > 1024:
  194. x = x / 1024
  195. else:
  196. return str(round(x, 2))+" "+l[i]
  197. return str(round(x, 2))+" "+l[i]
  198. # This next function will select the amount of ::: for a given
  199. # input.
  200. def typing_dots(text="", to_text=True, to_add_dots=False, give_space=False):
  201. depth = len(inspect.stack()) # This is the depth of the stack
  202. # since this function call adds 1 to the stack we need
  203. # to decrease the number by one
  204. depth -= 1
  205. if not text or not to_add_dots:
  206. depth -= 1
  207. # Now I want to select a sequence of colors.
  208. x = ["bdma","bdbu", "bdrd", "bdgr", "bdcy", "bdyl"]
  209. ret = " "+clr["bold"]
  210. for i in reversed(range(depth)):
  211. ret = ret + clr["tbwh"] + clr[x[i % len(x)]] + ":"
  212. ret = ret + clr["norm"]+" "
  213. w, h = tsize()
  214. if text and to_text:
  215. side_string = clr["tbwh"]+" < "+text+" "
  216. put_at = w-len(side_string)-1
  217. if not give_space:
  218. put_at = int(w/2)-int(len(side_string)/2)
  219. print(wdth("", put_at)+clr["bdma"]+clr["bold"]+side_string+clr["norm"], end="")
  220. ret = "\r"+ret
  221. return ret
  222. def tsize():
  223. # This funtion will get the size of the terminal and
  224. # return it to the variables provided width, height
  225. # On some systems this may not work. So there is a
  226. # try function.
  227. try:
  228. # Getting the size of the terminal
  229. import os
  230. w, h = os.get_terminal_size()
  231. # Sometimes when the terminal width is either
  232. # even or odd. It breaks code for some other
  233. # thing written differenly. For example:
  234. # You may have an even width ( like 84 ) when
  235. # writing a function. And then it works on different
  236. # widths as well like 62 and 80 and 48. All of them
  237. # are still even. Then you scale the terminal to be
  238. # something off like 63 and the function breaks. You
  239. # have one character too much or one character too little.
  240. # This is why I do not want to have a difference. And
  241. # force width to be one less, if it's not divisible by 2.
  242. if not w % 2:
  243. w = w - 1
  244. return w, h
  245. except:
  246. # If, by any reason the terminal can't get it's size.
  247. # We want to return some size regardless.
  248. w = 60
  249. h = 20
  250. return w, h
  251. def logo():
  252. # This function will draw a pretty FastLBRY logo to the user
  253. # at startup.
  254. # Getting terminal size
  255. w, h = tsize()
  256. if w > 50:
  257. l = []
  258. l.append( "โ–ˆโ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–“โ–“โ–ˆโ–“โ–ˆโ–ˆโ–“โ–“โ–“โ–“โ–“โ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–ˆโ–ˆโ–“โ–“โ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–ˆ" )
  259. l.append( "โ–“โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–“โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–“โ–“โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–“โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–“โ–’โ–’โ–’โ–’โ–“โ–’โ–“" )
  260. l.append( "โ–ˆโ–ˆโ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–“โ–“" )
  261. l.append( "โ–“โ–“โ–‘ โ–‘ โ–‘ โ–‘ โ–  โ– โ–‘โ–‘โ–’โ–“" )
  262. l.append( "โ–“โ–’โ–’ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ–  โ–‘ โ•”โ•โ•โ•โ•โ•— โ•”โ•โ•โ•โ•โ•— โ•‘ โ–‘ โ•‘ โ–‘โ–“โ–ˆ" )
  263. l.append( "โ–“โ–’โ–‘ โ•‘ โ–‘ โ•‘ โ•‘ โ•‘ โ•‘ โ•‘ โ•‘ โ•‘ โ–‘โ–’โ–“" )
  264. l.append( "โ–ˆโ–“โ–‘โ–‘โ•‘ โ•‘ โ• โ•โ•โ•โ•โ•ฃ โ• โ•โ•ฆโ•โ•โ• โ•šโ•โ•โ•ฆโ•โ•โ• โ–’โ–’โ–“" )
  265. l.append( "โ–“โ–’โ–’ โ• โ•โ• AST โ– โ•‘ โ•‘ โ•‘ โ•‘ โ•šโ•โ•โ•— โ•‘ โ–‘โ–‘โ–’โ–ˆ" )
  266. l.append( "โ–ˆโ–’โ–‘ โ•‘ โ•‘ โ•‘ โ•‘ โ•‘ โ•‘ โ•‘ โ–‘โ–“โ–“" )
  267. l.append( "โ–“โ–“โ–‘ โ•‘ โ–‘ โ•šโ•โ•โ•โ•โ•โ– โ•šโ•โ•โ•โ•โ• โ–  โ–  โ–‘ โ•‘ โ–‘ โ–‘โ–’โ–“" )
  268. l.append( "โ–“โ–’โ–‘โ–‘โ•‘ โ–‘ THE TERMINAL CLIENT โ•‘ โ–’โ–’โ–ˆ" )
  269. l.append( "โ–ˆโ–’โ–’ โ–  โ–‘ โ–‘ โ–  โ–’โ–‘ โ–‘โ–“โ–“" )
  270. l.append( "โ–“โ–’โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–“โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–’โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–’โ–ˆ" )
  271. l.append( "โ–“โ–“โ–’โ–’โ–’โ–’โ–“โ–’โ–’โ–’โ–’โ–’โ–“โ–’โ–’โ–’โ–’โ–“โ–’โ–’โ–“โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–“โ–“โ–’โ–’โ–’โ–’โ–’โ–’โ–“โ–’โ–’โ–’โ–’โ–’โ–“โ–“โ–“" )
  272. l.append( "โ–ˆโ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–“โ–ˆโ–ˆโ–ˆโ–ˆโ–“โ–“โ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–ˆโ–ˆโ–“โ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–“โ–ˆโ–“โ–“โ–“โ–“โ–ˆโ–ˆ" )
  273. print(" "+clr["bdma"]+(" "*(w-8))+clr["norm"])
  274. # I want to fill the width of the terminal around the logo
  275. # with a texture. But since it's text based I will need to
  276. # code a texture into it. I can use the blocks seen below
  277. # and select randomly between them.
  278. # You can see I included multiple of darkest block and
  279. # almost non bright blocks. This will increase the
  280. # probability of the dark blocks.
  281. block = "โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–“โ–“โ–“โ–’" #for the random to choose
  282. import random
  283. # Now let's output
  284. for i in l:
  285. f = "" # Texture fill string.
  286. # Fill the f string with random blocks
  287. for g in range(int(w/2-27)):
  288. f = f + random.choice(block)
  289. # Print a line with random filler and the line it self.
  290. print (" "+clr["bdma"]+" "+clr["norm"]+f+i+f+clr["bdma"]+" "+clr["norm"])
  291. else:
  292. center( "FastLBRY")
  293. center( "terminal")
  294. center("")
  295. print()
  296. def table(data, number=True):
  297. # This function will present data in a pretty table thing.
  298. # So let's first of all get the size of the terminal
  299. w, h = tsize()
  300. if number:
  301. w = w - 4
  302. # Then let's draw the categories for this we need to extract
  303. # it's sizes. If there is no 'size' variable the sizes of
  304. # each category will be spread equally.
  305. size = [] # Here the size will go as pure character value.
  306. if "size" in data:
  307. for i in data["size"]:
  308. size.append(int(( w - 10 ) / sum(data["size"]) * i))
  309. while sum(size) < w - 10:
  310. size[-1] += 1
  311. # printing categories
  312. nb = ""
  313. if number:
  314. nb = " "
  315. s = " "+clr["bdma"]+" "+clr["tbwh"]+nb
  316. for n, item in enumerate(data["categories"]):
  317. s = s + wdth(item.upper(), size[n])
  318. print(s+clr["bdma"]+" "+clr["norm"])
  319. size[-1] += 1
  320. # printing items
  321. for b, i in enumerate(data["data"]):
  322. # dark bright sequence thingy
  323. if b % 2:
  324. d = "b"
  325. else:
  326. d = "d"
  327. nb = ""
  328. if number:
  329. nb = clr["tbwh"]+wdth(b,4)
  330. s = " "+clr["bdma"]+" "+nb+clr["norm"]+clr["b"+d+"bu"]#+clr["tbwh"]
  331. for n, item in enumerate(i):
  332. s = s +clr["b"+d+"bu"]+ clr["tbwh"]+wdth(item, size[n]-1)+clr["bdma"]+" "
  333. print(s+clr["norm"])
  334. def center(line, c="bdma", blink=False):
  335. # This funtiocn will bring a given string of text
  336. # in the center of the terminal with a nice backgroud
  337. # around it.
  338. w, h = tsize()
  339. if blink:
  340. blink = clr["blnk"]
  341. else:
  342. blink = ""
  343. if len(line) % 2:
  344. line = line + " "
  345. if len(line) < w - 11:
  346. print(" "+clr[c],
  347. wdth(" ", int((w-10)/2 - (len(line)/2))),
  348. clr["bold"]+clr["tbwh"]+blink+line,
  349. wdth(" ", int((w-10)/2 - (len(line)/2))-1),
  350. clr["norm"])
  351. else:
  352. print(" "+clr[c],
  353. clr["bold"]+clr["tbwh"]+blink+wdth(line,w-10),
  354. clr["norm"])
  355. def timestring(tleft):
  356. # This crazy function will convert the microsecond into something
  357. # a bit more usefull. Like 03:20:90.06 Kind a thing.
  358. tleftX = tleft
  359. tleft = int(tleftX)
  360. addend = tleftX - tleft
  361. valt = str(tleft)
  362. if tleft > 60 :
  363. le = tleft
  364. tleft = int(tleft / 60)
  365. le = le - int(tleft * 60)
  366. stleft = "0"*(2-len(str(tleft)))+str(tleft)
  367. sle = "0"*(2-len(str(le)))+str(le)
  368. valt = stleft+":"+ sle
  369. if tleft > 60 :
  370. lele = le
  371. le = tleft
  372. tleft = int(tleft / 60)
  373. le = le - int(tleft * 60)
  374. lele = (lele - le)
  375. if lele < 0:
  376. lele = int(lele * -1)
  377. stleft = "0"*(2-len(str(tleft)))+str(tleft)
  378. sle = "0"*(2-len(str(le)))+str(le)
  379. slele = "0"*(2-len(str(lele)))+str(lele)
  380. valt = stleft+":"+ sle + ":" + slele
  381. if tleft > 24 :
  382. le = tleft
  383. tleft = int(tleft / 24)
  384. le = le - int(tleft * 24)
  385. valt = str(tleft)+" DAYS AND "+ str(le) + " HRS"
  386. return valt + "." + str(int(addend*100))
  387. # This a list of known licenses, info a and links
  388. licenses = [
  389. # NAME , URL , COMMENT
  390. ["GNU General Public License Version 3 (or later)",
  391. "https://www.gnu.org/licenses/gpl-3.0.html",
  392. "Strong Copyleft. Recommended for Software."],
  393. ["GNU General Public License Version 3 (only)",
  394. "https://www.gnu.org/licenses/gpl-3.0.html",
  395. "Strong Copyleft."],
  396. ["GNU Free Documentation License",
  397. "https://www.gnu.org/licenses/fdl-1.3.html",
  398. "Strong Copyleft. Recommended for books."],
  399. ["Creative Commons Attribution-ShareAlike 4.0 International",
  400. "https://creativecommons.org/licenses/by-sa/4.0/",
  401. "Copylefted, Recommended for Art."],
  402. ["Creative Commons Attribution 4.0 International",
  403. "https://creativecommons.org/licenses/by/4.0/",
  404. "Non Copylefted, Free License."],
  405. ["Creative Commons Zero 1.0 International",
  406. "https://creativecommons.org/publicdomain/zero/1.0/",
  407. "Public Domain"],
  408. ["Creative Commons Attribution-NoDerivatives 4.0 International",
  409. "https://creativecommons.org/licenses/by-nd/4.0/",
  410. "Does not allow changes. Recommended for opinion pieces."]
  411. ]
  412. def progress_bar(now, total, name=""):
  413. # This function will draw a pretty progress bar that fills up
  414. # one problem. It requires an empty print line after it. Or it
  415. # will start printing whatever in the same line as the progress
  416. # bar.
  417. # dimensions
  418. w, h = tsize()
  419. fullw = w - 8
  420. # string
  421. string = " "+str(int(round(now/total*100)))+"% "+str(now)+" / "+str(total)+" "+name
  422. #string = string+" "*(fullw-len(string))
  423. string = wdth(string, fullw)
  424. howfar = int(round(fullw / total * now))
  425. pstring = clr["tbwh"]+clr["bold"]+clr["bdcy"]+string[:howfar]+clr["bdma"]+string[howfar:]
  426. print("\r "+pstring, end=clr["norm"])
  427. # We need a system of auto-filling commands. As well as a history type thing.
  428. # so people could come back to a previous command by pressing the up arrow.
  429. # Now all systems will have readline since it's a GNU package
  430. complete_commands = []
  431. def complete(commands, add=False):
  432. # This will make sure that we can add commands to
  433. # the completer after it's set.
  434. global complete_commands
  435. if not add:
  436. complete_commands = commands
  437. else:
  438. for i in commands:
  439. complete_commands.append(i)
  440. commands = complete_commands
  441. try:
  442. import readline
  443. # Then we need to specify a function for completion
  444. def completer(text, state):
  445. options = [i for i in commands if i.startswith(text)]
  446. if state < len(options):
  447. return options[state]
  448. else:
  449. return None
  450. # And we need to setup the completer
  451. readline.parse_and_bind("tab: complete")
  452. readline.set_completer(completer)
  453. except Exception as e:
  454. center("Auto-completer error: "+str(e), "bdrd")
  455. def print_web_instance(url):
  456. from flbry import settings
  457. web_instances = [
  458. # NAME URL MAINTAINER INTERFACE
  459. ["Odysee", "https://odysee.com/", "LBRY Inc.", "JavaScript"],
  460. ["Madiator", "https://madiator.com/", "Madiator2011", "JavaScript"],
  461. ["Spee.ch", "https://spee.ch/", "LBRY Inc.", "Direct Files"]
  462. ]
  463. # If the "librarian_instance" setting is set, use that as the URL
  464. librarian_instance = ["Librarian", "https://librarian.bcow.xyz/", "imabritishcow", "Invidous-like web interface"]
  465. libinstance = settings.get("librarian_instance")
  466. if libinstance:
  467. librarian_instance[1] = libinstance
  468. librarian_instance[2] = "Depends on instance"
  469. web_instances.append(librarian_instance)
  470. d = {"categories":["Name", "URL", "Maintainer", "Interface"],
  471. "size":[1,2,1,1],
  472. "data":web_instances}
  473. table(d)
  474. center("")
  475. # Choose an instance
  476. which = input(typing_dots())
  477. # Some web clients don't work with '#' in the URL
  478. web = url.replace("#", ":")
  479. try:
  480. center(web.replace("lbry://", web_instances[int(which)][1]))
  481. except:
  482. center(web.replace("lbry://", web_instances[0][1]))
  483. def file_or_editor(args, comment, editor=None):
  484. # We gonna check if the user added anything after the command
  485. # reply emacs
  486. # reply gedit
  487. # reply vim
  488. # Or something like
  489. # reply /home/username/filename.txt
  490. # reply /home/username/filename.md
  491. # That might be useful to input multiline text.
  492. import subprocess
  493. import os
  494. if editor:
  495. a = editor
  496. else:
  497. a = args
  498. a = os.path.expanduser(a)
  499. try:
  500. text = open(a, "r")
  501. text = text.read()
  502. except:
  503. a = a.split()
  504. text = open("/tmp/fastlbrycommentwriter.txt", "w")
  505. text.write(comment)
  506. text.close()
  507. subprocess.run([*a, "/tmp/fastlbrycommentwriter.txt"])
  508. center("Press Enter when the file is ready and saved.")
  509. input()
  510. text = open("/tmp/fastlbrycommentwriter.txt", "r")
  511. text = text.read()
  512. return text.rstrip()
  513. def get_cn(c, prompt=""):
  514. # This gets a number from a command
  515. if " " in c:
  516. try:
  517. cn = int(c[c.find(" ")+1:])
  518. except:
  519. return 0
  520. else:
  521. cn = input(typing_dots(prompt))
  522. try:
  523. cn = int(cn)
  524. except:
  525. return 0
  526. return cn
  527. def choose_license():
  528. lsnzs = []
  529. for i in licenses:
  530. lsnzs.append([i[0],i[2]])
  531. d = {"categories":["Name","Comment"],
  532. "size":[1,1],
  533. "data":lsnzs}
  534. table(d)
  535. center("---choose a license or press enter for custom---")
  536. lc = input(typing_dots())
  537. try:
  538. lselect = licenses[int(lc)]
  539. lname = lselect[0]
  540. llink = lselect[1]
  541. except:
  542. lname = input(typing_dots("License Name", give_space=True, to_add_dots=True))
  543. llink = input(typing_dots("License Link", give_space=True, to_add_dots=True))
  544. return lname, llink
  545. def spdx_license(identifier):
  546. """Takes a string and returns the name and url of the license if it is in the SPDX license list, else it returns the identifier"""
  547. with open("flbry/licenses.json") as f:
  548. licenses = json.load(f)
  549. licenses = licenses["licenses"]
  550. for i, l in enumerate(licenses):
  551. if l["licenseId"] == identifier:
  552. lname = l["name"]
  553. llink = l["seeAlso"][0]
  554. # Warn the user if the license identifier is nonfree or not FSF libre
  555. if not "isFsfLibre" in l:
  556. if not l["isOsiApproved"]:
  557. center("License is not free or open source", "bdrd")
  558. else:
  559. center("License is OSI-approved but is not considered free by the FSF")
  560. return {"name": lname, "link": llink}
  561. return {"name": identifier}
  562. flbry_globals = {
  563. "lbrynet": "flbry/lbrynet",
  564. "comment_api": "https://comments.odysee.com/api/v2",
  565. }
  566. def try_getting_git_commit():
  567. import subprocess
  568. try:
  569. ghash = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().rstrip()
  570. center("Git commit hash: "+ghash)
  571. except Exception as e:
  572. # Git isn't installed
  573. center("Error getting commit hash: "+str(e), "bdrd")
  574. pass
  575. def ruler_sideways(width, offset=0):
  576. w, h = tsize() # For reference, the 'width' value will be
  577. # The actual width of the ruler. 'w' is used
  578. # For rendering.
  579. # This one prints a sideways ruler giving each next column
  580. # a line number, skiping one space between the numbers like:
  581. # 0 2 4 6 8 10 13 16 19 21
  582. # First raw of the printout will be a simple rythmic pattern
  583. # similar to : |---------|---------|--------|--------|---------|
  584. pattern = " "+clr["bdma"]+(" "*offset)+" "+clr["tbwh"]
  585. for i in range(width+1):
  586. a = " "
  587. if i % 10 == 0:
  588. a = "โ–’"
  589. elif i % 2 == 0:
  590. a = "โ–‘"
  591. pattern = pattern + a
  592. print(pattern+" "+clr["norm"])
  593. ret = " "*offset
  594. skipto = 0
  595. for i in range(width):
  596. if i == skipto:
  597. ret = ret + str(i) + " "
  598. skipto = i + len(str(i)) + 1
  599. ret = wdth(ret,w-10-len(str(width))-1)
  600. ret = ret + " " + str(width)
  601. print(" "+clr["bdma"],
  602. clr["bold"]+clr["tbwh"]+ret,
  603. clr["norm"])