-
Notifications
You must be signed in to change notification settings - Fork 1
/
spreadsheet.py
238 lines (196 loc) · 7.59 KB
/
spreadsheet.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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
from beem.discussions import Query, Discussions_by_created
from beem.comment import Comment
from datetime import date, datetime, timedelta
from oauth2client.service_account import ServiceAccountCredentials
from urllib.parse import urlparse
import constants
import gspread
import json
import logging
import os
import re
def valid_category(tags):
"""
Returns True if category is valid, otherwise False
"""
for category in tags:
if "task-" in category:
if "bug" in category:
return True, "task-bug-hunting"
return True, category
if category == "blog" or category == "blogs":
return True, "blog"
elif category == "iamutopian":
return True, "iamutopian"
elif "idea" in category or "suggestion" in category:
return True, "ideas"
elif category == "development":
return True, "development"
elif category == "graphic" or category == "graphics":
return True, "graphics"
elif "bughunt" in category or "bug-hunt" in category:
return True, "bug-hunting"
elif "analysis" in category:
return True, "analysis"
elif "visibility" in category or "social" in category:
return True, "social"
elif "videotut" in category or "video-tut" in category:
return True, "video-tutorials"
elif category == "tutorial" or category == "tutorials":
return True, "tutorials"
elif "copywrit" in category:
return True, "copywriting"
elif "document" in category:
return True, "documentation"
elif "translation" in category:
return True, "translations"
elif category == "antiabuse" or category == "anti-abuse":
return True, "anti-abuse"
return False, ""
def get_repository(post):
"""
Returns the first repository found in the given post.
"""
pattern = re.compile(constants.REPOSITORY_REGEX)
if "links" in post.json_metadata.keys():
for link in post.json_metadata["links"]:
if link.startswith("/exit?url="):
link = link[len("/exit?url="):]
try:
result = pattern.search(link).group(0)
return result
except AttributeError:
continue
else:
for line in post.body.split():
try:
result = pattern.search(line).group(0)
return result
except AttributeError:
continue
return ""
def moderator_points():
"""
Return a dictionary containing a moderator and their points.
"""
moderators = {}
collection = constants.DB.moderators
community_managers = [
moderator["account"] for moderator in
collection.find({"supermoderator": True})]
utopian_fest = constants.UTOPIAN_FEST.col_values(1)
for moderator in set(community_managers + utopian_fest):
moderators.setdefault(moderator, 0)
if moderator in community_managers:
moderators[moderator] += 100.0
# Check for BOSSPOEM or TECHSLUT
if moderator == "espoem" or moderator == "techslut":
moderators[moderator] = 400.0
# Utopian Fest bonus
if moderator in utopian_fest:
moderators[moderator] += 50.0
# Save dictionary as JSON with date of last Thursday
with open(
f"/home/amos/utopian/utopian/static/{constants.THIS_WEEK}.json",
"w") as fp:
json.dump(moderators, fp, indent=4)
def get_urls():
"""
Returns all the URLs of the currently relevant worksheets.
"""
return (constants.UNREVIEWED.col_values(3) +
constants.REVIEWED.col_values(3) +
constants.LAST.col_values(3))
def banned_comment(url):
"""
Comments on the given contribution letting them know that they are banned.
"""
post = Comment(url)
comment = constants.COMMENT_BANNED.format(post.author)
post.reply(comment, author="amosbastian")
def exponential_vote(score, category):
"""Calculates the exponential vote for the bot."""
status = ""
try:
max_vote = constants.MAX_VOTE[category]
except:
max_vote = constants.MAX_TASK_REQUEST
else:
power = constants.EXP_POWER
weight = pow(
score / 100.0,
power - (score / 100.0 * (power - 1.0))) * max_vote
return float(weight)
def percentage(part, whole):
return 100 * float(part) / float(whole)
def store_contribution(post, category):
"""Stores a contribution in database for voting."""
contributions = constants.DB_UTEMPIAN.contributions.find(
{"author": post.author, "category": category})
scores = [contribution["score"] for contribution in contributions
if contribution["score"]]
if not scores:
return
rejected = scores.count(0)
accepted = len(scores) - rejected
upvote_percentage = percentage(accepted, len(scores))
if upvote_percentage < 66.0:
return
average_score = sum(scores) / len(scores)
weight = exponential_vote(average_score, category)
new_weight = (weight / max(constants.MAX_VOTE.values()) * 100.0) / constants.SCALER
collection = constants.DB_UTEMPIAN.pending_contributions
age = post.time_elapsed()
collection.insert({
"url": post.authorperm,
"upvote_time": datetime.now() + timedelta(minutes=10) - age,
"inserted": datetime.now(),
"upvoted": False,
"weight": new_weight
})
def main():
"""Iterates over the most recently created contributions and adds them to
the spreadsheet if not already in there.
"""
query = Query(limit=100, tag="utopian-io")
result = get_urls()
moderators = [moderator["account"] for moderator
in constants.DB_UTEMPIAN.moderators.find()]
for post in Discussions_by_created(query):
steemit_url = (
f"{constants.STEEMIT_URL}{post.category}/{post.authorperm}")
if steemit_url not in result:
tags = post.json_metadata["tags"]
# Checking if valid post
if (len(tags) < 2 or post["created"].date() < constants.THIS_WEEK):
continue
else:
is_valid, category = valid_category(tags)
if not is_valid:
continue
elif (category == "translations" and
post.author not in constants.UTOPIAN_TRANSLATORS):
constants.LOGGER.error(
f"{steemit_url} not made by accepted translator!")
continue
elif (category == "iamutopian" and
post.author not in moderators):
continue
repository = get_repository(post)
# If user banned, set moderator as BANNED and score to 0
if (post.author, "Yes") not in constants.BANNED_USERS:
row = ["", "", steemit_url, repository, category]
else:
today = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
row = ["BANNED", str(today), steemit_url, repository, category,
"0", "", "", "", "", 0]
constants.LOGGER.info(
f"Commenting on {steemit_url} - BANNED.")
banned_comment(steemit_url)
constants.UNREVIEWED.append_row(row)
result = get_urls()
constants.LOGGER.info(
f"{steemit_url} has tags: {tags} and was added.")
store_contribution(post, category)
if __name__ == '__main__':
main()