epicyon/question.py

151 lines
5.9 KiB
Python
Raw Normal View History

2020-04-04 10:12:34 +00:00
__filename__ = "question.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
2022-02-03 13:58:20 +00:00
__version__ = "1.3.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-29 21:55:09 +00:00
def question_update_votes(base_dir: str, nickname: str, domain: str,
2021-12-31 11:23:00 +00:00
reply_json: {}) -> ({}, 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-31 11:23:00 +00:00
if not has_object_dict(reply_json):
return None, None
2021-12-31 11:23:00 +00:00
if not reply_json['object'].get('inReplyTo'):
return None, None
2021-12-31 11:23:00 +00:00
if not reply_json['object']['inReplyTo']:
return None, None
2021-12-31 11:23:00 +00:00
if not isinstance(reply_json['object']['inReplyTo'], str):
return None, None
2021-12-31 11:23:00 +00:00
if not reply_json['object'].get('name'):
return None, None
2021-12-31 11:23:00 +00:00
in_reply_to = reply_json['object']['inReplyTo']
question_post_filename = \
locate_post(base_dir, nickname, domain, in_reply_to)
if not question_post_filename:
return None, None
2021-12-31 11:23:00 +00:00
question_json = load_json(question_post_filename)
if not question_json:
return None, None
2021-12-31 11:23:00 +00:00
if not has_object_dict(question_json):
return None, None
2021-12-31 11:23:00 +00:00
if not question_json['object'].get('type'):
return None, None
2021-12-31 11:23:00 +00:00
if question_json['type'] != 'Question':
return None, None
2021-12-31 11:23:00 +00:00
if not question_json['object'].get('oneOf'):
return None, None
2021-12-31 11:23:00 +00:00
if not isinstance(question_json['object']['oneOf'], list):
return None, None
2021-12-31 11:23:00 +00:00
if not question_json['object'].get('content'):
return None, None
2021-12-31 11:23:00 +00:00
reply_vote = reply_json['object']['name']
2020-01-30 10:11:08 +00:00
# does the reply name field match any possible question option?
2021-12-31 11:23:00 +00:00
found_answer = None, None
for possible_answer in question_json['object']['oneOf']:
if not possible_answer.get('name'):
2019-11-29 18:46:21 +00:00
continue
2021-12-31 11:23:00 +00:00
if possible_answer['name'] == reply_vote:
found_answer = possible_answer
2019-11-29 18:46:21 +00:00
break
2021-12-31 11:23:00 +00:00
if not found_answer:
return None, None
2019-11-29 18:46:21 +00:00
# update the voters file
2021-12-31 11:23:00 +00:00
voters_file_separator = ';;;'
voters_filename = question_post_filename.replace('.json', '.voters')
if not os.path.isfile(voters_filename):
2019-11-29 18:46:21 +00:00
# create a new voters file
2021-12-31 11:23:00 +00:00
try:
with open(voters_filename, 'w+') as voters_file:
voters_file.write(reply_json['actor'] +
voters_file_separator +
found_answer + '\n')
except OSError:
print('EX: unable to write voters file ' + voters_filename)
2019-11-29 18:46:21 +00:00
else:
2021-12-31 11:23:00 +00:00
if reply_json['actor'] not in open(voters_filename).read():
2019-11-29 18:46:21 +00:00
# append to the voters file
2021-12-31 11:23:00 +00:00
try:
with open(voters_filename, 'a+') as voters_file:
voters_file.write(reply_json['actor'] +
voters_file_separator +
found_answer + '\n')
except OSError:
print('EX: unable to append to voters file ' + voters_filename)
2019-11-29 18:46:21 +00:00
else:
# change an entry in the voters file
2021-12-31 11:23:00 +00:00
with open(voters_filename, 'r') as voters_file:
lines = voters_file.readlines()
2020-04-04 10:12:34 +00:00
newlines = []
2021-12-31 11:23:00 +00:00
save_voters_file = False
for vote_line in lines:
if vote_line.startswith(reply_json['actor'] +
voters_file_separator):
new_vote_line = reply_json['actor'] + \
voters_file_separator + found_answer + '\n'
if vote_line == new_vote_line:
2019-11-29 18:46:21 +00:00
break
2021-12-31 11:23:00 +00:00
save_voters_file = True
newlines.append(new_vote_line)
2019-11-29 19:22:11 +00:00
else:
2021-12-31 11:23:00 +00:00
newlines.append(vote_line)
if save_voters_file:
try:
with open(voters_filename, 'w+') as voters_file:
for vote_line in newlines:
voters_file.write(vote_line)
except OSError:
print('EX: unable to write voters file2 ' +
voters_filename)
2019-11-29 19:22:11 +00:00
else:
return None, None
2019-11-29 18:46:21 +00:00
# update the vote counts
2021-12-31 11:23:00 +00:00
question_totals_changed = False
for possible_answer in question_json['object']['oneOf']:
if not possible_answer.get('name'):
2019-11-29 18:46:21 +00:00
continue
2021-12-31 11:23:00 +00:00
total_items = 0
with open(voters_filename, 'r') as voters_file:
lines = voters_file.readlines()
for vote_line in lines:
if vote_line.endswith(voters_file_separator +
possible_answer['name'] + '\n'):
total_items += 1
if possible_answer['replies']['totalItems'] != total_items:
possible_answer['replies']['totalItems'] = total_items
question_totals_changed = True
if not question_totals_changed:
return None, None
2019-11-29 19:22:11 +00:00
# save the question with altered totals
2021-12-31 11:23:00 +00:00
save_json(question_json, question_post_filename)
return question_json, question_post_filename
2020-11-09 15:40:24 +00:00
2021-12-29 21:55:09 +00:00
def is_question(postObjectJson: {}) -> bool:
2020-11-09 15:40:24 +00:00
""" 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