diff --git a/apps/signal.json b/apps/signal.json new file mode 100644 index 0000000..a7b6d73 --- /dev/null +++ b/apps/signal.json @@ -0,0 +1,49 @@ +{ + "comment": "A cross-platform centralized encrypted instant messaging service developed by the non-profit Signal Foundation and Signal Messenger LLC.", + "formats_read": [], + "formats_write": [], + "generic_name": [ + "Messenger", + "Group Messenger" + ], + "interface": [ + "JavaScript", + "Touch", + "Custom", + "Electron" + ], + "issues": [ + "Requires a Cell-Phone" + ], + "languages": [ + "Java", + "Kotlin" + ], + "licenses": [ + "AGPL-3.0", + "GPL-3.0" + ], + "links": { + "git": "https://github.com/signalapp/Signal-Android", + "icon": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Signal-Logo.svg/150px-Signal-Logo.svg.png", + "website": "https://www.signal.org/" + }, + "names": [ + "Signal", + "Signal Messenger" + ], + "networks_read": [ + "signal" + ], + "networks_write": [ + "signal" + ], + "platforms": [ + "GNU/Linux", + "MacOS", + "Windows", + "iOS", + "Android", + "Web" + ] +} \ No newline at end of file diff --git a/editor.py b/editor.py new file mode 100644 index 0000000..18cc3b3 --- /dev/null +++ b/editor.py @@ -0,0 +1,566 @@ +######################################################### +# # +# THIS SOFTWARE IS (C) J.Y.Amihud and contributors 2022 # +# AND IT'S UNDER THE GNU AGPLv3 or any later version. # +# # +######################################################### + +# I will try to do something crazy stupid. I will try to +# Make an entire graphical editor using GTK in one python +# script. Which will not be very wise. But I will give it +# a shot. + +# A lot of the decisions will be made because of this fact +# so be aware of that. + +######################################################### +# # +# IMPORTING VARIOUS MODULES # +# # +######################################################### + +import os +import time +import json +import threading +from gi.repository import Gtk +from gi.repository import GLib + + +######################################################### +# # +# CONFIGURING THE WINDOW # +# # +######################################################### + +win = Gtk.Window() +win.set_size_request(600, 600) +win.connect("destroy", Gtk.main_quit) +scrl = Gtk.ScrolledWindow() +win.add(scrl) +box = Gtk.VBox() +scrl.add(box) + +######################################################### +# # +# LOADING PRESETS # +# # +######################################################### + +# I want to load all kinds of presets for the auto-fill +# For this we will nee to read all of the files. And it +# will be done before we have a GUI running. So the out +# put of this should be done in terminal it self. + +def pbar(now, total): + + # Simple terminal progress bar + + ################------------------------------ + + # That's roughly 30% with such a graph. + + w, h = os.get_terminal_size() + + n = "#" + t = "-" + + ns = int(w/total*now) + + string = "\r"+(n*ns)+(t*(w-ns)) + print(string, end="") + + + +# We assume that it's in a correct folder +print(" ----- LOADING AUTO-FILL DATA ------ ") + +win.full = {} + +all_apps = list(os.listdir(os.getcwd()+"/apps")) +for n, i in enumerate(all_apps): + pbar(n, len(all_apps)) + if i.endswith(".json"): + # we found a file on an app: + try: + with open("apps/"+i) as f: + this_file = json.load(f) + for key in this_file: + if key not in win.full: + win.full[key] = this_file[key] + elif type(this_file[key]) == list: + for item in this_file[key]: + if item not in win.full[key]: + win.full[key].append(item) + elif type(this_file[key]) == dict: + for thekey in this_file[key]: + win.full[key][thekey] = "" + + + except Exception as e: + pass + + +print(" ----- DONE LOADING AUTO-FILL DATA ------ ") + +######################################################### +# # +# LIST EDITOR ( TAG EDITOR ) # +# # +######################################################### + +# This piece of code I wrote for FastLBRY GTK, but it will +# be very handy here. I did a few modifications to remove +# the dependancy on the icon system in FastLBRY GTK + +def tags_editor(win, data, return_edit_functions=False, auto_fill=[]): + + def update(new_data): + old = data.copy() + for t in old: + data.remove(t) + for t in new_data: + data.append(t) + for i in tagsbox.get_children(): + i.destroy() + for tag in data: + add_tag(tag) + + + tagscont = Gtk.HBox() + + + tagscrl = Gtk.ScrolledWindow() + tagscrl.set_size_request(40,40) + tagscont.pack_start(tagscrl, True, True, 0) + + tagsbox = Gtk.HBox() + tagscrl.add_with_viewport(tagsbox) + + def add_tag(tag): + + if not tag: + return + + if tag not in data: + data.append(tag) + tagb = Gtk.HBox() + tagb.pack_start(Gtk.Label(" "+tag+" "), False, False, 0) + def kill(w): + tagb.destroy() + data.remove(tag) + tagk = Gtk.Button("-") + tagk.connect("clicked", kill) + tagk.set_relief(Gtk.ReliefStyle.NONE) + tagb.pack_start(tagk, False, False, 0) + tagb.pack_start(Gtk.VSeparator(), False, False, 5) + tagsbox.pack_start(tagb, False, False, 0) + tagsbox.show_all() + + # Scroll to the last + def later(): + time.sleep(0.1) + def now(): + a = tagscrl.get_hadjustment() + a.set_value(a.get_upper()) + GLib.idle_add(now) + load_thread = threading.Thread(target=later) + load_thread.start() + # The threading is needed, since we want to wait + # while GTK will update the UI and only then move + # the adjustent. Becuase else, it will move to the + # last previous, not to the last last. + + addt = Gtk.Button("+") + addt.set_relief(Gtk.ReliefStyle.NONE) + tagscont.pack_end(addt, False, False, 0) + def on_entry(w): + add_tag(tagentry.get_text()) + tagentry.set_text("") + + + + tagentry = Gtk.Entry() + + if auto_fill: + + liststore = Gtk.ListStore(str) + completion = Gtk.EntryCompletion() + completion.set_model(liststore) + completion.set_text_column(0) + + for i in auto_fill: + liststore.append((i,)) + + tagentry.set_completion(completion) + completion.set_minimum_key_length(0) + completion.complete() + + tagentry.connect("activate", on_entry) + addt.connect("clicked", on_entry) + tagscont.pack_end(tagentry, False, False, False) + + + + for tag in data: + add_tag(tag) + + if not return_edit_functions: + return tagscont + else: + return tagscont, update + + + +######################################################### +# # +# TOOL BAR # +# # +######################################################### + +# Tool bar will not going to have icons and things like +# this. It's not about being pretty. It's about giving +# the contributor a handy tool to contribute. + + +pannel = Gtk.HeaderBar() +pannel.set_show_close_button(True) +win.set_titlebar(pannel) + + +# We are going to make a little trick on our self ( I do +# that everywhere ). I gonna put important variables into +# the GTK Window. + +win.data_is = { + "names":[], + "comment":"", + "links":{}, + "licenses":[], + "platforms":[], + "interface":[], + "languages":[], + "networks_read":[], + "networks_write":[], + "formats_read":[], + "formats_write":[], + "generic_name":[], + "issues":[], + +} + +##################### OPEN BUTTON ####################### + +def on_open(w): + + dialog = Gtk.FileChooserDialog("Choose a file", + None, + Gtk.FileChooserAction.OPEN, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + dialog.set_current_folder(os.getcwd()+"/apps") + + filter_sup = Gtk.FileFilter() + filter_sup.set_name("Json Files") + filter_sup.add_pattern("*.json") + dialog.add_filter(filter_sup) + + response = dialog.run() + if response == Gtk.ResponseType.OK: + + # LOADING THE FILE + + with open(dialog.get_filename()) as f: + loaded_file = json.load(f) + + def type_min(i): + if type(win.data_is[i]) == list: + return [] + elif type(win.data_is[i]) == dict: + return {} + elif type(win.data_is[i]) == str: + return "" + + for i in win.data_is: + if i in loaded_file and type(win.data_is[i]) == type(loaded_file[i]): + + try: + updaters[i](loaded_file.get(i, type_min(i))) + except Exception as e: + win.data_is[i] = loaded_file.get(i, type_min(i)) + raise() + else: + try: + updaters[i](loaded_file.get(i, type_min(i))) + except: + win.data_is[i] = loaded_file.get(i, type_min(i)) + + + + + + dialog.destroy() + +open_button = Gtk.Button("Open") +open_button.set_relief(Gtk.ReliefStyle.NONE) +open_button.connect("clicked", on_open) +pannel.pack_start(open_button) + +##################### SAVE BUTTON ####################### + +# save_button = Gtk.Button("Save") +# pannel.pack_start(save_button) + +#################### SAVE AS BUTTON ##################### + +def on_save_as(w): + + tb = detext.get_buffer() + win.data_is["comment"] = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True) + + dialog = Gtk.FileChooserDialog("Choose a file", + None, + Gtk.FileChooserAction.SAVE, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + dialog.set_current_folder(os.getcwd()+"/apps") + + filter_sup = Gtk.FileFilter() + filter_sup.set_name("Json Files") + filter_sup.add_pattern("*.json") + dialog.add_filter(filter_sup) + + response = dialog.run() + if response == Gtk.ResponseType.OK: + savename = dialog.get_filename() + if not savename.endswith(".json"): + savename = savename+".json" + + with open(savename, 'w') as f: + json.dump(win.data_is, f, indent=4, sort_keys=True) + + dialog.destroy() + +save_as_button = Gtk.Button("Save As") +save_as_button.connect("clicked", on_save_as) +save_as_button.set_relief(Gtk.ReliefStyle.NONE) +pannel.pack_start(save_as_button) + +######################################################### +# # +# EDITOR IT SELF # +# # +######################################################### + +updaters = {} # Very important to make tags editor work + +#################### NAMES / COMMENT #################### + +collapsable = Gtk.Expander(label=" Names / Comment: ") +box.pack_start(collapsable, 0,0,5) +term_box = Gtk.VBox() +collapsable.add(term_box) + +# The list of names +term_box.pack_start(Gtk.Label("List of Names"),0,0,5) +names_editor, updaters["names"] = tags_editor(win, win.data_is["names"], True) +term_box.pack_start(names_editor,0,0,5) + +# The list of names +term_box.pack_start(Gtk.Label("Generic Names ( Features )"),0,0,5) +generic_editor, updaters["generic_name"] = tags_editor(win, win.data_is["generic_name"], True, win.full.get("generic_name",[])) +term_box.pack_start(generic_editor,0,0,5) + +term_box.pack_start(Gtk.Label("Comment (HTML)"),0,0,5) + +def comment_updater(new): + detext.get_buffer().set_text(new) + win.data_is["comment"] = new + +updaters["comment"] = comment_updater + +descrl = Gtk.ScrolledWindow() +descrl.set_size_request(100,100) +detext = Gtk.TextView() +detext.set_wrap_mode(Gtk.WrapMode.WORD) +detext.get_buffer().set_text(win.data_is["comment"]) +descrl.add(detext) + +term_box.pack_start(descrl,0,0,5) + +#################### LINKS #################### + +collapsable = Gtk.Expander(label=" Links: ") +box.pack_start(collapsable, 0,0,5) +term_box = Gtk.VBox() +collapsable.add(term_box) + +# Links are a bit more complicated. It will require a +# special editor. + +def add_item_to_view(category, link): + itembox = Gtk.HBox() + itembox.pack_start(Gtk.Label(" "+category+": "), 0,0,0) + + itembox.pack_start(Gtk.VSeparator(), 0,0,0) + + itembox.pack_start(Gtk.Label(" "+link+" "), 0,0,0) + + def on_destroy(w, itembox, category): + + itembox.destroy() + del win.data_is["links"][category] + + + destroy = Gtk.Button("-") + destroy.set_relief(Gtk.ReliefStyle.NONE) + destroy.connect("clicked", on_destroy, itembox, category) + itembox.pack_end(destroy, 0,0,0) + + linksbox.pack_end(itembox, 0,0,0) + linksbox.show_all() + +def add_item(w): + + key = categoryInput.get_text() + value = linkInput.get_text() + if key not in win.data_is["links"]: + add_item_to_view(key, value) + win.data_is["links"][key] = value + + categoryInput.set_text("") + linkInput.set_text("") + categoryInput.grab_focus() + +def links_updater(new): + + for i in new: + add_item_to_view(i, new[i]) + win.data_is["links"][i] = new[i] +updaters["links"] = links_updater + +inputbox = Gtk.HBox() +term_box.pack_start(inputbox, 1, 0, 5) + +inputbox.pack_start(Gtk.Label("Category:"), 0,0,1) +categoryInput = Gtk.Entry() +inputbox.pack_start(categoryInput, 0,0,1) + +liststore = Gtk.ListStore(str) +completion = Gtk.EntryCompletion() +completion.set_model(liststore) +completion.set_text_column(0) + +for i in list(win.full["links"].keys()): + liststore.append((i,)) + +categoryInput.set_completion(completion) +completion.set_minimum_key_length(0) + +completion.complete() + + +inputbox.pack_start(Gtk.Label("Link:"), 0,0,1) +linkInput = Gtk.Entry() +linkInput.connect("activate", add_item) +inputbox.pack_start(linkInput, 1,1,1) + +addInput = Gtk.Button("+") +addInput.connect("clicked", add_item) +addInput.set_relief(Gtk.ReliefStyle.NONE) +inputbox.pack_end(addInput, 0,0,1) + +linksbox = Gtk.VBox() +term_box.pack_start(Gtk.HSeparator(), 1, 0, 5) +term_box.pack_start(linksbox, 1, 0, 5) + + + + +#################### LICENSES #################### + +collapsable = Gtk.Expander(label=" Licenses: ") +box.pack_start(collapsable, 0,0,5) +term_box = Gtk.VBox() +collapsable.add(term_box) + +# The list of licenses +#term_box.pack_start(Gtk.Label("Licenses:"),0,0,5) +licenses_editor, updaters["licenses"] = tags_editor(win, win.data_is["licenses"], True, win.full.get("licenses",[])) +term_box.pack_start(licenses_editor,0,0,5) + +#################### NERDY INFO ################## + +collapsable = Gtk.Expander(label=" Technical Info: ") +box.pack_start(collapsable, 0,0,5) +term_box = Gtk.VBox() +collapsable.add(term_box) + +# The list of Platforms +term_box.pack_start(Gtk.Label("Platforms:"),0,0,5) +platforms_editor, updaters["platforms"] = tags_editor(win, win.data_is["platforms"], True, win.full.get("platforms",[])) +term_box.pack_start(platforms_editor,0,0,5) + + +# The list of Interfaces +term_box.pack_start(Gtk.Label("Interfaces:"),0,0,5) +interface_editor, updaters["interface"] = tags_editor(win, win.data_is["interface"], True, win.full.get("interface",[])) +term_box.pack_start(interface_editor,0,0,5) + + +# The list of Languages +term_box.pack_start(Gtk.Label("Languages:"),0,0,5) +languages_editor, updaters["languages"] = tags_editor(win, win.data_is["languages"], True, win.full.get("languages",[])) +term_box.pack_start(languages_editor,0,0,5) + +#################### FORMATS / NETWORKS ################# + +collapsable = Gtk.Expander(label=" Formats / Networks: ") +box.pack_start(collapsable, 0,0,5) +term_box = Gtk.VBox() +collapsable.add(term_box) + +# The list of Networs read +term_box.pack_start(Gtk.Label("Networks it can access ( read ):"),0,0,5) +networks_read_editor, updaters["networks_read"] = tags_editor(win, win.data_is["networks_read"], True, win.full.get("networks_read",[])) +term_box.pack_start(networks_read_editor,0,0,5) + + +# The list of Networs write +term_box.pack_start(Gtk.Label("Networks it can post to ( write ):"),0,0,5) +networks_write_editor, updaters["networks_write"] = tags_editor(win, win.data_is["networks_write"], True, win.full.get("networks_write",[])) +term_box.pack_start(networks_write_editor,0,0,5) + + +# The list of Opens files +term_box.pack_start(Gtk.Label("File formats it reads:"),0,0,5) +formats_read_editor, updaters["formats_read"] = tags_editor(win, win.data_is["formats_read"], True, win.full.get("formats_read",[])) +term_box.pack_start(formats_read_editor,0,0,5) + + +# The list of saves files +term_box.pack_start(Gtk.Label("File formats it saves to:"),0,0,5) +formats_write_editor, updaters["formats_write"] = tags_editor(win, win.data_is["formats_write"], True, win.full.get("formats_write",[])) +term_box.pack_start(formats_write_editor,0,0,5) + +#################### ANTI-FEATURES ################# + +collapsable = Gtk.Expander(label=" Anti-Features ( Malware ): ") +box.pack_start(collapsable, 0,0,5) +term_box = Gtk.VBox() +collapsable.add(term_box) + +# The list of saves files +issues_editor, updaters["issues"] = tags_editor(win, win.data_is["issues"], True, win.full.get("issues",[])) +term_box.pack_start(issues_editor,0,0,5) + + + +######################################################### +# # +# STARTING EVERYTHING # +# # +######################################################### + +win.show_all() +Gtk.main() diff --git a/ocGL.mkv b/ocGL.mkv new file mode 100644 index 0000000..dd46276 Binary files /dev/null and b/ocGL.mkv differ diff --git a/ocUj.mkv b/ocUj.mkv new file mode 100644 index 0000000..85f15db Binary files /dev/null and b/ocUj.mkv differ