123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- # GPL3 or any later version
- import os
- import json
- import time
- import gi
- import threading
- gi.require_version('Gtk', '3.0')
- from gi.repository import Gtk
- from gi.repository import Gdk
- from gi.repository import GLib
- from modules import wallet
- from modules import images
- from modules import ui
- from modules import transactions as tmodule
- from modules import graphs
- def select_dialogue(win, mode="normal"):
- # This is an item selector.
- dialogWindow = Gtk.Dialog("Select Item",
- buttons=(),
- )
- dialogWindow.set_size_request(400, 400)
- r = Gtk.VBox()
- r.ret = None
-
- def todo(w, win, item):
- r.ret = item
- try:
- if type(item) == dict:
- item["amount"] = item["amount"].get_value()
- item["price"] = item["price"].get_value()
- except:
- pass
- dialogWindow.destroy()
-
- box = dialogWindow.get_content_area()
- select_widget(win, box, todo, mode=mode)
-
- box.show_all()
- response = dialogWindow.run()
- dialogWindow.destroy()
- return r.ret
-
- def select_widget(win, box, todo, mode="normal"):
- # Draws widget for searching and selecting items.
- search_box = Gtk.HBox()
- box.pack_start(search_box, 0,0,1)
- amount_entry, price_entry = False, False
-
- if mode == "transaction_add":
- totals = wallet.get_totals(win.wallet)
- currancy = totals.get("currancy", "$")
- # amount of the item
- search_box.pack_start(Gtk.Label(" x "),0,0,0)
- amount_adjust = Gtk.Adjustment(1,
- lower=-10000000000000000000,
- upper=10000000000000000000,
- step_increment=1)
- amount_entry = Gtk.SpinButton(adjustment=amount_adjust,
- digits=2)
- search_box.pack_start(amount_entry,0,0,0)
- search_box.pack_start(Gtk.Label(" "+currancy+" "),0,0,0)
- price_adjust = Gtk.Adjustment(0,
- lower=-10000000000000000000,
- upper=10000000000000000000,
- step_increment=1)
- price_entry = Gtk.SpinButton(adjustment=price_adjust,
- digits=2)
- search_box.pack_start(price_entry,0,0,0)
- sepbox = Gtk.HBox()
- sepbox.set_size_request(20,20)
- search_box.pack_start(sepbox,0,0,0)
- def on_changed(w):
- win.search_item = search.get_text()
- def on_search(w):
- refresh_items(win, pack, todo, amount_entry, price_entry, mode=mode, search=search.get_text())
-
- search = Gtk.Entry()
- search.connect("changed", on_changed)
- search.connect("activate", on_search)
- search_box.pack_start(search, 1,1,0)
-
- scrl = Gtk.ScrolledWindow()
- scrl.set_vexpand(0)
- box.pack_start(scrl, 1,1,1)
- pack = Gtk.VBox()
- scrl.add(pack)
- refresh_items(win, pack, todo, amount_entry, price_entry, mode=mode)
- return (win, pack, todo, amount_entry, price_entry, "", mode)
- def refresh_items(win, pack, todo, amount_entry, price_entry, search="", mode="normal"):
-
- for i in pack.get_children():
- i.destroy()
-
- flowbox = Gtk.FlowBox()
- flowbox.set_valign(Gtk.Align.START)
- flowbox.set_max_children_per_line(30)
- flowbox.set_selection_mode(Gtk.SelectionMode.NONE)
-
- def on_add_item(w):
- editor(win, new=True)
- refresh_items(win, pack, todo, amount_entry, price_entry, search=search, mode=mode)
-
- add_item = Gtk.Button()
- add_item.add(ui.icon(win, "list-add"))
- add_item.set_relief(Gtk.ReliefStyle.NONE)
- flowbox.add(add_item)
- add_item.connect("clicked", on_add_item)
- folder = wallet.save_folder()+"items/"
- try:
- items = list(os.walk(folder))[0][2]
- items = sorted(items)
- except:
- items = []
-
- for i in items:
- with open(folder+i) as json_file:
- idata = json.load(json_file)
- if search:
- if search.lower() not in idata.get("name").lower() and search.lower() not in i.lower():
- continue
-
- item_button = Gtk.Button()
- if mode == "transaction_add":
- item_button.connect("clicked", todo, win, {"item":i.replace(".json", ""),
- "amount":amount_entry,
- "price":price_entry})
- else:
- item_button.connect("clicked", todo, win, i)
- item_button.set_relief(Gtk.ReliefStyle.NONE)
- item_box = Gtk.VBox()
- item_button.add(item_box)
- save_as = idata.get("image", "")
- if os.path.exists(save_as):
- image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
- else:
- image = ui.icon(win, "package-x-generic")
- item_box.pack_start(image, 0,0,0)
- item_box.pack_start(Gtk.Label(str(idata.get("name", ""))), 0,0,0)
- item_box.pack_start(Gtk.Label(i.replace(".json", "")),0,0,0)
- flowbox.add(item_button)
-
- flowbox.show_all()
- pack.pack_start(flowbox, 1,1,1)
- def editor(win, item="", new=False):
- # editor
- currancy = wallet.get_totals(win.wallet).get("currancy", "$")
-
- folder = wallet.save_folder()+"items/"
- try:
- os.makedirs(folder)
- except:
- pass
- data = {}
- edit_id = True
- try:
- search = win.search_item
- except:
- search = ""
- if not item:
- item = search
-
- if item:
- try:
- if not item.endswith(".json"):
- item = item+".json"
- with open(folder+item) as json_file:
- data = json.load(json_file)
- item = item.replace(".json", "")
- edit_id = False
- except:
- pass
-
-
- if not data:
-
- data = {
- "name":"",
- "image":""}
-
- try:
- item = str(int(search))
- except:
- data["name"] = search
-
-
- dialogWindow = Gtk.Dialog("Item",
- buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
- Gtk.STOCK_OK, Gtk.ResponseType.OK),
- )
- dialogWindow.set_size_request(200, 200)
-
- box = dialogWindow.get_content_area()
- main_data_box = Gtk.HBox()
- box.pack_start(main_data_box, 0,1,1)
- # IMAGE
- def image_edit(w):
- search = id_entry.get_text()+" "+name_entry.get_text()
- if search:
- images.select_image(win, search)
- save_as = win.return_search
- data["image"] = save_as
- add_image.get_children()[0].destroy()
-
- image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
- add_image.add(image)
- add_image.show_all()
-
- add_image = Gtk.Button()
- main_data_box.pack_start(add_image, 0,0,0)
- add_image.connect("clicked", image_edit)
- add_image.set_relief(Gtk.ReliefStyle.NONE)
-
- if not data.get("image"):
- add_image.add(ui.icon(win, "image-x-generic"))
-
- else:
- save_as = data.get("image")
- image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
- add_image.add(image)
-
- text_data_box = Gtk.VBox()
- main_data_box.pack_start(text_data_box, 1,1,1)
- # ID
- def on_entry(w, d):
- data[d] = w.get_text()
-
- id_box = Gtk.HBox()
- text_data_box.pack_start(id_box, 0,0,5)
- id_box.pack_start(Gtk.Label(" ID: "), 0,0,0)
- id_entry = Gtk.Entry()
- id_entry.grab_focus()
- id_entry.set_sensitive(edit_id)
-
- id_box.pack_end(id_entry, 0,0,0)
- # NAME
- name_box = Gtk.HBox()
- text_data_box.pack_start(name_box, 0,0,5)
- name_box.pack_start(Gtk.Label(" Name: "), 0,0,0)
- name_entry = Gtk.Entry()
- name_entry.connect("changed", on_entry, "name")
- name_box.pack_end(name_entry, 0,0,0)
- # TOTALS
- total_amount = 0
- total_money = 0
- all_prices = []
- all_trans = []
- graph_data = {"items":[],
- "zoom":[0,0],
- "allow_negative":True
- }
-
- tfolder = wallet.save_folder()+"wallets/"+win.wallet+"/transactions/"
- try:
- transactions = list(os.walk(tfolder))[0][2]
- transactions = sorted(transactions)
- except:
- transactions = []
-
- for i in transactions:
- try:
- with open(tfolder+i) as json_file:
- tdata = json.load(json_file)
- for b in tdata.get("items", []):
-
- if b.get("item") == item:
- all_trans.append(i)
- total_money = total_money + ( b.get("price", 0) * b.get("amount", 0))
- graph_data["items"].append({"amount":b.get("price", 0) * b.get("amount", 0),
- "timestamp":int(i.replace(".json", ""))
- })
- all_prices.append(b.get("price", 0))
- total_amount = total_amount + b.get("amount", 0)
- except Exception as e:
- print(i, e )
-
- try:
- average_price = sum(all_prices) / len(all_prices)
- except:
- average_price = 0
-
- # Notebook
- notebook = Gtk.Notebook()
- notebook.set_scrollable(True)
- if not new:
- box.pack_start(notebook, 1,1,1)
- totals_box = Gtk.VBox()
- totals_box.pack_start(Gtk.Label("Total Items: "+str(round(total_amount, 2))), 0,0,0)
- totals_box.pack_start(Gtk.Label("Total Money: "+currancy+str(round(total_money,2))), 0,0,0)
- totals_box.pack_start(Gtk.Label("Average Price: "+currancy+str(round(average_price,2))), 0,0,0)
-
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(Gtk.Label(" Totals "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(totals_box, detailsbox)
- # TRANSACTIONS
- transactions_scrl = Gtk.ScrolledWindow()
- trbox = Gtk.VBox()
- transactions_scrl.add(trbox)
- for i in all_trans:
- with open(tfolder+i) as json_file:
- tdata = json.load(json_file)
- def on_tbutton(w, name):
- tmodule.editor(win, name)
-
- tbutton = Gtk.Button()
- tbutton.connect("clicked", on_tbutton, i)
- tbutton.set_relief(Gtk.ReliefStyle.NONE)
- tbox = Gtk.HBox()
- tbutton.add(tbox)
- tbox.pack_start(ui.icon(win,"task-past-due"), 0,0,0)
- try:
- tdate = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(i.replace(".json", ""))))
- except Exception as e:
- print( e )
- tdate = "[Date Unknown]"
- tbox.pack_start(Gtk.Label(tdate), 1,1,1)
- tbox.pack_end(Gtk.Label(str(round(tdata.get("total", 0), 2))), 0,0,5)
- trbox.pack_start(tbutton, 0,0,0)
-
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(Gtk.Label(" Transactions "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(transactions_scrl, detailsbox)
-
- # GRAPH
- the_graph = graphs.graph(win, graph_data, "Graph", currancy=currancy, add_value=0)
- detailsbox = Gtk.HBox()
- detailsbox.pack_start(Gtk.Label(" Graph "), True, True, True)
- detailsbox.show_all()
- notebook.append_page(the_graph, detailsbox)
-
- # Auto filling
- if item:
- id_entry.set_text( str(item).replace(".json", "") )
- name_entry.grab_focus()
- name_entry.set_text(str(data.get("name", "")))
- box.show_all()
-
- response = dialogWindow.run()
- if response == Gtk.ResponseType.OK:
- item = id_entry.get_text()
- if new: # Failsafe for in case the user will accidentaly overwrite
- n = 0 # an existing item by mistake.
- nn = item
- while os.path.exists(folder+str(item)+".json"):
- n = n + 1
- item = nn+"_"+str(n)
-
- filename = folder+str(item)+".json"
- with open(filename, "w") as fp:
- json.dump(data, fp, indent=4)
- dialogWindow.destroy()
|