hive-nectar 0.0.2__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.
Potentially problematic release.
This version of hive-nectar might be problematic. Click here for more details.
- hive_nectar-0.0.2.dist-info/METADATA +182 -0
- hive_nectar-0.0.2.dist-info/RECORD +86 -0
- hive_nectar-0.0.2.dist-info/WHEEL +4 -0
- hive_nectar-0.0.2.dist-info/entry_points.txt +2 -0
- hive_nectar-0.0.2.dist-info/licenses/LICENSE.txt +23 -0
- nectar/__init__.py +32 -0
- nectar/account.py +4371 -0
- nectar/amount.py +475 -0
- nectar/asciichart.py +270 -0
- nectar/asset.py +82 -0
- nectar/block.py +446 -0
- nectar/blockchain.py +1178 -0
- nectar/blockchaininstance.py +2284 -0
- nectar/blockchainobject.py +221 -0
- nectar/blurt.py +563 -0
- nectar/cli.py +6285 -0
- nectar/comment.py +1217 -0
- nectar/community.py +513 -0
- nectar/constants.py +111 -0
- nectar/conveyor.py +309 -0
- nectar/discussions.py +1709 -0
- nectar/exceptions.py +149 -0
- nectar/hive.py +546 -0
- nectar/hivesigner.py +420 -0
- nectar/imageuploader.py +72 -0
- nectar/instance.py +129 -0
- nectar/market.py +1013 -0
- nectar/memo.py +449 -0
- nectar/message.py +357 -0
- nectar/nodelist.py +444 -0
- nectar/price.py +557 -0
- nectar/profile.py +65 -0
- nectar/rc.py +308 -0
- nectar/snapshot.py +726 -0
- nectar/steem.py +582 -0
- nectar/storage.py +53 -0
- nectar/transactionbuilder.py +622 -0
- nectar/utils.py +545 -0
- nectar/version.py +2 -0
- nectar/vote.py +557 -0
- nectar/wallet.py +472 -0
- nectar/witness.py +617 -0
- nectarapi/__init__.py +11 -0
- nectarapi/exceptions.py +123 -0
- nectarapi/graphenerpc.py +589 -0
- nectarapi/node.py +178 -0
- nectarapi/noderpc.py +229 -0
- nectarapi/rpcutils.py +97 -0
- nectarapi/version.py +2 -0
- nectarbase/__init__.py +14 -0
- nectarbase/ledgertransactions.py +75 -0
- nectarbase/memo.py +243 -0
- nectarbase/objects.py +429 -0
- nectarbase/objecttypes.py +22 -0
- nectarbase/operationids.py +102 -0
- nectarbase/operations.py +1297 -0
- nectarbase/signedtransactions.py +48 -0
- nectarbase/transactions.py +11 -0
- nectarbase/version.py +2 -0
- nectargrapheneapi/__init__.py +6 -0
- nectargraphenebase/__init__.py +27 -0
- nectargraphenebase/account.py +846 -0
- nectargraphenebase/aes.py +52 -0
- nectargraphenebase/base58.py +192 -0
- nectargraphenebase/bip32.py +494 -0
- nectargraphenebase/bip38.py +134 -0
- nectargraphenebase/chains.py +149 -0
- nectargraphenebase/dictionary.py +3 -0
- nectargraphenebase/ecdsasig.py +326 -0
- nectargraphenebase/objects.py +123 -0
- nectargraphenebase/objecttypes.py +6 -0
- nectargraphenebase/operationids.py +3 -0
- nectargraphenebase/operations.py +23 -0
- nectargraphenebase/prefix.py +11 -0
- nectargraphenebase/py23.py +38 -0
- nectargraphenebase/signedtransactions.py +201 -0
- nectargraphenebase/types.py +419 -0
- nectargraphenebase/unsignedtransactions.py +283 -0
- nectargraphenebase/version.py +2 -0
- nectarstorage/__init__.py +38 -0
- nectarstorage/base.py +306 -0
- nectarstorage/exceptions.py +16 -0
- nectarstorage/interfaces.py +237 -0
- nectarstorage/masterpassword.py +239 -0
- nectarstorage/ram.py +30 -0
- nectarstorage/sqlite.py +334 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import json
|
|
3
|
+
import threading
|
|
4
|
+
from datetime import datetime, timedelta, timezone
|
|
5
|
+
|
|
6
|
+
from nectar.instance import shared_blockchain_instance
|
|
7
|
+
from nectargraphenebase.py23 import integer_types, string_types
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ObjectCache(dict):
|
|
11
|
+
def __init__(self, initial_data={}, default_expiration=10, auto_clean=True):
|
|
12
|
+
super(ObjectCache, self).__init__(initial_data)
|
|
13
|
+
self.set_expiration(default_expiration)
|
|
14
|
+
self.auto_clean = auto_clean
|
|
15
|
+
self.lock = threading.RLock()
|
|
16
|
+
|
|
17
|
+
def __setitem__(self, key, value):
|
|
18
|
+
data = {
|
|
19
|
+
"expires": datetime.now(timezone.utc) + timedelta(seconds=self.default_expiration),
|
|
20
|
+
"data": value,
|
|
21
|
+
}
|
|
22
|
+
with self.lock:
|
|
23
|
+
if key in self:
|
|
24
|
+
del self[key]
|
|
25
|
+
dict.__setitem__(self, key, data)
|
|
26
|
+
if self.auto_clean:
|
|
27
|
+
self.clear_expired_items()
|
|
28
|
+
|
|
29
|
+
def __getitem__(self, key):
|
|
30
|
+
with self.lock:
|
|
31
|
+
if key in self:
|
|
32
|
+
value = dict.__getitem__(self, key)
|
|
33
|
+
if value is not None:
|
|
34
|
+
return value["data"]
|
|
35
|
+
|
|
36
|
+
def get(self, key, default):
|
|
37
|
+
with self.lock:
|
|
38
|
+
if key in self:
|
|
39
|
+
if self[key] is not None:
|
|
40
|
+
return self[key]
|
|
41
|
+
else:
|
|
42
|
+
return default
|
|
43
|
+
else:
|
|
44
|
+
return default
|
|
45
|
+
|
|
46
|
+
def clear_expired_items(self):
|
|
47
|
+
with self.lock:
|
|
48
|
+
del_list = []
|
|
49
|
+
utc_now = datetime.now(timezone.utc)
|
|
50
|
+
for key in self:
|
|
51
|
+
value = dict.__getitem__(self, key)
|
|
52
|
+
if value is None:
|
|
53
|
+
del_list.append(key)
|
|
54
|
+
continue
|
|
55
|
+
if utc_now >= value["expires"]:
|
|
56
|
+
del_list.append(key)
|
|
57
|
+
for key in del_list:
|
|
58
|
+
del self[key]
|
|
59
|
+
|
|
60
|
+
def __contains__(self, key):
|
|
61
|
+
with self.lock:
|
|
62
|
+
if dict.__contains__(self, key):
|
|
63
|
+
value = dict.__getitem__(self, key)
|
|
64
|
+
if value is None:
|
|
65
|
+
return False
|
|
66
|
+
if datetime.now(timezone.utc) < value["expires"]:
|
|
67
|
+
return True
|
|
68
|
+
else:
|
|
69
|
+
value["data"] = None
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
def __str__(self):
|
|
73
|
+
if self.auto_clean:
|
|
74
|
+
self.clear_expired_items()
|
|
75
|
+
n = 0
|
|
76
|
+
with self.lock:
|
|
77
|
+
n = len(list(self.keys()))
|
|
78
|
+
return "ObjectCache(n={}, default_expiration={})".format(n, self.default_expiration)
|
|
79
|
+
|
|
80
|
+
def set_expiration(self, expiration):
|
|
81
|
+
"""Set new default expiration time in seconds (default: 10s)"""
|
|
82
|
+
self.default_expiration = expiration
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class BlockchainObject(dict):
|
|
86
|
+
space_id = 1
|
|
87
|
+
type_id = None
|
|
88
|
+
type_ids = []
|
|
89
|
+
|
|
90
|
+
_cache = ObjectCache()
|
|
91
|
+
|
|
92
|
+
def __init__(
|
|
93
|
+
self,
|
|
94
|
+
data,
|
|
95
|
+
klass=None,
|
|
96
|
+
space_id=1,
|
|
97
|
+
object_id=None,
|
|
98
|
+
lazy=False,
|
|
99
|
+
use_cache=True,
|
|
100
|
+
id_item=None,
|
|
101
|
+
blockchain_instance=None,
|
|
102
|
+
*args,
|
|
103
|
+
**kwargs,
|
|
104
|
+
):
|
|
105
|
+
if blockchain_instance is None:
|
|
106
|
+
if kwargs.get("steem_instance"):
|
|
107
|
+
blockchain_instance = kwargs["steem_instance"]
|
|
108
|
+
elif kwargs.get("hive_instance"):
|
|
109
|
+
blockchain_instance = kwargs["hive_instance"]
|
|
110
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
111
|
+
self.cached = False
|
|
112
|
+
self.identifier = None
|
|
113
|
+
|
|
114
|
+
# We don't read lists, sets, or tuples
|
|
115
|
+
if isinstance(data, (list, set, tuple)):
|
|
116
|
+
raise ValueError("Cannot interpret lists! Please load elements individually!")
|
|
117
|
+
|
|
118
|
+
if id_item and isinstance(id_item, string_types):
|
|
119
|
+
self.id_item = id_item
|
|
120
|
+
else:
|
|
121
|
+
self.id_item = "id"
|
|
122
|
+
if klass and isinstance(data, klass):
|
|
123
|
+
self.identifier = data.get(self.id_item)
|
|
124
|
+
super(BlockchainObject, self).__init__(data)
|
|
125
|
+
elif isinstance(data, dict):
|
|
126
|
+
self.identifier = data.get(self.id_item)
|
|
127
|
+
super(BlockchainObject, self).__init__(data)
|
|
128
|
+
elif isinstance(data, integer_types):
|
|
129
|
+
# This is only for block number basically
|
|
130
|
+
self.identifier = data
|
|
131
|
+
if not lazy and not self.cached:
|
|
132
|
+
self.refresh()
|
|
133
|
+
# make sure to store the blocknumber for caching
|
|
134
|
+
self[self.id_item] = data
|
|
135
|
+
# Set identifier again as it is overwritten in super() in refresh()
|
|
136
|
+
self.identifier = data
|
|
137
|
+
elif isinstance(data, string_types):
|
|
138
|
+
self.identifier = data
|
|
139
|
+
if not lazy and not self.cached:
|
|
140
|
+
self.refresh()
|
|
141
|
+
self[self.id_item] = str(data)
|
|
142
|
+
self.identifier = data
|
|
143
|
+
else:
|
|
144
|
+
self.identifier = data
|
|
145
|
+
if self.test_valid_objectid(self.identifier):
|
|
146
|
+
# Here we assume we deal with an id
|
|
147
|
+
self.testid(self.identifier)
|
|
148
|
+
if self.iscached(data):
|
|
149
|
+
super(BlockchainObject, self).__init__(self.getcache(data))
|
|
150
|
+
elif not lazy and not self.cached:
|
|
151
|
+
self.refresh()
|
|
152
|
+
|
|
153
|
+
if use_cache and not lazy:
|
|
154
|
+
self.cache()
|
|
155
|
+
self.cached = True
|
|
156
|
+
|
|
157
|
+
@staticmethod
|
|
158
|
+
def clear_cache():
|
|
159
|
+
BlockchainObject._cache = ObjectCache()
|
|
160
|
+
|
|
161
|
+
def test_valid_objectid(self, i):
|
|
162
|
+
if isinstance(i, string_types):
|
|
163
|
+
return True
|
|
164
|
+
elif isinstance(i, integer_types):
|
|
165
|
+
return True
|
|
166
|
+
else:
|
|
167
|
+
return False
|
|
168
|
+
|
|
169
|
+
def testid(self, id):
|
|
170
|
+
if not self.type_id:
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
if not self.type_ids:
|
|
174
|
+
self.type_ids = [self.type_id]
|
|
175
|
+
|
|
176
|
+
def cache(self):
|
|
177
|
+
# store in cache
|
|
178
|
+
if dict.__contains__(self, self.id_item):
|
|
179
|
+
BlockchainObject._cache[self.get(self.id_item)] = self
|
|
180
|
+
|
|
181
|
+
def clear_cache_from_expired_items(self):
|
|
182
|
+
BlockchainObject._cache.clear_expired_items()
|
|
183
|
+
|
|
184
|
+
def set_cache_expiration(self, expiration):
|
|
185
|
+
BlockchainObject._cache.default_expiration = expiration
|
|
186
|
+
|
|
187
|
+
def set_cache_auto_clean(self, auto_clean):
|
|
188
|
+
BlockchainObject._cache.auto_clean = auto_clean
|
|
189
|
+
|
|
190
|
+
def get_cache_expiration(self):
|
|
191
|
+
return BlockchainObject._cache.default_expiration
|
|
192
|
+
|
|
193
|
+
def get_cache_auto_clean(self):
|
|
194
|
+
return BlockchainObject._cache.auto_clean
|
|
195
|
+
|
|
196
|
+
def iscached(self, id):
|
|
197
|
+
return id in BlockchainObject._cache
|
|
198
|
+
|
|
199
|
+
def getcache(self, id):
|
|
200
|
+
return BlockchainObject._cache.get(id, None)
|
|
201
|
+
|
|
202
|
+
def __getitem__(self, key):
|
|
203
|
+
if not self.cached:
|
|
204
|
+
self.refresh()
|
|
205
|
+
return super(BlockchainObject, self).__getitem__(key)
|
|
206
|
+
|
|
207
|
+
def items(self):
|
|
208
|
+
if not self.cached:
|
|
209
|
+
self.refresh()
|
|
210
|
+
return list(super(BlockchainObject, self).items())
|
|
211
|
+
|
|
212
|
+
def __contains__(self, key):
|
|
213
|
+
if not self.cached:
|
|
214
|
+
self.refresh()
|
|
215
|
+
return super(BlockchainObject, self).__contains__(key)
|
|
216
|
+
|
|
217
|
+
def __repr__(self):
|
|
218
|
+
return "<%s %s>" % (self.__class__.__name__, str(self.identifier))
|
|
219
|
+
|
|
220
|
+
def json(self):
|
|
221
|
+
return json.loads(str(json.dumps(self)))
|