diff --git a/daemon.py b/daemon.py
index 4255e5d02..2465e8d3c 100644
--- a/daemon.py
+++ b/daemon.py
@@ -3341,7 +3341,7 @@ class PubServer(BaseHTTPRequestHandler):
bold_reading = True
msg = \
- html_new_post(False, self.server.translate,
+ html_new_post({}, False, self.server.translate,
base_dir,
http_prefix,
report_path, None,
@@ -3370,6 +3370,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertube_instances,
self.server.allow_local_network_access,
self.server.system_language,
+ self.server.languages_understood,
self.server.max_like_count,
self.server.signing_priv_key_pem,
self.server.cw_lists,
@@ -3488,7 +3489,7 @@ class PubServer(BaseHTTPRequestHandler):
bold_reading = True
msg = \
- html_new_post(False, self.server.translate,
+ html_new_post({}, False, self.server.translate,
base_dir,
http_prefix,
report_path, None, [],
@@ -3516,6 +3517,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertube_instances,
self.server.allow_local_network_access,
self.server.system_language,
+ self.server.languages_understood,
self.server.max_like_count,
self.server.signing_priv_key_pem,
self.server.cw_lists,
@@ -15047,7 +15049,8 @@ class PubServer(BaseHTTPRequestHandler):
self._write(msg)
return True
- def _show_new_post(self, calling_domain: str, path: str,
+ def _show_new_post(self, edit_post_params: {},
+ calling_domain: str, path: str,
media_instance: bool, translate: {},
base_dir: str, http_prefix: str,
in_reply_to_url: str, reply_to_list: [],
@@ -15103,7 +15106,7 @@ class PubServer(BaseHTTPRequestHandler):
bold_reading = True
msg = \
- html_new_post(media_instance,
+ html_new_post(edit_post_params, media_instance,
translate,
base_dir,
http_prefix,
@@ -15134,6 +15137,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertube_instances,
self.server.allow_local_network_access,
self.server.system_language,
+ self.server.languages_understood,
self.server.max_like_count,
self.server.signing_priv_key_pem,
self.server.cw_lists,
@@ -18210,6 +18214,46 @@ class PubServer(BaseHTTPRequestHandler):
self.server.getreq_busy = False
return
+ # Edit a post
+ edit_post_params = {}
+ if authorized and \
+ '/users/' in self.path and \
+ '/editpost?scope=' in self.path and \
+ ';postid=' in self.path and \
+ ';actor=' in self.path:
+ post_scope = self.path.split('?scope=')[1]
+ if ';' in post_scope:
+ post_scope = post_scope.split(';')[0]
+ edit_post_params['scope'] = post_scope
+ message_id = self.path.split(';postid=')[1]
+ if ';' in message_id:
+ message_id = message_id.split(';')[0]
+ edit_post_params['postid'] = message_id
+ actor = self.path.split(';actor=')[1]
+ if ';' in actor:
+ actor = actor.split(';')[0]
+ edit_post_params['actor'] = actor
+ nickname = get_nickname_from_actor(self.path.split('?')[0])
+ edit_post_params['nickname'] = nickname
+ if not nickname:
+ self._404()
+ self.server.getreq_busy = False
+ return
+ if nickname != actor:
+ self._404()
+ self.server.getreq_busy = False
+ return
+ post_url = \
+ local_actor_url(self.server.http_prefix, nickname,
+ self.server.domain_full) + \
+ '/statuses/' + message_id
+ edit_post_params['post_url'] = post_url
+ # use the new post functions, but using edit_post_params
+ new_post_scope = post_scope
+ if post_scope == 'public':
+ new_post_scope = 'post'
+ self.path = '/users/' + nickname + '/new' + new_post_scope
+
# list of known crawlers accessing nodeinfo or masto API
if self._show_known_crawlers(calling_domain, self.path,
self.server.base_dir,
@@ -18263,7 +18307,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.getreq_busy = False
return
- if self._show_new_post(calling_domain, self.path,
+ if self._show_new_post(edit_post_params,
+ calling_domain, self.path,
self.server.media_instance,
self.server.translate,
self.server.base_dir,
@@ -19155,6 +19200,13 @@ class PubServer(BaseHTTPRequestHandler):
print('WARN: no nickname found when receiving ' + post_type +
' path ' + path)
return -1
+ # get the message id of an edited post
+ edited_postid = None
+ if '?editid=' in path:
+ edited_postid = path.split('?editid=')[1]
+ if '?' in edited_postid:
+ edited_postid = edited_postid.split('?')[0]
+
length = int(headers['Content-Length'])
if length > self.server.max_post_length:
print('POST size too large')
@@ -19357,6 +19409,16 @@ class PubServer(BaseHTTPRequestHandler):
languages_understood,
self.server.translate)
if message_json:
+ if edited_postid:
+ message_json['id'] = \
+ edited_postid + '/activity'
+ message_json['object']['id'] = \
+ edited_postid
+ message_json['object']['url'] = \
+ edited_postid
+ message_json['type'] = 'Update'
+ print('DEBUG: sending edited public post ' +
+ str(message_json))
if fields['schedulePost']:
return 1
if pin_to_profile:
@@ -19613,6 +19675,17 @@ class PubServer(BaseHTTPRequestHandler):
languages_understood,
self.server.translate)
if message_json:
+ if edited_postid:
+ message_json['id'] = \
+ edited_postid + '/activity'
+ message_json['object']['id'] = \
+ edited_postid
+ message_json['object']['url'] = \
+ edited_postid
+ message_json['type'] = 'Update'
+ print('DEBUG: sending edited unlisted post ' +
+ str(message_json))
+
if fields['schedulePost']:
return 1
if self._post_to_outbox(message_json,
@@ -19674,6 +19747,17 @@ class PubServer(BaseHTTPRequestHandler):
languages_understood,
self.server.translate)
if message_json:
+ if edited_postid:
+ message_json['id'] = \
+ edited_postid + '/activity'
+ message_json['object']['id'] = \
+ edited_postid
+ message_json['object']['url'] = \
+ edited_postid
+ message_json['type'] = 'Update'
+ print('DEBUG: sending edited followers post ' +
+ str(message_json))
+
if fields['schedulePost']:
return 1
if self._post_to_outbox(message_json,
@@ -19747,6 +19831,17 @@ class PubServer(BaseHTTPRequestHandler):
reply_is_chat,
self.server.translate)
if message_json:
+ if edited_postid:
+ message_json['id'] = \
+ edited_postid + '/activity'
+ message_json['object']['id'] = \
+ edited_postid
+ message_json['object']['url'] = \
+ edited_postid
+ message_json['type'] = 'Update'
+ print('DEBUG: sending edited dm post ' +
+ str(message_json))
+
if fields['schedulePost']:
return 1
print('Sending new DM to ' +
diff --git a/utils.py b/utils.py
index 9b6551648..480fc62e3 100644
--- a/utils.py
+++ b/utils.py
@@ -2353,6 +2353,23 @@ def is_public_post(post_json_object: {}) -> bool:
return False
+def is_followers_post(post_json_object: {}) -> bool:
+ """Returns true if the given post is to followers
+ """
+ if not post_json_object.get('type'):
+ return False
+ if post_json_object['type'] != 'Create':
+ return False
+ if not has_object_dict(post_json_object):
+ return False
+ if not post_json_object['object'].get('to'):
+ return False
+ for recipient in post_json_object['object']['to']:
+ if recipient.endswith('/followers'):
+ return True
+ return False
+
+
def is_unlisted_post(post_json_object: {}) -> bool:
"""Returns true if the given post is unlisted
"""
diff --git a/webapp_create_post.py b/webapp_create_post.py
index 620ff8efa..ffb38ab61 100644
--- a/webapp_create_post.py
+++ b/webapp_create_post.py
@@ -8,6 +8,11 @@ __status__ = "Production"
__module_group__ = "Web Interface"
import os
+from utils import remove_html
+from utils import get_content_from_post
+from utils import has_object_dict
+from utils import load_json
+from utils import locate_post
from utils import get_new_post_endpoints
from utils import is_public_post_from_url
from utils import get_nickname_from_actor
@@ -31,6 +36,7 @@ from webapp_utils import edit_currency_field
from webapp_post import individual_post_as_html
from maps import get_map_preferences_url
from maps import get_map_preferences_coords
+from maps import get_location_from_tags
def _html_following_data_list(base_dir: str, nickname: str,
@@ -197,7 +203,34 @@ def _html_new_post_drop_down(scope_icon: str, scope_description: str,
return drop_down_content
-def html_new_post(media_instance: bool, translate: {},
+def _get_date_from_tags(tags: []) -> (str, str):
+ """Returns the date from the tags list
+ """
+ for tag_item in tags:
+ if not tag_item.get('type'):
+ continue
+ if tag_item['type'] != 'Event':
+ continue
+ if not tag_item.get('startTime'):
+ continue
+ if not isinstance(tag_item['startTime'], str):
+ continue
+ if 'T' not in tag_item['startTime']:
+ continue
+ start_time = tag_item['startTime']
+ if not tag_item.get('endTime'):
+ return start_time, ''
+ if not isinstance(tag_item['endTime'], str):
+ return start_time, ''
+ if 'T' not in tag_item['endTime']:
+ return start_time, ''
+ end_time = tag_item['endTime']
+ return start_time, end_time
+ return '', ''
+
+
+def html_new_post(edit_post_params: {},
+ media_instance: bool, translate: {},
base_dir: str, http_prefix: str,
path: str, in_reply_to: str,
mentions: [],
@@ -221,6 +254,7 @@ def html_new_post(media_instance: bool, translate: {},
peertube_instances: [],
allow_local_network_access: bool,
system_language: str,
+ languages_understood: [],
max_like_count: int, signing_priv_key_pem: str,
cw_lists: {}, lists_enabled: str,
box_name: str,
@@ -229,6 +263,48 @@ def html_new_post(media_instance: bool, translate: {},
min_images_for_accounts: []) -> str:
"""New post screen
"""
+ # get the json if this is an edited post
+ edited_post_json = None
+ if edit_post_params:
+ if edit_post_params.get('post_url'):
+ edited_post_filename = \
+ locate_post(base_dir, nickname,
+ domain, edit_post_params['post_url'])
+ if edited_post_filename:
+ edited_post_json = load_json(edited_post_filename)
+ if not has_object_dict(edited_post_json):
+ return ''
+ if not edited_post_json:
+ return ''
+ if edited_post_json['object'].get('conversation'):
+ conversation_id = edited_post_json['object']['conversation']
+
+ # default subject line or content warning
+ default_subject = ''
+ if share_description:
+ default_subject = share_description
+
+ default_location = ''
+ default_start_time = ''
+ default_end_time = ''
+ if edited_post_json:
+ # if this is an edited post then get the subject line or
+ # content warning
+ summary_str = get_content_from_post(edited_post_json, system_language,
+ languages_understood, "summary")
+ if summary_str:
+ default_subject = remove_html(summary_str)
+
+ if edited_post_json['object'].get('tag'):
+ # if this is an edited post then get the location
+ location_str = \
+ get_location_from_tags(edited_post_json['object']['tag'])
+ if location_str:
+ default_location = location_str
+ # if this is an edited post then get the start and end time
+ default_start_time, default_end_time = \
+ _get_date_from_tags(edited_post_json['object']['tag'])
+
reply_str = ''
is_new_reminder = False
@@ -244,15 +320,25 @@ def html_new_post(media_instance: bool, translate: {},
# select a date and time for this post
date_and_time_str += '\n'
- date_and_time_str += '\n'
+ date_default = ''
+ time_default = ''
+ if default_start_time:
+ date_default = ' value="' + default_start_time.split('T')[0] + '"'
+ time_default = ' value="' + default_start_time.split('T')[1] + '"'
+ if default_end_time:
+ end_time_default = ' value="' + default_end_time.split('T')[1] + '"'
+ date_and_time_str += \
+ '\n'
date_and_time_str += '\n
\n'
+ '\n
\n'
date_and_time_str += '\n
\n' + \ - edit_text_field(location_label_with_link, 'location', '', + edit_text_field(location_label_with_link, 'location', + default_location, 'https://www.openstreetmap.org/#map=') + '
\n' date_and_location += end_edit_section() @@ -844,10 +933,17 @@ def html_new_post(media_instance: bool, translate: {}, # reporting a post to moderator mentions_str = 'Re: ' + report_url + '\n\n' + mentions_str - new_post_form += \ - '