forked from MasterGroosha/telegram-reminder-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shelver.py
171 lines (152 loc) · 5.23 KB
/
shelver.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
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
# -*- coding: utf-8 -*-
"""
My custom wrapper for shelve module
"""
import shelve
from re import match
class SaveValueError(Exception):
def __init__(self, message):
self.message = message
super(SaveValueError, self).__init__('{0}'.format(self.message))
class GetValueError(Exception):
def __init__(self, message):
self.message = message
super(GetValueError, self).__init__('{0}'.format(self.message))
class NoKeyError(Exception):
def __init__(self, message):
self.message = message
super(NoKeyError, self).__init__('{0}'.format(self.message))
class Shelver:
def __init__(self, database):
self.storage = shelve.open(database)
def create_key(self, key):
"""
creates key without value
:param key: key name
"""
self.storage[key] = None
return True
def save(self, key, value, force_save=False):
"""
Saves value for key.
:param key: key name
:param value: value to save
:param force_save: if False, raise NoKeyError when key doesn't exist
if True, creates key and saves value to it
:return: True, if value is saved
:raise SaveValueError: when fail to save key
:raise NoKeyError: if key doesn't exist and force_save == False
"""
if not self.exists(key) and force_save is False:
raise NoKeyError('No such key: {0!s}'.format(key))
if not self.exists(key) and force_save is True:
self.create_key(key)
self.save(key, value)
return True
if self.exists(key):
try:
self.storage[key] = value
return True
except Exception as ex:
raise SaveValueError('{0}: {1}'.format(type(ex).__name__, 'failed to save value'))
def get(self, key):
"""
Gets value from key.
If key doesn't exist, throws NoKeyError
:param key: key name
:return: value for that key
:raise NoKeyError: if key doesn't exist
"""
if key in self.storage:
return self.storage[key]
else:
raise NoKeyError('No such key in offset_storage: ' + str(key))
def get_with_create(self, key, default):
"""
Gets value from key.
If key doesn't exist, creates one with "default" value and returns it
:param key: key name
:param default: if key doesn't exist, default value for new key with "key" name
:return: value for that key
"""
try:
if key in self.storage and not None:
value = self.storage[key]
return value
else:
self.create_key(key)
self.save(key, default)
return default
except Exception as ex:
raise GetValueError(
'{0}: {1}'.format(type(ex).__name__, 'failed to get value from offset_storage'))
def append(self, key, value, strict=True):
"""
Gets list for key and appends "value" to it
:param strict: if True, raise NoKeyError, if key doesn't exist
if False, create key with "value" value
:param key: key name
:param value: value to append
:return: True if value appended
:raise NoKeyError: if key doesn't exist
"""
if strict and key not in self.storage:
raise NoKeyError('No such key in offset_storage: ' + str(key))
else:
tmp = list(self.get_with_create(key, []))
tmp.append(value)
self.save(key, tmp)
return True
def remove(self, key, value):
"""
Gets list for key and removes "value" value from it
If there's no such value in list, do nothing
:param key: key name
:param value: value to remove
:return: True, if value is removed
:raise NoKeyError: if no such key in storage
"""
if key in self.storage:
tmp = list(self.storage[key])
if value in tmp:
tmp.remove(value)
self.save(key, tmp)
return True
else:
raise NoKeyError('No such key in offset_storage: ' + str(key))
def find_all(self, pattern):
"""
Finds all keys mathing desired pattern
:param pattern: pattern (regular expression)
:return: list of keys matching pattern
"""
keys = self.storage.keys()
result = []
for k in keys:
if match(pattern, k):
result.append(k)
return result
def find_single(self, pattern):
"""
Finds first key mathing desired pattern
:param pattern: pattern (regular expression)
:return: first matching key or None
"""
keys = self.storage.keys()
for k in keys:
if match(pattern, k):
return k
else:
return None
def exists(self, key):
"""
Checks, if key exists in storage
:param key: key name
:return: True if key exists; False if doesn't
"""
if key in self.storage.keys():
return True
else:
return False
def close(self):
self.storage.close()