ui.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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 will contain elements used a lot with in the application.
  30. # They are all built upon GTK, so it's implementable without using these
  31. # but it may simplify your modification. Since the elements in will be
  32. # specific to making something like this application easier.
  33. import os
  34. import urllib.request
  35. import threading
  36. import json
  37. from subprocess import *
  38. from gi.repository import Gtk
  39. from gi.repository import Gio
  40. from gi.repository import Gdk
  41. from gi.repository import Pango
  42. from gi.repository import GdkPixbuf
  43. from PIL import Image, ImageSequence
  44. def icon( win, name, f="png"):
  45. # This function returns an icon of the current setting, or a
  46. # system default icon if there is no such icon in the set icon theme.
  47. # For this, of course, we will need to store names of what those
  48. # icons are called in the system. Not everthing is the same.
  49. # I could name the icons in the custom theme the same way, but
  50. # this would require using some hilarious names.
  51. system_names = {
  52. "settings":"application-menu",
  53. "connect":"network-connect",
  54. "disconnect":"network-disconnect",
  55. "loading":"accept_time_event",
  56. "launch":"player_play"
  57. }
  58. try_icon = "icons/"+win.settings["GTK_icon_theme"]+"/"+name+"."+f
  59. if os.path.exists(try_icon):
  60. return Gtk.Image.new_from_file(try_icon)
  61. else:
  62. # Real GTK Spinner for loading ? Why not?
  63. if name == "loading":
  64. s = Gtk.Spinner()
  65. s.set_size_request(64,64)
  66. s.start()
  67. return s
  68. except_icon = Gio.Icon.new_for_string(system_names.get(name, name))
  69. return Gtk.Image.new_from_gicon(except_icon, Gtk.IconSize.DND)
  70. def resize_gif(filename, new_file, size):
  71. # This function will resize a gif
  72. gif = Image.open(filename)
  73. layers = ImageSequence.Iterator(gif)
  74. def rs(l):
  75. for i in l:
  76. rsv = i.copy()
  77. rsv.thumbnail(size, Image.ANTIALIAS)
  78. yield rsv
  79. layers = rs(layers)
  80. # Overwrite the original gif
  81. f = next(layers)
  82. f.info = gif.info
  83. f.save(new_file, save_all=True, append_images=list(layers))
  84. def load(win, widget_function, *args):
  85. # This function will load widgets that take time to load.
  86. # It will show a spinner while the widget is loading. And when
  87. # the widget_function will return a finished widget, it will
  88. # swap the spinner for the final widget.
  89. wbox = Gtk.HBox()
  90. widget = icon(win, "loading", "gif")
  91. wbox.pack_start(widget, True, True, True)
  92. def resolve_widget_thread(widget, wbox, wf, *args):
  93. new_widget = wf(*args)
  94. widget.destroy()
  95. wbox.pack_start(new_widget, True, True, True)
  96. #wbox.show_all()
  97. win.show_all()
  98. load_thread = threading.Thread(target=resolve_widget_thread, args=(widget, wbox, widget_function, *args))
  99. load_thread.setDaemon(True)
  100. load_thread.start()
  101. return wbox
  102. def net_image( url, size, save_as, allow_gif):
  103. ret = Gtk.Image()
  104. delete = False
  105. if not save_as:
  106. delete = True
  107. good = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOOPASDFGHJKLZXCVBNM_"
  108. for i in url:
  109. if i in good:
  110. save_as = save_as + i
  111. else:
  112. save_as = save_as + "_"
  113. save_as = "/tmp/"+save_as
  114. # This function will load the image in a separate thread.
  115. try:
  116. urllib.request.urlretrieve(url, save_as)
  117. except Exception as e:
  118. f = open(save_as, "w")
  119. f.close()
  120. if size:
  121. try:
  122. pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(save_as, size, size)
  123. ret = Gtk.Image.new_from_pixbuf(pixbuf)
  124. except:
  125. try:
  126. os.rename(save_as, save_as+".gif")
  127. resize_gif(save_as+".gif", save_as+"_2.gif", [size,size])
  128. ret = Gtk.Image.new_from_file(save_as+"_2.gif")
  129. os.remove(save_as+"_2.gif")
  130. os.rename(save_as+".gif", save_as)
  131. except Exception as e:
  132. print("GIF RESIZING ERROR", e)
  133. if allow_gif:
  134. ret = Gtk.Image.new_from_file(save_as)
  135. else:
  136. ret = Gtk.Image.new_from_file(save_as)
  137. if delete:
  138. try:
  139. os.remove(save_as)
  140. except:
  141. pass
  142. return ret