123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- #####################################################################
- # #
- # 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 is managing the downloads
- import os
- import time
- import json
- import threading
- import urllib.request
- from gi.repository import Gtk
- from gi.repository import Gdk
- from gi.repository import GLib
- from gi.repository import Pango
- from gi.repository import GdkPixbuf
- from subprocess import *
- from flbry import markdown
- from flbry import ui
- from flbry import fetch
- from flbry import settings
- from flbry import data_view
- from flbry import url
- from flbry import analytics
- def window(win):
- # The window of the dialog
- dwin = Gtk.Window()
- dwin.set_title("FastLBRY GTK: Downloads")
- dwin.set_size_request(500, 500)
- win.downloads["ui"] = {}
- box = Gtk.VBox()
- dwin.add(box)
- # I want to have a pie chart on the top to show
- # how much does LBRY effects the filesystem.
- settings = fetch.lbrynet("settings_get")
- download_folder = settings["download_dir"]
- lbry_folder = settings["data_dir"]
-
- def get_folder_size(Folder):
- size = 0
- for path, dirs, files in os.walk(Folder):
- for f in files:
- fp = os.path.join(path, f)
- size += os.path.getsize(fp)
- return size
-
-
- file_stats = os.statvfs(download_folder)
- downloads_size = get_folder_size(download_folder)
- lbry_data_size = get_folder_size(lbry_folder)
- full_disk = file_stats.f_blocks*file_stats.f_bsize
- free_space = file_stats.f_bavail*file_stats.f_bsize
- # We need to remove both downloads and lbry data from the ocupied space
- pie_data = {
- "Downloads":downloads_size,
- "LBRY Blobs / Data":lbry_data_size,
- "Unrelated to LBRY":full_disk-free_space-downloads_size-lbry_data_size,
- "Free Space":free_space
- }
- box.pack_start(analytics.pie_chart(win, pie_data, "Totals", converter=url.csize), 0, 0 , 0)
- scrl = Gtk.ScrolledWindow()
- scrl.set_hexpand(False)
- box.pack_start(scrl, True, True, 0)
-
- main_lbox = Gtk.VBox() # Needed for dynaimc loading
- scrl.add(main_lbox)
-
- draw_all(win, main_lbox, 1)
-
- dwin.show_all()
-
- def draw_all(win, main_lbox, page=1):
- #print("NEW PAGE", wasat)
- out = load(win, {"reverse":True,
- "page":page})
-
- lbox = Gtk.VBox() # The Main list box
- main_lbox.pack_start(lbox, 1,1,0)
-
- # Let's render it
- for item in reversed(out["items"]):
- sep = Gtk.HSeparator()
- lbox.pack_end(sep, 0,1,10)
-
- ############# FULL DATA ###############
-
- expand = Gtk.Expander(label=" Details: ")
- det_view = data_view.data_widget(item)
- expand.add(det_view)
- lbox.pack_end(expand, 1,0,0)
- ############ ITEM'S CONTROLLS #########
-
- hbox = Gtk.HBox() # The box of each item
- lbox.pack_end(hbox, 1,1,0)
- claim_id = item["claim_id"]
-
- try:
- thumb = item["metadata"]["thumbnail"]["url"]
- image = ui.load(win, ui.net_image_calculation, ui.net_image_render, thumb, 70, "", True)
- hbox.pack_start(image, 0,0,5)
- except:
- pass
- rbox = Gtk.VBox() # The things excluding the thumbnail
- hbox.pack_start(rbox, 0,0,0)
-
- try:
- title = item["metadata"]["title"]
- except:
- title = item["claim_name"]
- #print("title", title)
-
- tlabel = Gtk.Label(title)
- tlabel.set_line_wrap_mode( Pango.WrapMode.WORD_CHAR )
- tlabel.set_line_wrap(True)
-
- rbox.pack_start(tlabel, 0,0,10)
- tbox = Gtk.HBox() # The toolbar with the buttons
- rbox.pack_start(tbox, 0,1,0)
- ############ RESOLVE BUTTON #######
-
- def on_resolve(w, claim_id, claim_name):
- link = claim_name+":"+claim_id
- win.resolve_tab = "new_tab"
- win.url.set_text(link)
- win.url.activate()
-
- dbutton = Gtk.Button()
- dbutton.connect("clicked", on_resolve, item["claim_id"], item["claim_name"])
- dbutton.set_relief(Gtk.ReliefStyle.NONE)
- dbox = Gtk.HBox()
- dbutton.add(dbox)
- dbox.pack_start(ui.icon(win, "system-search"), 0,0,0)
- dbox.pack_start(Gtk.Label("Resolve"), 0,0,0)
-
- tbox.pack_start(dbutton, 0,0,1)
-
- filename = item["download_path"]
-
- ############ DELETE BUTTON #################
-
- def on_delete(w, claim_id, filename, hbox, expand, sep):
- print("deleting",filename)
- url.delete_file(claim_id)
- try:
- os.remove(filename)
- except Exception as e:
- print(e)
- hbox.destroy()
- expand.destroy()
- sep.destroy()
- dbutton = Gtk.Button()
- dbutton.connect("clicked", on_delete, item["claim_id"], filename, hbox, expand, sep)
- dbutton.set_relief(Gtk.ReliefStyle.NONE)
- dbox = Gtk.HBox()
- dbutton.add(dbox)
- dbox.pack_start(ui.icon(win, "edit-delete"), 0,0,0)
- dbox.pack_start(Gtk.Label("Delete"), 0,0,0)
-
- tbox.pack_start(dbutton, 0,0,1)
- ############ PLAY BUTTON ###############
- if filename and os.path.exists(filename):
-
- def on_play(w, filename):
- Popen(["xdg-open", filename])
-
- dbutton = Gtk.Button()
- dbutton.connect("clicked", on_play, filename)
- dbutton.set_relief(Gtk.ReliefStyle.NONE)
- dbox = Gtk.HBox()
- dbutton.add(dbox)
- dbox.pack_start(ui.icon(win, "media-playback-start"), 0,0,0)
- dbox.pack_start(Gtk.Label("Launch"), 0,0,0)
-
- tbox.pack_start(dbutton, 0,0,1)
-
-
- if win.downloads["data"]["total_pages"] > page:
- lastthing(win, page, main_lbox)
- main_lbox.show_all()
- def lastthing(win, page, box):
- # I'm implementing it again and have no idea what I'm doing
- # This is needed to dynamically load more stuff as you scroll down.
-
- spinner_more = ui.icon(win, "loading", "gif")
-
- box.pack_start(spinner_more, False, False, 0)
-
- def draw_event(w, e):
- w.destroy()
-
- draw_all(win, box, page+1)
-
-
- spinner_more.connect("draw", draw_event)
-
- def load(win, args={}):
- print("LOADING:",args)
-
- out = fetch.lbrynet("file_list", args)
- if "data" not in win.downloads:
- win.downloads["data"] = out
- else:
- claims = []
- for i in win.downloads["data"]["items"]:
- claims.append(i["claim_id"])
- for i in out["items"]:
- if i["claim_id"] not in claims:
- win.downloads["data"]["items"].append(i)
-
-
- return out
|