python-simpletables 0.1.27__py3-none-any.whl → 0.1.28__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,24 +25,24 @@ class ExampleApp(tk.Tk):
25
25
  self.all_tables=[]
26
26
  self.all_buttons={}
27
27
  selector = lambda name: lambda: self.select_table(name)
28
- for name,title,fields in [
28
+ for name,title,fields,primary in [
29
29
  ("Customers","Заказчики",[
30
- Field("id","ID",show=showid,primary=True),
30
+ Field("id","ID",show=showid),
31
31
  Field("name","ФИО / Организация"),
32
32
  Field("inn","ИНН"),
33
33
  Field("addres","Адрес"),
34
34
  Field("phone","Телефон"),
35
35
  Field("salesman","Продавец?",show=showbool),
36
36
  Field("buyer","Покупатель?",show=showbool),
37
- ]),
37
+ ],"id"),
38
38
  ("Goods","Товары",[
39
- Field("id","ID",show=showid,primary=True),
39
+ Field("id","ID",show=showid),
40
40
  Field("name","Наименование",multiply=2.5),
41
41
  Field("price_for_unit","Цена за ед."),
42
42
  Field("unit","Ед.изм."),
43
- ]),
43
+ ],"id"),
44
44
  ]:
45
- self.all_tables.append(Table(conn,box,name,fields))
45
+ self.all_tables.append(Table(conn,box,name,fields,primary))
46
46
  self.all_buttons[name]=tk.Button(tabs,text=title,command=selector(name))
47
47
  self.all_buttons[name].pack(side="left")
48
48
  self.select_table(self.all_tables[0].name)
@@ -11,14 +11,15 @@ class Field:
11
11
  name:str
12
12
  title:str
13
13
  show:object = str
14
- primary:bool = False
15
14
  width:int = 0
16
15
  multiply:float = 1
16
+ is_valid:object = lambda e: True
17
17
  class Table(tk.Frame):
18
- def __init__(self,conn,master,name,fields):
18
+ def __init__(self,conn,master,name,fields,primary):
19
19
  self.conn = conn
20
20
  self.name = name
21
21
  self.fields = fields
22
+ self.primary = primary
22
23
  super().__init__(master)
23
24
  self.buttons = tk.Frame(self)
24
25
  self.buttons.pack(side="bottom",fill="x")
@@ -36,8 +37,8 @@ class Table(tk.Frame):
36
37
  for field in fields:
37
38
  self.tree.column(field.name,width=field.width or int(max(30,len(field.title)*8)*field.multiply))
38
39
  self.tree.heading(field.name,text=field.title)
39
- self.update()
40
- def update(self):
40
+ self.update_values()
41
+ def update_values(self):
41
42
  self.tree.delete(*self.tree.get_children())
42
43
  for raw in self.conn.execute(f"SELECT * FROM {q(self.name)}").fetchall():
43
44
  values = [e.show(self,e,raw[i]) for i,e in enumerate(self.fields)]
@@ -46,14 +47,101 @@ class Table(tk.Frame):
46
47
  def ui_create(self): pass
47
48
  def ui_edit(self): pass
48
49
  def ui_delete(self): pass
49
- def ui_import_json(self): pass
50
+ def ui_import_json(self):
51
+ file = fd.askopenfile(title="Имортировать файл",filetypes=[
52
+ ("JSON-файлы","*.json"),
53
+ ("Все файлы","*"),
54
+ ])
55
+ if file and not self.import_json(file): self.badfile()
56
+ def import_json(self,file):
57
+ with open(file,"r",encoding="utf8") as f:
58
+ data = json.loads(f.read())
59
+ if type(data)!=list: return False
60
+ for e in data:
61
+ if not self.is_valid(e): return False
62
+ self.data_add(data)
63
+ return True
64
+ def badfile(self): mb.showerror("Ошибка импортирования","Файл повреждён или имеет некорректную структуру.")
50
65
  def ui_import_excel(self):
51
66
  file = fd.askopenfile(title="Имортировать файл",filetypes=[
52
- ("Таблицы","*.xlsx","*.xls","*.csv"),
67
+ ("Таблицы","*.xlsx","*.xls"),
68
+ ("Все файлы","*"),
69
+ ])
70
+ if file and not self.import_excel(file): self.badfile()
71
+ def import_excel(file):
72
+ df=pd.read_excel(file,sheet_name=0)
73
+ started=False
74
+ for i in range(df.shape()[0]):
75
+ row=df.iloc(i)
76
+ if self.is_valid(row):
77
+ started=True
78
+ self.data_add(row)
79
+ elif started: break
80
+ else: pass
81
+ if not started: return False
82
+ return True
83
+ def data_get(self,primary_value,error_ok=False):
84
+ matches = self.conn.execute(f"SELECT * FROM {q(self.name)} WHERE {q(self.primary)} = ?",primary_value).fetchall()
85
+ if len(matches)==0:
86
+ if error_ok: return None
87
+ else: raise KeyError(f"cannot find row with key {primary_value!r}")
88
+ elif len(matches)==1:
89
+ return matches[0]
90
+ else:
91
+ raise RuntimeError("unexpected situation")
92
+ def data_add(self,row):
93
+ if not self.is_valid(row): raise ValueError(f"invalid line: {row!r}")
94
+ row = self.normalize(row)
95
+ actual = self.data_get(self.primary,True)
96
+ if actual==None:
97
+ self.data_create(row)
98
+ self.conn.commit()
99
+ else: self.data_set(row[0],row)
100
+ def data_create(self,row):
101
+ if not self.is_valid(row): raise ValueError(f"invalid line: {row!r}")
102
+ row = self.normalize(row)
103
+ self.conn.execute(f"INSERT INTO {q(self.name)} VALUES ("+",".join('?' for _ in self.fields)+")",row)
104
+ self.conn.commit()
105
+ def data_set(self,key,row):
106
+ if not self.is_valid(row): raise ValueError(f"invalid line: {row!r}")
107
+ row = self.normalize(row)
108
+ self.conn.execute(f"UPDATE {q(self.name)} SET "+", ".join(f"{q(f.name)} = ?" for _ in self.fields)+" WHERE {q(self.primary)} = ?",[*row,key])
109
+ self.conn.commit()
110
+ def data_readall(self):
111
+ return [self.normalize(e) for e in self.conn.execute(f"SELECT * FROM {q(self.name)}").fetchall()]
112
+ def is_valid(self,row):
113
+ if type(row)==dict:
114
+ row = [*row.items()]
115
+ pattern = dict((e.name,e) for e in self.fields)
116
+ while row:
117
+ key,value = row.pop(0)
118
+ field = pattern.get(key,None)
119
+ if field and field.is_valid(value):
120
+ del pattenr[key]
121
+ continue
122
+ else:
123
+ return False
124
+ return len(pattern)==0
125
+ else:
126
+ if len(row)<len(self.fields): return False
127
+ for i in range(len(self.fields)):
128
+ if not self.fields[i].is_valid(row[i]): return False
129
+ return True
130
+ def normalize(self,row):
131
+ if type(row)!=dict:
132
+ new={}
133
+ for i,field in self.fields:
134
+ new[field.name]=row[i]
135
+ return new
136
+ def ui_export_json(self):
137
+ file = fd.asksaveasfilename(title="Имортировать файл",filetypes=[
138
+ ("JSON-файлы","*.json"),
53
139
  ("Все файлы","*"),
54
140
  ])
55
- def ui_export_json(self): pass
56
- def ui_export_excel(self): pass
141
+ if file: self.export_json(file)
142
+ def export_json(self,file):
143
+ with open(file,"w",encoding="utf8") as f:
144
+ file.write(json.dumps(self.data_readall(),ensure_ascii=False))
57
145
 
58
146
 
59
147
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python_simpletables
3
- Version: 0.1.27
3
+ Version: 0.1.28
4
4
  Summary: Simple connection between SQL and tkinter.
5
5
  Author-email: Захар Васильев <vasilyev.zakhar@gmail.com>
6
6
  License: MIT
@@ -0,0 +1,8 @@
1
+ python_simpletables/__init__.py,sha256=tT2si4YdJPkxm4gGLVUfI7ORt-VM86_O0bFdgYXMyyo,41
2
+ python_simpletables/__main__.py,sha256=mE5ni3HDA9kR0z5FK2oOZ-XtZKvkIsSOdhCxfKr4gUs,2704
3
+ python_simpletables/app.py,sha256=V9baO6lyOzlNZjue3DHGeaKZGJTm9KUTwGkxIX5p_kk,1753
4
+ python_simpletables/table.py,sha256=p49WQ4Jtdzq5hIllmIRjVVDCvpfcdwUFfJ7VQJ7m5ew,6368
5
+ python_simpletables-0.1.28.dist-info/METADATA,sha256=_swKvMlPdUzKO9Z0h8KJbA0mYX52D9om8wP1_Hy5Z-0,228
6
+ python_simpletables-0.1.28.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
7
+ python_simpletables-0.1.28.dist-info/top_level.txt,sha256=WhVQcD7ccNKNb-lZhcmTM0kTkcbxh7tE11YiN1ZwE9E,20
8
+ python_simpletables-0.1.28.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- python_simpletables/__init__.py,sha256=tT2si4YdJPkxm4gGLVUfI7ORt-VM86_O0bFdgYXMyyo,41
2
- python_simpletables/__main__.py,sha256=SmrDS11Gp4UDBLA42owx14IOoYF1PCrSFdt2QaKBzbk,2704
3
- python_simpletables/app.py,sha256=V9baO6lyOzlNZjue3DHGeaKZGJTm9KUTwGkxIX5p_kk,1753
4
- python_simpletables/table.py,sha256=GfpIlX-2Dx5BdCX9EWV-4ye8SFYdhXgzlYGNgfQTKAQ,2387
5
- python_simpletables-0.1.27.dist-info/METADATA,sha256=jLNRjmb0Y3LikHJPTUiyRfAUVZzgqv2ZsFnoPJHgGxs,228
6
- python_simpletables-0.1.27.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
7
- python_simpletables-0.1.27.dist-info/top_level.txt,sha256=WhVQcD7ccNKNb-lZhcmTM0kTkcbxh7tE11YiN1ZwE9E,20
8
- python_simpletables-0.1.27.dist-info/RECORD,,