123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- #####################################################################
- # #
- # THIS IS A SOURCE CODE FILE FROM A PROGRAM TO INTERACT WITH THE #
- # LBRY PROTOCOL ( lbry.com ). IT WILL USE THE LBRY SDK ( lbrynet ) #
- # FROM THEIR REPOSITORY ( https://github.com/lbryio/lbry-sdk ) #
- # WHICH I GONNA PRESENT TO YOU AS A BINARY. SINCE I DID NOT DEVELOP #
- # IT AND I'M LAZY TO INTEGRATE IN A MORE SMART WAY. THE SOURCE CODE #
- # OF THE SDK IS AVAILABLE IN THE REPOSITORY MENTIONED ABOVE. #
- # #
- # ALL THE CODE IN THIS REPOSITORY INCLUDING THIS FILE IS #
- # (C) J.Y.Amihud and Other Contributors 2021. EXCEPT THE LBRY SDK. #
- # YOU CAN USE THIS FILE AND ANY OTHER FILE IN THIS REPOSITORY UNDER #
- # THE TERMS OF GNU GENERAL PUBLIC LICENSE VERSION 3 OR ANY LATER #
- # VERSION. TO FIND THE FULL TEXT OF THE LICENSE GO TO THE GNU.ORG #
- # WEBSITE AT ( https://www.gnu.org/licenses/gpl-3.0.html ). #
- # #
- # THE LBRY SDK IS UNFORTUNATELY UNDER THE MIT LICENSE. IF YOU ARE #
- # NOT INTENDING TO USE MY CODE AND JUST THE SDK. YOU CAN FIND IT ON #
- # THEIR OFFICIAL REPOSITORY ABOVE. THEIR LICENSE CHOICE DOES NOT #
- # SPREAD ONTO THIS PROJECT. DON'T GET A FALSE ASSUMPTION THAT SINCE #
- # THEY USE A PUSH-OVER LICENSE, I GONNA DO THE SAME. I'M NOT. #
- # #
- # THE LICENSE CHOSEN FOR THIS PROJECT WILL PROTECT THE 4 ESSENTIAL #
- # FREEDOMS OF THE USER FURTHER, BY NOT ALLOWING ANY WHO TO CHANGE #
- # THE LICENSE AT WILL. SO NO PROPRIETARY SOFTWARE DEVELOPER COULD #
- # TAKE THIS CODE AND MAKE THEIR USER-SUBJUGATING SOFTWARE FROM IT. #
- # #
- #####################################################################
- # This file will contain elements used a lot with in the application.
- # They are all built upon GTK, so it's implementable without using these
- # but it may simplify your modification. Since the elements in will be
- # specific to making something like this application easier.
- import os
- import time
- import urllib.request
- import threading
- import json
- from subprocess import *
- from gi.repository import Gtk
- from gi.repository import Gio
- from gi.repository import Gdk
- from gi.repository import GLib
- from gi.repository import Pango
- from gi.repository import GdkPixbuf
- from PIL import Image, ImageSequence
- def icon( win, name, f="png", size=Gtk.IconSize.DND):
- # This function returns a fitting icon of the current theme,
- # or if not available from another theme on the system.
- # If a custom icon theme is set, it returns the icon from the corresponding folder.
- if Gtk.IconTheme.get_default().has_icon(name):
- return Gtk.Image.new_from_icon_name(name, size)
- else:
- # Real GTK Spinner for loading ? Why not?
- if name == "loading":
- s = Gtk.Spinner()
- s.set_size_request(32,32)
- s.start()
- return s
- else:
- return Gtk.HBox()
-
- def resize_gif(filename, new_file, size):
- # This function will resize a gif
- gif = Image.open(filename)
- layers = ImageSequence.Iterator(gif)
- def rs(l):
- for i in l:
- rsv = i.copy()
- rsv.thumbnail(size, Image.ANTIALIAS)
- yield rsv
- layers = rs(layers)
- # Overwrite the original gif
- f = next(layers)
- f.info = gif.info
- f.save(new_file, save_all=True, append_images=list(layers))
-
- def load(win, calculation_function, render_function, *args, wait=True):
- # This function will load widgets that take time to load.
- # Due to the peculiarities of the GTK main thread. I need
- # to separate the computation and the rendering part of
- # the job into two distingt functions.
- # One will do all the job to get the file or resolve the url
- # or whatever it needs to do, which does not require GTK to
- # be done. The second will be the GTK commands. The rendering,
- # done with in the GTK main thread.
-
- wbox = Gtk.HBox()
- widget = icon(win, "loading", "gif")
- wbox.pack_start(widget, True, False, False)
- widget.loaddo = True
-
- def resolve_widget_thread(widget, wbox, wf, rf, *args):
-
- calculations = wf(*args)
-
- def gtk_schedule(calculations, rf):
- # It seems to be important to edit GTK only
- # in the main thread. This will schedule it.
- new_widget = rf(calculations)
- widget.destroy()
- wbox.pack_start(new_widget, True, True, True)
- wbox.show_all()
- GLib.idle_add(gtk_schedule, calculations, rf)
- def load_event(w,e):
- if w.loaddo:
- load_thread = threading.Thread(target=resolve_widget_thread, args=(widget, wbox, calculation_function, render_function, *args))
- load_thread.setDaemon(True)
- load_thread.start()
- w.loaddo = False
- if wait:
- widget.connect("draw", load_event)
- else:
- load_event(widget, False)
-
- return wbox
- image_cache = "/tmp/JYTRANSACTION_GTK_image_cashe/"
- def image_save_name(url, image_cache=image_cache):
- save_as = ""
- good = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOOPASDFGHJKLZXCVBNM_1234567890"
- for i in url:
- if i in good:
- save_as = save_as + i
- else:
- save_as = save_as + "_"
- try:
- os.mkdir(image_cache)
- except:
- pass
- save_as = image_cache+save_as
- return save_as
- def clean_image_cache():
- for i in os.listdir(image_cache):
- os.remove(image_cache+i)
- def net_image_calculation( url, size, save_as=False, allow_gif=False):
- ret = ["file", save_as]
-
- # This is when we want to load a file
-
- if save_as == "FORCELOAD":
- try:
- open(url)
- save_as = url
- except:
- save_as = ""
-
- if not save_as:
- save_as = image_save_name(url)
-
- # This function will load the image in a separate thread.
- try:
- open(save_as) # In case it's already been saved
- except Exception as e:
- pass
-
- try:
- urllib.request.urlretrieve(url, save_as)
- except Exception as e:
- f = open(save_as, "w")
- f.close()
- if size:
- try:
-
- pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(save_as, size, size)
- ret = ["pixbuf", pixbuf] #Gtk.Image.new_from_pixbuf(pixbuf)
- except Exception as e:
- if "image file format" in str(e):
- try:
- PILImage = Image.open(save_as).convert("RGBA")
- PILImage.save(save_as+".png", "png")
- pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(save_as+".png", size, size)
- ret = ["pixbuf", pixbuf]
- except:
- ret = ["file", save_as]
-
- else:
- try:
- os.rename(save_as, save_as+".gif")
- resize_gif(save_as+".gif", save_as+"_2.gif", [size,size])
- ret = ["file", save_as+"_2.gif"] # Gtk.Image.new_from_file(save_as+"_2.gif")
- os.remove(save_as+"_2.gif")
- os.rename(save_as+".gif", save_as)
-
- except Exception as e:
- if allow_gif:
- ret = ["file", save_as] #Gtk.Image.new_from_file(save_as)
-
- else:
- ret = ["file", save_as] #Gtk.Image.new_from_file(save_as)
- return ret
- def net_image_render(calc):
- # This will make the image itself.
- ret = Gtk.Image()
- if calc[0] == "file":
- ret = Gtk.Image.new_from_file(calc[1])
- elif calc[0] == "pixbuf":
- ret = Gtk.Image.new_from_pixbuf(calc[1])
-
- return ret
|