Display shared item from profile

main
Bob Mottram 2023-08-23 11:37:27 +01:00
parent 3f6adb0c1e
commit ea06eb438c
2 changed files with 157 additions and 0 deletions

View File

@ -268,6 +268,9 @@ from webapp_welcome import html_welcome_screen
from webapp_welcome import is_welcome_screen_complete from webapp_welcome import is_welcome_screen_complete
from webapp_welcome_profile import html_welcome_profile from webapp_welcome_profile import html_welcome_profile
from webapp_welcome_final import html_welcome_final from webapp_welcome_final import html_welcome_final
from shares import get_share_category
from shares import vf_proposal_from_id
from shares import actor_attached_shares
from shares import add_shares_to_actor from shares import add_shares_to_actor
from shares import merge_shared_item_tokens from shares import merge_shared_item_tokens
from shares import run_federated_shares_daemon from shares import run_federated_shares_daemon
@ -17314,6 +17317,94 @@ class PubServer(BaseHTTPRequestHandler):
self.server.debug) self.server.debug)
return return
# show a shared item if it is listed within actor attachment
if self.path.startswith('/users/') and '/shareditems/' in self.path:
nickname = self.path.split('/users/')[1]
if '/' in nickname:
nickname = nickname.split('/')[0]
shared_item_display_name = self.path.split('/shareditems/')[1]
if not nickname or not shared_item_display_name:
self._404()
return
if not self._has_accept(calling_domain):
self._404()
return
# get the actor from the cache
actor = \
self._get_instance_url(calling_domain) + '/users/' + nickname
actor_json = get_person_from_cache(self.server.base_dir, actor,
self.server.person_cache)
if not actor_json:
actor_filename = acct_dir(self.server.base_dir, nickname,
self.server.domain) + '.json'
if os.path.isfile(actor_filename):
actor_json = load_json(actor_filename, 1, 1)
if not actor_json:
self._404()
return
attached_shares = actor_attached_shares(actor_json)
if not attached_shares:
self._404()
return
# is the given shared item in the list?
share_id = None
for share_item in attached_shares:
if not share_item.get('href'):
continue
if not isinstance(share_item['href'], str):
continue
if share_item['href'].endswith(self.path):
share_id = share_item['href'].replace('://', '___')
share_id = share_id.replace('/', '--')
break
if not share_id:
self._404()
return
# show the shared item
shares_file_type = 'shares'
if self._request_http():
# get the category for share_id
share_category = \
get_share_category(self.server.base_dir,
nickname, self.server.domain,
shares_file_type, share_id)
msg = \
html_show_share(self.server.base_dir,
self.server.domain, nickname,
self.server.http_prefix,
self.server.domain_full,
share_id, self.server.translate,
self.server.shared_items_federated_domains,
self.server.default_timeline,
self.server.theme_name, shares_file_type,
share_category)
if msg:
msg = msg.encode('utf-8')
msglen = len(msg)
self._set_headers('text/html', msglen,
None, calling_domain, True)
self._write(msg)
return
else:
# get json for the shared item in ValueFlows format
share_json = \
vf_proposal_from_id(self.server.base_dir,
nickname, self.server.domain,
shares_file_type, share_id)
if share_json:
msg_str = json.dumps(share_json)
msg_str = self._convert_domains(calling_domain,
referer_domain,
msg_str)
msg = msg_str.encode('utf-8')
msglen = len(msg)
self._set_headers('application/json', msglen,
None, calling_domain, True)
self._write(msg)
return
self._404()
return
# shared items offers collection for this instance # shared items offers collection for this instance
# this is only accessible to instance members or to # this is only accessible to instance members or to
# other instances which present an authorization token # other instances which present an authorization token

View File

@ -2138,6 +2138,72 @@ def vf_proposal_from_share(shared_item: {},
return offer_item return offer_item
def get_share_category(base_dir: str, nickname: str, domain: str,
shares_file_type: str, share_id: str) -> str:
"""Returns the category for a shared item
"""
shares_filename = \
acct_dir(base_dir, nickname, domain) + '/' + shares_file_type + '.json'
if not os.path.isfile(shares_filename):
return ''
shares_json = load_json(shares_filename)
if not shares_json:
return ''
if not shares_json.get(share_id):
return ''
if not shares_json[share_id].get('category'):
return ''
return shares_json[share_id]['category']
def vf_proposal_from_id(base_dir: str, nickname: str, domain: str,
shares_file_type: str, share_id: str) -> {}:
"""Returns a ValueFlows proposal from a shared item id
"""
shares_filename = \
acct_dir(base_dir, nickname, domain) + '/' + shares_file_type + '.json'
if not os.path.isfile(shares_filename):
return {}
shares_json = load_json(shares_filename)
if not shares_json:
return {}
if not shares_json.get(share_id):
return {}
if shares_file_type == 'shares':
share_type = 'Proposal'
publishes_direction = "provider"
reciprocal_direction = "receiver"
else:
share_type = 'Want'
publishes_direction = "receiver"
reciprocal_direction = "provider"
return vf_proposal_from_share(shares_json[share_id],
share_type,
publishes_direction,
reciprocal_direction)
def actor_attached_shares(actor_json: {}) -> []:
"""Returns any shared items attached to an actor
https://codeberg.org/fediverse/fep/src/branch/main/fep/0837/fep-0837.md
"""
if not actor_json.get('attachment'):
return []
attached_shares = []
for attach_item in actor_json['attachment']:
if 'rel' in attach_item and 'href' in attach_item:
if isinstance(attach_item['rel'], list) and \
isinstance(attach_item['href'], str):
if len(attach_item['rel']) == 2:
if attach_item['rel'][0] == 'payment' and \
attach_item['rel'][1].endswith('/valueflows/Proposal'):
attached_shares.append(attach_item['href'])
return attached_shares
def add_shares_to_actor(base_dir: str, def add_shares_to_actor(base_dir: str,
nickname: str, domain: str, nickname: str, domain: str,
actor_json: {}, actor_json: {},