diff --git a/daemon.py b/daemon.py index 9147de8a0..a20c696a3 100644 --- a/daemon.py +++ b/daemon.py @@ -207,9 +207,11 @@ from shares import getSharesFeedForPerson from shares import addShare from shares import removeSharedItem from shares import expireShares +from shares import sharesCatalogEndpoint from categories import setHashtagCategory from languages import getActorLanguages from languages import setActorLanguages +from utils import isfloat from utils import validPassword from utils import removeLineEndings from utils import getBaseContentFromPost @@ -10618,7 +10620,6 @@ class PubServer(BaseHTTPRequestHandler): self._benchmarkGETtimings(GETstartTime, GETtimings, 'show logout', 'get cookie') - # manifest for progressive web apps if '/manifest.json' in self.path: if self._hasAccept(callingDomain): if not self._requestHTTP(): @@ -10654,6 +10655,34 @@ class PubServer(BaseHTTPRequestHandler): self._benchmarkGETtimings(GETstartTime, GETtimings, 'show logout', 'isAuthorized') + if self.path.startswith('/dfc-catalog'): + catalogAuthorized = False + if authorized: + catalogAuthorized = True + else: + if self.headers.get('Authorization'): + if authorize(self.server.baseDir, self.path, + self.headers['Authorization'], + self.server.debug): + catalogAuthorized = True + # show shared items DFC catalog + if self._hasAccept(callingDomain) and catalogAuthorized: + if not self._requestHTTP(): + catalogJson = \ + sharesCatalogEndpoint(self.server.baseDir, + self.server.httpPrefix, + self.server.domainFull, + self.server.path) + msg = json.dumps(catalogJson, + ensure_ascii=False).encode('utf-8') + msglen = len(msg) + self._set_headers('application/json', + msglen, None, callingDomain) + self._write(msg) + return + else: + self.path = '/' + # minimal mastodon api if self._mastoApi(self.path, callingDomain, authorized, self.server.httpPrefix, @@ -13657,9 +13686,9 @@ class PubServer(BaseHTTPRequestHandler): if fields['itemQty']: if fields['itemQty'].isdigit(): itemQty = int(fields['itemQty']) - itemPrice = "0" + itemPrice = "0.00" if fields['itemPrice']: - if fields['itemPrice'].isdigit(): + if isfloat(fields['itemPrice']): itemPrice = fields['itemPrice'] itemCurrency = "EUR" if fields['itemCurrency']: diff --git a/epicyon.py b/epicyon.py index 574203e50..f65c29786 100644 --- a/epicyon.py +++ b/epicyon.py @@ -562,7 +562,7 @@ parser.add_argument('--itemQty', dest='itemQty', type=int, default=1, help='Quantity of items being shared') parser.add_argument('--itemPrice', dest='itemPrice', type=str, - default="0", + default="0.00", help='Total price of items being shared') parser.add_argument('--itemCurrency', dest='itemCurrency', type=str, default="EUR", diff --git a/shares.py b/shares.py index 10ccdc7f4..da878e2fc 100644 --- a/shares.py +++ b/shares.py @@ -25,6 +25,7 @@ from utils import hasObjectDict from utils import removeDomainPort from utils import isAccountDir from utils import acctDir +from utils import isfloat from media import processMetaData @@ -723,21 +724,51 @@ def outboxUndoShareUpload(baseDir: str, httpPrefix: str, print('DEBUG: shared item removed via c2s') +def _sharesCatalogParams(path: str) -> (bool, float, float, str): + """Returns parameters when accessing the shares catalog + """ + today = False + minPrice = 0 + maxPrice = 9999999 + matchPattern = None + if '?' not in path: + return today, minPrice, maxPrice, matchPattern + args = path.split('?', 1)[1] + argList = args.split('?') + for arg in argList: + if '=' not in arg: + continue + key = arg.split('=')[0].lower() + value = arg.split('=')[1] + if key == 'today': + value = value.lower() + if 'true' in value or 'y' in value or '1' in value: + today = True + elif key.startswith('min'): + if isfloat(value): + minPrice = float(value) + elif key.startswith('max'): + if isfloat(value): + maxPrice = float(value) + elif key.startswith('match'): + matchPattern = value + return today, minPrice, maxPrice, matchPattern + + def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str, nickname: str, domain: str, domainFull: str, - path: str, today: bool, - minPrice: float, maxPrice: float, - matchPattern: str) -> {}: + path: str) -> {}: """Returns the endpoint for the shares catalog of a particular account See https://github.com/datafoodconsortium/ontology """ + today, minPrice, maxPrice, matchPattern = _sharesCatalogParams(path) dfcUrl = \ "http://static.datafoodconsortium.org/ontologies/DFC_FullModel.owl#" dfcPtUrl = \ "http://static.datafoodconsortium.org/data/productTypes.rdf#" owner = httpPrefix + '://' + domainFull + '/users/' + nickname - dfcInstanceId = owner + '/catalog' + dfcInstanceId = owner + '/dfc-catalog' endpoint = { "@context": { "DFC": dfcUrl, @@ -802,17 +833,16 @@ def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str, def sharesCatalogEndpoint(baseDir: str, httpPrefix: str, domainFull: str, - path: str, today: bool, - minPrice: float, maxPrice: float, - matchPattern: str) -> {}: + path: str) -> {}: """Returns the endpoint for the shares catalog for the instance See https://github.com/datafoodconsortium/ontology """ + today, minPrice, maxPrice, matchPattern = _sharesCatalogParams(path) dfcUrl = \ "http://static.datafoodconsortium.org/ontologies/DFC_FullModel.owl#" dfcPtUrl = \ "http://static.datafoodconsortium.org/data/productTypes.rdf#" - dfcInstanceId = httpPrefix + '://' + domainFull + '/catalog' + dfcInstanceId = httpPrefix + '://' + domainFull + '/dfc-catalog' endpoint = { "@context": { "DFC": dfcUrl, diff --git a/tests.py b/tests.py index f483b4be8..c8f3b3b54 100644 --- a/tests.py +++ b/tests.py @@ -3273,7 +3273,6 @@ def _testFunctions(): 'setOrganizationScheme', 'fill_headers', '_nothing', - 'sharesCatalogEndpoint', 'sharesCatalogAccountEndpoint' ] excludeImports = [ diff --git a/utils.py b/utils.py index 6d0bea5f6..b5debfc54 100644 --- a/utils.py +++ b/utils.py @@ -2626,3 +2626,11 @@ def validPassword(password: str) -> bool: if not re.match("^[a-zA-Z0-9!]*$", password): return False return True + + +def isfloat(value): + try: + float(value) + return True + except ValueError: + return False diff --git a/webapp_search.py b/webapp_search.py index 013fff788..a031a4333 100644 --- a/webapp_search.py +++ b/webapp_search.py @@ -25,6 +25,7 @@ from utils import firstParagraphFromString from utils import searchBoxPosts from utils import getAltPath from utils import acctDir +from utils import isfloat from skills import noOfActorSkills from skills import getSkillsFromList from categories import getHashtagCategory @@ -191,7 +192,7 @@ def htmlSearchSharedItems(cssCache: {}, translate: {}, ': ' + sharedItem['location'] if sharedItem.get('itemPrice') and \ sharedItem.get('itemCurrency'): - if sharedItem['itemPrice'].isdigit(): + if isfloat(sharedItem['itemPrice']): if float(sharedItem['itemPrice']) > 0: sharedItemsForm += \ ' ' + translate['Price'] + \ diff --git a/webapp_timeline.py b/webapp_timeline.py index 265634b12..8175ff10f 100644 --- a/webapp_timeline.py +++ b/webapp_timeline.py @@ -16,6 +16,7 @@ from utils import getFullDomain from utils import isEditor from utils import removeIdEnding from utils import acctDir +from utils import isfloat from follow import followerApprovalActive from person import isPersonSnoozed from markdown import markdownToHtml @@ -832,7 +833,7 @@ def htmlIndividualShare(actor: str, item: {}, translate: {}, profileStr += \ '' + translate['Location'] + ': ' + item['location'] if item.get('itemPrice') and item.get('itemCurrency'): - if item['itemPrice'].isdigit(): + if isfloat(item['itemPrice']): if float(item['itemPrice']) > 0: profileStr += ' ' + \ '' + translate['Price'] + ': ' + \