Add files from 6a34355fda commit of FastLBRY-GTK notabug.org repo by jyamihud without the flbry/lbrynet binary
711 lines
25 KiB
Python
711 lines
25 KiB
Python
#####################################################################
|
|
# #
|
|
# 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 json
|
|
import random
|
|
import threading
|
|
import mimetypes
|
|
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 flbry import markdown
|
|
from flbry import ui
|
|
from flbry import fetch
|
|
from flbry import settings
|
|
|
|
##################################################################
|
|
# This file touches publication to LBRY network. #
|
|
##################################################################
|
|
|
|
|
|
def lbryname(name="", force=True):
|
|
|
|
# This creates a random string of characters.
|
|
|
|
good = "qwertyuiopasdfghjklzxcvbnm-_QWERTYUIOPASDFGHJKLZXCVBNM1234567890"
|
|
if not name and force:
|
|
for i in range(70):
|
|
name = name + random.choice(good)
|
|
return name
|
|
|
|
# This removes all non-good characters from the name
|
|
|
|
new_name = unicodedata.normalize('NFD', name).strip().casefold()
|
|
# Patterns to keep out.
|
|
# Hint from <lbry-sdk>/lbry/schema/url.py
|
|
# - replaced "[^=" with "[="
|
|
# - replaced 'FF]+"' with 'FF" \'
|
|
# - added 'r"\s]+"' line
|
|
bad_pattern = re.compile(
|
|
r"[=&#:$@%?;\"/\\<>%{}|^~`\[\]" \
|
|
r"\u0000-\u0020\uD800-\uDFFF\uFFFE-\uFFFF" \
|
|
r"\s]+"
|
|
)
|
|
new_name = bad_pattern.sub("-", new_name)
|
|
|
|
return new_name
|
|
|
|
DEFAULT_DATA = {"name":"",
|
|
"bid":0.001,
|
|
"file_path":"",
|
|
"title":"",
|
|
"license":"",
|
|
"license_url":"",
|
|
"thumbnail_url":"",
|
|
"channel_id":"",
|
|
"channel_name":"",
|
|
"description":"",
|
|
"fee_amount":0,
|
|
"tags":[]
|
|
}
|
|
|
|
LICENSES = [
|
|
# NAME , URL , COMMENT
|
|
["GNU General Public License Version 3 (or later)",
|
|
"https://www.gnu.org/licenses/gpl-3.0.html",
|
|
"Strong Copyleft. Recommended for Software."],
|
|
["GNU General Public License Version 3 (only)",
|
|
"https://www.gnu.org/licenses/gpl-3.0.html",
|
|
"Strong Copyleft."],
|
|
["GNU Free Documentation License",
|
|
"https://www.gnu.org/licenses/fdl-1.3.html",
|
|
"Strong Copyleft. Recommended for books."],
|
|
["Creative Commons Attribution-ShareAlike 4.0 International",
|
|
"https://creativecommons.org/licenses/by-sa/4.0/",
|
|
"Copylefted, Recommended for Art."],
|
|
["Creative Commons Attribution 4.0 International",
|
|
"https://creativecommons.org/licenses/by/4.0/",
|
|
"Non Copylefted, Free License."],
|
|
["Creative Commons Zero 1.0 International",
|
|
"https://creativecommons.org/publicdomain/zero/1.0/",
|
|
"Public Domain"],
|
|
["Creative Commons Attribution-NoDerivatives 4.0 International",
|
|
"https://creativecommons.org/licenses/by-nd/4.0/",
|
|
"Does not allow changes. Recommended for opinion pieces."]
|
|
]
|
|
|
|
|
|
def window(win, data=DEFAULT_DATA):
|
|
|
|
# First, the data recieved could be not full.
|
|
|
|
for i in DEFAULT_DATA:
|
|
if i not in data:
|
|
data[i] = DEFAULT_DATA[i]
|
|
|
|
# Upload window
|
|
|
|
dialogWindow = Gtk.Dialog("Publish",
|
|
buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
|
Gtk.STOCK_OK, Gtk.ResponseType.OK),
|
|
)
|
|
|
|
box = dialogWindow.get_content_area()
|
|
|
|
#######################################################################
|
|
# #
|
|
# PRESETS #
|
|
# #
|
|
#######################################################################
|
|
|
|
#making sure the folder exists
|
|
try:
|
|
os.mkdir(settings.get_settings_folder()+"presets")
|
|
except:
|
|
pass
|
|
|
|
presets_list = []
|
|
for i in os.listdir(settings.get_settings_folder()+"presets"):
|
|
if i.endswith(".json"):
|
|
presets_list.append(i.replace(".json", ""))
|
|
|
|
def on_set_preset(w):
|
|
|
|
# This might be a little long one, but to hell with it.
|
|
######################################################
|
|
|
|
pn = presets_list[presets.get_active()]
|
|
|
|
# Opening the preset's json.
|
|
|
|
with open(settings.get_settings_folder()+"presets/"+pn+'.json') as f:
|
|
pdata = json.load(f)
|
|
|
|
# The data should be very similar. It was saved ( hopefully ) from
|
|
# the same data as what we use to publish.
|
|
|
|
exclude = ["name", "file_path", "tags"]
|
|
|
|
for d in pdata:
|
|
if d in exclude:
|
|
continue
|
|
|
|
data[d] = pdata[d]
|
|
|
|
|
|
|
|
# Now let's update the UI itself
|
|
|
|
# THIS SHOULD NOT RUN BEFORE THE UI IS FULLY LOADED !!!
|
|
|
|
# BID
|
|
bid_entry.set_value(data["bid"])
|
|
|
|
# TITLE
|
|
title.set_text(data["title"])
|
|
|
|
# LICENSE
|
|
for n, ch in enumerate(LICENSES):
|
|
if data["license"] == ch[0]:
|
|
licenses.set_active(n)
|
|
|
|
# THUMBNAIL_URL
|
|
thumbentry.set_text(data["thumbnail_url"])
|
|
refresh_thumb()
|
|
|
|
# CHANNEL_NAME
|
|
try:
|
|
for n, ch in enumerate(win.my_channels["items"]):
|
|
if data["channel_name"] == ch["name"] or \
|
|
data["channel_id"] == ch["claim_id"]:
|
|
select = n+1
|
|
channels_select.set_active(select)
|
|
except:
|
|
pass
|
|
|
|
# DESCRIPTION
|
|
detext.get_buffer().set_text(data["description"])
|
|
|
|
# FEE_AMOUNT
|
|
price_entry.set_value(data["fee_amount"])
|
|
|
|
# TAGS
|
|
|
|
# Tags ( because of the tags editor ) is a special case
|
|
# and we need to do this, so not to create a separate id()
|
|
# for the tags list. ( Tags editor is a separate function
|
|
# that accesses the same list and edit's it.
|
|
|
|
# First we need to remove all of the data.
|
|
tags = data["tags"].copy()
|
|
for t in tags:
|
|
data["tags"].remove(t)
|
|
# And now we want to add all of the tags one by one.
|
|
for t in pdata["tags"]:
|
|
data["tags"].append(t)
|
|
# And finally we want to give commands obtained from the tags
|
|
# object to update it visually.
|
|
for i in tagsbox.get_children():
|
|
i.destroy()
|
|
for tag in data["tags"]:
|
|
add_tag(tag)
|
|
|
|
|
|
presbox = Gtk.HBox()
|
|
box.pack_start(presbox, False, False, 0)
|
|
|
|
presbox.pack_start(Gtk.Label(" Presets: "), False, False, 0)
|
|
|
|
presets = Gtk.ComboBoxText()
|
|
presets.connect("changed", on_set_preset)
|
|
for n, ch in enumerate(presets_list):
|
|
presets.append_text(ch)
|
|
|
|
presbox.pack_start(presets, True, True, 0)
|
|
|
|
#####################################################################
|
|
|
|
presetsave = Gtk.Popover()
|
|
addb = Gtk.MenuButton(popover=presetsave)
|
|
addb.set_relief(Gtk.ReliefStyle.NONE)
|
|
addb.add(ui.icon(win, "list-add"))
|
|
presbox.pack_start(addb, False, False, 0)
|
|
|
|
psavebox = Gtk.VBox()
|
|
presetsave.add(psavebox)
|
|
|
|
pname = Gtk.Entry()
|
|
pname.set_text("name")
|
|
psavebox.pack_start(pname, False, False, False)
|
|
|
|
def save_preset(w):
|
|
|
|
update_data() # Making sure all data is in 'data'
|
|
|
|
pn = pname.get_text()
|
|
|
|
# Write the json file
|
|
with open(settings.get_settings_folder()+"presets/"+pn+'.json', 'w') as f:
|
|
json.dump(data, f, indent=4, sort_keys=True)
|
|
|
|
# Add the preset into presets
|
|
if pn not in presets_list:
|
|
presets.append_text(pn)
|
|
presets_list.append(pn)
|
|
|
|
# Select the current preset
|
|
for n, ch in enumerate(presets_list):
|
|
if ch == pn:
|
|
presets.set_active(n)
|
|
|
|
presets.grab_focus() # Closing the menu
|
|
pname.set_text("name")
|
|
|
|
psave = Gtk.Button("Save")
|
|
psave.connect("clicked", save_preset)
|
|
pname.connect("activate", save_preset)
|
|
psave.set_relief(Gtk.ReliefStyle.NONE)
|
|
psavebox.pack_start(psave, False, False, False)
|
|
psavebox.show_all()
|
|
|
|
|
|
#######################################################################
|
|
# #
|
|
# LBRY URL PART #
|
|
# #
|
|
#######################################################################
|
|
|
|
box.pack_start(Gtk.Label(" Channel | LBRY url "), False, True, 5)
|
|
|
|
urlbox = Gtk.HBox()
|
|
box.pack_start(urlbox, False, False, 0)
|
|
|
|
urlbox.pack_start(Gtk.Label(" lbry:// "), False, False, 0)
|
|
|
|
|
|
# This will work separately from the main channel selector, though it
|
|
# will be influenced by the main channel selector a bit.
|
|
|
|
def on_channel_changed(w):
|
|
ch = channels_select.get_active() - 1
|
|
|
|
if ch == -1:
|
|
data["channel_name"] = ""
|
|
data["channel_id"] = ""
|
|
else:
|
|
data["channel_name"] = win.my_channels["items"][ch]["name"]
|
|
data["channel_id"] = win.my_channels["items"][ch]["claim_id"]
|
|
|
|
|
|
channels_select = Gtk.ComboBoxText()
|
|
channels_select.connect("changed", on_channel_changed)
|
|
|
|
# Let's get a list of channels to show
|
|
channels = ["[anonymous]"]
|
|
select = 0
|
|
try: # could be no channel. So publication only anonymous
|
|
for n, ch in enumerate(win.my_channels["items"]):
|
|
channels.append(ch["name"]+":"+ch["claim_id"][0])
|
|
if data["channel_name"] == ch["name"] or \
|
|
data["channel_id"] == ch["claim_id"] or \
|
|
win.channel["claim_id"] == ch["claim_id"]:
|
|
select = n+1
|
|
|
|
except Exception as e:
|
|
print("DAMN!", e)
|
|
|
|
for ch in channels:
|
|
channels_select.append_text(ch)
|
|
channels_select.set_active(select)
|
|
|
|
urlbox.pack_start(channels_select, False, False, 0)
|
|
|
|
urlbox.pack_start(Gtk.Label(" / "), False, False, 0)
|
|
|
|
def on_url(w):
|
|
url_field.set_text(lbryname(url_field.get_text(), force=False))
|
|
|
|
url_field = Gtk.Entry()
|
|
url_field.connect("changed", on_url)
|
|
url_field.set_text(data["name"])
|
|
urlbox.pack_start(url_field, True, True, 0)
|
|
|
|
#######################################################################
|
|
# #
|
|
# THUMBNAIL #
|
|
# #
|
|
#######################################################################
|
|
|
|
box.pack_start(Gtk.HSeparator(), False, False, 5)
|
|
|
|
thumb_file_box = Gtk.HBox()
|
|
box.pack_start(thumb_file_box, False, False, 0)
|
|
|
|
######################################################################
|
|
|
|
thumbvbox = Gtk.VBox()
|
|
thumb_file_box.pack_start(thumbvbox, False, False, 0)
|
|
|
|
def refresh_thumb():
|
|
if thumbentry.get_text():
|
|
t = ui.load(win, ui.net_image_calculation, ui.net_image_render, thumbentry.get_text(), 300, 300, "FORCELOAD", True)
|
|
for ch in thumbbox.get_children():
|
|
ch.destroy()
|
|
thumbbox.pack_start(t, True, True, 0)
|
|
thumbbox.show_all()
|
|
|
|
def on_thumb(w):
|
|
ans = ui.select_file(data["thumbnail_url"], filter=["*jpg", "*png", "*webp", "*gif"])
|
|
if ans:
|
|
thumbentry.set_text(ans)
|
|
refresh_thumb()
|
|
|
|
thumb = Gtk.Button()
|
|
thumb.connect("clicked", on_thumb)
|
|
thumb.set_size_request(300,300)
|
|
thumb.set_relief(Gtk.ReliefStyle.NONE)
|
|
|
|
thumbbox = Gtk.HBox()
|
|
thumbbox.pack_start(ui.icon(win, "image-x-generic"), False, True, 0)
|
|
thumbbox.pack_start(Gtk.Label(" Thumbnail "), False, True, 0)
|
|
thumb.add(thumbbox)
|
|
|
|
|
|
thumbvbox.pack_start(thumb, False, False, 0)
|
|
|
|
def on_toggle(w):
|
|
thumbentry.set_visible(w.get_active())
|
|
thumb.set_visible(not w.get_active())
|
|
refresh_thumb()
|
|
|
|
manually = Gtk.ToggleButton("Set thumbnail manually")
|
|
manually.connect("clicked", on_toggle)
|
|
manually.set_relief(Gtk.ReliefStyle.NONE)
|
|
thumbvbox.pack_end(manually, False, False, 0)
|
|
|
|
thumbentry = Gtk.Entry()
|
|
thumbentry.set_text(data["thumbnail_url"])
|
|
refresh_thumb()
|
|
thumbvbox.pack_end(thumbentry, False, False, 0)
|
|
|
|
thumb_file_box.pack_start(Gtk.VSeparator(), False, False, 5)
|
|
|
|
|
|
|
|
#######################################################################
|
|
# #
|
|
# TITLE #
|
|
# #
|
|
#######################################################################
|
|
|
|
filebox = Gtk.VBox()
|
|
thumb_file_box.pack_start(filebox, True, True, 0)
|
|
|
|
#######################################################################
|
|
|
|
titlebox = Gtk.HBox()
|
|
filebox.pack_start(titlebox, False, False, 5)
|
|
titlebox.pack_start(Gtk.Label(" Title: "), False, False, False)
|
|
def on_title(w):
|
|
data["title"] = title.get_text()
|
|
|
|
title = Gtk.Entry()
|
|
title.set_text(data["title"])
|
|
title.connect("changed", on_title)
|
|
titlebox.pack_start(title, True, True, False)
|
|
|
|
#######################################################################
|
|
# #
|
|
# FILE #
|
|
# #
|
|
#######################################################################
|
|
|
|
|
|
def choose_file(filename=""):
|
|
|
|
for ch in filebbox.get_children():
|
|
ch.destroy()
|
|
|
|
if filename:
|
|
icon_is = mimetypes.guess_type(filename)[0].replace("/", "-")
|
|
name_of_file = filename[filename.rfind("/")+1:]
|
|
|
|
def clear_name(name):
|
|
name = name[:name.rfind(".")]
|
|
name = name.replace("_", " ")
|
|
try:
|
|
name = name[0].upper()+name[1:]
|
|
except:
|
|
pass
|
|
return name
|
|
|
|
ofilename = data["file_path"]
|
|
if not title.get_text() or clear_name(ofilename[ofilename.rfind("/")+1:]) == title.get_text():
|
|
title.set_text(clear_name(name_of_file))
|
|
data["title"] = clear_name(name_of_file)
|
|
|
|
if not url_field.get_text() or lbryname(clear_name(ofilename[ofilename.rfind("/")+1:])) == url_field.get_text():
|
|
url_field.set_text(lbryname(title.get_text(), force=True))
|
|
else:
|
|
icon_is = "document-open"
|
|
name_of_file = "Choose File"
|
|
filebbox.pack_start(ui.icon(win, icon_is), False, True, 0)
|
|
filebbox.pack_start(Gtk.Label(" "+name_of_file+" "), False, True, 0)
|
|
filebbox.show_all()
|
|
|
|
def on_filebutton(w):
|
|
name = ui.select_file(data["file_path"])
|
|
choose_file(name)
|
|
data["file_path"] = name
|
|
|
|
filebutton = Gtk.Button()
|
|
filebutton.connect("clicked", on_filebutton)
|
|
filebbox = Gtk.HBox()
|
|
filebutton.add(filebbox)
|
|
choose_file(data["file_path"])
|
|
filebutton.set_relief(Gtk.ReliefStyle.NONE)
|
|
filebox.pack_start(filebutton, False, False, 0)
|
|
|
|
|
|
box.pack_start(Gtk.HSeparator(), False, False, 5)
|
|
|
|
|
|
#######################################################################
|
|
# #
|
|
# BID #
|
|
# #
|
|
#######################################################################
|
|
|
|
bid_adjust = Gtk.Adjustment(data["bid"],
|
|
lower=0.0001,
|
|
upper=1000000000,
|
|
step_increment=0.1)
|
|
bid_entry = Gtk.SpinButton(adjustment=bid_adjust,
|
|
digits=4)
|
|
bid_box = Gtk.HBox()
|
|
filebox.pack_start(bid_box, False, False, 5)
|
|
bid_box.pack_start(Gtk.Label(" Bid: "), False, False, 0)
|
|
bid_box.pack_end(bid_entry, False, False, 0)
|
|
|
|
#######################################################################
|
|
# #
|
|
# PRICE #
|
|
# #
|
|
#######################################################################
|
|
|
|
price_adjust = Gtk.Adjustment(data["fee_amount"],
|
|
lower=0,
|
|
upper=1000000000,
|
|
step_increment=0.1)
|
|
price_entry = Gtk.SpinButton(adjustment=price_adjust,
|
|
digits=4)
|
|
price_box = Gtk.HBox()
|
|
filebox.pack_start(price_box, False, False, 5)
|
|
price_box.pack_start(Gtk.Label(" Price: "), False, False, 0)
|
|
price_box.pack_end(price_entry, False, False, 0)
|
|
|
|
#######################################################################
|
|
# #
|
|
# DESCRIPTION #
|
|
# #
|
|
#######################################################################
|
|
|
|
filebox.pack_start(Gtk.Label(" Description: "), False, True, 5)
|
|
|
|
descrl = Gtk.ScrolledWindow()
|
|
detext = Gtk.TextView()
|
|
detext.set_wrap_mode(Gtk.WrapMode.WORD)
|
|
detext.get_buffer().set_text(data["description"])
|
|
descrl.add(detext)
|
|
|
|
filebox.pack_start(descrl, True, True, 0)
|
|
|
|
#######################################################################
|
|
# #
|
|
# TAGS #
|
|
# #
|
|
#######################################################################
|
|
|
|
box.pack_start(Gtk.Label(" Tags "), False, True, 5)
|
|
|
|
tags_editor, tagsbox, add_tag = ui.tags_editor(win, data["tags"], return_edit_functions=True)
|
|
|
|
box.pack_start(tags_editor, False, False, 0)
|
|
|
|
|
|
#######################################################################
|
|
# #
|
|
# LICENSE #
|
|
# #
|
|
#######################################################################
|
|
|
|
box.pack_start(Gtk.Label(" License "), False, True, 5)
|
|
|
|
def on_license(w):
|
|
l = licenses.get_active()
|
|
data["license"] = LICENSES[l][0]
|
|
data["license_url"] = LICENSES[l][1]
|
|
|
|
licenses = Gtk.ComboBoxText()
|
|
licenses.connect("changed", on_license)
|
|
|
|
for n, ch in enumerate(LICENSES):
|
|
licenses.append_text(ch[0])
|
|
if data["license"] == ch[0]:
|
|
licenses.set_active(n)
|
|
box.pack_start(licenses, False, True, 0)
|
|
|
|
|
|
#######################################################################
|
|
# #
|
|
# RUNING THE SETTINGS DIALOG #
|
|
# #
|
|
#######################################################################
|
|
|
|
|
|
box.show_all()
|
|
|
|
|
|
def update_data():
|
|
|
|
# Not all widgets update data automatically. We need this function
|
|
# whenever we want the up-to-date data.
|
|
|
|
data["name"] = url_field.get_text()
|
|
data["thumbnail_url"] = thumbentry.get_text()
|
|
data["bid"] = bid_entry.get_value()
|
|
data["fee_amount"] = price_entry.get_value()
|
|
|
|
tb = detext.get_buffer()
|
|
data["description"] = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True)
|
|
|
|
|
|
|
|
# Hide all hidden
|
|
thumbentry.set_visible(False)
|
|
|
|
response = dialogWindow.run()
|
|
|
|
if response == Gtk.ResponseType.OK:
|
|
|
|
update_data()
|
|
|
|
print("\n\n############## PUBLISH INPUT ###########\n\n{")
|
|
for i in data:
|
|
print(' "'+i+'" :', data[i])
|
|
print("}\n")
|
|
|
|
out = upload(data)
|
|
|
|
print("\n\n############## PUBLISH OUTPUT ###########\n\n")
|
|
print(out)
|
|
|
|
try:
|
|
ui.notify(win, "Published successfully to: ", out['outputs'][0]['permanent_url']+"\n\nConfirming...")
|
|
except:
|
|
try:
|
|
ui.notify(win, "Error while publishing!!!", out["message"])
|
|
except:
|
|
ui.notify(win, "Error while publishing!!!", str(out))
|
|
|
|
# It has to be DESTORYED
|
|
dialogWindow.destroy()
|
|
|
|
def upload(data):
|
|
|
|
###############################################################
|
|
# PUBLISH ! PUBLISH ! PUBLISH ! PUBLISH ! PUBLISH ! PUBLISH ! #
|
|
###############################################################
|
|
|
|
# The required datapoints
|
|
fetch_data = {"name":data["name"],
|
|
"bid":str(float(data["bid"])),
|
|
"file_path":data["file_path"]}
|
|
|
|
# Uploading the thumbnail maybe
|
|
data["thumbnail_url"] = speech_upload(data["thumbnail_url"])
|
|
|
|
for i in ["title", "license", "license_url", "thumbnail_url", "description", "channel_name", "fee_amount", "tags"]:
|
|
if i in data:
|
|
if data[i]:
|
|
if type(data[i]) not in [float, int]:
|
|
fetch_data[i] = data[i]
|
|
else:
|
|
fetch_data[i] = str(float(data[i]))
|
|
|
|
if data["fee_amount"]:
|
|
fetch_data["fee_currency"] = "LBC"
|
|
|
|
out = fetch.lbrynet("publish", fetch_data)
|
|
|
|
return out
|
|
|
|
def speech_upload(file, name="", fee=0, speech=True):
|
|
file = os.path.expanduser(file)
|
|
|
|
if os.path.isfile(file):
|
|
print("Uploading '"+file+"' to LBRY")
|
|
|
|
if not name:
|
|
rndname = ""
|
|
else:
|
|
rndname = name + "_"
|
|
|
|
length = 70 - len(rndname)
|
|
|
|
good = "qwertyuiopasdfghjklzxcvbnm-_QWERTYUIOPASDFGHJKLZXCVBNM1234567890"
|
|
for i in range(length):
|
|
rndname = rndname + random.choice(good)
|
|
|
|
try:
|
|
out = upload({"name":rndname,
|
|
"bid":0.001,
|
|
"file_path":file,
|
|
"title":"",
|
|
"license":"",
|
|
"license_url":"",
|
|
"thumbnail_url":"",
|
|
"channel_id":"",
|
|
"channel_name":"",
|
|
"description":"",
|
|
"fee_amount":fee,
|
|
"tags":[]
|
|
})
|
|
if speech:
|
|
return out['outputs'][0]['permanent_url'].replace("lbry://","https://spee.ch/")
|
|
else:
|
|
return out['outputs'][0]['permanent_url']
|
|
except:
|
|
return ""
|
|
|
|
|
|
else:
|
|
return file
|
|
|
|
# Gets Librarian URL from LBRY URL
|
|
def librarian_url(lbry_url, librarian_location):
|
|
# Get rid of ending slash if it has one
|
|
librarian_location = librarian_location.rstrip("/")
|
|
return lbry_url.replace("lbry:/", librarian_location, 1).replace("#", ":", 2)
|