variables.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  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 actuall 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. x = ""
  139. for i in y:
  140. if i in good:
  141. x = x + i
  142. else:
  143. x = x + "▓"
  144. # Now let's print what we've got.
  145. if len(y) < n:
  146. fac = n-len(y)
  147. fac1 = int(round(fac/2))
  148. fac2 = fac1
  149. while fac1 + fac2 > fac:
  150. fac2 -=1
  151. while fac1 + fac2 < fac:
  152. fac2 +=1
  153. x = (" "*fac1)+x+(" "*fac2)
  154. elif len(y) > n:
  155. if n > 10:
  156. x = x[:n-3]+"..."
  157. else:
  158. x = x[:n]
  159. if mode == "normal":
  160. return x
  161. else:
  162. return clr[mode]+clr["bold"]+x+clr["norm"]
  163. # A dictionary for translations of things from the SDK into
  164. # readable thing
  165. what = {
  166. "stream":"FILE",
  167. "repost":"SHARED",
  168. "channel": "CHANNEL",
  169. "collection": "PLAYLIST",
  170. "video":"VIDEO",
  171. "audio":"SOUND",
  172. "document":"TEXT",
  173. "binary":"FILE",
  174. "image":"PICTURE"
  175. }
  176. # This function will take a list and present in a pretty
  177. # way.
  178. def tgz(x):
  179. # Just in case
  180. if type(x) != list:
  181. x = x.split()
  182. y = ""
  183. for i in x:
  184. y = y + i + ", "
  185. return y[:-2]
  186. # This function will convert bites into readable data making sense
  187. def csize(x):
  188. x = float(x)
  189. l = ["B","KB", "MB", "GB", "TB"]
  190. for i in range(5):
  191. if x > 1024:
  192. x = x / 1024
  193. else:
  194. return str(round(x, 2))+" "+l[i]
  195. return str(round(x, 2))+" "+l[i]
  196. # This next function will select the amount of ::: for a given
  197. # input.
  198. def typing_dots(text="", to_text=True, to_add_dots=False, give_space=False):
  199. depth = len(inspect.stack()) # This is the depth of the stack
  200. # since this function call adds 1 to the stack we need
  201. # to decrease the number by one
  202. if not text or not to_add_dots:
  203. depth -= 1
  204. # Now I want to select a sequence of colors.
  205. x = ["bdma","bdbu", "bdrd", "bdgr", "bdcy", "bdyl"]
  206. ret = " "+clr["bold"]
  207. for i in reversed(range(depth)):
  208. ret = ret + clr["tbwh"] + clr[x[i % len(x)]] + ":"
  209. ret = ret + clr["norm"]+" "
  210. w, h = tsize()
  211. if text and to_text:
  212. side_string = " < "+text+" "
  213. put_at = w-len(side_string)-1
  214. if not give_space:
  215. put_at = int(w/2)-int(len(side_string)/2)
  216. print(wdth("", put_at)+clr["bdma"]+clr["bold"]+side_string+clr["norm"], end="")
  217. ret = "\r"+ret
  218. return ret
  219. def tsize():
  220. # This funtion will get the size of the terminal and
  221. # return it to the variables provided width, height
  222. # On some systems this may not work. So there is a
  223. # try function.
  224. try:
  225. # Getting the size of the terminal
  226. import os
  227. w, h = os.get_terminal_size()
  228. # Sometimes when the terminal width is either
  229. # even or odd. It breaks code for some other
  230. # thing written differenly. For example:
  231. # You may have an even width ( like 84 ) when
  232. # writing a function. And then it works on different
  233. # widths as well like 62 and 80 and 48. All of them
  234. # are still even. Then you scale the terminal to be
  235. # something off like 63 and the function breaks. You
  236. # have one character too much or one character too little.
  237. # This is why I do not want to have a difference. And
  238. # force width to be one less, if it's not divisible by 2.
  239. if not w % 2:
  240. w = w - 1
  241. return w, h
  242. except:
  243. # If, by any reason the terminal can't get it's size.
  244. # We want to return some size regardless.
  245. w = 60
  246. h = 20
  247. return w, h
  248. def logo():
  249. # This function will draw a pretty FastLBRY logo to the user
  250. # at startup.
  251. # Getting terminal size
  252. w, h = tsize()
  253. if w > 50:
  254. l = []
  255. l.append( "█▓▓█▓▓▓▓▓▓█▓██▓▓▓▓▓▓▓█▓▓▓▓▓▓█▓▓▓▓██▓▓▓▓█▓▓▓▓█" )
  256. l.append( "▓▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▓▒▒▒▒▓▒▓" )
  257. l.append( "██░░░▒░░░░░░▒░░░░░░░▒░░░░░░░░░▒░░▒░░░░░░░░▒▓▓" )
  258. l.append( "▓▓░ ░ ░ ░ ■ ■░░▒▓" )
  259. l.append( "▓▒▒ ╔════════■ ░ ╔════╗ ╔════╗ ║ ░ ║ ░▓█" )
  260. l.append( "▓▒░ ║ ░ ║ ║ ║ ║ ║ ║ ║ ░▒▓" )
  261. l.append( "█▓░░║ ║ ╠════╣ ╠═╦══╝ ╚══╦══╝ ▒▒▓" )
  262. l.append( "▓▒▒ ╠══ AST ■║ ║ ║ ║ ╚══╗ ║ ░░▒█" )
  263. l.append( "█▒░ ║ ║ ║ ║ ║ ║ ║ ░▓▓" )
  264. l.append( "▓▓░ ║ ░ ╚═════■╚════╝ ■ ■ ░ ║ ░ ░▒▓" )
  265. l.append( "▓▒░░║ ░ THE TERMINAL CLIENT ║ ▒▒█" )
  266. l.append( "█▒▒ ■ ░ ░ ■ ▒░ ░▓▓" )
  267. l.append( "▓▒░░░░░░░▒░░░░▓░░░░░▒░░░░░░░░░▒░░░░▒░░░░░░░▒█" )
  268. l.append( "▓▓▒▒▒▒▓▒▒▒▒▒▓▒▒▒▒▓▒▒▓▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▓▒▒▒▒▒▓▓▓" )
  269. l.append( "█▓▓█▓▓▓▓▓████▓▓▓▓█▓▓▓▓█▓▓▓▓██▓▓▓█▓▓▓▓▓█▓▓▓▓██" )
  270. print(" "+clr["bdma"]+(" "*(w-8))+clr["norm"])
  271. # I want to fill the width of the terminal around the logo
  272. # with a texture. But since it's text based I will need to
  273. # code a texture into it. I can use the blocks seen below
  274. # and select randomly between them.
  275. # You can see I included multiple of darkest block and
  276. # almost non bright blocks. This will increase the
  277. # probability of the dark blocks.
  278. block = "████████▓▓▓▒" #for the random to choose
  279. import random
  280. # Now let's output
  281. for i in l:
  282. f = "" # Texture fill string.
  283. # Fill the f string with random blocks
  284. for g in range(int(w/2-27)):
  285. f = f + random.choice(block)
  286. # Print a line with random filler and the line it self.
  287. print (" "+clr["bdma"]+" "+clr["norm"]+f+i+f+clr["bdma"]+" "+clr["norm"])
  288. else:
  289. center( "FastLBRY")
  290. center( "terminal")
  291. center("")
  292. print()
  293. def table(data, number=True):
  294. # This function will present data in a pretty table thing.
  295. # So let's first of all get the size of the terminal
  296. w, h = tsize()
  297. if number:
  298. w = w - 4
  299. # Then let's draw the categories for this we need to extract
  300. # it's sizes. If there is no 'size' variable the sizes of
  301. # each category will be spread equally.
  302. size = [] # Here the size will go as pure character value.
  303. if "size" in data:
  304. for i in data["size"]:
  305. size.append(int(( w - 10 ) / sum(data["size"]) * i))
  306. while sum(size) < w - 10:
  307. size[-1] += 1
  308. # printing categories
  309. nb = ""
  310. if number:
  311. nb = " "
  312. s = " "+clr["bdma"]+" "+clr["tbwh"]+nb
  313. for n, item in enumerate(data["categories"]):
  314. s = s + wdth(item.upper(), size[n])
  315. print(s+clr["bdma"]+" "+clr["norm"])
  316. size[-1] += 1
  317. # printing items
  318. for b, i in enumerate(data["data"]):
  319. # dark bright sequence thingy
  320. if b % 2:
  321. d = "b"
  322. else:
  323. d = "d"
  324. nb = ""
  325. if number:
  326. nb = clr["tbwh"]+wdth(b,4)
  327. s = " "+clr["bdma"]+" "+nb+clr["norm"]+clr["b"+d+"bu"]+clr["tbwh"]
  328. for n, item in enumerate(i):
  329. s = s +clr["b"+d+"bu"]+ wdth(item, size[n]-1)+clr["bdma"]+" "
  330. print(s+clr["norm"])
  331. def center(line, c="bdma", blink=False):
  332. # This funtiocn will bring a given string of text
  333. # in the center of the terminal with a nice backgroud
  334. # around it.
  335. w, h = tsize()
  336. if blink:
  337. blink = clr["blnk"]
  338. else:
  339. blink = ""
  340. if len(line) % 2:
  341. line = line + " "
  342. if len(line) < w - 11:
  343. print(" "+clr[c],
  344. wdth(" ", int((w-10)/2 - (len(line)/2))),
  345. clr["bold"]+clr["tbwh"]+blink+line,
  346. wdth(" ", int((w-10)/2 - (len(line)/2))-1),
  347. clr["norm"])
  348. else:
  349. print(" "+clr[c],
  350. clr["bold"]+clr["tbwh"]+blink+wdth(line,w-10),
  351. clr["norm"])
  352. def timestring(tleft):
  353. # This crazy function will convert the microsecond into something
  354. # a bit more usefull. Like 03:20:90.06 Kind a thing.
  355. tleftX = tleft
  356. tleft = int(tleftX)
  357. addend = tleftX - tleft
  358. valt = str(tleft)
  359. if tleft > 60 :
  360. le = tleft
  361. tleft = int(tleft / 60)
  362. le = le - int(tleft * 60)
  363. stleft = "0"*(2-len(str(tleft)))+str(tleft)
  364. sle = "0"*(2-len(str(le)))+str(le)
  365. valt = stleft+":"+ sle
  366. if tleft > 60 :
  367. lele = le
  368. le = tleft
  369. tleft = int(tleft / 60)
  370. le = le - int(tleft * 60)
  371. lele = (lele - le)
  372. if lele < 0:
  373. lele = int(lele * -1)
  374. stleft = "0"*(2-len(str(tleft)))+str(tleft)
  375. sle = "0"*(2-len(str(le)))+str(le)
  376. slele = "0"*(2-len(str(lele)))+str(lele)
  377. valt = stleft+":"+ sle + ":" + slele
  378. if tleft > 24 :
  379. le = tleft
  380. tleft = int(tleft / 24)
  381. le = le - int(tleft * 24)
  382. valt = str(tleft)+" DAYS AND "+ str(le) + " HRS"
  383. return valt + "." + str(int(addend*100))
  384. # This a list of known licenses, info a and links
  385. licenses = [
  386. # NAME , URL , COMMENT
  387. ["GNU General Public License Version 3 (or later)",
  388. "https://www.gnu.org/licenses/gpl-3.0.html",
  389. "Strong Copyleft. Recommended for Software."],
  390. ["GNU General Public License Version 3 (only)",
  391. "https://www.gnu.org/licenses/gpl-3.0.html",
  392. "Strong Copyleft."],
  393. ["GNU Free Documentation License",
  394. "https://www.gnu.org/licenses/fdl-1.3.html",
  395. "Strong Copyleft. Recommended for books."],
  396. ["Creative Commons Attribution-ShareAlike 4.0 International",
  397. "https://creativecommons.org/licenses/by-sa/4.0/",
  398. "Copylefted, Recommended for Art."],
  399. ["Creative Commons Attribution 4.0 International",
  400. "https://creativecommons.org/licenses/by/4.0/",
  401. "Non Copylefted, Free License."],
  402. ["Creative Commons Zero 1.0 International",
  403. "https://creativecommons.org/publicdomain/zero/1.0/",
  404. "Public Domain"],
  405. ["Creative Commons Attribution-NoDerivatives 4.0 International",
  406. "https://creativecommons.org/licenses/by-nd/4.0/",
  407. "Does not allow changes. Recommended for opinion pieces."]
  408. ]
  409. def progress_bar(now, total, name=""):
  410. # This function will draw a pretty progress bar that fills up
  411. # one problem. It requires an empty print line after it. Or it
  412. # will start printing whatever in the same line as the progress
  413. # bar.
  414. # dimensions
  415. w, h = tsize()
  416. fullw = w - 8
  417. # string
  418. string = " "+str(int(round(now/total*100)))+"% "+str(now)+" / "+str(total)+" "+name
  419. string = string+" "*(fullw-len(string))
  420. howfar = int(round(fullw / total * now))
  421. pstring = clr["tbwh"]+clr["bold"]+clr["bdcy"]+string[:howfar]+clr["bdma"]+string[howfar:]
  422. print("\r "+pstring, end=clr["norm"])
  423. # We need a system of auto-filling commands. As well as a history type thing.
  424. # so people could come back to a previous command by pressing the up arrow.
  425. # Now all systems will have readline since it's a GNU package
  426. complete_commands = []
  427. def complete(commands, add=False):
  428. # This will make sure that we can add commands to
  429. # the completer after it's set.
  430. global complete_commands
  431. if not add:
  432. complete_commands = commands
  433. else:
  434. for i in commands:
  435. complete_commands.append(i)
  436. commands = complete_commands
  437. try:
  438. import readline
  439. # Then we need to specify a function for completion
  440. def completer(text, state):
  441. options = [i for i in commands if i.startswith(text)]
  442. if state < len(options):
  443. return options[state]
  444. else:
  445. return None
  446. # And we need to setup the completer
  447. readline.parse_and_bind("tab: complete")
  448. readline.set_completer(completer)
  449. except Exception as e:
  450. center("Auto-completer error: "+str(e), "bdrd")
  451. # List of web instances of LBRY
  452. web_instances = [
  453. ["Odysee", "https://odysee.com/", "LBRY Inc.", "JavaScript"],
  454. ["Madiator", "https://madiator.com/", "Madiator2011", "JavaScript"],
  455. ["Spee.ch", "https://spee.ch/", "LBRY Inc.", "Direct Files"]
  456. ]
  457. def file_or_editor(args, comment):
  458. # We gonna check if dunring typing reply the user added
  459. # anything after the word reply.
  460. # reply emacs
  461. # reply gedit
  462. # reply vim
  463. # Or something like
  464. # reply /home/username/filename.txt
  465. # reply /home/username/filename.md
  466. # That might be useful to input multiline text.
  467. import os
  468. a = args.split()[0]
  469. a = os.path.expanduser(a)
  470. try:
  471. text = open(a, "r")
  472. text = text.read()
  473. except:
  474. text = open("/tmp/fastlbrycommentwriter.txt", "w")
  475. text.write(comment)
  476. text.close()
  477. os.system(a+" /tmp/fastlbrycommentwriter.txt")
  478. center("Press Enter when the file is ready and saved.")
  479. input()
  480. text = open("/tmp/fastlbrycommentwriter.txt", "r")
  481. text = text.read()
  482. return text.rstrip()
  483. def get_cn(c, prompt=""):
  484. # This gets a number from a command
  485. if " " in c:
  486. try:
  487. cn = int(c[c.find(" ")+1:])
  488. except:
  489. return 0
  490. else:
  491. cn = input(typing_dots(prompt))
  492. try:
  493. cn = int(cn)
  494. except:
  495. return 0
  496. return cn
  497. def choose_license():
  498. lsnzs = []
  499. for i in licenses:
  500. lsnzs.append([i[0],i[2]])
  501. d = {"categories":["Name","Comment"],
  502. "size":[1,1],
  503. "data":lsnzs}
  504. table(d)
  505. center("---choose a license or press enter for custom---")
  506. lc = input(typing_dots())
  507. try:
  508. lselect = licenses[int(lc)]
  509. lname = lselect[0]
  510. llink = lselect[1]
  511. except:
  512. lname = input(typing_dots("License Name", give_space=True, to_add_dots=True))
  513. llink = input(typing_dots("License Link", give_space=True, to_add_dots=True))
  514. return lname, llink
  515. def spdx_license(identifier):
  516. """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"""
  517. with open("flbry/licenses.json") as f:
  518. licenses = json.load(f)
  519. licenses = licenses["licenses"]
  520. for i, l in enumerate(licenses):
  521. if l["licenseId"] == identifier:
  522. lname = l["name"]
  523. llink = l["seeAlso"][0]
  524. # Warn the user if the license identifier is nonfree or not FSF libre
  525. if not "isFsfLibre" in l:
  526. if not l["isOsiApproved"]:
  527. center("License is not free or open source", "bdrd")
  528. else:
  529. center("License is OSI-approved but is not considered free by the FSF")
  530. return {"name": lname, "link": llink}
  531. return {"name": identifier}