hive-nectar 0.0.10__py3-none-any.whl → 0.1.0__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.10.dist-info → hive_nectar-0.1.0.dist-info}/METADATA +10 -11
- hive_nectar-0.1.0.dist-info/RECORD +88 -0
- nectar/__init__.py +1 -4
- nectar/account.py +791 -685
- nectar/amount.py +82 -21
- nectar/asset.py +1 -2
- nectar/block.py +34 -22
- nectar/blockchain.py +111 -143
- nectar/blockchaininstance.py +396 -247
- nectar/blockchainobject.py +33 -5
- nectar/cli.py +1058 -1349
- nectar/comment.py +317 -182
- nectar/community.py +39 -43
- nectar/constants.py +1 -14
- nectar/discussions.py +793 -139
- nectar/hive.py +137 -77
- nectar/hivesigner.py +106 -68
- nectar/imageuploader.py +33 -23
- nectar/instance.py +31 -79
- nectar/market.py +128 -264
- nectar/memo.py +40 -13
- nectar/message.py +23 -10
- nectar/nodelist.py +118 -82
- nectar/price.py +80 -61
- nectar/profile.py +6 -3
- nectar/rc.py +45 -25
- nectar/snapshot.py +285 -163
- nectar/storage.py +16 -5
- nectar/transactionbuilder.py +132 -41
- nectar/utils.py +37 -17
- nectar/version.py +1 -1
- nectar/vote.py +171 -30
- nectar/wallet.py +26 -19
- nectar/witness.py +153 -54
- nectarapi/graphenerpc.py +147 -133
- nectarapi/noderpc.py +12 -6
- nectarapi/rpcutils.py +12 -6
- nectarapi/version.py +1 -1
- nectarbase/ledgertransactions.py +24 -1
- nectarbase/objects.py +17 -6
- nectarbase/operations.py +160 -90
- nectarbase/signedtransactions.py +38 -2
- nectarbase/version.py +1 -1
- nectargraphenebase/account.py +295 -17
- nectargraphenebase/chains.py +0 -135
- nectargraphenebase/ecdsasig.py +152 -176
- nectargraphenebase/types.py +18 -4
- nectargraphenebase/unsignedtransactions.py +1 -1
- nectargraphenebase/version.py +1 -1
- hive_nectar-0.0.10.dist-info/RECORD +0 -91
- nectar/blurt.py +0 -562
- nectar/conveyor.py +0 -308
- nectar/steem.py +0 -581
- {hive_nectar-0.0.10.dist-info → hive_nectar-0.1.0.dist-info}/WHEEL +0 -0
- {hive_nectar-0.0.10.dist-info → hive_nectar-0.1.0.dist-info}/entry_points.txt +0 -0
- {hive_nectar-0.0.10.dist-info → hive_nectar-0.1.0.dist-info}/licenses/LICENSE.txt +0 -0
nectar/comment.py
CHANGED
|
@@ -5,9 +5,10 @@ import math
|
|
|
5
5
|
from datetime import date, datetime, timezone
|
|
6
6
|
|
|
7
7
|
from nectar.constants import (
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
HIVE_100_PERCENT,
|
|
9
|
+
HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF6,
|
|
10
|
+
HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF20,
|
|
11
|
+
HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF21,
|
|
11
12
|
)
|
|
12
13
|
from nectarbase import operations
|
|
13
14
|
|
|
@@ -34,16 +35,17 @@ class Comment(BlockchainObject):
|
|
|
34
35
|
:param str authorperm: identifier to post/comment in the form of
|
|
35
36
|
``@author/permlink``
|
|
36
37
|
:param str tags: defines which api is used. Can be bridge, tags, condenser or database (default = bridge)
|
|
37
|
-
:param
|
|
38
|
+
:param Blockchain blockchain_instance: Blockchain instance to use when accessing the RPC
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
.. code-block:: python
|
|
41
42
|
|
|
42
43
|
>>> from nectar.comment import Comment
|
|
43
44
|
>>> from nectar.account import Account
|
|
44
|
-
>>>
|
|
45
|
-
>>>
|
|
46
|
-
>>>
|
|
45
|
+
>>> # Create a Hive blockchain instance
|
|
46
|
+
>>> from nectar.blockchain import Blockchain as Hive
|
|
47
|
+
>>> hv = Hive()
|
|
48
|
+
>>> acc = Account("gtg", blockchain_instance=hv)
|
|
47
49
|
>>> authorperm = acc.get_blog(limit=1)[0]["authorperm"]
|
|
48
50
|
>>> c = Comment(authorperm)
|
|
49
51
|
>>> postdate = c["created"]
|
|
@@ -61,17 +63,25 @@ class Comment(BlockchainObject):
|
|
|
61
63
|
full=True,
|
|
62
64
|
lazy=False,
|
|
63
65
|
blockchain_instance=None,
|
|
64
|
-
**kwargs,
|
|
65
66
|
):
|
|
67
|
+
"""
|
|
68
|
+
Create a Comment object representing a Hive post or comment.
|
|
69
|
+
|
|
70
|
+
Supports initializing from either an author/permlink string ("author/permlink") or a dict containing at least "author" and "permlink". For a string input the constructor resolves and stores author, permlink, and authorperm. For a dict input the constructor normalizes the dict via _parse_json_data (timestamps, amounts, metadata) and sets the canonical "authorperm" before delegating to the BlockchainObject constructor.
|
|
71
|
+
|
|
72
|
+
Parameters:
|
|
73
|
+
authorperm: Either an "author/permlink" string or a dict with "author" and "permlink".
|
|
74
|
+
api: RPC bridge to use (defaults to "bridge"); stored on the instance.
|
|
75
|
+
observer: Optional observer identifier stored on the instance.
|
|
76
|
+
full: If True, load all fields immediately; if False, allow partial/lazy loading.
|
|
77
|
+
lazy: If True, delay full object loading until needed.
|
|
78
|
+
|
|
79
|
+
Note: The blockchain instance is taken from blockchain_instance (if provided) or the module's shared_blockchain_instance(). The constructor sets instance attributes and then calls the parent initializer with id_item="authorperm".
|
|
80
|
+
"""
|
|
66
81
|
self.full = full
|
|
67
82
|
self.lazy = lazy
|
|
68
83
|
self.api = api
|
|
69
84
|
self.observer = observer
|
|
70
|
-
if blockchain_instance is None:
|
|
71
|
-
if kwargs.get("steem_instance"):
|
|
72
|
-
blockchain_instance = kwargs["steem_instance"]
|
|
73
|
-
elif kwargs.get("hive_instance"):
|
|
74
|
-
blockchain_instance = kwargs["hive_instance"]
|
|
75
85
|
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
76
86
|
if isinstance(authorperm, str) and authorperm != "":
|
|
77
87
|
[author, permlink] = resolve_authorperm(authorperm)
|
|
@@ -89,10 +99,26 @@ class Comment(BlockchainObject):
|
|
|
89
99
|
id_item="authorperm",
|
|
90
100
|
lazy=lazy,
|
|
91
101
|
full=full,
|
|
92
|
-
blockchain_instance=
|
|
102
|
+
blockchain_instance=self.blockchain,
|
|
93
103
|
)
|
|
94
104
|
|
|
95
105
|
def _parse_json_data(self, comment):
|
|
106
|
+
"""
|
|
107
|
+
Normalize and convert raw comment JSON fields into Python-native types.
|
|
108
|
+
|
|
109
|
+
This parses and mutates the given comment dict in-place and returns it. Normalizations:
|
|
110
|
+
- Converts known timestamp strings (e.g., "created", "last_update", "cashout_time") to datetime using formatTimeString.
|
|
111
|
+
- Converts monetary fields backed by the chain's backed token (HBD) into Amount objects using the instance's backed_token_symbol.
|
|
112
|
+
- Ensures a "community" key exists and parses `json_metadata` (string/bytes) into a dict; extracts `tags` and `community` from that metadata when present.
|
|
113
|
+
- Converts numeric string fields like `author_reputation` and `net_rshares` to ints.
|
|
114
|
+
- Normalizes each entry in `active_votes`: converts vote `time` to datetime and numeric strings (`rshares`, `reputation`) to ints (falling back to 0 on parse errors).
|
|
115
|
+
|
|
116
|
+
Parameters:
|
|
117
|
+
comment (dict): Raw comment/post data as returned by the node RPC.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
dict: The same comment dict with normalized fields (timestamps as datetimes, amounts as Amount objects, json_metadata as dict, numeric fields as ints).
|
|
121
|
+
"""
|
|
96
122
|
parse_times = [
|
|
97
123
|
"active",
|
|
98
124
|
"cashout_time",
|
|
@@ -106,7 +132,7 @@ class Comment(BlockchainObject):
|
|
|
106
132
|
if p in comment and isinstance(comment.get(p), str):
|
|
107
133
|
comment[p] = formatTimeString(comment.get(p, "1970-01-01T00:00:00"))
|
|
108
134
|
# Parse Amounts
|
|
109
|
-
|
|
135
|
+
hbd_amounts = [
|
|
110
136
|
"total_payout_value",
|
|
111
137
|
"max_accepted_payout",
|
|
112
138
|
"pending_payout_value",
|
|
@@ -114,7 +140,7 @@ class Comment(BlockchainObject):
|
|
|
114
140
|
"total_pending_payout_value",
|
|
115
141
|
"promoted",
|
|
116
142
|
]
|
|
117
|
-
for p in
|
|
143
|
+
for p in hbd_amounts:
|
|
118
144
|
if p in comment and isinstance(comment.get(p), (str, list, dict)):
|
|
119
145
|
value = comment.get(p, "0.000 %s" % (self.blockchain.backed_token_symbol))
|
|
120
146
|
if (
|
|
@@ -124,6 +150,9 @@ class Comment(BlockchainObject):
|
|
|
124
150
|
value = value.split(" ")[0] + " " + self.blockchain.backed_token_symbol
|
|
125
151
|
comment[p] = Amount(value, blockchain_instance=self.blockchain)
|
|
126
152
|
|
|
153
|
+
if "community" not in comment:
|
|
154
|
+
comment["community"] = ""
|
|
155
|
+
|
|
127
156
|
# turn json_metadata into python dict
|
|
128
157
|
meta_str = comment.get("json_metadata", "{}")
|
|
129
158
|
if meta_str == "{}":
|
|
@@ -138,7 +167,7 @@ class Comment(BlockchainObject):
|
|
|
138
167
|
if isinstance(comment["json_metadata"], dict):
|
|
139
168
|
if "tags" in comment["json_metadata"]:
|
|
140
169
|
comment["tags"] = comment["json_metadata"]["tags"]
|
|
141
|
-
if "community" in comment["json_metadata"]
|
|
170
|
+
if "community" in comment["json_metadata"]:
|
|
142
171
|
comment["community"] = comment["json_metadata"]["community"]
|
|
143
172
|
|
|
144
173
|
parse_int = [
|
|
@@ -223,6 +252,19 @@ class Comment(BlockchainObject):
|
|
|
223
252
|
)
|
|
224
253
|
|
|
225
254
|
def json(self):
|
|
255
|
+
"""
|
|
256
|
+
Return a JSON-serializable dict representation of the Comment.
|
|
257
|
+
|
|
258
|
+
Removes internal-only keys (e.g., "authorperm", "tags"), ensures json-compatible types, and normalizes several fields so the result can be safely serialized to JSON and consumed by external callers or APIs. Normalizations performed:
|
|
259
|
+
- Serializes `json_metadata` to a compact JSON string.
|
|
260
|
+
- Converts datetime/date values in fields like "created", "updated", "last_payout", "cashout_time", "active", and "max_cashout_time" to formatted time strings.
|
|
261
|
+
- Converts Amount instances in HBD-related fields (e.g., "total_payout_value", "pending_payout_value", "curator_payout_value", "promoted", etc.) to their JSON representation via Amount.json().
|
|
262
|
+
- Converts selected integer fields ("author_reputation", "net_rshares") and vote numeric fields ("rshares", "reputation") to strings to preserve precision across transports.
|
|
263
|
+
- Normalizes times and numeric fields inside each entry of "active_votes".
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
dict: A JSON-safe copy of the comment data suitable for json.dumps or returning from an API.
|
|
267
|
+
"""
|
|
226
268
|
output = self.copy()
|
|
227
269
|
if "authorperm" in output:
|
|
228
270
|
output.pop("authorperm")
|
|
@@ -246,7 +288,7 @@ class Comment(BlockchainObject):
|
|
|
246
288
|
output[p] = formatTimeString(p_date)
|
|
247
289
|
else:
|
|
248
290
|
output[p] = p_date
|
|
249
|
-
|
|
291
|
+
hbd_amounts = [
|
|
250
292
|
"total_payout_value",
|
|
251
293
|
"max_accepted_payout",
|
|
252
294
|
"pending_payout_value",
|
|
@@ -254,7 +296,7 @@ class Comment(BlockchainObject):
|
|
|
254
296
|
"total_pending_payout_value",
|
|
255
297
|
"promoted",
|
|
256
298
|
]
|
|
257
|
-
for p in
|
|
299
|
+
for p in hbd_amounts:
|
|
258
300
|
if p in output and isinstance(output[p], Amount):
|
|
259
301
|
output[p] = output[p].json()
|
|
260
302
|
parse_int = [
|
|
@@ -377,7 +419,16 @@ class Comment(BlockchainObject):
|
|
|
377
419
|
|
|
378
420
|
@property
|
|
379
421
|
def reward(self):
|
|
380
|
-
"""
|
|
422
|
+
"""
|
|
423
|
+
Return the post's total estimated reward as an Amount.
|
|
424
|
+
|
|
425
|
+
This is the sum of `total_payout_value`, `curator_payout_value`, and `pending_payout_value`
|
|
426
|
+
(from the comment data). Each component is converted to an Amount using the comment's
|
|
427
|
+
blockchain-backed token symbol before summing.
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
Amount: Total estimated reward (in the blockchain's backed token, e.g., HBD).
|
|
431
|
+
"""
|
|
381
432
|
a_zero = Amount(0, self.blockchain.backed_token_symbol, blockchain_instance=self.blockchain)
|
|
382
433
|
author = Amount(self.get("total_payout_value", a_zero), blockchain_instance=self.blockchain)
|
|
383
434
|
curator = Amount(
|
|
@@ -398,52 +449,74 @@ class Comment(BlockchainObject):
|
|
|
398
449
|
return post_age_days < 7.0 and float(total) == 0
|
|
399
450
|
|
|
400
451
|
def time_elapsed(self):
|
|
401
|
-
"""
|
|
452
|
+
"""
|
|
453
|
+
Return the time elapsed since the post was created as a timedelta.
|
|
454
|
+
|
|
455
|
+
The difference is computed as now (UTC) minus the post's `created` timestamp (a timezone-aware datetime).
|
|
456
|
+
A positive timedelta indicates the post is in the past; a negative value can occur if `created` is in the future.
|
|
457
|
+
"""
|
|
402
458
|
return datetime.now(timezone.utc) - self["created"]
|
|
403
459
|
|
|
404
|
-
def
|
|
405
|
-
"""
|
|
406
|
-
|
|
460
|
+
def curation_penalty_compensation_hbd(self):
|
|
461
|
+
"""
|
|
462
|
+
Calculate the HBD payout a post would need (after 15 minutes) to fully compensate the curation penalty for voting earlier than 15 minutes.
|
|
463
|
+
|
|
464
|
+
This refreshes the comment data, selects the reverse-auction window based on the blockchain hardfork (HF6/HF20/HF21), and computes the required payout using the post's current reward and age.
|
|
465
|
+
|
|
466
|
+
Returns:
|
|
467
|
+
Amount: Estimated HBD payout required to offset the early-vote curation penalty.
|
|
407
468
|
"""
|
|
408
469
|
self.refresh()
|
|
409
|
-
if self.blockchain.hardfork >= 21:
|
|
410
|
-
reverse_auction_window_seconds =
|
|
411
|
-
elif self.blockchain.hardfork >= 20:
|
|
412
|
-
reverse_auction_window_seconds =
|
|
470
|
+
if self.blockchain.hardfork() >= 21:
|
|
471
|
+
reverse_auction_window_seconds = HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF21
|
|
472
|
+
elif self.blockchain.hardfork() >= 20:
|
|
473
|
+
reverse_auction_window_seconds = HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF20
|
|
413
474
|
else:
|
|
414
|
-
reverse_auction_window_seconds =
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
475
|
+
reverse_auction_window_seconds = HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF6
|
|
476
|
+
elapsed_minutes = max((self.time_elapsed()).total_seconds() / 60, 1e-6)
|
|
477
|
+
return self.reward * reverse_auction_window_seconds / (elapsed_minutes**2)
|
|
478
|
+
|
|
479
|
+
def estimate_curation_hbd(self, vote_value_hbd, estimated_value_hbd=None):
|
|
480
|
+
"""
|
|
481
|
+
Estimate the curation reward (in HBD) for a given vote on this post.
|
|
482
|
+
|
|
483
|
+
Refreshes the post data from the chain before computing. If `estimated_value_hbd` is not provided, the current post reward is used as the estimated total post value. The returned value is an estimate of the curator's HBD payout for a vote of size `vote_value_hbd`, accounting for the current curation penalty.
|
|
420
484
|
|
|
421
|
-
|
|
422
|
-
|
|
485
|
+
Parameters:
|
|
486
|
+
vote_value_hbd (float): Vote value in HBD used to compute the curation share.
|
|
487
|
+
estimated_value_hbd (float, optional): Estimated total post value in HBD to scale the curation; defaults to the post's current reward.
|
|
423
488
|
|
|
424
|
-
:
|
|
425
|
-
|
|
426
|
-
:param float estimated_value_SBD: When set, this value is used for calculate
|
|
427
|
-
the curation. When not set, the current post value is used.
|
|
489
|
+
Returns:
|
|
490
|
+
float: Estimated curation reward in HBD for the provided vote value.
|
|
428
491
|
"""
|
|
429
492
|
self.refresh()
|
|
430
|
-
if
|
|
431
|
-
|
|
493
|
+
if estimated_value_hbd is None:
|
|
494
|
+
estimated_value_hbd = float(self.reward)
|
|
432
495
|
t = 1.0 - self.get_curation_penalty()
|
|
433
|
-
k =
|
|
496
|
+
k = vote_value_hbd / (vote_value_hbd + float(self.reward))
|
|
434
497
|
K = (1 - math.sqrt(1 - k)) / 4 / k
|
|
435
|
-
return K *
|
|
498
|
+
return K * vote_value_hbd * t * math.sqrt(estimated_value_hbd)
|
|
436
499
|
|
|
437
500
|
def get_curation_penalty(self, vote_time=None):
|
|
438
|
-
"""
|
|
439
|
-
|
|
501
|
+
"""
|
|
502
|
+
Return the curation penalty factor for a vote at a given time.
|
|
503
|
+
|
|
504
|
+
Calculates a value in [0.0, 1.0] representing the fraction of curation rewards
|
|
505
|
+
that will be removed due to early voting (0.0 = no penalty, 1.0 = full penalty).
|
|
506
|
+
The penalty is based on the elapsed time between the post's creation and
|
|
507
|
+
the vote time, scaled by the Hive reverse-auction window for the node's
|
|
508
|
+
current hardfork (HF21, HF20, or HF6).
|
|
509
|
+
|
|
510
|
+
Parameters:
|
|
511
|
+
vote_time (datetime | date | str | None): Time of the vote. If None,
|
|
512
|
+
the current time is used. If a string is given it will be parsed
|
|
513
|
+
with the module's time formatter.
|
|
440
514
|
|
|
441
|
-
:
|
|
442
|
-
|
|
443
|
-
When set to None, the current date is used.
|
|
444
|
-
:returns: Float number between 0 and 1 (0.0 -> no penalty, 1.0 -> 100 % curation penalty)
|
|
445
|
-
:rtype: float
|
|
515
|
+
Returns:
|
|
516
|
+
float: Penalty fraction in the range [0.0, 1.0].
|
|
446
517
|
|
|
518
|
+
Raises:
|
|
519
|
+
ValueError: If vote_time is not None and not a datetime, date, or parseable string.
|
|
447
520
|
"""
|
|
448
521
|
if vote_time is None:
|
|
449
522
|
elapsed_seconds = self.time_elapsed().total_seconds()
|
|
@@ -453,25 +526,33 @@ class Comment(BlockchainObject):
|
|
|
453
526
|
elapsed_seconds = (vote_time - self["created"]).total_seconds()
|
|
454
527
|
else:
|
|
455
528
|
raise ValueError("vote_time must be a string or a datetime")
|
|
456
|
-
if self.blockchain.hardfork >= 21:
|
|
457
|
-
reward = elapsed_seconds /
|
|
458
|
-
elif self.blockchain.hardfork >= 20:
|
|
459
|
-
reward = elapsed_seconds /
|
|
529
|
+
if self.blockchain.hardfork() >= 21:
|
|
530
|
+
reward = elapsed_seconds / HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF21
|
|
531
|
+
elif self.blockchain.hardfork() >= 20:
|
|
532
|
+
reward = elapsed_seconds / HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF20
|
|
460
533
|
else:
|
|
461
|
-
reward = elapsed_seconds /
|
|
534
|
+
reward = elapsed_seconds / HIVE_REVERSE_AUCTION_WINDOW_SECONDS_HF6
|
|
462
535
|
if reward > 1:
|
|
463
536
|
reward = 1.0
|
|
464
537
|
return 1.0 - reward
|
|
465
538
|
|
|
466
539
|
def get_vote_with_curation(self, voter=None, raw_data=False, pending_payout_value=None):
|
|
467
|
-
"""
|
|
540
|
+
"""
|
|
541
|
+
Return the specified voter's vote for this comment, optionally augmented with curation data.
|
|
542
|
+
|
|
543
|
+
If `voter` is not found in the comment's votes returns None. When a vote is found:
|
|
544
|
+
- If `raw_data` is True or the post is not pending payout, returns the raw vote dict.
|
|
545
|
+
- If the post is pending and `raw_data` is False, returns the vote dict augmented with:
|
|
546
|
+
- `curation_reward`: the vote's curation reward (in HBD)
|
|
547
|
+
- `ROI`: percent return on the voter's effective voting value
|
|
468
548
|
|
|
469
|
-
:
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
:type pending_payout_SBD: float, str
|
|
549
|
+
Parameters:
|
|
550
|
+
voter (str or Account, optional): Voter name or Account. If omitted, defaults to the post author as an Account.
|
|
551
|
+
raw_data (bool, optional): If True, return the found vote without adding curation/ROI fields.
|
|
552
|
+
pending_payout_value (float or str, optional): If provided, use this HBD value instead of the current pending payout when computing curation rewards.
|
|
474
553
|
|
|
554
|
+
Returns:
|
|
555
|
+
dict or None: The vote dictionary (possibly augmented with `curation_reward` and `ROI`) or None if the voter has not voted.
|
|
475
556
|
"""
|
|
476
557
|
specific_vote = None
|
|
477
558
|
if voter is None:
|
|
@@ -491,12 +572,16 @@ class Comment(BlockchainObject):
|
|
|
491
572
|
return specific_vote
|
|
492
573
|
elif specific_vote is not None:
|
|
493
574
|
curation_reward = self.get_curation_rewards(
|
|
494
|
-
|
|
575
|
+
pending_payout_hbd=True, pending_payout_value=pending_payout_value
|
|
495
576
|
)
|
|
496
577
|
specific_vote["curation_reward"] = curation_reward["active_votes"][voter["name"]]
|
|
497
578
|
specific_vote["ROI"] = (
|
|
498
579
|
float(curation_reward["active_votes"][voter["name"]])
|
|
499
|
-
/ float(
|
|
580
|
+
/ float(
|
|
581
|
+
voter.get_voting_value(
|
|
582
|
+
voting_power=None, voting_weight=specific_vote["percent"] / 100
|
|
583
|
+
)
|
|
584
|
+
)
|
|
500
585
|
* 100
|
|
501
586
|
)
|
|
502
587
|
return specific_vote
|
|
@@ -504,32 +589,35 @@ class Comment(BlockchainObject):
|
|
|
504
589
|
return None
|
|
505
590
|
|
|
506
591
|
def get_beneficiaries_pct(self):
|
|
507
|
-
"""
|
|
592
|
+
"""
|
|
593
|
+
Return the sum of beneficiary weights as a fraction of the full payout.
|
|
594
|
+
|
|
595
|
+
If the post has a `beneficiaries` list of dicts with integer `weight` fields (0–10000 representing 0%–100%), this returns the total weight divided by 100.0 (i.e., a float in 0.0–100.0/100 range; typical values are 0.0–1.0).
|
|
596
|
+
"""
|
|
508
597
|
beneficiaries = self["beneficiaries"]
|
|
509
598
|
weight = 0
|
|
510
599
|
for b in beneficiaries:
|
|
511
600
|
weight += b["weight"]
|
|
512
|
-
return weight /
|
|
601
|
+
return weight / HIVE_100_PERCENT
|
|
513
602
|
|
|
514
603
|
def get_rewards(self):
|
|
515
|
-
"""
|
|
516
|
-
|
|
604
|
+
"""
|
|
605
|
+
Return the post's total, author, and curator payouts as Amount objects (HBD).
|
|
517
606
|
|
|
518
|
-
|
|
519
|
-
`author_payout` and the `total_payout`
|
|
607
|
+
If the post is pending, returns an estimated total based on pending_payout_value and derives the author's share via get_author_rewards(); curator_payout is computed as the difference. For finalized posts, uses total_payout_value and curator_payout_value.
|
|
520
608
|
|
|
521
|
-
|
|
609
|
+
Note: beneficiary rewards (if any) are already deducted from the returned author_payout and total_payout.
|
|
522
610
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
611
|
+
Returns:
|
|
612
|
+
dict: {
|
|
613
|
+
"total_payout": Amount,
|
|
614
|
+
"author_payout": Amount,
|
|
615
|
+
"curator_payout": Amount,
|
|
527
616
|
}
|
|
528
|
-
|
|
529
617
|
"""
|
|
530
618
|
if self.is_pending():
|
|
531
619
|
total_payout = Amount(self["pending_payout_value"], blockchain_instance=self.blockchain)
|
|
532
|
-
author_payout = self.get_author_rewards()["
|
|
620
|
+
author_payout = self.get_author_rewards()["total_payout_HBD"]
|
|
533
621
|
curator_payout = total_payout - author_payout
|
|
534
622
|
else:
|
|
535
623
|
author_payout = Amount(self["total_payout_value"], blockchain_instance=self.blockchain)
|
|
@@ -544,30 +632,38 @@ class Comment(BlockchainObject):
|
|
|
544
632
|
}
|
|
545
633
|
|
|
546
634
|
def get_author_rewards(self):
|
|
547
|
-
"""
|
|
548
|
-
|
|
635
|
+
"""
|
|
636
|
+
Return the computed author-side rewards for this post.
|
|
549
637
|
|
|
638
|
+
If the post payout is not pending, returns zero HP/HBD payouts and the concrete total payout as `total_payout_HBD`. If the payout is pending, computes the author’s share after curation and beneficiaries, and—when price history and percent_hbd are available—splits that share into HBD and HP equivalents.
|
|
550
639
|
|
|
551
|
-
|
|
640
|
+
Returns:
|
|
641
|
+
dict: A dictionary with the following keys:
|
|
642
|
+
- pending_rewards (bool): True when the post payout is still pending.
|
|
643
|
+
- payout_HP (Amount or None): Estimated Hive Power payout (Amount) when pending and convertible; otherwise 0 Amount (when not pending) or None.
|
|
644
|
+
- payout_HBD (Amount or None): Estimated HBD payout (Amount) when pending and convertible; otherwise 0 Amount (when not pending) or None.
|
|
645
|
+
- total_payout_HBD (Amount): Total author-side payout expressed in HBD-equivalent units when pending, or the concrete total payout when not pending.
|
|
646
|
+
- total_payout (Amount, optional): Present only for pending payouts in the non-convertible branch; the author-side token amount before HBD/HP splitting.
|
|
647
|
+
- Note: When price/percent data is not available, `payout_HP` and `payout_HBD` will be None and only `total_payout_HBD`/`total_payout` convey the author share.
|
|
552
648
|
|
|
649
|
+
Example:
|
|
553
650
|
{
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
651
|
+
"pending_rewards": True,
|
|
652
|
+
"payout_HP": Amount(...), # HP equivalent (when convertible)
|
|
653
|
+
"payout_HBD": Amount(...), # HBD portion (when convertible)
|
|
654
|
+
"total_payout_HBD": Amount(...) # Total author share in HBD-equivalent
|
|
558
655
|
}
|
|
559
|
-
|
|
560
656
|
"""
|
|
561
657
|
if not self.is_pending():
|
|
562
658
|
return {
|
|
563
659
|
"pending_rewards": False,
|
|
564
|
-
"
|
|
660
|
+
"payout_HP": Amount(
|
|
565
661
|
0, self.blockchain.token_symbol, blockchain_instance=self.blockchain
|
|
566
662
|
),
|
|
567
|
-
"
|
|
663
|
+
"payout_HBD": Amount(
|
|
568
664
|
0, self.blockchain.backed_token_symbol, blockchain_instance=self.blockchain
|
|
569
665
|
),
|
|
570
|
-
"
|
|
666
|
+
"total_payout_HBD": Amount(
|
|
571
667
|
self["total_payout_value"], blockchain_instance=self.blockchain
|
|
572
668
|
),
|
|
573
669
|
}
|
|
@@ -579,70 +675,52 @@ class Comment(BlockchainObject):
|
|
|
579
675
|
curation_tokens = self.reward * author_reward_factor
|
|
580
676
|
author_tokens = self.reward - curation_tokens
|
|
581
677
|
curation_rewards = self.get_curation_rewards()
|
|
582
|
-
if self.blockchain.hardfork >= 20 and median_hist is not None:
|
|
678
|
+
if self.blockchain.hardfork() >= 20 and median_hist is not None:
|
|
583
679
|
author_tokens += median_price * curation_rewards["unclaimed_rewards"]
|
|
584
|
-
|
|
585
|
-
benefactor_tokens = author_tokens * beneficiaries_pct / 100.0
|
|
680
|
+
benefactor_tokens = author_tokens * beneficiaries_pct / HIVE_100_PERCENT
|
|
586
681
|
author_tokens -= benefactor_tokens
|
|
587
682
|
|
|
588
|
-
if median_hist is not None and "
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
author_tokens -
|
|
683
|
+
if median_hist is not None and "percent_hbd" in self:
|
|
684
|
+
hbd_payout = author_tokens * self["percent_hbd"] / 20000.0
|
|
685
|
+
hp_payout = median_price.as_base(self.blockchain.token_symbol) * (
|
|
686
|
+
author_tokens - hbd_payout
|
|
592
687
|
)
|
|
593
688
|
return {
|
|
594
689
|
"pending_rewards": True,
|
|
595
|
-
"
|
|
596
|
-
"
|
|
597
|
-
"
|
|
598
|
-
}
|
|
599
|
-
elif median_hist is not None and "percent_hbd" in self:
|
|
600
|
-
sbd_steem = author_tokens * self["percent_hbd"] / 20000.0
|
|
601
|
-
vesting_steem = median_price.as_base(self.blockchain.token_symbol) * (
|
|
602
|
-
author_tokens - sbd_steem
|
|
603
|
-
)
|
|
604
|
-
return {
|
|
605
|
-
"pending_rewards": True,
|
|
606
|
-
"payout_SP": vesting_steem,
|
|
607
|
-
"payout_SBD": sbd_steem,
|
|
608
|
-
"total_payout_SBD": author_tokens,
|
|
690
|
+
"payout_HP": hp_payout,
|
|
691
|
+
"payout_HBD": hbd_payout,
|
|
692
|
+
"total_payout_HBD": author_tokens,
|
|
609
693
|
}
|
|
610
694
|
else:
|
|
611
695
|
return {
|
|
612
696
|
"pending_rewards": True,
|
|
613
697
|
"total_payout": author_tokens,
|
|
614
|
-
|
|
615
|
-
"
|
|
698
|
+
# HBD/HP primary fields
|
|
699
|
+
"total_payout_HBD": author_tokens,
|
|
700
|
+
"payout_HBD": None,
|
|
701
|
+
"payout_HP": None,
|
|
616
702
|
}
|
|
617
703
|
|
|
618
|
-
def get_curation_rewards(self,
|
|
619
|
-
"""
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
:
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
{
|
|
634
|
-
'pending_rewards': True, 'unclaimed_rewards': 0.245 STEEM,
|
|
635
|
-
'active_votes': {
|
|
636
|
-
'leprechaun': 0.006 STEEM, 'timcliff': 0.186 STEEM,
|
|
637
|
-
'st3llar': 0.000 STEEM, 'crokkon': 0.015 STEEM, 'feedyourminnows': 0.003 STEEM,
|
|
638
|
-
'isnochys': 0.003 STEEM, 'loshcat': 0.001 STEEM, 'greenorange': 0.000 STEEM,
|
|
639
|
-
'qustodian': 0.123 STEEM, 'jpphotography': 0.002 STEEM, 'thinkingmind': 0.001 STEEM,
|
|
640
|
-
'oups': 0.006 STEEM, 'mattockfs': 0.001 STEEM, 'thecrazygm': 0.003 STEEM, 'michaelizer': 0.004 STEEM,
|
|
641
|
-
'flugschwein': 0.010 STEEM, 'ulisessabeque': 0.000 STEEM, 'hakancelik': 0.002 STEEM, 'sbi2': 0.008 STEEM,
|
|
642
|
-
'zcool': 0.000 STEEM, 'steemhq': 0.002 STEEM, 'rowdiya': 0.000 STEEM, 'qurator-tier-1-2': 0.012 STEEM
|
|
643
|
-
}
|
|
704
|
+
def get_curation_rewards(self, pending_payout_hbd=False, pending_payout_value=None):
|
|
705
|
+
"""
|
|
706
|
+
Calculate curation rewards for this post and distribute them across active voters.
|
|
707
|
+
|
|
708
|
+
Parameters:
|
|
709
|
+
pending_payout_hbd (bool): If True, compute and return rewards in HBD (do not convert to HIVE/HP). Default False.
|
|
710
|
+
pending_payout_value (float | str | Amount | None): Optional override for the post's pending payout value used when the post is still pending.
|
|
711
|
+
- If None and the post is pending, the function uses the post's stored pending_payout_value.
|
|
712
|
+
- Accepted types: numeric, string amount, or an Amount instance.
|
|
713
|
+
|
|
714
|
+
Returns:
|
|
715
|
+
dict: {
|
|
716
|
+
"pending_rewards": bool, # True if the post is still within the payout window (uses pending_payout_value)
|
|
717
|
+
"unclaimed_rewards": Amount, # Amount reserved for unclaimed curation (e.g., self-votes or early votes)
|
|
718
|
+
"active_votes": dict # Mapping voter_name -> Amount of curation reward allocated to that voter
|
|
644
719
|
}
|
|
645
720
|
|
|
721
|
+
Notes:
|
|
722
|
+
- The function splits the curation pool using the protocol's curator share (50% by default) and prorates per-voter claims by vote weight.
|
|
723
|
+
- When a current median price history is available, rewards may be converted between HBD and the chain's token (HP) according to pending_payout_hbd.
|
|
646
724
|
"""
|
|
647
725
|
median_hist = self.blockchain.get_current_median_history()
|
|
648
726
|
if median_hist is not None:
|
|
@@ -666,7 +744,7 @@ class Comment(BlockchainObject):
|
|
|
666
744
|
total_vote_weight += vote["weight"]
|
|
667
745
|
|
|
668
746
|
if not self.is_pending():
|
|
669
|
-
if
|
|
747
|
+
if pending_payout_hbd or median_hist is None:
|
|
670
748
|
max_rewards = Amount(
|
|
671
749
|
self["curator_payout_value"], blockchain_instance=self.blockchain
|
|
672
750
|
)
|
|
@@ -694,7 +772,7 @@ class Comment(BlockchainObject):
|
|
|
694
772
|
pending_payout_value = Amount(
|
|
695
773
|
pending_payout_value, blockchain_instance=self.blockchain
|
|
696
774
|
)
|
|
697
|
-
if
|
|
775
|
+
if pending_payout_hbd or median_hist is None:
|
|
698
776
|
max_rewards = pending_payout_value * curator_reward_factor
|
|
699
777
|
else:
|
|
700
778
|
max_rewards = median_price.as_base(self.blockchain.token_symbol) * (
|
|
@@ -921,19 +999,22 @@ class Comment(BlockchainObject):
|
|
|
921
999
|
)
|
|
922
1000
|
|
|
923
1001
|
def delete(self, account=None, identifier=None):
|
|
924
|
-
"""
|
|
1002
|
+
"""
|
|
1003
|
+
Delete this post or comment from the blockchain.
|
|
1004
|
+
|
|
1005
|
+
If `identifier` is provided it must be an author/permlink string (e.g. "@author/permlink"); otherwise the current Comment's author and permlink are used. If `account` is not provided the method will use `blockchain.config["default_account"]` when present; otherwise a ValueError is raised.
|
|
925
1006
|
|
|
926
|
-
:
|
|
927
|
-
``account`` is not defined, the ``default_account`` will be
|
|
928
|
-
taken or a ValueError will be raised.
|
|
1007
|
+
Note: a post/comment can only be deleted if it has no replies and no positive rshares.
|
|
929
1008
|
|
|
930
|
-
:
|
|
931
|
-
|
|
932
|
-
|
|
1009
|
+
Parameters:
|
|
1010
|
+
account (str, optional): Account name to perform the deletion. If omitted, the configured default_account is used.
|
|
1011
|
+
identifier (str, optional): Author/permlink of the post to delete (format "@author/permlink"). Defaults to the current Comment.
|
|
933
1012
|
|
|
934
|
-
|
|
935
|
-
|
|
1013
|
+
Returns:
|
|
1014
|
+
dict: Result of the blockchain finalizeOp / transaction broadcast.
|
|
936
1015
|
|
|
1016
|
+
Raises:
|
|
1017
|
+
ValueError: If no account is provided and no default_account is configured.
|
|
937
1018
|
"""
|
|
938
1019
|
if not account:
|
|
939
1020
|
if "default_account" in self.blockchain.config:
|
|
@@ -949,13 +1030,19 @@ class Comment(BlockchainObject):
|
|
|
949
1030
|
op = operations.Delete_comment(**{"author": post_author, "permlink": post_permlink})
|
|
950
1031
|
return self.blockchain.finalizeOp(op, account, "posting")
|
|
951
1032
|
|
|
952
|
-
def
|
|
953
|
-
"""
|
|
1033
|
+
def reblog(self, identifier=None, account=None):
|
|
1034
|
+
"""
|
|
1035
|
+
Create a reblog (resteem) for the specified post.
|
|
1036
|
+
|
|
1037
|
+
Parameters:
|
|
1038
|
+
identifier (str, optional): Post identifier in the form "@author/permlink". If omitted, uses this Comment's identifier.
|
|
1039
|
+
account (str, optional): Name of the posting account to perform the reblog. If omitted, the configured `default_account` is used.
|
|
954
1040
|
|
|
955
|
-
:
|
|
956
|
-
|
|
957
|
-
to (defaults to ``default_account``)
|
|
1041
|
+
Returns:
|
|
1042
|
+
dict: Result from the blockchain custom_json operation.
|
|
958
1043
|
|
|
1044
|
+
Raises:
|
|
1045
|
+
ValueError: If no account is provided and no `default_account` is configured.
|
|
959
1046
|
"""
|
|
960
1047
|
if not account:
|
|
961
1048
|
account = self.blockchain.configStorage.get("default_account")
|
|
@@ -977,7 +1064,7 @@ class RecentReplies(list):
|
|
|
977
1064
|
:param str author: author
|
|
978
1065
|
:param bool skip_own: (optional) Skip replies of the author to him/herself.
|
|
979
1066
|
Default: True
|
|
980
|
-
:param
|
|
1067
|
+
:param Blockchain blockchain_instance: Blockchain instance to use when accessing the RPC
|
|
981
1068
|
"""
|
|
982
1069
|
|
|
983
1070
|
def __init__(
|
|
@@ -989,13 +1076,24 @@ class RecentReplies(list):
|
|
|
989
1076
|
lazy=False,
|
|
990
1077
|
full=True,
|
|
991
1078
|
blockchain_instance=None,
|
|
992
|
-
**kwargs,
|
|
993
1079
|
):
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1080
|
+
"""
|
|
1081
|
+
Create a list of recent replies to a given account.
|
|
1082
|
+
|
|
1083
|
+
Initializes the instance as a list of Comment objects built from the account's recent "replies" feed. By default replies authored by the same account are omitted when skip_own is True. If no blockchain connection is available during construction, initialization is aborted (the constructor returns early).
|
|
1084
|
+
|
|
1085
|
+
Parameters:
|
|
1086
|
+
author (str): Account name whose replies to collect.
|
|
1087
|
+
skip_own (bool): If True, omit replies authored by `author`. Default True.
|
|
1088
|
+
start_permlink (str): Legacy/paging parameter; currently ignored by this implementation.
|
|
1089
|
+
limit (int): Maximum number of replies to collect; currently ignored (the underlying API call controls results).
|
|
1090
|
+
lazy (bool): If True, create Comment objects in lazy mode.
|
|
1091
|
+
full (bool): If True, create Comment objects with full data populated.
|
|
1092
|
+
|
|
1093
|
+
Notes:
|
|
1094
|
+
- The blockchain_instance parameter is used to resolve RPC access and is intentionally undocumented here as a shared service.
|
|
1095
|
+
- The underlying account.get_account_posts(sort="replies", raw_data=True) call provides the source data; when it returns None or the instance is not connected, construction exits early.
|
|
1096
|
+
"""
|
|
999
1097
|
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
1000
1098
|
if not self.blockchain.is_connected():
|
|
1001
1099
|
return None
|
|
@@ -1020,7 +1118,7 @@ class RecentByPath(list):
|
|
|
1020
1118
|
:param str path: path
|
|
1021
1119
|
:param str tag: tag
|
|
1022
1120
|
:param str observer: observer
|
|
1023
|
-
:param
|
|
1121
|
+
:param Blockchain blockchain_instance: Blockchain instance to use when accessing the RPC
|
|
1024
1122
|
"""
|
|
1025
1123
|
|
|
1026
1124
|
def __init__(
|
|
@@ -1032,13 +1130,18 @@ class RecentByPath(list):
|
|
|
1032
1130
|
full=True,
|
|
1033
1131
|
limit=20,
|
|
1034
1132
|
blockchain_instance=None,
|
|
1035
|
-
**kwargs,
|
|
1036
1133
|
):
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1134
|
+
"""
|
|
1135
|
+
Create a RecentByPath list by fetching ranked posts for a given path/tag and initializing the list with those posts.
|
|
1136
|
+
|
|
1137
|
+
Parameters:
|
|
1138
|
+
path (str): Ranking category to fetch (e.g., "trending", "hot").
|
|
1139
|
+
tag (str): Optional tag to filter posts.
|
|
1140
|
+
observer (str): Observer account used for context-aware fetches (affects reward/curation visibility).
|
|
1141
|
+
lazy (bool): If True, create Comment objects lazily (defer full data loading).
|
|
1142
|
+
full (bool): If True, initialize Comment objects with full data when available.
|
|
1143
|
+
limit (int): Maximum number of posts to fetch.
|
|
1144
|
+
"""
|
|
1042
1145
|
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
1043
1146
|
|
|
1044
1147
|
# Create RankedPosts with proper parameters
|
|
@@ -1050,7 +1153,6 @@ class RecentByPath(list):
|
|
|
1050
1153
|
lazy=lazy,
|
|
1051
1154
|
full=full,
|
|
1052
1155
|
blockchain_instance=self.blockchain,
|
|
1053
|
-
**kwargs,
|
|
1054
1156
|
)
|
|
1055
1157
|
|
|
1056
1158
|
super(RecentByPath, self).__init__(ranked_posts)
|
|
@@ -1065,7 +1167,7 @@ class RankedPosts(list):
|
|
|
1065
1167
|
:param int limit: limits the number of returns comments
|
|
1066
1168
|
:param str start_author: start author
|
|
1067
1169
|
:param str start_permlink: start permlink
|
|
1068
|
-
:param
|
|
1170
|
+
:param Blockchain blockchain_instance: Blockchain instance to use when accessing the RPC
|
|
1069
1171
|
"""
|
|
1070
1172
|
|
|
1071
1173
|
def __init__(
|
|
@@ -1080,13 +1182,29 @@ class RankedPosts(list):
|
|
|
1080
1182
|
full=True,
|
|
1081
1183
|
raw_data=False,
|
|
1082
1184
|
blockchain_instance=None,
|
|
1083
|
-
**kwargs,
|
|
1084
1185
|
):
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1186
|
+
"""
|
|
1187
|
+
Initialize a RankedPosts list by fetching paginated ranked posts from the blockchain.
|
|
1188
|
+
|
|
1189
|
+
Fetches up to `limit` posts for the given `sort` and `tag` using the bridge `get_ranked_posts`
|
|
1190
|
+
RPC, paging with `start_author` / `start_permlink`. Results are appended to the list as raw
|
|
1191
|
+
post dicts when `raw_data` is True, or as Comment objects otherwise. The constructor:
|
|
1192
|
+
- uses `blockchain_instance` (or the shared instance) and returns early (None) if not connected;
|
|
1193
|
+
- pages through results with an API page size up to 100, updating `start_author`/`start_permlink`;
|
|
1194
|
+
- avoids repeating the last item returned by the API; and
|
|
1195
|
+
- on an RPC error, returns partial results if any posts were already collected, otherwise re-raises.
|
|
1196
|
+
|
|
1197
|
+
Parameters:
|
|
1198
|
+
sort (str): Ranking to query (e.g., "trending", "hot", "created").
|
|
1199
|
+
tag (str): Optional tag/category to filter by.
|
|
1200
|
+
observer (str): Optional observer account used by the bridge API (affects personalized results).
|
|
1201
|
+
limit (int): Maximum number of posts to return.
|
|
1202
|
+
start_author (str): Author to start paging from (inclusive/exclusive depends on the API).
|
|
1203
|
+
start_permlink (str): Permlink to start paging from.
|
|
1204
|
+
lazy (bool): If False, wrap results in Comment objects fully; if True, create Comment objects in lazy mode.
|
|
1205
|
+
full (bool): If True, request full Comment initialization when wrapping results.
|
|
1206
|
+
raw_data (bool): If True, return raw post dictionaries instead of Comment objects.
|
|
1207
|
+
"""
|
|
1090
1208
|
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
1091
1209
|
if not self.blockchain.is_connected():
|
|
1092
1210
|
return None
|
|
@@ -1151,7 +1269,7 @@ class AccountPosts(list):
|
|
|
1151
1269
|
:param int limit: limits the number of returns comments
|
|
1152
1270
|
:param str start_author: start author
|
|
1153
1271
|
:param str start_permlink: start permlink
|
|
1154
|
-
:param
|
|
1272
|
+
:param Blockchain blockchain_instance: Blockchain instance to use when accessing the RPC
|
|
1155
1273
|
"""
|
|
1156
1274
|
|
|
1157
1275
|
def __init__(
|
|
@@ -1166,13 +1284,30 @@ class AccountPosts(list):
|
|
|
1166
1284
|
full=True,
|
|
1167
1285
|
raw_data=False,
|
|
1168
1286
|
blockchain_instance=None,
|
|
1169
|
-
**kwargs,
|
|
1170
1287
|
):
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1288
|
+
"""
|
|
1289
|
+
Initialize an AccountPosts list by fetching posts for a given account (paginated).
|
|
1290
|
+
|
|
1291
|
+
This constructor populates the list with posts returned by the bridge.get_account_posts RPC call,
|
|
1292
|
+
respecting paging (start_author/start_permlink) and the requested limit. Each item is either the
|
|
1293
|
+
raw post dict (when raw_data=True) or a Comment object constructed with the same blockchain instance.
|
|
1294
|
+
|
|
1295
|
+
Parameters:
|
|
1296
|
+
sort (str): The post list type to fetch (e.g., "blog", "comments", "replies", "feed").
|
|
1297
|
+
account (str): Account name whose posts are requested.
|
|
1298
|
+
observer (str): Optional observer account name used by the API (affects visibility/context).
|
|
1299
|
+
limit (int): Maximum number of posts to collect.
|
|
1300
|
+
start_author (str): Author to start paging from (inclusive/exclusive depends on API).
|
|
1301
|
+
start_permlink (str): Permlink to start paging from.
|
|
1302
|
+
lazy (bool): If False, Comment objects are fully loaded; if True, they are initialized lazily.
|
|
1303
|
+
full (bool): If True, Comment objects include full data; otherwise minimal fields.
|
|
1304
|
+
raw_data (bool): If True, return raw post dicts instead of Comment objects.
|
|
1305
|
+
|
|
1306
|
+
Behavior notes:
|
|
1307
|
+
- If the blockchain instance is not connected, initialization returns early (no posts are fetched).
|
|
1308
|
+
- On an RPC error, if some posts have already been collected, the constructor returns those partial results;
|
|
1309
|
+
if no posts were collected, the exception is propagated.
|
|
1310
|
+
"""
|
|
1176
1311
|
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
1177
1312
|
if not self.blockchain.is_connected():
|
|
1178
1313
|
return None
|