123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- #####################################################################
- # #
- # 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 is the seach mechanism
- import threading
- from flbry import ui
- from flbry import fetch
- from gi.repository import Gtk
- from gi.repository import GLib
- def find(win, arg="", channel_ids=[], page=1, r={}, flowbox=False):
-
- # This is very dumb. I did a mess with the inputs of this command
- # now I'm trying to add a new feature, without rewriting a whole
- # lot. And it requires form me to give it a weird kind of thing.
- sr = r.copy()
-
- if "method" in r:
- method = r["method"]
- del r["method"]
- c = {}
- c["page"] = page
- else:
- method = "claim_search"
-
- c = {}
- c["text"] = arg
-
- c["channel_ids"] = channel_ids
- c["page"] = page
-
-
- c["order_by"] = "creation_height" #{"order_by":"release_time"}
- c["remove_duplicates"] = True
- # TAGS TO EXCLUDE ( E.G. 'mature', 'porn' )
- tags = win.settings["filter_tags"] # It's set in the settings
- c["not_tags"] = tags
- # Any overwrites ?
-
- for i in r:
- if r[i]:
- c[i] = r[i]
- elif c[i]:
- del c[i]
-
- channel_load = True
- if len(channel_ids) == 1:
- channel_load = False
- out = fetch.lbrynet(method, c)
-
- same = [win, arg, channel_ids, page+1, sr]
- if flowbox:
- def add_to_flowbox(flowbox, out):
- for i in out["items"]:
- flowbox.add(ui.search_item(win, i, channel_load))
- if len(out["items"]) > 1:
- lastthing(win, same, flowbox)
- flowbox.show_all()
- GLib.idle_add(add_to_flowbox, flowbox, out)
- else:
- return [win, out, channel_load, same, sr]
- def render(out):
- win, out, channel_load, same, r = out
- overlay = Gtk.Overlay()
-
- scrolled = Gtk.ScrolledWindow()
- scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
- flowbox = Gtk.FlowBox()
- flowbox.set_valign(Gtk.Align.START)
- flowbox.set_max_children_per_line(30)
- flowbox.set_selection_mode(Gtk.SelectionMode.NONE)
- scrolled.add(flowbox)
-
- box = Gtk.VBox()
- for i in out["items"]:
- flowbox.add(ui.search_item(win, i, channel_load))
- if len(out["items"]) > 1:
- lastthing(win, same, flowbox)
- overlay.add(scrolled)
- ############ SEARCH MENU ##############
- settings_menu = Gtk.Popover()
- settings_scroll = Gtk.ScrolledWindow()
- settings_menu.add(settings_scroll)
- settings_scroll.set_size_request(400,400)
- menu_box = Gtk.VBox()
- settings_scroll.add(menu_box)
-
- menu_box.pack_start(Gtk.Label(" Search Options: "), 0,0,5)
- #### SEARCH TERMS ###
- # name - the LBRY url of publication.
- collapsable = Gtk.Expander(label=" By Text Query: ")
- menu_box.pack_start(collapsable, 0,0,5)
- term_box = Gtk.VBox()
- collapsable.add(term_box)
- hbox = Gtk.HBox()
- term_box.pack_start(hbox, 0,0,5)
- hbox.pack_start(Gtk.Label(" LBRY url: "), 0,0,0)
-
- lbry_name_entry = Gtk.Entry()
- if same[-1].get("name"):
- lbry_name_entry.set_text(same[-1]["name"])
- hbox.pack_end(lbry_name_entry, 1,1,0)
-
- # text - the text in title
- hbox = Gtk.HBox()
- term_box.pack_start(hbox, 0,0,5)
- hbox.pack_start(Gtk.Label(" Search by Text: "), 0,0,0)
-
- text_entry = Gtk.Entry()
- if same[1]:
- text_entry.set_text(same[1])
- elif same[-1].get("text"):
- text_entry.set_text(same[-1]["text"])
- hbox.pack_end(text_entry, 1,1,0)
-
- # claim_id - search partial of full claim_id
- collapsable = Gtk.Expander(label=" By Claim ID: ")
- menu_box.pack_start(collapsable, 0,0,5)
- term_box = Gtk.VBox()
- collapsable.add(term_box)
- hbox = Gtk.HBox()
- term_box.pack_start(hbox, 0,0,5)
- hbox.pack_start(Gtk.Label(" Claim ID: "), 0,0,0)
-
- claim_id_entry = Gtk.Entry()
- if same[-1].get("claim_id"):
- claim_id_entry.set_text(same[-1]["claim_id"])
- hbox.pack_start(claim_id_entry, 1,1,0)
- # claim_ids - search partial of full claim_id
- term_box.pack_start(Gtk.Label(" Many Full Claim IDs "), 0,0,5)
- claim_ids_list = []
- if same[-1].get("claim_ids"):
- claim_ids_list = same[-1].get("claim_ids")
-
- claim_ids_editor = ui.tags_editor(win, claim_ids_list)
- term_box.pack_start(claim_ids_editor, 0,0,0)
- ## TAGS ##
- collapsable = Gtk.Expander(label=" Tags: ")
- menu_box.pack_start(collapsable, 0,0,5)
- term_box = Gtk.VBox()
- collapsable.add(term_box)
- term_box.pack_start(Gtk.Label(" Any of: "), 0,0,5)
- any_tags_list = []
- if same[-1].get("any_tags"):
- any_tags_list = same[-1].get("any_tags")
-
- tags_editor = ui.tags_editor(win, any_tags_list)
- term_box.pack_start(tags_editor, 0,0,0)
- term_box.pack_start(Gtk.Label(" All of: "), 0,0,5)
- all_tags_list = []
- if same[-1].get("all_tags"):
- all_tags_list = same[-1].get("all_tags")
-
- tags_editor = ui.tags_editor(win, all_tags_list)
- term_box.pack_start(tags_editor, 0,0,0)
- term_box.pack_start(Gtk.Label(" Excluding: "), 0,0,5)
- not_tags_list = []
- if same[-1].get("not_tags"):
- not_tags_list = same[-1].get("not_tags")
-
-
- tags_editor = ui.tags_editor(win, not_tags_list)
- term_box.pack_start(tags_editor, 0,0,0)
- ## CHANNELS ##
- collapsable = Gtk.Expander(label=" Channels: ")
- menu_box.pack_start(collapsable, 0,0,5)
- term_box = Gtk.VBox()
- collapsable.add(term_box)
-
- hbox = Gtk.HBox()
- term_box.pack_start(hbox, 0,0,5)
- hbox.pack_start(Gtk.Label(" Channel Name: "), 0,0,0)
-
- channel_entry = Gtk.Entry()
- if same[-1].get("channel"):
- channel_entry.set_text(same[-1]["channel"])
- hbox.pack_start(channel_entry, 1,1,0)
-
- term_box.pack_start(Gtk.Label(" Anything from (channel's claim IDs): "), 0,0,5)
-
- any_channels_list = []
- if same[2]:
- any_channels_list = same[2]
- elif same[-1].get("channel_ids"):
- any_channels_list = same[-1]["channel_ids"]
-
- tags_editor = ui.tags_editor(win, any_channels_list)
- term_box.pack_start(tags_editor, 0,0,0)
- term_box.pack_start(Gtk.Label(" Excluding (channel's claim IDs): "), 0,0,5)
- not_channels_list = []
- if same[-1].get("not_channel_ids"):
- not_channels_list = same[-1]["not_channel_ids"]
-
- tags_editor = ui.tags_editor(win, not_channels_list)
- term_box.pack_start(tags_editor, 0,0,0)
-
- ## ORDER BY ##
- collapsable = Gtk.Expander(label=" Order: ")
- menu_box.pack_start(collapsable, 0,0,5)
- term_box = Gtk.VBox()
- collapsable.add(term_box)
- order_by_rules = {
- "Name":"name",
- "Release Time":"release_time",
- "Trending":"trending_mixed",
- "Trending (Global)":"trending_global",
- "Trending (Group)":"trending_group",
- "Trending (Local)":"trending_local",
- "Bid":"amount",
- "Support":"support_amount",
- "Support plus Bid":"effective_amount",
- "Block Height":"height",
- "Start Block":"activation_height"
-
- }
-
- order_by = Gtk.ComboBoxText()
-
- was_set = False
- for n, i in enumerate(order_by_rules):
- order_by.append_text(i)
- if order_by_rules[i] in str(same[-1].get("order_by")):
- order_by.set_active(n)
- was_set = True
- if not was_set:
- order_by.set_active(1)
- term_box.pack_start(order_by, 0,0,5)
-
- hbox = Gtk.HBox()
- term_box.pack_start(hbox, 0,0,5)
- hbox.pack_start(Gtk.Label(" Reverse: "), 0,0,0)
- order_reverse = Gtk.Switch()
- if "^" in str(same[-1].get("order_by")):
- order_reverse.set_active(True)
- hbox.pack_end(order_reverse, 0,0,0)
-
- ## ORDER BY ##
- collapsable = Gtk.Expander(label=" Type: ")
- menu_box.pack_start(collapsable, 0,0,5)
- term_box = Gtk.VBox()
- collapsable.add(term_box)
- claim_types = {
- "Every Claim Type":"",
- "Channel":"channel",
- "File":"stream",
- "Re-Post":"repost",
- "Collection":"collection"
- }
- claim_type = Gtk.ComboBoxText()
- was_set = False
- for n, i in enumerate(claim_types):
- claim_type.append_text(i)
- if claim_types[i] in str(same[-1].get("claim_type")):
- claim_type.set_active(n)
- was_set = True
- if not was_set:
- claim_type.set_active(0)
- term_box.pack_start(claim_type, 0,0,5)
- ## FILETYPES ##
-
- term_box.pack_start(Gtk.Label(" Filetypes: "), 0,0,5)
-
- stream_types = []
- if same[-1].get("stream_types"):
- stream_types = same[-1]["stream_types"]
-
- stream_types_editor = ui.tags_editor(win, stream_types)
- stream_types_editor.set_tooltip_text("Types of a file. For example: video, audio, image, document, binary.")
- term_box.pack_start(stream_types_editor, 0,0,5)
- ## MIME-TYPES ##
-
- term_box.pack_start(Gtk.Label(" Mime-Types: "), 0,0,5)
-
- media_types = []
- if same[-1].get("media_types"):
- media_types = same[-1]["media_types"]
-
- media_types_editor = ui.tags_editor(win, media_types)
- media_types_editor.set_tooltip_text("Precise Formats. For example: image/png, audio/ogg, application/x-ext-blend")
-
- term_box.pack_start(media_types_editor, 0,0,5)
-
-
- ####### !!! RE _ SEARCH !!! #######
- def do_re_search(w):
- request = {}
- ## TEXT ##
- if lbry_name_entry.get_text():
- request["name"] = lbry_name_entry.get_text()
- if text_entry.get_text():
- request["text"] = text_entry.get_text()
- ## CLAIM ID ##
- if claim_id_entry.get_text():
- request["claim_id"] = claim_id_entry.get_text()
- if claim_ids_list:
- request["claim_ids"] = claim_ids_list
- ## TAGS ##
- if any_tags_list:
- request["any_tags"] = any_tags_list
- if all_tags_list:
- request["all_tags"] = all_tags_list
- if any_tags_list:
- request["not_tags"] = not_tags_list
- ## CHANNELS ##
- if channel_entry.get_text():
- request["channel"] = channel_entry.get_text()
- if any_channels_list:
- request["channel_ids"] = any_channels_list
- if not_channels_list:
- request["not_channel_ids"] = not_channels_list
- ## Order by ##
- prefix = ""
- if order_reverse.get_active():
- prefix = "^"
- request["order_by"] = prefix+list(order_by_rules.values())[order_by.get_active()]
- ## CLAIM TYPE ##
- if list(claim_types.values())[claim_type.get_active()]:
- request["claim_type"] = list(claim_types.values())[claim_type.get_active()]
- # Some logic related to what the user will percieve
- if request["channel_ids"] and not request.get("claim_ids") and request["claim_type"] == "channel":
- request["claim_ids"] = request["channel_ids"]
- request["channel_ids"] = []
- ## STREAM TYPE ##
- if stream_types:
- request["stream_types"] = stream_types
- ## MIME TYPES ##
- if media_types:
- request["media_types"] = media_types
-
- box = overlay.get_parent()
- overlay.destroy()
- resolve = ui.load(win, find, render, win, "", [], 1, request)
- box.pack_start(resolve, 1,1,0)
- box.show_all()
-
- re_search = Gtk.Button()
- re_search.connect("clicked", do_re_search)
- re_search.set_relief(Gtk.ReliefStyle.NONE)
- b = Gtk.HBox()
- b.pack_start(ui.icon(win, "system-search"),0,0,0)
- b.pack_start(Gtk.Label(" Re-Search "),0,0,0)
- re_search.add(b)
-
- menu_box.pack_end(re_search, 0,0,0)
-
-
- settings_scroll.show_all()
-
- b = Gtk.MenuButton(popover=settings_menu)
- b.add(ui.icon(win, "preferences-system"))
- b.set_halign(Gtk.Align.END)
- b.set_valign(Gtk.Align.END)
- # Set margins for scrollbar
- b.set_margin_right(20)
- b.set_margin_bottom(20)
- overlay.add_overlay(b)
-
- return overlay
- def lastthing(win, same, flowbox):
- # THis is a hack. I use a spinner to get a draw event
- # when the user scrolls far enough, it will execute it
- # to load more stuff
- spinner_more = ui.icon(win, "loading", "gif")
- flowbox.add(spinner_more)
- def draw_event(w, e):
-
- print("EVENT MOTHERFUCKER")
- w.destroy()
- same.append(flowbox)
- print("SAME:", same)
- load_thread = threading.Thread(target=find, args=[*same])
- load_thread.setDaemon(True)
- load_thread.start()
- spinner_more.connect("draw", draw_event)
-
-
|