translator.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import logging
  2. from collections import defaultdict
  3. from flask import request
  4. from rdflib.term import URIRef
  5. from lakesuperior.dictionaries.namespaces import ns_collection as nsc
  6. from lakesuperior.store_layouts.rdf.base_rdf_layout import BaseRdfLayout
  7. class Translator:
  8. '''
  9. Utility class to perform translations of strings and their wrappers.
  10. All static methods.
  11. '''
  12. _logger = logging.getLogger(__name__)
  13. @staticmethod
  14. def base_url():
  15. return request.host_url + request.path.split('/')[1]
  16. @staticmethod
  17. def camelcase(word):
  18. '''
  19. Convert a string with underscores with a camel-cased one.
  20. Ripped from https://stackoverflow.com/a/6425628
  21. '''
  22. return ''.join(x.capitalize() or '_' for x in word.split('_'))
  23. @staticmethod
  24. def uuid_to_uri(uuid):
  25. '''Convert a UUID to a URI.
  26. @return URIRef
  27. '''
  28. return URIRef('{}rest/{}'.format(request.host_url, uuid))
  29. @staticmethod
  30. def localize_string(s):
  31. '''Convert URIs into URNs in a string using the application base URI.
  32. @param string s Input string.
  33. @return string
  34. '''
  35. #import pdb; pdb.set_trace()
  36. return s.replace(Translator.base_url()+'/', str(nsc['fcres']))\
  37. .replace(Translator.base_url(), str(nsc['fcres']))
  38. @staticmethod
  39. def localize_term(uri):
  40. '''
  41. Convert an URI into an URN.
  42. @param rdflib.term.URIRef urn Input URI.
  43. @return rdflib.term.URIRef
  44. '''
  45. #import pdb; pdb.set_trace()
  46. Translator._logger.debug('Input URI: {}'.format(uri))
  47. if uri.strip('/') == Translator.base_url():
  48. return BaseRdfLayout.ROOT_NODE_URN
  49. return URIRef(Translator.localize_string(str(uri)))
  50. @staticmethod
  51. def globalize_string(s):
  52. '''Convert URNs into URIs in a string using the application base URI.
  53. @param string s Input string.
  54. @return string
  55. '''
  56. return s.replace(
  57. str(nsc['fcres']),
  58. request.host_url + 'rest/'
  59. )
  60. @staticmethod
  61. def globalize_term(urn):
  62. '''
  63. Convert an URN into an URI using the application base URI.
  64. @param rdflib.term.URIRef urn Input URN.
  65. @return rdflib.term.URIRef
  66. '''
  67. if urn == BaseRdfLayout.ROOT_NODE_URN:
  68. urn = nsc['fcres']
  69. return URIRef(Translator.globalize_string(str(urn)))
  70. @staticmethod
  71. def globalize_graph(g):
  72. '''
  73. Globalize a graph.
  74. '''
  75. from lakesuperior.model.ldpr import Ldpr
  76. q = '''
  77. CONSTRUCT {{ ?s ?p ?o . }} WHERE {{
  78. {{
  79. ?s ?p ?o .
  80. FILTER (
  81. STRSTARTS(str(?s), "{0}")
  82. ||
  83. STRSTARTS(str(?o), "{0}")
  84. ||
  85. STRSTARTS(str(?s), "{1}")
  86. ||
  87. STRSTARTS(str(?o), "{1}")
  88. ) .
  89. }}
  90. }}'''.format(nsc['fcres'], BaseRdfLayout.ROOT_NODE_URN)
  91. flt_g = g.query(q)
  92. for t in flt_g:
  93. global_s = Translator.globalize_term(t[0])
  94. global_o = Translator.globalize_term(t[2]) \
  95. if isinstance(t[2], URIRef) \
  96. else t[2]
  97. g.remove(t)
  98. g.add((global_s, t[1], global_o))
  99. return g
  100. @staticmethod
  101. def globalize_rsrc(rsrc):
  102. '''
  103. Globalize a resource.
  104. '''
  105. g = rsrc.graph
  106. urn = rsrc.identifier
  107. global_g = Translator.globalize_graph(g)
  108. global_uri = Translator.globalize_term(urn)
  109. return global_g.resource(global_uri)
  110. @staticmethod
  111. def parse_rfc7240(h_str):
  112. '''
  113. Parse `Prefer` header as per https://tools.ietf.org/html/rfc7240
  114. The `cgi.parse_header` standard method does not work with all possible
  115. use cases for this header.
  116. @param h_str (string) The header(s) as a comma-separated list of Prefer
  117. statements, excluding the `Prefer: ` token.
  118. '''
  119. parsed_hdr = defaultdict(dict)
  120. # Split up headers by comma
  121. hdr_list = [ x.strip() for x in h_str.split(',') ]
  122. for hdr in hdr_list:
  123. parsed_pref = defaultdict(dict)
  124. # Split up tokens by semicolon
  125. token_list = [ token.strip() for token in hdr.split(';') ]
  126. prefer_token = token_list.pop(0).split('=')
  127. prefer_name = prefer_token[0]
  128. # If preference has a '=', it has a value, else none.
  129. if len(prefer_token)>1:
  130. parsed_pref['value'] = prefer_token[1].strip('"')
  131. for param_token in token_list:
  132. # If the token list had a ';' the preference has a parameter.
  133. print('Param token: {}'.format(param_token))
  134. param_parts = [ prm.strip().strip('"') \
  135. for prm in param_token.split('=') ]
  136. param_value = param_parts[1] if len(param_parts) > 1 else None
  137. parsed_pref['parameters'][param_parts[0]] = param_value
  138. parsed_hdr[prefer_name] = parsed_pref
  139. return parsed_hdr