-
Notifications
You must be signed in to change notification settings - Fork 0
/
tools.py
112 lines (92 loc) · 4.1 KB
/
tools.py
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
from string import ascii_letters, digits
from blake3 import blake3
import os
import html
from uuid import UUID
from encryption_assistant import get_user_db, get_set_db, get_org_db, get_group_db
from random import shuffle
from thefuzz import process as fuzz_process
def is_valid_email(email: str) -> bool:
email = email.split("@")
if len(email) != 2:
return False
for character in email[0]:
if character not in ascii_letters + digits + "!#$%&'*+-/=?^_`{|}~.":
return False
for character in email[1]:
if character not in ascii_letters + digits + ".-": # No underscores in domain names
return False
# Else
return True
def sort_by_value(d, reverse=False): # Thanks to Devin Jeanpierre on StackOverflow
return {k: v for k, v in sorted(d.items(), key=lambda item: item[1], reverse=reverse)}
def hash_file(filename):
with open(filename, "rb") as file:
file_hash = blake3()
chunk = file.read(8192)
while chunk:
file_hash.update(chunk)
chunk = file.read(8192)
return file_hash.hexdigest()
def listdir_recursive(directory, remove_extension=False):
file_paths = []
for root, directories, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
file_path = file_path.replace(directory + '/', '', 1)
if remove_extension:
file_path = '.'.join(file_path.split('.')[:-1])
file_paths.append(file_path)
return file_paths
def get_data_filenames(directory, preserve_extension=False):
"""
Strips the mapfiles out of the directory listing
:param directory:
:return:
"""
return [file if preserve_extension else '.'.join(file.split('.')[:-1]) for file in os.listdir(directory) if
not file.startswith('_')]
def metatags(title="HashCards", description="Create, find, share, and study flashcards for free without limits.",
image=None, path=None, card="summary_large_image", type="website"):
title = html.escape(title)
description = html.escape(description)
image = html.escape(image)
path = html.escape(path)
card = html.escape(card)
type = html.escape(type)
rendered = [
# Primary
f"""<meta name="title" content="{title}{' | HashCards' if title != 'HashCards' else ''}" />""",
f"""<meta name="description" content="{description}" />""",
# Open graph / Facebook
f"""<meta property="og:type" content="{type}" />""",
f"""<meta property="og:url" content="https://hashcards.net{path}" />""" if path is not None else '',
f"""<meta property="og:title" content="{title}" />""",
f"""<meta property="og:description" content="{description}" />""",
f"""<meta property="og:image" content="https://hashcards.net/static/images/{image}" />""" if image else '',
# Twitter / X
f"""<meta property="twitter:card" content="{card}" />""",
f"""<meta property="twitter:url" content="https://hashcards.net{path}" />""" if path is not None else '',
f"""<meta property="twitter:title" content="{title}" />""",
f"""<meta property="twitter:description" content="{description}" />""",
f"""<meta property="twitter:image" content="https://hashcards.net/static/images/{image}" />""" if image else ''
]
return '\n'.join(rendered)
def verify_uuid(uuid, version=4):
try:
result = UUID(uuid, version=version)
except ValueError:
return False
return str(result) == uuid
# Study mode functions
def find_similar_results(set_id, looking_for, card_id):
set_db = get_set_db(set_id)
answer = set_db.cards.get(card_id).get(looking_for)()
search_through = {card: set_db.cards.get(card).get(looking_for)() for card in tuple(set_db.cards().keys()) if set_db.cards.get(card).get(looking_for)().lower() != answer.lower()}
results = fuzz_process.extract(answer, search_through, limit=3)
results = {r[2]: r[0] for r in results}
results[card_id] = answer
results = list(results.items())
shuffle(results)
results = dict(results)
return results