Generalize the shares file so that there can be separate shares and wanted items

merge-requests/30/head
Bob Mottram 2021-08-09 14:07:32 +01:00
parent 42762ef6bd
commit 641963dc05
9 changed files with 146 additions and 81 deletions

View File

@ -3172,7 +3172,8 @@ class PubServer(BaseHTTPRequestHandler):
httpPrefix, httpPrefix,
domainFull, domainFull,
actorStr, callingDomain, actorStr, callingDomain,
sharedItemsFederatedDomains) sharedItemsFederatedDomains,
'shares')
if sharedItemsStr: if sharedItemsStr:
msg = sharedItemsStr.encode('utf-8') msg = sharedItemsStr.encode('utf-8')
msglen = len(msg) msglen = len(msg)
@ -3390,7 +3391,7 @@ class PubServer(BaseHTTPRequestHandler):
shareDomain, sharePort = getDomainFromActor(shareActor) shareDomain, sharePort = getDomainFromActor(shareActor)
removeSharedItem(baseDir, removeSharedItem(baseDir,
shareNickname, shareDomain, itemID, shareNickname, shareDomain, itemID,
httpPrefix, domainFull) httpPrefix, domainFull, 'shares')
if callingDomain.endswith('.onion') and onionDomain: if callingDomain.endswith('.onion') and onionDomain:
originPathStr = 'http://' + onionDomain + usersPath originPathStr = 'http://' + onionDomain + usersPath
@ -9488,12 +9489,12 @@ class PubServer(BaseHTTPRequestHandler):
onionDomain: str, i2pDomain: str, onionDomain: str, i2pDomain: str,
GETstartTime, GETtimings: {}, GETstartTime, GETtimings: {},
proxyType: str, cookie: str, proxyType: str, cookie: str,
debug: str) -> bool: debug: str, sharesFileType: str) -> bool:
"""Shows the shares feed """Shows the shares feed
""" """
shares = \ shares = \
getSharesFeedForPerson(baseDir, domain, port, path, getSharesFeedForPerson(baseDir, domain, port, path,
httpPrefix, sharesPerPage) httpPrefix, sharesFileType, sharesPerPage)
if shares: if shares:
if self._requestHTTP(): if self._requestHTTP():
pageNumber = 1 pageNumber = 1
@ -9503,7 +9504,7 @@ class PubServer(BaseHTTPRequestHandler):
shares = \ shares = \
getSharesFeedForPerson(baseDir, domain, port, getSharesFeedForPerson(baseDir, domain, port,
path + '?page=true', path + '?page=true',
httpPrefix, httpPrefix, sharesFileType,
sharesPerPage) sharesPerPage)
else: else:
pageNumberStr = path.split('?page=')[1] pageNumberStr = path.split('?page=')[1]
@ -9514,7 +9515,7 @@ class PubServer(BaseHTTPRequestHandler):
searchPath = path.split('?page=')[0] searchPath = path.split('?page=')[0]
getPerson = \ getPerson = \
personLookup(domain, personLookup(domain,
searchPath.replace('/shares', ''), searchPath.replace('/' + sharesFileType, ''),
baseDir) baseDir)
if getPerson: if getPerson:
if not self.server.session: if not self.server.session:
@ -9549,7 +9550,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.projectVersion, self.server.projectVersion,
baseDir, httpPrefix, baseDir, httpPrefix,
authorized, authorized,
getPerson, 'shares', getPerson, sharesFileType,
self.server.session, self.server.session,
self.server.cachedWebfingers, self.server.cachedWebfingers,
self.server.personCache, self.server.personCache,
@ -10865,7 +10866,7 @@ class PubServer(BaseHTTPRequestHandler):
sharesCatalogEndpoint(self.server.baseDir, sharesCatalogEndpoint(self.server.baseDir,
self.server.httpPrefix, self.server.httpPrefix,
self.server.domainFull, self.server.domainFull,
self.path) self.path, 'shares')
else: else:
domainFull = self.server.domainFull domainFull = self.server.domainFull
httpPrefix = self.server.httpPrefix httpPrefix = self.server.httpPrefix
@ -10881,7 +10882,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.domain, self.server.domain,
domainFull, domainFull,
self.path, self.path,
self.server.debug) self.server.debug,
'shares')
msg = json.dumps(catalogJson, msg = json.dumps(catalogJson,
ensure_ascii=False).encode('utf-8') ensure_ascii=False).encode('utf-8')
msglen = len(msg) msglen = len(msg)
@ -10895,7 +10897,8 @@ class PubServer(BaseHTTPRequestHandler):
sharesCatalogCSVEndpoint(self.server.baseDir, sharesCatalogCSVEndpoint(self.server.baseDir,
self.server.httpPrefix, self.server.httpPrefix,
self.server.domainFull, self.server.domainFull,
self.path).encode('utf-8') self.path,
'shares').encode('utf-8')
msglen = len(msg) msglen = len(msg)
self._set_headers('text/csv', self._set_headers('text/csv',
msglen, None, callingDomain) msglen, None, callingDomain)
@ -11363,7 +11366,7 @@ class PubServer(BaseHTTPRequestHandler):
itemID, self.server.translate, itemID, self.server.translate,
self.server.sharedItemsFederatedDomains, self.server.sharedItemsFederatedDomains,
self.server.defaultTimeline, self.server.defaultTimeline,
self.server.themeName) self.server.themeName, 'shares')
if not msg: if not msg:
if callingDomain.endswith('.onion') and \ if callingDomain.endswith('.onion') and \
self.server.onionDomain: self.server.onionDomain:
@ -11396,7 +11399,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.translate, self.server.translate,
self.server.baseDir, self.server.baseDir,
actor, itemID, actor, itemID,
callingDomain) callingDomain, 'shares')
if not msg: if not msg:
if callingDomain.endswith('.onion') and \ if callingDomain.endswith('.onion') and \
self.server.onionDomain: self.server.onionDomain:
@ -13145,7 +13148,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.i2pDomain, self.server.i2pDomain,
GETstartTime, GETtimings, GETstartTime, GETtimings,
self.server.proxyType, self.server.proxyType,
cookie, self.server.debug): cookie, self.server.debug, 'shares'):
return return
self._benchmarkGETtimings(GETstartTime, GETtimings, self._benchmarkGETtimings(GETstartTime, GETtimings,
@ -14009,7 +14012,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.debug, self.server.debug,
city, itemPrice, itemCurrency, city, itemPrice, itemCurrency,
self.server.systemLanguage, self.server.systemLanguage,
self.server.translate) self.server.translate, 'shares')
if filename: if filename:
if os.path.isfile(filename): if os.path.isfile(filename):
os.remove(filename) os.remove(filename)

View File

@ -2381,7 +2381,7 @@ if args.testdata:
"mechanical", "mechanical",
"City", "0", "GBP", "City", "0", "GBP",
"2 months", "2 months",
debug, city, args.language, {}) debug, city, args.language, {}, 'shares')
addShare(baseDir, addShare(baseDir,
httpPrefix, nickname, domain, port, httpPrefix, nickname, domain, port,
"witch hat", "witch hat",
@ -2391,7 +2391,7 @@ if args.testdata:
"clothing", "clothing",
"City", "0", "GBP", "City", "0", "GBP",
"3 months", "3 months",
debug, city, args.language, {}) debug, city, args.language, {}, 'shares')
deleteAllPosts(baseDir, nickname, domain, 'inbox') deleteAllPosts(baseDir, nickname, domain, 'inbox')
deleteAllPosts(baseDir, nickname, domain, 'outbox') deleteAllPosts(baseDir, nickname, domain, 'outbox')

109
shares.py
View File

@ -36,6 +36,7 @@ from utils import isAccountDir
from utils import acctDir from utils import acctDir
from utils import isfloat from utils import isfloat
from utils import getCategoryTypes from utils import getCategoryTypes
from utils import getSharesFilesList
from media import processMetaData from media import processMetaData
from filters import isFilteredGlobally from filters import isFilteredGlobally
from siteactive import siteIsActive from siteactive import siteIsActive
@ -113,17 +114,22 @@ def _getValidSharedItemID(actor: str, displayName: str) -> str:
def removeSharedItem(baseDir: str, nickname: str, domain: str, def removeSharedItem(baseDir: str, nickname: str, domain: str,
itemID: str, itemID: str,
httpPrefix: str, domainFull: str) -> None: httpPrefix: str, domainFull: str,
sharesFileType: str) -> None:
"""Removes a share for a person """Removes a share for a person
""" """
sharesFilename = acctDir(baseDir, nickname, domain) + '/shares.json' sharesFilename = \
acctDir(baseDir, nickname, domain) + '/' + sharesFileType + '.json'
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
print('ERROR: missing shares.json ' + sharesFilename) print('ERROR: remove shared item, missing ' +
sharesFileType + '.json ' + sharesFilename)
return return
sharesJson = loadJson(sharesFilename) sharesJson = loadJson(sharesFilename)
if not sharesJson: if not sharesJson:
print('ERROR: shares.json could not be loaded from ' + sharesFilename) print('ERROR: remove shared item, ' +
sharesFileType + '.json could not be loaded from ' +
sharesFilename)
return return
if sharesJson.get(itemID): if sharesJson.get(itemID):
@ -279,7 +285,8 @@ def addShare(baseDir: str,
itemQty: float, itemType: str, itemCategory: str, location: str, itemQty: float, itemType: str, itemCategory: str, location: str,
duration: str, debug: bool, city: str, duration: str, debug: bool, city: str,
price: str, currency: str, price: str, currency: str,
systemLanguage: str, translate: {}) -> None: systemLanguage: str, translate: {},
sharesFileType: str) -> None:
"""Adds a new share """Adds a new share
""" """
if isFilteredGlobally(baseDir, if isFilteredGlobally(baseDir,
@ -287,7 +294,8 @@ def addShare(baseDir: str,
itemType + ' ' + itemCategory): itemType + ' ' + itemCategory):
print('Shared item was filtered due to content') print('Shared item was filtered due to content')
return return
sharesFilename = acctDir(baseDir, nickname, domain) + '/shares.json' sharesFilename = \
acctDir(baseDir, nickname, domain) + '/' + sharesFileType + '.json'
sharesJson = {} sharesJson = {}
if os.path.isfile(sharesFilename): if os.path.isfile(sharesFilename):
sharesJson = loadJson(sharesFilename, 1, 2) sharesJson = loadJson(sharesFilename, 1, 2)
@ -367,16 +375,20 @@ def expireShares(baseDir: str) -> None:
continue continue
nickname = account.split('@')[0] nickname = account.split('@')[0]
domain = account.split('@')[1] domain = account.split('@')[1]
_expireSharesForAccount(baseDir, nickname, domain) for sharesFileType in getSharesFilesList():
_expireSharesForAccount(baseDir, nickname, domain,
sharesFileType)
break break
def _expireSharesForAccount(baseDir: str, nickname: str, domain: str) -> None: def _expireSharesForAccount(baseDir: str, nickname: str, domain: str,
sharesFileType: str) -> None:
"""Removes expired items from shares for a particular account """Removes expired items from shares for a particular account
""" """
handleDomain = removeDomainPort(domain) handleDomain = removeDomainPort(domain)
handle = nickname + '@' + handleDomain handle = nickname + '@' + handleDomain
sharesFilename = baseDir + '/accounts/' + handle + '/shares.json' sharesFilename = \
baseDir + '/accounts/' + handle + '/' + sharesFileType + '.json'
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
return return
sharesJson = loadJson(sharesFilename, 1, 2) sharesJson = loadJson(sharesFilename, 1, 2)
@ -403,10 +415,11 @@ def _expireSharesForAccount(baseDir: str, nickname: str, domain: str) -> None:
def getSharesFeedForPerson(baseDir: str, def getSharesFeedForPerson(baseDir: str,
domain: str, port: int, domain: str, port: int,
path: str, httpPrefix: str, path: str, httpPrefix: str,
sharesPerPage=12) -> {}: sharesFileType: str,
sharesPerPage: int = 12) -> {}:
"""Returns the shares for an account from GET requests """Returns the shares for an account from GET requests
""" """
if '/shares' not in path: if '/' + sharesFileType not in path:
return None return None
# handle page numbers # handle page numbers
headerOnly = True headerOnly = True
@ -423,13 +436,15 @@ def getSharesFeedForPerson(baseDir: str,
path = path.split('?page=')[0] path = path.split('?page=')[0]
headerOnly = False headerOnly = False
if not path.endswith('/shares'): if not path.endswith('/' + sharesFileType):
return None return None
nickname = None nickname = None
if path.startswith('/users/'): if path.startswith('/users/'):
nickname = path.replace('/users/', '', 1).replace('/shares', '') nickname = \
path.replace('/users/', '', 1).replace('/' + sharesFileType, '')
if path.startswith('/@'): if path.startswith('/@'):
nickname = path.replace('/@', '', 1).replace('/shares', '') nickname = \
path.replace('/@', '', 1).replace('/' + sharesFileType, '')
if not nickname: if not nickname:
return None return None
if not validNickname(domain, nickname): if not validNickname(domain, nickname):
@ -438,7 +453,9 @@ def getSharesFeedForPerson(baseDir: str,
domain = getFullDomain(domain, port) domain = getFullDomain(domain, port)
handleDomain = removeDomainPort(domain) handleDomain = removeDomainPort(domain)
sharesFilename = acctDir(baseDir, nickname, handleDomain) + '/shares.json' sharesFilename = \
acctDir(baseDir, nickname, handleDomain) + '/' + \
sharesFileType + '.json'
if headerOnly: if headerOnly:
noOfShares = 0 noOfShares = 0
@ -449,8 +466,8 @@ def getSharesFeedForPerson(baseDir: str,
idStr = httpPrefix + '://' + domain + '/users/' + nickname idStr = httpPrefix + '://' + domain + '/users/' + nickname
shares = { shares = {
'@context': 'https://www.w3.org/ns/activitystreams', '@context': 'https://www.w3.org/ns/activitystreams',
'first': idStr + '/shares?page=1', 'first': idStr + '/' + sharesFileType + '?page=1',
'id': idStr + '/shares', 'id': idStr + '/' + sharesFileType,
'totalItems': str(noOfShares), 'totalItems': str(noOfShares),
'type': 'OrderedCollection' 'type': 'OrderedCollection'
} }
@ -463,15 +480,14 @@ def getSharesFeedForPerson(baseDir: str,
idStr = httpPrefix + '://' + domain + '/users/' + nickname idStr = httpPrefix + '://' + domain + '/users/' + nickname
shares = { shares = {
'@context': 'https://www.w3.org/ns/activitystreams', '@context': 'https://www.w3.org/ns/activitystreams',
'id': idStr + '/shares?page=' + str(pageNumber), 'id': idStr + '/' + sharesFileType + '?page=' + str(pageNumber),
'orderedItems': [], 'orderedItems': [],
'partOf': idStr + '/shares', 'partOf': idStr + '/' + sharesFileType,
'totalItems': 0, 'totalItems': 0,
'type': 'OrderedCollectionPage' 'type': 'OrderedCollectionPage'
} }
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
print("test5")
return shares return shares
currPage = 1 currPage = 1
pageCtr = 0 pageCtr = 0
@ -495,7 +511,7 @@ def getSharesFeedForPerson(baseDir: str,
if nextPageNumber > lastPage: if nextPageNumber > lastPage:
shares['next'] = \ shares['next'] = \
httpPrefix + '://' + domain + '/users/' + nickname + \ httpPrefix + '://' + domain + '/users/' + nickname + \
'/shares?page=' + str(lastPage) '/' + sharesFileType + '?page=' + str(lastPage)
return shares return shares
@ -816,7 +832,7 @@ def outboxShareUpload(baseDir: str, httpPrefix: str,
debug, city, debug, city,
messageJson['object']['itemPrice'], messageJson['object']['itemPrice'],
messageJson['object']['itemCurrency'], messageJson['object']['itemCurrency'],
systemLanguage, translate) systemLanguage, translate, 'shares')
if debug: if debug:
print('DEBUG: shared item received via c2s') print('DEBUG: shared item received via c2s')
@ -847,7 +863,7 @@ def outboxUndoShareUpload(baseDir: str, httpPrefix: str,
domainFull = getFullDomain(domain, port) domainFull = getFullDomain(domain, port)
removeSharedItem(baseDir, nickname, domain, removeSharedItem(baseDir, nickname, domain,
messageJson['object']['displayName'], messageJson['object']['displayName'],
httpPrefix, domainFull) httpPrefix, domainFull, 'shares')
if debug: if debug:
print('DEBUG: shared item removed via c2s') print('DEBUG: shared item removed via c2s')
@ -886,7 +902,8 @@ def _sharesCatalogParams(path: str) -> (bool, float, float, str):
def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str, def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str,
nickname: str, domain: str, nickname: str, domain: str,
domainFull: str, domainFull: str,
path: str, debug: bool) -> {}: path: str, debug: bool,
sharesFileType: str) -> {}:
"""Returns the endpoint for the shares catalog of a particular account """Returns the endpoint for the shares catalog of a particular account
See https://github.com/datafoodconsortium/ontology See https://github.com/datafoodconsortium/ontology
""" """
@ -896,7 +913,10 @@ def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str,
dfcPtUrl = \ dfcPtUrl = \
"http://static.datafoodconsortium.org/data/productTypes.rdf#" "http://static.datafoodconsortium.org/data/productTypes.rdf#"
owner = httpPrefix + '://' + domainFull + '/users/' + nickname owner = httpPrefix + '://' + domainFull + '/users/' + nickname
dfcInstanceId = owner + '/catalog' if sharesFileType == 'shares':
dfcInstanceId = owner + '/catalog'
else:
dfcInstanceId = owner + '/wantedItems'
endpoint = { endpoint = {
"@context": { "@context": {
"DFC": dfcUrl, "DFC": dfcUrl,
@ -911,10 +931,11 @@ def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str,
currDate = datetime.datetime.utcnow() currDate = datetime.datetime.utcnow()
currDateStr = currDate.strftime("%Y-%m-%d") currDateStr = currDate.strftime("%Y-%m-%d")
sharesFilename = acctDir(baseDir, nickname, domain) + '/shares.json' sharesFilename = \
acctDir(baseDir, nickname, domain) + '/' + sharesFileType + '.json'
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
if debug: if debug:
print('shares.json file not found: ' + sharesFilename) print(sharesFileType + '.json file not found: ' + sharesFilename)
return endpoint return endpoint
sharesJson = loadJson(sharesFilename, 1, 2) sharesJson = loadJson(sharesFilename, 1, 2)
if not sharesJson: if not sharesJson:
@ -970,7 +991,7 @@ def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str,
def sharesCatalogEndpoint(baseDir: str, httpPrefix: str, def sharesCatalogEndpoint(baseDir: str, httpPrefix: str,
domainFull: str, domainFull: str,
path: str) -> {}: path: str, sharesFileType: str) -> {}:
"""Returns the endpoint for the shares catalog for the instance """Returns the endpoint for the shares catalog for the instance
See https://github.com/datafoodconsortium/ontology See https://github.com/datafoodconsortium/ontology
""" """
@ -1003,7 +1024,8 @@ def sharesCatalogEndpoint(baseDir: str, httpPrefix: str,
owner = httpPrefix + '://' + domainFull + '/users/' + nickname owner = httpPrefix + '://' + domainFull + '/users/' + nickname
sharesFilename = \ sharesFilename = \
acctDir(baseDir, nickname, domain) + '/shares.json' acctDir(baseDir, nickname, domain) + '/' + \
sharesFileType + '.json'
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
continue continue
print('Test 78363 ' + sharesFilename) print('Test 78363 ' + sharesFilename)
@ -1056,11 +1078,12 @@ def sharesCatalogEndpoint(baseDir: str, httpPrefix: str,
def sharesCatalogCSVEndpoint(baseDir: str, httpPrefix: str, def sharesCatalogCSVEndpoint(baseDir: str, httpPrefix: str,
domainFull: str, domainFull: str,
path: str) -> str: path: str, sharesFileType: str) -> str:
"""Returns a CSV version of the shares catalog """Returns a CSV version of the shares catalog
""" """
catalogJson = \ catalogJson = \
sharesCatalogEndpoint(baseDir, httpPrefix, domainFull, path) sharesCatalogEndpoint(baseDir, httpPrefix, domainFull, path,
sharesFileType)
if not catalogJson: if not catalogJson:
return '' return ''
if not catalogJson.get('DFC:supplies'): if not catalogJson.get('DFC:supplies'):
@ -1257,7 +1280,8 @@ def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
baseDir: str, domainFull: str, baseDir: str, domainFull: str,
httpPrefix: str, httpPrefix: str,
tokensJson: {}, debug: bool, tokensJson: {}, debug: bool,
systemLanguage: str) -> None: systemLanguage: str,
sharesFileType: str) -> None:
"""Updates the cache of federated shares for the instance. """Updates the cache of federated shares for the instance.
This enables shared items to be available even when other instances This enables shared items to be available even when other instances
might not be online might not be online
@ -1266,7 +1290,10 @@ def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
cacheDir = baseDir + '/cache' cacheDir = baseDir + '/cache'
if not os.path.isdir(cacheDir): if not os.path.isdir(cacheDir):
os.mkdir(cacheDir) os.mkdir(cacheDir)
catalogsDir = cacheDir + '/catalogs' if sharesFileType == 'shares':
catalogsDir = cacheDir + '/catalogs'
else:
catalogsDir = cacheDir + '/wantedItems'
if not os.path.isdir(catalogsDir): if not os.path.isdir(catalogsDir):
os.mkdir(catalogsDir) os.mkdir(catalogsDir)
@ -1285,7 +1312,10 @@ def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
continue continue
if not siteIsActive(httpPrefix + '://' + federatedDomainFull): if not siteIsActive(httpPrefix + '://' + federatedDomainFull):
continue continue
url = httpPrefix + '://' + federatedDomainFull + '/catalog' if sharesFileType == 'shares':
url = httpPrefix + '://' + federatedDomainFull + '/catalog'
else:
url = httpPrefix + '://' + federatedDomainFull + '/wantedItems'
asHeader['Authorization'] = tokensJson[federatedDomainFull] asHeader['Authorization'] = tokensJson[federatedDomainFull]
catalogJson = getJson(session, url, asHeader, None, catalogJson = getJson(session, url, asHeader, None,
debug, __version__, httpPrefix, None) debug, __version__, httpPrefix, None)
@ -1300,7 +1330,8 @@ def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
baseDir, systemLanguage) baseDir, systemLanguage)
if sharesJson: if sharesJson:
sharesFilename = \ sharesFilename = \
catalogsDir + '/' + federatedDomainFull + '.shares.json' catalogsDir + '/' + federatedDomainFull + '.' + \
sharesFileType + '.json'
saveJson(sharesJson, sharesFilename) saveJson(sharesJson, sharesFilename)
print('Converted shares catalog for ' + federatedDomainFull) print('Converted shares catalog for ' + federatedDomainFull)
else: else:
@ -1441,9 +1472,11 @@ def runFederatedSharesDaemon(baseDir: str, httpd, httpPrefix: str,
continue continue
session = createSession(proxyType) session = createSession(proxyType)
_updateFederatedSharesCache(session, sharedItemsFederatedDomains, for sharesFileType in getSharesFilesList():
baseDir, domainFull, httpPrefix, _updateFederatedSharesCache(session, sharedItemsFederatedDomains,
tokensJson, debug, systemLanguage) baseDir, domainFull, httpPrefix,
tokensJson, debug, systemLanguage,
sharesFileType)
time.sleep(secondsPerHour * 6) time.sleep(secondsPerHour * 6)

View File

@ -2830,3 +2830,9 @@ def getCategoryTypes(baseDir: str) -> []:
categories.append(ontologyFilename.replace('Types', '')) categories.append(ontologyFilename.replace('Types', ''))
break break
return categories return categories
def getSharesFilesList() -> []:
"""Returns the possible shares files
"""
return ('shares', 'wanted')

View File

@ -43,7 +43,7 @@ def _getLeftColumnShares(baseDir: str,
sharesJson, lastPage = \ sharesJson, lastPage = \
sharesTimelineJson(actor, pageNumber, maxSharesInLeftColumn, sharesTimelineJson(actor, pageNumber, maxSharesInLeftColumn,
baseDir, domain, nickname, maxSharesInLeftColumn, baseDir, domain, nickname, maxSharesInLeftColumn,
sharedItemsFederatedDomains) sharedItemsFederatedDomains, 'shares')
if not sharesJson: if not sharesJson:
return [] return []

View File

@ -105,19 +105,21 @@ def htmlConfirmDelete(cssCache: {},
def htmlConfirmRemoveSharedItem(cssCache: {}, translate: {}, baseDir: str, def htmlConfirmRemoveSharedItem(cssCache: {}, translate: {}, baseDir: str,
actor: str, itemID: str, actor: str, itemID: str,
callingDomain: str) -> str: callingDomain: str,
sharesFileType: str) -> str:
"""Shows a screen asking to confirm the removal of a shared item """Shows a screen asking to confirm the removal of a shared item
""" """
nickname = getNicknameFromActor(actor) nickname = getNicknameFromActor(actor)
domain, port = getDomainFromActor(actor) domain, port = getDomainFromActor(actor)
domainFull = getFullDomain(domain, port) domainFull = getFullDomain(domain, port)
sharesFile = acctDir(baseDir, nickname, domain) + '/shares.json' sharesFile = \
acctDir(baseDir, nickname, domain) + '/' + sharesFileType + '.json'
if not os.path.isfile(sharesFile): if not os.path.isfile(sharesFile):
print('ERROR: no shares file ' + sharesFile) print('ERROR: no ' + sharesFileType + ' file ' + sharesFile)
return None return None
sharesJson = loadJson(sharesFile) sharesJson = loadJson(sharesFile)
if not sharesJson: if not sharesJson:
print('ERROR: unable to load shares.json') print('ERROR: unable to load ' + sharesFileType + '.json')
return None return None
if not sharesJson.get(itemID): if not sharesJson.get(itemID):
print('ERROR: share named "' + itemID + '" is not in ' + sharesFile) print('ERROR: share named "' + itemID + '" is not in ' + sharesFile)
@ -148,7 +150,12 @@ def htmlConfirmRemoveSharedItem(cssCache: {}, translate: {}, baseDir: str,
' <p class="followText">' + translate['Remove'] + \ ' <p class="followText">' + translate['Remove'] + \
' ' + sharedItemDisplayName + ' ?</p>\n' ' ' + sharedItemDisplayName + ' ?</p>\n'
postActor = getAltPath(actor, domainFull, callingDomain) postActor = getAltPath(actor, domainFull, callingDomain)
sharesStr += ' <form method="POST" action="' + postActor + '/rmshare">\n' if sharesFileType == 'shares':
endpoint = 'rmshare'
else:
endpoint = 'rmwanted'
sharesStr += \
' <form method="POST" action="' + postActor + '/' + endpoint + '">\n'
sharesStr += \ sharesStr += \
' <input type="hidden" name="actor" value="' + actor + '">\n' ' <input type="hidden" name="actor" value="' + actor + '">\n'
sharesStr += ' <input type="hidden" name="itemID" value="' + \ sharesStr += ' <input type="hidden" name="itemID" value="' + \

View File

@ -210,7 +210,8 @@ def htmlSearchSharedItems(cssCache: {}, translate: {},
httpPrefix: str, httpPrefix: str,
domainFull: str, actor: str, domainFull: str, actor: str,
callingDomain: str, callingDomain: str,
sharedItemsFederatedDomains: []) -> str: sharedItemsFederatedDomains: [],
sharesFileType: str) -> str:
"""Search results for shared items """Search results for shared items
""" """
currPage = 1 currPage = 1
@ -227,11 +228,13 @@ def htmlSearchSharedItems(cssCache: {}, translate: {},
getConfigParam(baseDir, 'instanceTitle') getConfigParam(baseDir, 'instanceTitle')
sharedItemsForm = \ sharedItemsForm = \
htmlHeaderWithExternalStyle(cssFilename, instanceTitle) htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
if sharesFileType == 'shares':
titleStr = translate['Shared Items Search']
else:
titleStr = translate['Wanted Items Search']
sharedItemsForm += \ sharedItemsForm += \
'<center><h1>' + \ '<center><h1>' + \
'<a href="' + actor + '/search">' + \ '<a href="' + actor + '/search">' + titleStr + '</a></h1></center>'
translate['Shared Items Search'] + \
'</a></h1></center>'
resultsExist = False resultsExist = False
for subdir, dirs, files in os.walk(baseDir + '/accounts'): for subdir, dirs, files in os.walk(baseDir + '/accounts'):
for handle in dirs: for handle in dirs:
@ -239,7 +242,7 @@ def htmlSearchSharedItems(cssCache: {}, translate: {},
continue continue
contactNickname = handle.split('@')[0] contactNickname = handle.split('@')[0]
sharesFilename = baseDir + '/accounts/' + handle + \ sharesFilename = baseDir + '/accounts/' + handle + \
'/shares.json' '/' + sharesFileType + '.json'
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
continue continue
@ -264,13 +267,16 @@ def htmlSearchSharedItems(cssCache: {}, translate: {},
break break
# search federated shared items # search federated shared items
catalogsDir = baseDir + '/cache/catalogs' if sharesFileType == 'shares':
catalogsDir = baseDir + '/cache/catalogs'
else:
catalogsDir = baseDir + '/cache/wantedItems'
if currPage <= pageNumber and os.path.isdir(catalogsDir): if currPage <= pageNumber and os.path.isdir(catalogsDir):
for subdir, dirs, files in os.walk(catalogsDir): for subdir, dirs, files in os.walk(catalogsDir):
for f in files: for f in files:
if '#' in f: if '#' in f:
continue continue
if not f.endswith('.shares.json'): if not f.endswith('.' + sharesFileType + '.json'):
continue continue
federatedDomain = f.split('.')[0] federatedDomain = f.split('.')[0]
if federatedDomain not in sharedItemsFederatedDomains: if federatedDomain not in sharedItemsFederatedDomains:

View File

@ -699,7 +699,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
_htmlSharesTimeline(translate, pageNumber, itemsPerPage, _htmlSharesTimeline(translate, pageNumber, itemsPerPage,
baseDir, actor, nickname, domain, port, baseDir, actor, nickname, domain, port,
maxSharesPerAccount, httpPrefix, maxSharesPerAccount, httpPrefix,
sharedItemsFederatedDomains) + sharedItemsFederatedDomains, 'shares') +
_htmlTimelineEnd(baseDir, nickname, domainFull, _htmlTimelineEnd(baseDir, nickname, domainFull,
httpPrefix, translate, httpPrefix, translate,
moderator, editor, moderator, editor,
@ -916,13 +916,14 @@ def _htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
baseDir: str, actor: str, baseDir: str, actor: str,
nickname: str, domain: str, port: int, nickname: str, domain: str, port: int,
maxSharesPerAccount: int, httpPrefix: str, maxSharesPerAccount: int, httpPrefix: str,
sharedItemsFederatedDomains: []) -> str: sharedItemsFederatedDomains: [],
sharesFileType: str) -> str:
"""Show shared items timeline as html """Show shared items timeline as html
""" """
sharesJson, lastPage = \ sharesJson, lastPage = \
sharesTimelineJson(actor, pageNumber, itemsPerPage, sharesTimelineJson(actor, pageNumber, itemsPerPage,
baseDir, domain, nickname, maxSharesPerAccount, baseDir, domain, nickname, maxSharesPerAccount,
sharedItemsFederatedDomains) sharedItemsFederatedDomains, sharesFileType)
domainFull = getFullDomain(domain, port) domainFull = getFullDomain(domain, port)
actor = httpPrefix + '://' + domainFull + '/users/' + nickname actor = httpPrefix + '://' + domainFull + '/users/' + nickname
adminNickname = getConfigParam(baseDir, 'admin') adminNickname = getConfigParam(baseDir, 'admin')
@ -935,7 +936,7 @@ def _htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
if pageNumber > 1: if pageNumber > 1:
timelineStr += \ timelineStr += \
' <center>\n' + \ ' <center>\n' + \
' <a href="' + actor + '/tlshares?page=' + \ ' <a href="' + actor + '/tl' + sharesFileType + '?page=' + \
str(pageNumber - 1) + \ str(pageNumber - 1) + \
'"><img loading="lazy" class="pageicon" src="/' + \ '"><img loading="lazy" class="pageicon" src="/' + \
'icons/pageup.png" title="' + translate['Page up'] + \ 'icons/pageup.png" title="' + translate['Page up'] + \
@ -968,12 +969,12 @@ def _htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
ctr += 1 ctr += 1
if ctr == 0: if ctr == 0:
timelineStr += _getHelpForTimeline(baseDir, 'tlshares') timelineStr += _getHelpForTimeline(baseDir, 'tl' + sharesFileType)
if not lastPage: if not lastPage:
timelineStr += \ timelineStr += \
' <center>\n' + \ ' <center>\n' + \
' <a href="' + actor + '/tlshares?page=' + \ ' <a href="' + actor + '/tl' + sharesFileType + '?page=' + \
str(pageNumber + 1) + \ str(pageNumber + 1) + \
'"><img loading="lazy" class="pageicon" src="/' + \ '"><img loading="lazy" class="pageicon" src="/' + \
'icons/pagedown.png" title="' + translate['Page down'] + \ 'icons/pagedown.png" title="' + translate['Page down'] + \

View File

@ -340,7 +340,8 @@ def scheduledPostsExist(baseDir: str, nickname: str, domain: str) -> bool:
def sharesTimelineJson(actor: str, pageNumber: int, itemsPerPage: int, def sharesTimelineJson(actor: str, pageNumber: int, itemsPerPage: int,
baseDir: str, domain: str, nickname: str, baseDir: str, domain: str, nickname: str,
maxSharesPerAccount: int, maxSharesPerAccount: int,
sharedItemsFederatedDomains: []) -> ({}, bool): sharedItemsFederatedDomains: [],
sharesFileType: str) -> ({}, bool):
"""Get a page on the shared items timeline as json """Get a page on the shared items timeline as json
maxSharesPerAccount helps to avoid one person dominating the timeline maxSharesPerAccount helps to avoid one person dominating the timeline
by sharing a large number of things by sharing a large number of things
@ -351,7 +352,7 @@ def sharesTimelineJson(actor: str, pageNumber: int, itemsPerPage: int,
if not isAccountDir(handle): if not isAccountDir(handle):
continue continue
accountDir = baseDir + '/accounts/' + handle accountDir = baseDir + '/accounts/' + handle
sharesFilename = accountDir + '/shares.json' sharesFilename = accountDir + '/' + sharesFileType + '.json'
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
continue continue
sharesJson = loadJson(sharesFilename) sharesJson = loadJson(sharesFilename)
@ -376,13 +377,16 @@ def sharesTimelineJson(actor: str, pageNumber: int, itemsPerPage: int,
break break
break break
if sharedItemsFederatedDomains: if sharedItemsFederatedDomains:
catalogsDir = baseDir + '/cache/catalogs' if sharesFileType == 'shares':
catalogsDir = baseDir + '/cache/catalogs'
else:
catalogsDir = baseDir + '/cache/wantedItems'
if os.path.isdir(catalogsDir): if os.path.isdir(catalogsDir):
for subdir, dirs, files in os.walk(catalogsDir): for subdir, dirs, files in os.walk(catalogsDir):
for f in files: for f in files:
if '#' in f: if '#' in f:
continue continue
if not f.endswith('.shares.json'): if not f.endswith('.' + sharesFileType + '.json'):
continue continue
federatedDomain = f.split('.')[0] federatedDomain = f.split('.')[0]
if federatedDomain not in sharedItemsFederatedDomains: if federatedDomain not in sharedItemsFederatedDomains:
@ -1342,7 +1346,8 @@ def htmlShowShare(baseDir: str, domain: str, nickname: str,
httpPrefix: str, domainFull: str, httpPrefix: str, domainFull: str,
itemID: str, translate: {}, itemID: str, translate: {},
sharedItemsFederatedDomains: [], sharedItemsFederatedDomains: [],
defaultTimeline: str, theme: str) -> str: defaultTimeline: str, theme: str,
sharesFileType: str) -> str:
"""Shows an individual shared item after selecting it from the left column """Shows an individual shared item after selecting it from the left column
""" """
sharesJson = None sharesJson = None
@ -1355,20 +1360,24 @@ def htmlShowShare(baseDir: str, domain: str, nickname: str,
if '://' + domainFull + '/' in shareUrl: if '://' + domainFull + '/' in shareUrl:
# shared item on this instance # shared item on this instance
sharesFilename = \ sharesFilename = \
acctDir(baseDir, contactNickname, domain) + '/shares.json' acctDir(baseDir, contactNickname, domain) + '/' + \
sharesFileType + '.json'
if not os.path.isfile(sharesFilename): if not os.path.isfile(sharesFilename):
return None return None
sharesJson = loadJson(sharesFilename) sharesJson = loadJson(sharesFilename)
else: else:
# federated shared item # federated shared item
catalogsDir = baseDir + '/cache/catalogs' if sharesFileType == 'shares':
catalogsDir = baseDir + '/cache/catalogs'
else:
catalogsDir = baseDir + '/cache/wantedItems'
if not os.path.isdir(catalogsDir): if not os.path.isdir(catalogsDir):
return None return None
for subdir, dirs, files in os.walk(catalogsDir): for subdir, dirs, files in os.walk(catalogsDir):
for f in files: for f in files:
if '#' in f: if '#' in f:
continue continue
if not f.endswith('.shares.json'): if not f.endswith('.' + sharesFileType + '.json'):
continue continue
federatedDomain = f.split('.')[0] federatedDomain = f.split('.')[0]
if federatedDomain not in sharedItemsFederatedDomains: if federatedDomain not in sharedItemsFederatedDomains: