variables.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  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. if not text or not to_add_dots:
  205. depth -= 1
  206. # Now I want to select a sequence of colors.
  207. x = ["bdma","bdbu", "bdrd", "bdgr", "bdcy", "bdyl"]
  208. ret = " "+clr["bold"]
  209. for i in reversed(range(depth)):
  210. ret = ret + clr["tbwh"] + clr[x[i % len(x)]] + ":"
  211. ret = ret + clr["norm"]+" "
  212. w, h = tsize()
  213. if text and to_text:
  214. side_string = " < "+text+" "
  215. put_at = w-len(side_string)-1
  216. if not give_space:
  217. put_at = int(w/2)-int(len(side_string)/2)
  218. print(wdth("", put_at)+clr["bdma"]+clr["bold"]+side_string+clr["norm"], end="")
  219. ret = "\r"+ret
  220. return ret
  221. def tsize():
  222. # This funtion will get the size of the terminal and
  223. # return it to the variables provided width, height
  224. # On some systems this may not work. So there is a
  225. # try function.
  226. try:
  227. # Getting the size of the terminal
  228. import os
  229. w, h = os.get_terminal_size()
  230. # Sometimes when the terminal width is either
  231. # even or odd. It breaks code for some other
  232. # thing written differenly. For example:
  233. # You may have an even width ( like 84 ) when
  234. # writing a function. And then it works on different
  235. # widths as well like 62 and 80 and 48. All of them
  236. # are still even. Then you scale the terminal to be
  237. # something off like 63 and the function breaks. You
  238. # have one character too much or one character too little.
  239. # This is why I do not want to have a difference. And
  240. # force width to be one less, if it's not divisible by 2.
  241. if not w % 2:
  242. w = w - 1
  243. return w, h
  244. except:
  245. # If, by any reason the terminal can't get it's size.
  246. # We want to return some size regardless.
  247. w = 60
  248. h = 20
  249. return w, h
  250. def logo():
  251. # This function will draw a pretty FastLBRY logo to the user
  252. # at startup.
  253. # Getting terminal size
  254. w, h = tsize()
  255. if w > 50:
  256. l = []
  257. l.append( "█▓▓█▓▓▓▓▓▓█▓██▓▓▓▓▓▓▓█▓▓▓▓▓▓█▓▓▓▓██▓▓▓▓█▓▓▓▓█" )
  258. l.append( "▓▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▓▒▒▒▒▓▒▓" )
  259. l.append( "██░░░▒░░░░░░▒░░░░░░░▒░░░░░░░░░▒░░▒░░░░░░░░▒▓▓" )
  260. l.append( "▓▓░ ░ ░ ░ ■ ■░░▒▓" )
  261. l.append( "▓▒▒ ╔════════■ ░ ╔════╗ ╔════╗ ║ ░ ║ ░▓█" )
  262. l.append( "▓▒░ ║ ░ ║ ║ ║ ║ ║ ║ ║ ░▒▓" )
  263. l.append( "█▓░░║ ║ ╠════╣ ╠═╦══╝ ╚══╦══╝ ▒▒▓" )
  264. l.append( "▓▒▒ ╠══ AST ■║ ║ ║ ║ ╚══╗ ║ ░░▒█" )
  265. l.append( "█▒░ ║ ║ ║ ║ ║ ║ ║ ░▓▓" )
  266. l.append( "▓▓░ ║ ░ ╚═════■╚════╝ ■ ■ ░ ║ ░ ░▒▓" )
  267. l.append( "▓▒░░║ ░ THE TERMINAL CLIENT ║ ▒▒█" )
  268. l.append( "█▒▒ ■ ░ ░ ■ ▒░ ░▓▓" )
  269. l.append( "▓▒░░░░░░░▒░░░░▓░░░░░▒░░░░░░░░░▒░░░░▒░░░░░░░▒█" )
  270. l.append( "▓▓▒▒▒▒▓▒▒▒▒▒▓▒▒▒▒▓▒▒▓▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▓▒▒▒▒▒▓▓▓" )
  271. l.append( "█▓▓█▓▓▓▓▓████▓▓▓▓█▓▓▓▓█▓▓▓▓██▓▓▓█▓▓▓▓▓█▓▓▓▓██" )
  272. print(" "+clr["bdma"]+(" "*(w-8))+clr["norm"])
  273. # I want to fill the width of the terminal around the logo
  274. # with a texture. But since it's text based I will need to
  275. # code a texture into it. I can use the blocks seen below
  276. # and select randomly between them.
  277. # You can see I included multiple of darkest block and
  278. # almost non bright blocks. This will increase the
  279. # probability of the dark blocks.
  280. block = "████████▓▓▓▒" #for the random to choose
  281. import random
  282. # Now let's output
  283. for i in l:
  284. f = "" # Texture fill string.
  285. # Fill the f string with random blocks
  286. for g in range(int(w/2-27)):
  287. f = f + random.choice(block)
  288. # Print a line with random filler and the line it self.
  289. print (" "+clr["bdma"]+" "+clr["norm"]+f+i+f+clr["bdma"]+" "+clr["norm"])
  290. else:
  291. center( "FastLBRY")
  292. center( "terminal")
  293. center("")
  294. print()
  295. def table(data, number=True):
  296. # This function will present data in a pretty table thing.
  297. # So let's first of all get the size of the terminal
  298. w, h = tsize()
  299. if number:
  300. w = w - 4
  301. # Then let's draw the categories for this we need to extract
  302. # it's sizes. If there is no 'size' variable the sizes of
  303. # each category will be spread equally.
  304. size = [] # Here the size will go as pure character value.
  305. if "size" in data:
  306. for i in data["size"]:
  307. size.append(int(( w - 10 ) / sum(data["size"]) * i))
  308. while sum(size) < w - 10:
  309. size[-1] += 1
  310. # printing categories
  311. nb = ""
  312. if number:
  313. nb = " "
  314. s = " "+clr["bdma"]+" "+clr["tbwh"]+nb
  315. for n, item in enumerate(data["categories"]):
  316. s = s + wdth(item.upper(), size[n])
  317. print(s+clr["bdma"]+" "+clr["norm"])
  318. size[-1] += 1
  319. # printing items
  320. for b, i in enumerate(data["data"]):
  321. # dark bright sequence thingy
  322. if b % 2:
  323. d = "b"
  324. else:
  325. d = "d"
  326. nb = ""
  327. if number:
  328. nb = clr["tbwh"]+wdth(b,4)
  329. s = " "+clr["bdma"]+" "+nb+clr["norm"]+clr["b"+d+"bu"]+clr["tbwh"]
  330. for n, item in enumerate(i):
  331. s = s +clr["b"+d+"bu"]+ wdth(item, size[n]-1)+clr["bdma"]+" "
  332. print(s+clr["norm"])
  333. def center(line, c="bdma", blink=False):
  334. # This funtiocn will bring a given string of text
  335. # in the center of the terminal with a nice backgroud
  336. # around it.
  337. w, h = tsize()
  338. if blink:
  339. blink = clr["blnk"]
  340. else:
  341. blink = ""
  342. if len(line) % 2:
  343. line = line + " "
  344. if len(line) < w - 11:
  345. print(" "+clr[c],
  346. wdth(" ", int((w-10)/2 - (len(line)/2))),
  347. clr["bold"]+clr["tbwh"]+blink+line,
  348. wdth(" ", int((w-10)/2 - (len(line)/2))-1),
  349. clr["norm"])
  350. else:
  351. print(" "+clr[c],
  352. clr["bold"]+clr["tbwh"]+blink+wdth(line,w-10),
  353. clr["norm"])
  354. def timestring(tleft):
  355. # This crazy function will convert the microsecond into something
  356. # a bit more usefull. Like 03:20:90.06 Kind a thing.
  357. tleftX = tleft
  358. tleft = int(tleftX)
  359. addend = tleftX - tleft
  360. valt = str(tleft)
  361. if tleft > 60 :
  362. le = tleft
  363. tleft = int(tleft / 60)
  364. le = le - int(tleft * 60)
  365. stleft = "0"*(2-len(str(tleft)))+str(tleft)
  366. sle = "0"*(2-len(str(le)))+str(le)
  367. valt = stleft+":"+ sle
  368. if tleft > 60 :
  369. lele = le
  370. le = tleft
  371. tleft = int(tleft / 60)
  372. le = le - int(tleft * 60)
  373. lele = (lele - le)
  374. if lele < 0:
  375. lele = int(lele * -1)
  376. stleft = "0"*(2-len(str(tleft)))+str(tleft)
  377. sle = "0"*(2-len(str(le)))+str(le)
  378. slele = "0"*(2-len(str(lele)))+str(lele)
  379. valt = stleft+":"+ sle + ":" + slele
  380. if tleft > 24 :
  381. le = tleft
  382. tleft = int(tleft / 24)
  383. le = le - int(tleft * 24)
  384. valt = str(tleft)+" DAYS AND "+ str(le) + " HRS"
  385. return valt + "." + str(int(addend*100))
  386. # This a list of known licenses, info a and links
  387. licenses = [
  388. # NAME , URL , COMMENT
  389. ["GNU General Public License Version 3 (or later)",
  390. "https://www.gnu.org/licenses/gpl-3.0.html",
  391. "Strong Copyleft. Recommended for Software."],
  392. ["GNU General Public License Version 3 (only)",
  393. "https://www.gnu.org/licenses/gpl-3.0.html",
  394. "Strong Copyleft."],
  395. ["GNU Free Documentation License",
  396. "https://www.gnu.org/licenses/fdl-1.3.html",
  397. "Strong Copyleft. Recommended for books."],
  398. ["Creative Commons Attribution-ShareAlike 4.0 International",
  399. "https://creativecommons.org/licenses/by-sa/4.0/",
  400. "Copylefted, Recommended for Art."],
  401. ["Creative Commons Attribution 4.0 International",
  402. "https://creativecommons.org/licenses/by/4.0/",
  403. "Non Copylefted, Free License."],
  404. ["Creative Commons Zero 1.0 International",
  405. "https://creativecommons.org/publicdomain/zero/1.0/",
  406. "Public Domain"],
  407. ["Creative Commons Attribution-NoDerivatives 4.0 International",
  408. "https://creativecommons.org/licenses/by-nd/4.0/",
  409. "Does not allow changes. Recommended for opinion pieces."]
  410. ]
  411. def progress_bar(now, total, name=""):
  412. # This function will draw a pretty progress bar that fills up
  413. # one problem. It requires an empty print line after it. Or it
  414. # will start printing whatever in the same line as the progress
  415. # bar.
  416. # dimensions
  417. w, h = tsize()
  418. fullw = w - 8
  419. # string
  420. string = " "+str(int(round(now/total*100)))+"% "+str(now)+" / "+str(total)+" "+name
  421. #string = string+" "*(fullw-len(string))
  422. string = wdth(string, fullw)
  423. howfar = int(round(fullw / total * now))
  424. pstring = clr["tbwh"]+clr["bold"]+clr["bdcy"]+string[:howfar]+clr["bdma"]+string[howfar:]
  425. print("\r "+pstring, end=clr["norm"])
  426. # We need a system of auto-filling commands. As well as a history type thing.
  427. # so people could come back to a previous command by pressing the up arrow.
  428. # Now all systems will have readline since it's a GNU package
  429. complete_commands = []
  430. def complete(commands, add=False):
  431. # This will make sure that we can add commands to
  432. # the completer after it's set.
  433. global complete_commands
  434. if not add:
  435. complete_commands = commands
  436. else:
  437. for i in commands:
  438. complete_commands.append(i)
  439. commands = complete_commands
  440. try:
  441. import readline
  442. # Then we need to specify a function for completion
  443. def completer(text, state):
  444. options = [i for i in commands if i.startswith(text)]
  445. if state < len(options):
  446. return options[state]
  447. else:
  448. return None
  449. # And we need to setup the completer
  450. readline.parse_and_bind("tab: complete")
  451. readline.set_completer(completer)
  452. except Exception as e:
  453. center("Auto-completer error: "+str(e), "bdrd")
  454. def print_web_instance(url):
  455. from flbry import settings
  456. web_instances = [
  457. # NAME URL MAINTAINER INTERFACE
  458. ["Odysee", "https://odysee.com/", "LBRY Inc.", "JavaScript"],
  459. ["Madiator", "https://madiator.com/", "Madiator2011", "JavaScript"],
  460. ["Spee.ch", "https://spee.ch/", "LBRY Inc.", "Direct Files"]
  461. ]
  462. # If the "librarian_instance" setting is set, use that as the URL
  463. librarian_instance = ["Librarian", "https://librarian.bcow.xyz/", "imabritishcow", "Invidous-like web interface"]
  464. libinstance = settings.get("librarian_instance")
  465. if libinstance:
  466. librarian_instance[1] = libinstance
  467. librarian_instance[2] = "Depends on instance"
  468. web_instances.append(librarian_instance)
  469. d = {"categories":["Name", "URL", "Maintainer", "Interface"],
  470. "size":[1,2,1,1],
  471. "data":web_instances}
  472. table(d)
  473. center("")
  474. # Choose an instance
  475. which = input(typing_dots())
  476. # Some web clients don't work with '#' in the URL
  477. web = url.replace("#", ":")
  478. try:
  479. center(web.replace("lbry://", web_instances[int(which)][1]))
  480. except:
  481. center(web.replace("lbry://", web_instances[0][1]))
  482. def file_or_editor(args, comment, editor=None):
  483. # We gonna check if the user added anything after the command
  484. # reply emacs
  485. # reply gedit
  486. # reply vim
  487. # Or something like
  488. # reply /home/username/filename.txt
  489. # reply /home/username/filename.md
  490. # That might be useful to input multiline text.
  491. import subprocess
  492. import os
  493. if editor:
  494. a = editor
  495. else:
  496. a = args
  497. a = os.path.expanduser(a)
  498. try:
  499. text = open(a, "r")
  500. text = text.read()
  501. except:
  502. a = a.split()
  503. text = open("/tmp/fastlbrycommentwriter.txt", "w")
  504. text.write(comment)
  505. text.close()
  506. subprocess.run([*a, "/tmp/fastlbrycommentwriter.txt"])
  507. center("Press Enter when the file is ready and saved.")
  508. input()
  509. text = open("/tmp/fastlbrycommentwriter.txt", "r")
  510. text = text.read()
  511. return text.rstrip()
  512. def get_cn(c, prompt=""):
  513. # This gets a number from a command
  514. if " " in c:
  515. try:
  516. cn = int(c[c.find(" ")+1:])
  517. except:
  518. return 0
  519. else:
  520. cn = input(typing_dots(prompt))
  521. try:
  522. cn = int(cn)
  523. except:
  524. return 0
  525. return cn
  526. def choose_license():
  527. lsnzs = []
  528. for i in licenses:
  529. lsnzs.append([i[0],i[2]])
  530. d = {"categories":["Name","Comment"],
  531. "size":[1,1],
  532. "data":lsnzs}
  533. table(d)
  534. center("---choose a license or press enter for custom---")
  535. lc = input(typing_dots())
  536. try:
  537. lselect = licenses[int(lc)]
  538. lname = lselect[0]
  539. llink = lselect[1]
  540. except:
  541. lname = input(typing_dots("License Name", give_space=True, to_add_dots=True))
  542. llink = input(typing_dots("License Link", give_space=True, to_add_dots=True))
  543. return lname, llink
  544. def spdx_license(identifier):
  545. """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"""
  546. with open("flbry/licenses.json") as f:
  547. licenses = json.load(f)
  548. licenses = licenses["licenses"]
  549. for i, l in enumerate(licenses):
  550. if l["licenseId"] == identifier:
  551. lname = l["name"]
  552. llink = l["seeAlso"][0]
  553. # Warn the user if the license identifier is nonfree or not FSF libre
  554. if not "isFsfLibre" in l:
  555. if not l["isOsiApproved"]:
  556. center("License is not free or open source", "bdrd")
  557. else:
  558. center("License is OSI-approved but is not considered free by the FSF")
  559. return {"name": lname, "link": llink}
  560. return {"name": identifier}
  561. # This is a dictionary because modifying a normal variable does not
  562. # work, but modifying a dictionary object does.
  563. # Apparently this has something to do with the variable's place in memory
  564. lbrynet_binary = {"b":"flbry/lbrynet"}
  565. def try_getting_git_commit():
  566. import subprocess
  567. try:
  568. ghash = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().rstrip()
  569. center("Git commit hash: "+ghash)
  570. except Exception as e:
  571. # Git isn't installed
  572. center("Error getting commit hash: "+str(e), "bdrd")
  573. pass