-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.py
More file actions
executable file
·396 lines (365 loc) · 14.7 KB
/
test.py
File metadata and controls
executable file
·396 lines (365 loc) · 14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
#!/usr/bin/env python3
from secf import save, load
from colorama import Fore, Style
import os, time
import re
def hashtag_search(content, hashtags, fnc):
for line in content:
if fnc(hashtag in line.split() for hashtag in hashtags):
yield line
def snp_hashtag(header, content, hashtags, fnc):
for line in hashtag_search(content, hashtags, fnc):
print(f"[out] {header}) {line}")
path = os.path.join(os.path.expanduser("~"), ".sectionify")
os.makedirs(path, exist_ok=True)
path = path + "/"
file = {}
changed = False
existing_slots = set()
print(
"Welcome to my CLI tool.\nThis is used to store data in form of sections and it's entries.\nYou can choose to save data into one of the 3 slots(slot 0, slot 1, slot 2) availaible. You can also choose to restore from a slot at anytime by issueing the appropriate command.\nEnter '??' for help. Press Ctrl+C to exit this interface."
)
for i in range(3):
if os.path.exists(f"{path}slot{i}"):
existing_slots.add(str(i))
if existing_slots:
print(
f"\n[out] There are {len(existing_slots)} saved states in slot {', '.join(existing_slots)}."
)
while True:
try:
query = input("\nEnter your Query >> ").strip()
if not query:
continue
# Quit method:
except KeyboardInterrupt:
if changed:
try:
dec = input(
Fore.YELLOW
+ Style.BRIGHT
+ f"\n[Warn] You have performed some operations since your last save. Please save them else you'll lose the data.\n[out] Press Ctrl+C again to quit, press any other key to cancel quit operation.\n>>"
+ Style.RESET_ALL
)
continue
except KeyboardInterrupt:
print(Fore.CYAN + Style.BRIGHT + "\nBye :)" + Style.RESET_ALL)
exit(130)
print(Fore.CYAN + Style.BRIGHT + "\nBye :)" + Style.RESET_ALL)
exit(130)
if query == "?s":
for section in file:
print("[out] " + section)
elif query == "??" or query == "help":
print(f"[out] Commands availiable:")
print(f"[out] +s <section name> - Add a new Section")
print(f"[out] +e <section name> - Add an entry to an existing Section")
print(
"""[out] ?s - List existing sections.\
\n[out] ?e <section name> - Print an entry in a section. Use '*' to print all the entries\
\n[out] -e <section name> - Delete an entry from an existing section\
\n[out] -s <section name> - Delete a Section\
\n[out] #<string> - List all the entries along with it's section name where the hashtag was used\
\n[out] ?s <section name> () #<string> - List all the entries of the given section where the hashtag was used\
\n[out] (Note: For below commands you can specify 2 or more hashtags)\
\n[out] | #<string> #<string> - List all the entries along with it's section name where either of the hashtags were used\
\n[out] & #<string> #<string> - List all the entries along with it's section name where all of the hashtags were used\
\n[out] ?s <section name> () | #<string> #<string> - List all the entries of the given section where either of the hashtags were used\
\n[out] ?s <section name> () & #<string> #<string> - List all the entries of the given section where all of the hashtags were used\
\n[out] save <slot_no> - Save the state of the program to given slot number\
\n[out] restore <slot_no> - Restore the previously stored state of the program\
\n[out] slots - Print all the available slots, and their status\
\n[out] ?? - Print this message.\
\n[out] help - Print this message. """
)
elif query == "slots":
for i in range(3):
if str(i) in existing_slots:
st = os.stat(f"{path}slot" + str(i))
print(
f"[out] Slot {i} -- {len(load(f'{path}slot'+str(i)))} section(s) -- {time.asctime(time.localtime(st[9]))}"
)
else:
print(f"[out] Slot {i} -- unused")
# elif re.search("^(#[^ ]+ )+$", query + " "):
# hashtags = query.split()
# for header, content in file.items():
# snp_hashtag(header, content, hashtags, any)
# elif re.search(r"^&( #[^ ]+)+$", query):
# hashtags = query.split()[1:]
# for header, content in file.items():
# snp_hashtag(header, content, hashtags, all)
# elif re.search(r"^\|( #[^ ]+)+$", query):
# hashtags = query.split()[1:]
# for header, content in file.items():
# snp_hashtag(header, content, hashtags, any)
elif re.search(r"^([|&])?\s*((#[^\s#]+\s+)*(#[^\s#]+))$", query):
fnc = any
p = re.search(r"^([|&])?\s*((#[^\s#]+\s+)*(#[^\s#]+))$", query)
operation = p.group(1)
hashtags = p.group(2).split()
if operation == "&":
fnc = all
for header, content in file.items():
snp_hashtag(header, content, hashtags, fnc)
elif re.match(
r"^\?e\s+([^()]+)\s*\(\)\s*([&|])?\s*((#[^\s#]+\s+)*(#[^\s#]+))$", query
):
fnc = any
p = re.match(
r"^\?e\s+([^()]+)\s*\(\)\s*([&|])?\s*((#[^\s#]+\s+)*(#[^\s#]+))$", query
)
section = p.group(1)
if section not in file:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err ] Section doesn't exist."
+ Style.RESET_ALL
)
continue
operation = p.group(2)
hashtags = p.group(3).split()
if operation == "":
fnc = any
elif operation == "&":
fnc = all
elif operation == "|":
fnc = any
snp_hashtag(section, file[section], hashtags, fnc)
# elif re.search(r"^\?e ([^\(\)]+) \(\) ((#[^\s]+ )+)$", query + " "):
# p = re.search(r"^\?e ([^\(\)]+) \(\) ((#[^\s]+ )+)$", query + " ")
# section = p.group(1)
# if section not in file:
# print(
# Fore.RED
# + Style.BRIGHT
# + "[Err ] Section doesn't exist."
# + Style.RESET_ALL
# )
# continue
# hashtags = p.group(2).split()
# snp_hashtag(section, file[section], hashtags, any)
# elif re.search(r"^\?e ([^\(\)]+) \(\) \|(( #[^\s]+)+)$", query):
# p = re.search(r"^\?e ([^\(\)]+) \(\) \|(( #[^\s]+)+)$", query)
# section = p.group(1)
# if section not in file:
# print(
# Fore.RED
# + Style.BRIGHT
# + "[Err ] Section doesn't exist."
# + Style.RESET_ALL
# )
# continue
# hashtags = p.group(2).split()
# snp_hashtag(section, file[section], hashtags, any)
# elif re.search(r"^\?e ([^\(\)]+) \(\) &(( #[^ ]+)+)$", query):
# p = re.search(r"^\?e ([^\(\)]+) \(\) &(( #[^ ]+)+)$", query)
# section = p.group(1)
# if section not in file:
# print(
# Fore.RED
# + Style.BRIGHT
# + "[Err ] Section doesn't exist."
# + Style.RESET_ALL
# )
# continue
# hashtags = p.group(2).split()
# snp_hashtag(section, file[section], hashtags, all)
else:
command, *arg = query.split()
arg = " ".join(arg)
if "(" in arg or ")" in arg:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err] We don't allow '(' or ')' in section name or entry."
+ Style.RESET_ALL
)
continue
if command == "+s":
if arg in file:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err] Section already exists, use +e to add new entry."
+ Style.RESET_ALL
)
elif not arg:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err] Section name can't be blank."
+ Style.RESET_ALL
)
else:
file[arg] = []
print(
Fore.GREEN
+ Style.BRIGHT
+ f"[out] New Section '{arg}' added."
+ Style.RESET_ALL
)
changed = True
elif command == "+e":
if arg not in file:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err] Section doesn't exist. Use '+s' to create a section."
+ Style.RESET_ALL
)
continue
line = input("line >> ").strip()
if not line:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err] Blank line entry not yet supported."
+ Style.RESET_ALL
)
else:
file[arg].append(line)
print(
Fore.GREEN
+ Style.BRIGHT
+ f"[out] Entry added. Reference no. is '{len(file[arg])}'."
+ Style.RESET_ALL
)
changed = True
elif command == "?e":
if arg not in file:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err] Section doesn't exist."
+ Style.RESET_ALL
)
continue
ref_no = input("Ref No>> ").strip()
if ref_no == "*":
for i in range(len(file[arg])):
print(f"[out] ({i+1}.) {file[arg][i]}")
elif ref_no == "":
continue
else:
try:
print(file[arg][int(ref_no) - 1])
except:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err ] Enter from existing Reference numbers."
+ Style.RESET_ALL
)
continue
elif command[0] == "-":
if arg not in file:
print(
Fore.RED
+ Style.BRIGHT
+ "[Err ] Section doesn't exist."
+ Style.RESET_ALL
)
continue
if command[1] == "s":
decision = (
input(
f"This section contains {len(file[arg])} entries, This will delete all its entries along with section.\n"
+ "Press 'Y' to delete, press any other key to cancel this operation\n>> "
)
.strip()
.upper()
)
if decision == "Y":
file.pop(arg)
print(
Fore.GREEN
+ Style.BRIGHT
+ f"[out] Section {arg} and its entries deleted."
+ Style.RESET_ALL
)
changed = True
else:
print("[out] Deletion Aborted.")
continue
elif command[1] == "e":
ref_no = input("Ref No>> ").strip()
if ref_no == "*":
decision = (
input(
"All the entries will be deleted.\nPress 'Y' to delete, press any other key to cancel this operation\n>> "
)
.strip()
.upper()
)
if decision == "Y":
file[arg].clear()
print(
Fore.GREEN
+ Style.BRIGHT
+ "Entries deleted."
+ Style.RESET_ALL
)
changed = True
else:
decision = input(
Fore.RED
+ Style.BRIGHT
+ f"You are deleting: {file[arg][int(ref_no)-1]}\nPress 'Y' to delete, press any other key to cancel this operation\n>> "
+ Style.RESET_ALL
).strip()
if decision == "Y":
file[arg].pop(int(ref_no) - 1)
print(
Fore.GREEN
+ Style.BRIGHT
+ "Entry deleted."
+ Style.RESET_ALL
)
changed = True
elif command == "save":
if arg not in ["0", "1", "2"]:
continue
if not changed:
print("[out] There's nothing to save")
continue
slot = f"{path}slot" + arg
if arg in existing_slots:
des = input(
Fore.RED
+ Style.BRIGHT
+ f"[out] This will overwrite the contents in slot {arg}\n[out] Press 'O' to Overwrite, press any other key to cancel save operation.\n>>"
+ Style.RESET_ALL
).strip()
if des != "O":
continue
res = save(file, slot)
if res:
print(
Fore.GREEN
+ Style.BRIGHT
+ f"[out] saved all sections and its contents to slot {arg}."
+ Style.RESET_ALL
)
existing_slots.add(arg)
changed = False
else:
print("some error")
continue
elif command == "restore":
if arg not in ["0", "1", "2"]:
continue
if changed:
des = input(
Fore.RED
+ Style.BRIGHT
+ f"[out] Loading from slot {arg} will overwrite the sections present in this session,\n[out] Press 'R' to continue restoring, press any other key to cancel this operation.\n>>"
+ Style.RESET_ALL
)
if des != "R":
continue
file = load(f"{path}slot{arg}")
print(f"[out] sucessfully restored from slot {arg}.")
else:
print("Invalid command. Enter '??' for help.")