123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892 |
- #####################################################################
- # #
- # 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. #
- # #
- #####################################################################
- import os
- import time
- import urllib.request
- import threading
- import json
- from subprocess import *
- 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 PIL import Image, ImageSequence
- from flbry import markdown
- from flbry import data_view
- from flbry import ui
- from flbry import fetch
- from flbry import claim_search
- from flbry import comments
- from flbry import follow
- from flbry import publish
- from flbry import analytics
- from flbry import livestreams
- from flbry import suggest
- from flbry import odysee
- from flbry import oscalls
- def resolve(w, win, url):
-
- # This function will draw a widget of resolved url
- #####################################################
- # RESOLVING PART ( NO GTK ) #
- #####################################################
- out = fetch.lbrynet("resolve",
- {"urls":[url]}
- )
- out = out[url]
- # Saving the resolved thing into the win for later use
- win.resolved = out
-
- # out = check_output(["flbry/lbrynet",
- # "resolve", url])
- # raw_data = out.decode("utf-8")
-
- # # Now we want to parse the json
- # try:
- # out = json.loads(out)
- # out = out[url]
- # except:
- # print("Resolve Failed")
- # return False
- try:
- is_channel = "value_type" in out and out["value_type"] == "channel"
- percentage = downloaded(out["claim_id"])
- except:
- # If this fails we activate search
- return ["search", False, False, w, win, url, False]
-
- # make sure the url path starts with lbry://
- if not url.startswith("lbry://"):
- url = "lbry://"+url
- win.url.set_text(url)
- if is_channel:
- stream_data = livestreams.get_data(out["claim_id"])
- else:
- try:
- stream_data = livestreams.get_data(out["signing_channel"]["claim_id"])
- except:
- stream_data = {}
-
- return [out, is_channel, percentage, w, win, url, stream_data]
- def render_resolve(data):
- out, is_channel, percentage, w, win, url, stream_data = data
- # It could be failed
- if out == "search":
- return ui.load(win, claim_search.find, claim_search.render, win, win.url.get_text(), [], 1, {"order_by":""})
-
-
- #####################################################
- # DRAWING PART ( GTK ) #
- #####################################################
- try:
- price = out["value"]["fee"]["amount"]
- except:
- price = 0
- try:
- currency = out["value"]["fee"]["currency"]
- except:
- currency = "LBC"
-
-
-
- box = Gtk.HBox()
- outbox = Gtk.VBox()
- #### THUMBNAIL ###
- thumb = ""
- try:
- thumb = out["value"]["thumbnail"]["url"]
- thumb_url = ui.image_save_name(thumb)
- def thumb_open(w):
- oscalls.Open(thumb_url)
- thumb_button = Gtk.Button()
- thumb_button.set_tooltip_text(thumb)
- if is_channel:
- thumb_image = ui.load(win, ui.net_image_calculation, ui.net_image_render, thumb, 150, "", True)
- else:
- thumb_image = ui.load(win, ui.net_image_calculation, ui.net_image_render, thumb, 400, "", True)
- thumb_button.add(thumb_image)
- thumb_button.set_relief(Gtk.ReliefStyle.NONE)
- thumb_button.connect("clicked", thumb_open)
- box.pack_start(thumb_button, False, False, False)
- except:
- pass
-
- outbox.pack_start(box, False, False, False)
- from_right_to_thumbnail = Gtk.VBox()
- box.pack_end(from_right_to_thumbnail, True, True, False)
- # If channel load banner
- if is_channel:
- if "cover" in out["value"]:
- # This is a hack to set the scroller at the center
- # of the cover image
- def render_cover(calc):
- # So this fucntion pretends to be the net_image_render
-
- r = ui.net_image_render(calc) # It does call it though
- # But we need the size of the image and we need to do
- # something after the image is loaded.
- def wait():
- # This will execute after a delay
-
- v = channel_scroll.get_vadjustment()
- h = channel_scroll.get_hadjustment()
- # TODO: Check that the math is correct. It seems
- # to move the scrolls a bit too far.
- v.set_value( r.get_pixbuf().get_height() / 2 - 75)
- h.set_value( r.get_pixbuf().get_width() / 2 - 100)
-
- def start_waiting():
- # This is the delay thread
-
- time.sleep(0.1)
- GLib.idle_add(wait) # Making sure to use GLib so not
- # to get Segmentation Fault
-
- load_thread = threading.Thread(target=start_waiting)
- load_thread.start()
- # And we need to give the renderer the image itself, so it
- # could be added into the UI.
- return r # This happens before we scroll to the center
- # So think about it:
- # 1. ui.load loads the ui.net_image_calclation which downloads the cover
- # 2. This function runs. Activating ui.net_image_render getting the Gtk.Image
- # 3. We setup the thread that waits for 0.1 seconds
- # 4. Meanwhile ui.load recieves the ui.image and window updates with it
- # 5. 0.1 seconds later: we calculate the width and height of the image
- # and set the scroll adjustments accordilgly.
- # Simple isn't it?
-
- channel_banner = ui.load(win, ui.net_image_calculation, render_cover, out["value"]["cover"]["url"], False, "", True)
- channel_scroll = Gtk.ScrolledWindow()
- channel_scroll.set_size_request(400,150)
- channel_scroll.add_with_viewport(channel_banner)
- from_right_to_thumbnail.pack_start(channel_scroll, False, False, False)
- else:
- try:
- channel_scroll.destroy()
- except:
- pass
-
-
- #### NAME / CHANNEL ####
- the_packing_box = from_right_to_thumbnail
- if is_channel:
- the_packing_box = outbox
-
- name_channel_box = Gtk.VBox()
- the_packing_box.pack_start(name_channel_box, False, False, False)
- # Channel
- if "signing_channel" in out:
- chbox = Gtk.HBox()
- name_channel_box.pack_start(chbox, False, False, 0)
- chbox.pack_start(ui.go_to_channel(win, out["signing_channel"]),True,True,False)
-
- fbutton = follow.button(win, out["signing_channel"]["permanent_url"])
- chbox.pack_start(fbutton, False, False, 0 )
- elif is_channel:
- fbutton = follow.button(win, out["permanent_url"])
- name_channel_box.pack_start(fbutton, False, False, False)
-
- # name it self
- title = out["name"]
- try:
- title = out["value"]["title"]
- except:
- pass
- title_label = Gtk.Label()
- title_label.set_line_wrap_mode( Gtk.WrapMode.WORD )
- title_label.set_line_wrap(True)
- title_label.set_markup('<span size="x-large"> '+title+'</span> ')
- title_label.set_selectable(True)
- title_label.set_css_name("")
- name_channel_box.pack_start(title_label, False, False, False)
- ################# TOOL BAR ##################
- print("streamdata ++++++++++++++++++++++++++++++++++++ ", stream_data)
- toolbox = Gtk.HBox()
- the_packing_box.pack_start(toolbox, False, False,False)
- # The channel might be live from a different publication. I want to give a button to resolve it.
- active_id = stream_data.get("data",{}).get("ActiveClaim", {}).get("ClaimID", "")
- if stream_data.get("data",{}).get("Live", False) and active_id != out["claim_id"]:
-
- live_elsewhere_box = Gtk.HBox()
- the_packing_box.pack_start(Gtk.HSeparator(), False, False, 5)
- the_packing_box.pack_start(live_elsewhere_box, False, False,False)
- live_elsewhere_box.pack_start(Gtk.VSeparator(), 0,0,10)
- live_elsewhere_box.pack_start(ui.icon(win, "dialog-warning"), 0,0,0)
-
- live_elsewhere_box.pack_start(Gtk.Label(" Currently Streaming! "), 0,0,0)
- def go_to_livestream(widget):
- resolve_url = fetch.lbrynet("claim_search", {"claim_id":active_id}).get("items", [{}])[0].get("canonical_url","")
- win.resolve_tab = "new_tab"
- win.url.set_text(resolve_url)
- win.url.activate()
-
- go_button = Gtk.Button()
- go_button.set_relief(Gtk.ReliefStyle.NONE)
- go_box = Gtk.HBox()
- go_button.add(go_box)
- go_box.pack_start(ui.icon(win, "go-jump"), 0,0,0)
- go_box.pack_start(Gtk.Label(" Go To Livestream "),0,0,0)
- go_button.connect("clicked", go_to_livestream)
- live_elsewhere_box.pack_start(go_button, 0,0,0)
-
- if not is_channel:
- # LIVESTREAM LAUNCH
- if stream_data.get("data",{}).get("Live", False) and active_id == out["claim_id"]:
- def live_launch_action(w):
- suggest.record_tags_to_suggestions(out.get("value", {}).get("tags", []))
- Popen([win.settings["live_stream_player"], win.settings["librarian_instance"]+"/live/content/"+out["signing_channel"]["claim_id"]+"/master.m3u8"])
- live_launch_button = Gtk.Button()
- live_launch_button.connect("clicked", live_launch_action)
- live_launch_button.set_relief(Gtk.ReliefStyle.NONE)
- live_launch_box = Gtk.HBox()
- live_launch_button.add(live_launch_box)
- live_launch_icon = ui.icon(win, "media-playback-start")
- live_launch_box.pack_start(live_launch_icon, False, False, False)
- live_launch_box.pack_start(Gtk.Label(" Watch Livestream "), False, False, False)
- toolbox.pack_start(live_launch_button, False,False,False)
- else:
- def download_action(w):
- suggest.record_tags_to_suggestions(out.get("value", {}).get("tags", []))
- start_downloading(url)
- download_button = Gtk.Button()
- download_button.connect("clicked", download_action)
- download_button.set_relief(Gtk.ReliefStyle.NONE)
- download_box = Gtk.HBox()
- download_button.add(download_box)
- download_icon = ui.icon(win, "go-down")
- download_box.pack_start(download_icon, False, False, False)
- #filesize
- labeltext = " Download"
- if price:
- labeltext = " Buy for "+str(price)+" "+currency
- try:
- filesize = out["value"]["source"]["size"]
- labeltext = labeltext + " ("+csize(filesize)+")"
- except:
- filesize = 0
- download_box.pack_start(Gtk.Label(labeltext), False, False, False)
- toolbox.pack_start(download_button, False,False,False)
- download_bar = Gtk.ProgressBar()
- the_packing_box.pack_start(download_bar, False, False,False)
- def delete_action(w):
- filename = get_downloaded_file(out["claim_id"])
- delete_file(out["claim_id"])
- try:
- os.remove(filename)
- except:
- pass
- delete_button = Gtk.Button()
- delete_button.connect("clicked", delete_action)
- delete_button.set_relief(Gtk.ReliefStyle.NONE)
- delete_box = Gtk.HBox()
- delete_button.add(delete_box)
- delete_icon = ui.icon(win,"edit-delete")
- delete_box.pack_start(delete_icon, False, False, False)
- delete_box.pack_start(Gtk.Label(" Delete "), False, False, False)
- toolbox.pack_start(delete_button, False,False,False)
- def launch_action(w):
- oscalls.Open(get_downloaded_file(out["claim_id"]))
- launch_button = Gtk.Button()
- launch_button.connect("clicked", launch_action)
- launch_button.set_relief(Gtk.ReliefStyle.NONE)
- launch_box = Gtk.HBox()
- launch_button.add(launch_box)
- launch_icon = ui.icon(win, "media-playback-start")
- launch_box.pack_start(launch_icon, False, False, False)
- launch_box.pack_start(Gtk.Label(" Launch "), False, False, False)
- toolbox.pack_start(launch_button, False,False,False)
- win.download_buttons[out["claim_id"]] = True
- t = threading.Thread(target=downloading_check_thread, args=(win, out["claim_id"],download_button, delete_button, launch_button, download_bar))
- t.setDaemon(True)
- t.start()
- def kill_daemon(w):
- win.download_buttons[out["claim_id"]] = False
- download_button.connect("destroy", kill_daemon)
- #################### REPOST BUTTON #######################
- toolbox.pack_start(Gtk.HSeparator(), False,False,5)
- def repost_action(w):
- print("name", repost_name_entry.get_text())
- print("bid", repost_bid_entry.get_value())
- print("channel", win.channel["name"])
- print("channel_id", win.channel["claim_id"])
- repost_out = fetch.lbrynet("stream_repost",
- {"name":repost_name_entry.get_text(),
- "bid":str(float(repost_bid_entry.get_value())),
- "claim_id":out["claim_id"],
- "channel_id":win.channel["claim_id"]})
- print(repost_out)
- if "error" in repost_out:
- ui.notify(win, "Error while reposting", str(repost_out["error"]))
- else:
- ui.notify(win, "Reposted succesfully.", "lbry://"+win.channel["name"]+"/"+repost_name_entry.get_text())
- repost_menu = Gtk.Popover()
- repost_menu_box = Gtk.VBox()
- repost_menu.add(repost_menu_box)
- # Repost requires 3 entries of data:
- # Name:
- def on_url(w):
- w.set_text(publish.lbryname(w.get_text(), force=False))
- repost_name_box = Gtk.HBox()
- repost_menu_box.pack_start(repost_name_box, 0,0,0)
- channel_name = win.channel.get("name", "")
- repost_name_box.pack_start(Gtk.Label(" lbry://"), 0,0,0)
- repost_name_entry = Gtk.Entry()
- repost_name_entry.connect("changed", on_url)
- repost_name_box.pack_start(repost_name_entry, 1,1,0)
- # Bid:
- repost_bid_box = Gtk.HBox()
- repost_menu_box.pack_start(repost_bid_box, 0,0,0)
- bid_adjust = Gtk.Adjustment(0.01,
- lower=0.0001,
- upper=1000000000,
- step_increment=0.1)
- repost_bid_entry = Gtk.SpinButton(adjustment=bid_adjust,
- digits=4)
- repost_bid_box.pack_start(Gtk.Label(" Bid: "), False, False, 0)
- repost_bid_box.pack_end(repost_bid_entry, False, False, 0)
- # Repost button
- do_repost_button = Gtk.Button()
- do_repost_button.connect("clicked", repost_action)
- do_repost_button.set_relief(Gtk.ReliefStyle.NONE)
- do_repost_box = Gtk.HBox()
- do_repost_box.pack_start(ui.icon(win, "media-playlist-repeat"), 0,0,0)
- do_repost_box.pack_start(Gtk.Label(" Do Re-Post "), False, False, False)
- do_repost_button.add(do_repost_box)
- repost_menu_box.pack_start(do_repost_button, 0,0,0)
- repost_menu_box.show_all()
- repost_button = Gtk.MenuButton(popover=repost_menu)
- repost_button.set_relief(Gtk.ReliefStyle.NONE)
- repost_box = Gtk.HBox()
- repost_button.add(repost_box)
- repost_icon = ui.icon(win, "media-playlist-repeat")
- repost_box.pack_start(repost_icon, False, False, False)
- try:
- reposted_times = out["meta"]["reposted"]
- if not reposted_times:
- 1/0 # kill switch to go straig to except LOL. I'm hacking. What
- # do you want from me.
- repost_label = " Re-Post ( "+str(reposted_times)+" ) "
- except:
- repost_label = " Re-Post "
- repost_box.pack_start(Gtk.Label(repost_label), False, False, False)
- toolbox.pack_start(repost_button, False,False,False)
- ############# SUPPORT BUTTON ############
- support_menu = Gtk.Popover()
- support_menu_box = Gtk.VBox()
- support_menu.add(support_menu_box)
-
- # Bid:
- support_bid_box = Gtk.HBox()
- support_menu_box.pack_start(support_bid_box, 0,0,0)
- support_bid_adjust = Gtk.Adjustment(0.01,
- lower=0.0001,
- upper=1000000000,
- step_increment=0.1)
- support_bid_entry = Gtk.SpinButton(adjustment=support_bid_adjust,
- digits=4)
- support_bid_box.pack_start(Gtk.Label(" Amount: "), False, False, 0)
- support_bid_box.pack_end(support_bid_entry, False, False, 0)
- # Do button
- def support_action(w):
- print("support amount", support_bid_entry.get_value())
- print("channel", win.channel["name"])
- print("channel_id", win.channel["claim_id"])
- support_out = fetch.lbrynet("support_create",
- {"amount":str(float(support_bid_entry.get_value())),
- "claim_id":out["claim_id"],
- "channel_id":win.channel["claim_id"],
- "tip":True})
- print(support_out)
- if "error" in support_out:
- ui.notify(win, "Error while reposting", str(support_out["error"]))
- else:
- ui.notify(win, "Supported succesfully.")
-
- do_support_button = Gtk.Button()
- do_support_button.connect("clicked", support_action)
- do_support_button.set_relief(Gtk.ReliefStyle.NONE)
- do_support_box = Gtk.HBox()
- do_support_box.pack_start(ui.icon(win, "emblem-favorite"), 0,0,0)
- do_support_box.pack_start(Gtk.Label(" Do Support "), False, False, False)
- do_support_button.add(do_support_box)
- support_menu_box.pack_start(do_support_button, 0,0,0)
-
- support_menu_box.show_all()
- support_button = Gtk.MenuButton(popover=support_menu)
- support_button.set_relief(Gtk.ReliefStyle.NONE)
- support_box = Gtk.HBox()
- support_button.add(support_box)
- support_icon = ui.icon(win, "emblem-favorite")
- support_box.pack_start(support_icon, False, False, False)
- try:
- rounded = round(float(out["meta"]["effective_amount"]), 2)
- if not rounded:
- rounded = out["meta"]["effective_amount"]
- support_label = " Support ( "+str(rounded)+" ) "
- except Exception as e:
- print(e)
- support_label = " Support "
- support_box.pack_start(Gtk.Label(support_label), False, False, False)
- toolbox.pack_start(support_button, False,False,False)
-
- ########### BOTTOM NOTEBOOK ##############
- notebook = Gtk.Notebook()
- notebook.set_scrollable(True)
- outbox.pack_start(notebook, True, True,False)
-
-
-
- # If article read article
- try:
- if out["value"]["source"]["media_type"] == "text/markdown" and price == 0:
- suggest.record_tags_to_suggestions(out.get("value", {}).get("tags", []))
-
- # We download it first
-
- playout = fetch.lbrynet("get", {"uri":url, "save_file":True})
- # playout = check_output(["flbry/lbrynet",
- # "get", url])
- # # Parsing the Json
- # playout = json.loads(playout)
- md_text = open(playout['download_path'])
-
- md_text = md_text.read()
-
-
- # Markdown covenreted
- md_scrl = Gtk.ScrolledWindow()
- md_view = Gtk.TextView()
- md_view.set_wrap_mode(Gtk.WrapMode.WORD )
- md_buffer = md_view.get_buffer()
- md_view.set_editable(False)
- md_scrl.add(md_view)
- md_buffer.set_text(md_text)
- markdown.convert(win, md_view)
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "text-x-generic"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Read Article "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(md_scrl, detailsbox)
- # Markdown source
- md_scrl = Gtk.ScrolledWindow()
- md_view = Gtk.TextView()
- #md_view.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0.2,0.2,0.2, 1))
- #md_view.override_color(Gtk.StateType.NORMAL, Gdk.RGBA(0.9,0.9,0.9, 1))
- md_view.override_font(Pango.FontDescription("Monospace"))
- md_view.set_wrap_mode(Gtk.WrapMode.WORD )
- md_buffer = md_view.get_buffer()
- md_view.set_editable(False)
- md_scrl.add(md_view)
- md_buffer.set_text(md_text)
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "text-x-preview"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Source of Article "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(md_scrl, detailsbox)
-
- except Exception as e:
- print("FUCKING ERROR")
- print(e)
- print()
- # Channel Uploads / Publications
-
- if is_channel:
- uploads_box = ui.load(win, claim_search.find, claim_search.render, win, "", [out["claim_id"]], )
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "folder-remote"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Publications "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(uploads_box, detailsbox)
-
-
- ##### DESCRIPTION ####
-
- try:
- description_scrl = Gtk.ScrolledWindow()
- description_scrl.set_size_request(500,200)
- description_field = Gtk.TextView()
- description_field.set_wrap_mode(Gtk.WrapMode.WORD )
- description_field.set_editable(False)
- description_buffer = description_field.get_buffer()
- description_buffer.set_text(out["value"]["description"])
- markdown.convert(win, description_field)
- description_box = Gtk.VBox()
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "text-x-generic"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Description "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(description_scrl, detailsbox)
-
- description_box.pack_start(description_scrl, False, False, False)
- description_scrl.add(description_field)
- except:
- pass
- ######## COMMENTS ########
-
- com_box = Gtk.VPaned()
- com_box.set_position(250)
- com_scrl = Gtk.ScrolledWindow()
- com_scrl.set_vexpand(0)
- #com_scrl.set_hexpand(0)
- comments_widget = ui.load(win, comments.list_comments, comments.render_comments, win, out )
- com_scrl.add(comments_widget)
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "document-send"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Comments "), True, True, True)
- detailsbox.show_all()
- com_box.add1(comments.comment_input(win, out["claim_id"]))
- com_box.add2(com_scrl)
- notebook.append_page(com_box, detailsbox)
-
- ##### Details #######
- # Almost like Raw Data but shows only the important stuff
-
- details = {"LBRY URL: ":url,
- "Price: ":str(price)+" "+str(currency)}
- try:
- details["Claim ID: "] = out["claim_id"]
- except:
- pass
- try:
- details["Upload Bid: "] = out["amount"]+" LBC"
- except:
- pass
- try:
- details["Support: "] = out["meta"]["support_amount"]+" LBC"
- except:
- pass
- try:
- if is_channel:
- details["Odysee Subscribers: "] = odysee.get_odysee_subs(win, out["claim_id"])[0]
- else:
- details["Odysee Views: "] = odysee.get_odysee_views(win, out["claim_id"])[0]
- except:
- pass
-
- try:
- details["Filename: "] = out["value"]["source"]["name"]
- except:
- pass
- try:
- details["File Size:"] = csize(filesize)
- except:
- pass
- try:
- details["License: "] = out["value"]["license"]
- except:
- pass
- try:
- details["Released at: "] = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(out["value"]["release_time"])))
- except:
- pass
- try:
- #print(out["value"]["tags"])
- details["Tags: "] = out["value"]["tags"]
- except:
- pass
-
- det_scrl = Gtk.ScrolledWindow()
- det_view = data_view.data_widget(details)
- det_scrl.add(det_view)
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "dialog-information"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Details "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(det_scrl, detailsbox)
- ######### ANALYTICS GRAPH #######
-
- plot_chart = fetch.lbrynet("txo_plot", { "days_back":1000, # Fetch 100 days of txo
- "exclude_internal_transfers":True, # Without crap
- "is_not_my_input":True, # Not from me ( as in support only )
- "claim_id":out["claim_id"]
- })
- if plot_chart:
- chart_box = Gtk.VBox()
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "text-csv"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Analytics "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(chart_box, detailsbox)
- graph_data = {"items":[],
- "zoom":[0,0],
- "allow_negative":False
- }
-
- for i in plot_chart:
- a = {}
- a["amount"] = i["total"]
- a["timestamp"] = int(time.mktime(time.strptime(i["day"],"%Y-%m-%d")))
- graph_data["items"].append(a)
-
-
- the_graph = analytics.graph(win, graph_data, "Analytics")
- chart_box.pack_start(the_graph,1,1,1)
- try:
- t = title
- if is_channel:
- t = ""
-
- uploads_box = ui.load(win, claim_search.find, claim_search.render, win, t, [], 1, {"any_tags":out["value"]["tags"] , "claim_type":out["value_type"]} )
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "folder-remote"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Similar "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(uploads_box, detailsbox)
- except:
- pass
-
- ##### Raw Data #######
- raw_scrl = Gtk.ScrolledWindow()
- raw_view = data_view.data_widget(out)
- raw_scrl.add(raw_view)
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(ui.icon(win, "dialog-warning"), False, False, False)
- detailsbox.pack_start(Gtk.Label(" Extra Details "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(raw_scrl, detailsbox)
-
-
- #outbox.show_all()
- return outbox
- def downloaded(claim_id):
- # Returns a fraction ( from 0 to 1 ) of the download
- # percentage. If it's a 0, we can use it to display
- # the download button.
- #out = check_output(["flbry/lbrynet",
- # "file", "list", "--claim_id="+claim_id])
- out = fetch.lbrynet("file_list", {"claim_id":claim_id})
- #print(out, '\n\n')
-
- try:
- #out = json.loads(out)
- out = out["items"][0]
-
- if out["status"] == "finished":
- return 1
- else:
- return out["written_bytes"] / out["total_bytes"]
-
- except:
- return 0
- def get_downloaded_file(claim_id):
- #out = check_output(["flbry/lbrynet",
- # "file", "list", "--claim_id="+claim_id])
- out = fetch.lbrynet("file_list", {"claim_id":claim_id})
- try:
- #out = json.loads(out)
- out = out["items"][0]
- return out["download_path"]
- except:
- return ""
- def delete_file(claim_id):
- #check_output(["flbry/lbrynet",
- # "file", "delete", "--claim_id="+claim_id])
- fetch.lbrynet("file_delete", {"claim_id":claim_id})
- def start_downloading(url):
- out = fetch.lbrynet("get", {"uri":url, "save_file":True})
-
- def downloading_check_thread(win, claim_id,
- download_button,
- delete_button,
- launch_button,
- progress_bar):
- # This is a thread that will toggle buttons on/off
- # based on a curretly downloading file.
- def update(fraction):
- if not fraction: # if it's 0
- download_button.set_visible(True)
- delete_button.set_visible(False)
- launch_button.set_visible(False)
- progress_bar.set_visible(False)
- else:
- download_button.set_visible(False)
- delete_button.set_visible(True)
- launch_button.set_visible(True)
- progress_bar.set_visible(True)
- progress_bar.set_fraction(fraction)
- if fraction == 1:
- progress_bar.set_visible(False)
-
- while True:
-
- fraction = downloaded(claim_id)
- GLib.idle_add(update, fraction)
- time.sleep(2) # The new algorithm is too fast LOL
- if not win.download_buttons[claim_id]:
- return
- def csize(x):
- x = float(x)
- l = ["B","KB", "MB", "GB", "TB"]
- for i in range(5):
- if x > 1024:
- x = x / 1024
- else:
- return str(round(x, 2))+" "+l[i]
- return str(round(x, 2))+" "+l[i]
|