Convert dfc format to internal shares format

main
Bob Mottram 2021-07-27 13:55:44 +01:00
parent 80339ecf20
commit 0db65ae069
2 changed files with 97 additions and 8 deletions

View File

@ -15340,7 +15340,8 @@ def runDaemon(sharedItemsFederatedDomains: [],
threadWithTrace(target=runFederatedSharesDaemon, threadWithTrace(target=runFederatedSharesDaemon,
args=(baseDir, httpd, args=(baseDir, httpd,
httpPrefix, domain, httpPrefix, domain,
proxyType, debug), daemon=True) proxyType, debug,
httpd.systemLanguage), daemon=True)
# flags used when restarting the inbox queue # flags used when restarting the inbox queue
httpd.restartInboxQueueInProgress = False httpd.restartInboxQueueInProgress = False

102
shares.py
View File

@ -128,7 +128,7 @@ def removeSharedItem(baseDir: str, nickname: str, domain: str,
'" does not exist in ' + sharesFilename) '" does not exist in ' + sharesFilename)
def _addShareDurationSec(duration: str, published: str) -> int: def _addShareDurationSec(duration: str, published: int) -> int:
"""Returns the duration for the shared item in seconds """Returns the duration for the shared item in seconds
""" """
if ' ' not in duration: if ' ' not in duration:
@ -151,16 +151,17 @@ def _addShareDurationSec(duration: str, published: str) -> int:
def _getshareDfcId(baseDir: str, systemLanguage: str, def _getshareDfcId(baseDir: str, systemLanguage: str,
itemType: str, itemCategory: str, itemType: str, itemCategory: str,
translate: {}) -> str: translate: {}, dfcIds: {} = None) -> str:
"""Attempts to obtain a DFC Id for the shared item, """Attempts to obtain a DFC Id for the shared item,
based upon productTypes ontology. based upon productTypes ontology.
See https://github.com/datafoodconsortium/ontology See https://github.com/datafoodconsortium/ontology
""" """
if translate['food'] not in itemCategory.lower(): if translate['food'] not in itemCategory.lower():
return '' return ''
dfcIds = _loadDfcIds(baseDir, systemLanguage)
if not dfcIds: if not dfcIds:
return '' dfcIds = _loadDfcIds(baseDir, systemLanguage)
if not dfcIds:
return ''
itemTypeLower = itemType.lower() itemTypeLower = itemType.lower()
matchName = '' matchName = ''
matchId = '' matchId = ''
@ -185,6 +186,19 @@ def _getshareDfcId(baseDir: str, systemLanguage: str,
return matchId return matchId
def _getshareTypeFromDfcId(dfcUri: str, dfcIds: {}) -> str:
"""Attempts to obtain a share item type from its DFC Id,
based upon productTypes ontology.
See https://github.com/datafoodconsortium/ontology
"""
for name, uri in dfcIds.items():
if uri.endswith('#' + dfcUri):
return name
elif uri == dfcUri:
return name
return None
def _indicateNewShareAvailable(baseDir: str, httpPrefix: str, def _indicateNewShareAvailable(baseDir: str, httpPrefix: str,
domainFull: str) -> None: domainFull: str) -> None:
"""Indicate to each account that a new share is available """Indicate to each account that a new share is available
@ -1111,7 +1125,8 @@ def authorizeSharedItems(sharedItemsFederatedDomains: [],
def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [], def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
baseDir: str, domain: str, baseDir: str, domain: str,
httpPrefix: str, httpPrefix: str,
tokensJson: {}, debug: bool) -> None: tokensJson: {}, debug: bool,
systemLanguage: 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
@ -1147,6 +1162,13 @@ def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
catalogFilename = catalogsDir + '/' + federatedDomain + '.json' catalogFilename = catalogsDir + '/' + federatedDomain + '.json'
if saveJson(catalogJson, catalogFilename): if saveJson(catalogJson, catalogFilename):
print('Downloaded shared items catalog for ' + federatedDomain) print('Downloaded shared items catalog for ' + federatedDomain)
sharesJson = _dfcToSharesFormat(catalogJson,
baseDir, systemLanguage)
if sharesJson:
sharesFilename = \
catalogsDir + '/' + federatedDomain + '.shares.json'
saveJson(sharesJson, sharesFilename)
print('Converted shares catalog for ' + federatedDomain)
else: else:
time.sleep(2) time.sleep(2)
@ -1171,7 +1193,8 @@ def runFederatedSharesWatchdog(projectVersion: str, httpd) -> None:
def runFederatedSharesDaemon(baseDir: str, httpd, httpPrefix: str, def runFederatedSharesDaemon(baseDir: str, httpd, httpPrefix: str,
domain: str, proxyType: str, debug: bool) -> None: domain: str, proxyType: str, debug: bool,
systemLanguage: str) -> None:
"""Runs the daemon used to update federated shared items """Runs the daemon used to update federated shared items
""" """
secondsPerHour = 60 * 60 secondsPerHour = 60 * 60
@ -1208,5 +1231,70 @@ def runFederatedSharesDaemon(baseDir: str, httpd, httpPrefix: str,
session = createSession(proxyType) session = createSession(proxyType)
_updateFederatedSharesCache(session, sharedItemsFederatedDomains, _updateFederatedSharesCache(session, sharedItemsFederatedDomains,
baseDir, domain, httpPrefix, tokensJson, baseDir, domain, httpPrefix, tokensJson,
debug) debug, systemLanguage)
time.sleep(secondsPerHour * 6) time.sleep(secondsPerHour * 6)
def _dfcToSharesFormat(catalogJson: {},
baseDir: str, systemLanguage: str) -> {}:
"""Converts DFC format into the internal formal used to store shared items.
This simplifies subsequent search and display
"""
if not catalogJson.get('DFC:supplies'):
return {}
sharesJson = {}
dfcIds = _loadDfcIds(baseDir, systemLanguage)
currTime = int(time.time())
for item in catalogJson['DFC:supplies']:
if not item.get('@id') or \
not item.get('@type') or \
not item.get('DFC:hasType') or \
not item.get('DFC:startDate') or \
not item.get('DFC:expiryDate') or \
not item.get('DFC:quantity') or \
not item.get('DFC:price') or \
not item.get('DFC:Image') or \
not item.get('DFC:description'):
continue
if ' ' not in item['DFC:price']:
continue
if ':' not in item['DFC:description']:
continue
if ':' not in item['DFC:hasType']:
continue
try:
expiryTime = \
datetime.datetime.strptime(item['DFC:expiryDate'],
'%Y-%m-%dT%H:%M:%SZ')
except BaseException:
continue
durationSec = \
int((expiryTime - datetime.datetime(1970, 1, 1)).total_seconds())
if durationSec < currTime:
# has expired
continue
hasType = item['DFC:hasType'].split(':')[1]
itemType = _getshareTypeFromDfcId(hasType, dfcIds)
if not itemType:
continue
dfcId = dfcIds[itemType]
itemID = item['@id']
description = item['DFC:description'].split(':', 1)[1].strip()
sharesJson[itemID] = {
"displayName": item['DFC:description'].split(':')[0],
"summary": description,
"imageUrl": item['DFC:Image'],
"itemQty": item['DFC:quantity'],
"dfcId": dfcId,
"itemType": itemType,
"category": "food",
"location": "",
"published": item['DFC:startDate'],
"expire": durationSec,
"price": item['DFC:price'].split(' ')[0],
"currency": item['DFC:price'].split(' ')[1]
}
return sharesJson