Added an editor

This commit is contained in:
jyamihud 2022-05-12 14:54:44 +03:00
parent a8514174ad
commit 9c3b180bfa
4 changed files with 615 additions and 0 deletions

49
apps/signal.json Normal file
View file

@ -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"
]
}

566
editor.py Normal file
View file

@ -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()

BIN
ocGL.mkv Normal file

Binary file not shown.

BIN
ocUj.mkv Normal file

Binary file not shown.