forked from steemit/steem-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblog.py
97 lines (71 loc) · 2.76 KB
/
blog.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
from funcy.flow import silent
from funcy.funcs import complement
from funcy.seqs import take, first
from .account import Account
from .instance import shared_steemd_instance
from .post import Post
from .utils import is_comment
class Blog:
""" Obtain a list of blog posts for an account
Args:
account_name (str): Name of the account
comments_only (bool): (Default False). Toggle between posts and comments.
steemd_instance (Steemd): Steemd instance overload
Returns:
Generator with Post objects in reverse chronological order.
Example:
To get all posts, you can use either generator:
::
gen1 = Blog('furion')
gen2 = b.all()
next(gen1)
next(gen2)
To get some posts, you can call `take()`:
::
b = Blog('furion')
posts = b.take(5)
"""
def __init__(self, account_name: str, comments_only=False, steemd_instance=None):
self.steem = steemd_instance or shared_steemd_instance()
self.comments_only = comments_only
self.account = Account(account_name)
self.history = self.account.history_reverse(filter_by='comment')
self.seen_items = set()
def take(self, limit=5):
""" Take up to n (n = limit) posts/comments at a time.
You can call this method as many times as you want. Once
there are no more posts to take, it will return [].
Returns:
List of posts/comments in a batch of size up to `limit`.
"""
# get main posts only
comment_filter = is_comment if self.comments_only else complement(is_comment)
hist = filter(comment_filter, self.history)
# filter out reblogs
match_author = lambda x: x['author'] == self.account.name
hist2 = filter(match_author, hist)
# post edits will re-appear in history
# we should therefore filter out already seen posts
def ensure_unique(post):
if post['permlink'] not in self.seen_items:
self.seen_items.add(post['permlink'])
return True
unique = filter(ensure_unique, hist2)
serialized = filter(bool, map(silent(Post), unique))
batch = take(limit, serialized)
return batch
def all(self):
""" A generator that will return ALL of account history. """
while True:
chunk = self.take(10)
if chunk:
yield from iter(chunk)
else:
break
def __iter__(self):
return self
def __next__(self):
next_item = first(self.take(1))
if not next_item:
raise StopIteration
return next_item