epicyon/question.py

140 lines
5.3 KiB
Python
Raw Normal View History

2020-04-04 10:12:34 +00:00
__filename__ = "question.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
2021-01-26 10:07:42 +00:00
__version__ = "1.2.0"
2020-04-04 10:12:34 +00:00
__maintainer__ = "Bob Mottram"
2021-09-10 16:14:50 +00:00
__email__ = "bob@libreserver.org"
2020-04-04 10:12:34 +00:00
__status__ = "Production"
2021-06-15 15:08:12 +00:00
__module_group__ = "ActivityPub"
2019-11-29 18:46:21 +00:00
import os
2021-12-26 20:36:08 +00:00
from utils import locate_post
2021-12-26 15:13:34 +00:00
from utils import load_json
2021-12-26 14:47:21 +00:00
from utils import save_json
2021-12-26 10:57:03 +00:00
from utils import has_object_dict
2019-11-29 18:46:21 +00:00
2020-04-04 10:12:34 +00:00
2021-12-25 16:17:53 +00:00
def questionUpdateVotes(base_dir: str, nickname: str, domain: str,
replyJson: {}) -> ({}, str):
2019-11-29 18:46:21 +00:00
""" For a given reply update the votes on a question
2019-11-29 19:22:11 +00:00
Returns the question json object if the vote totals were changed
2019-11-29 18:46:21 +00:00
"""
2021-12-26 10:57:03 +00:00
if not has_object_dict(replyJson):
return None, None
2019-11-29 18:46:21 +00:00
if not replyJson['object'].get('inReplyTo'):
return None, None
2019-11-29 18:46:21 +00:00
if not replyJson['object']['inReplyTo']:
return None, None
2020-08-28 14:45:07 +00:00
if not isinstance(replyJson['object']['inReplyTo'], str):
return None, None
2020-01-30 10:11:08 +00:00
if not replyJson['object'].get('name'):
return None, None
2020-04-04 10:12:34 +00:00
inReplyTo = replyJson['object']['inReplyTo']
2021-12-26 20:36:08 +00:00
questionPostFilename = locate_post(base_dir, nickname, domain, inReplyTo)
2019-11-29 18:46:21 +00:00
if not questionPostFilename:
return None, None
2021-12-26 15:13:34 +00:00
questionJson = load_json(questionPostFilename)
2019-11-29 18:46:21 +00:00
if not questionJson:
return None, None
2021-12-26 10:57:03 +00:00
if not has_object_dict(questionJson):
return None, None
2019-11-29 18:46:21 +00:00
if not questionJson['object'].get('type'):
return None, None
2020-04-04 10:12:34 +00:00
if questionJson['type'] != 'Question':
return None, None
2019-11-29 18:46:21 +00:00
if not questionJson['object'].get('oneOf'):
return None, None
2019-11-29 18:46:21 +00:00
if not isinstance(questionJson['object']['oneOf'], list):
return None, None
2019-11-29 18:50:08 +00:00
if not questionJson['object'].get('content'):
return None, None
2020-04-04 10:12:34 +00:00
replyVote = replyJson['object']['name']
2020-01-30 10:11:08 +00:00
# does the reply name field match any possible question option?
foundAnswer = None, None
2019-11-29 18:46:21 +00:00
for possibleAnswer in questionJson['object']['oneOf']:
if not possibleAnswer.get('name'):
continue
2020-01-30 10:11:08 +00:00
if possibleAnswer['name'] == replyVote:
2020-04-04 10:12:34 +00:00
foundAnswer = possibleAnswer
2019-11-29 18:46:21 +00:00
break
if not foundAnswer:
return None, None
2019-11-29 18:46:21 +00:00
# update the voters file
2020-04-04 10:12:34 +00:00
votersFileSeparator = ';;;'
votersFilename = questionPostFilename.replace('.json', '.voters')
2019-11-29 18:46:21 +00:00
if not os.path.isfile(votersFilename):
# create a new voters file
2021-06-22 12:27:10 +00:00
with open(votersFilename, 'w+') as votersFile:
votersFile.write(replyJson['actor'] +
votersFileSeparator +
foundAnswer + '\n')
2019-11-29 18:46:21 +00:00
else:
if replyJson['actor'] not in open(votersFilename).read():
# append to the voters file
2021-06-22 12:27:10 +00:00
with open(votersFilename, 'a+') as votersFile:
votersFile.write(replyJson['actor'] +
votersFileSeparator +
foundAnswer + '\n')
2019-11-29 18:46:21 +00:00
else:
# change an entry in the voters file
2021-07-13 14:40:49 +00:00
with open(votersFilename, 'r') as votersFile:
2020-04-04 10:12:34 +00:00
lines = votersFile.readlines()
newlines = []
saveVotersFile = False
2019-11-29 19:22:11 +00:00
for voteLine in lines:
2020-04-04 10:12:34 +00:00
if voteLine.startswith(replyJson['actor'] +
votersFileSeparator):
newVoteLine = replyJson['actor'] + \
votersFileSeparator + foundAnswer + '\n'
if voteLine == newVoteLine:
2019-11-29 18:46:21 +00:00
break
2020-04-04 10:12:34 +00:00
saveVotersFile = True
2019-11-29 19:22:11 +00:00
newlines.append(newVoteLine)
else:
newlines.append(voteLine)
if saveVotersFile:
2020-08-29 11:14:19 +00:00
with open(votersFilename, 'w+') as votersFile:
2019-11-29 19:22:11 +00:00
for voteLine in newlines:
votersFile.write(voteLine)
else:
return None, None
2019-11-29 18:46:21 +00:00
# update the vote counts
2020-04-04 10:12:34 +00:00
questionTotalsChanged = False
2019-11-29 18:46:21 +00:00
for possibleAnswer in questionJson['object']['oneOf']:
if not possibleAnswer.get('name'):
continue
2020-04-04 10:12:34 +00:00
totalItems = 0
2021-07-13 14:40:49 +00:00
with open(votersFilename, 'r') as votersFile:
2020-04-04 10:12:34 +00:00
lines = votersFile.readlines()
2019-11-29 18:46:21 +00:00
for voteLine in lines:
2020-04-04 10:12:34 +00:00
if voteLine.endswith(votersFileSeparator +
possibleAnswer['name'] + '\n'):
totalItems += 1
if possibleAnswer['replies']['totalItems'] != totalItems:
possibleAnswer['replies']['totalItems'] = totalItems
questionTotalsChanged = True
2019-11-29 19:22:11 +00:00
if not questionTotalsChanged:
return None, None
2019-11-29 19:22:11 +00:00
# save the question with altered totals
2021-12-26 14:47:21 +00:00
save_json(questionJson, questionPostFilename)
return questionJson, questionPostFilename
2020-11-09 15:40:24 +00:00
def isQuestion(postObjectJson: {}) -> bool:
""" is the given post a question?
"""
if postObjectJson['type'] != 'Create' and \
postObjectJson['type'] != 'Update':
return False
2021-12-26 10:57:03 +00:00
if not has_object_dict(postObjectJson):
2020-11-09 15:40:24 +00:00
return False
if not postObjectJson['object'].get('type'):
return False
if postObjectJson['object']['type'] != 'Question':
return False
if not postObjectJson['object'].get('oneOf'):
return False
if not isinstance(postObjectJson['object']['oneOf'], list):
return False
return True