5
5
from rdflib import Graph , Namespace , URIRef , BNode , Literal , RDF , RDFS , XSD
6
6
from rdflib .namespace import DCTERMS
7
7
from pyldapi .profile import Profile
8
- from pyldapi .exceptions import ViewsFormatsException
8
+ from pyldapi .exceptions import ProfilesMediatypesException
9
9
import re
10
10
import connegp
11
11
@@ -73,12 +73,12 @@ def __init__(self,
73
73
self .profiles = profiles
74
74
# auto-add in an Alternates profile
75
75
self .profiles ['alt' ] = Profile (
76
+ 'http://www.w3.org/ns/dx/conneg/altr' , # the ConnegP URI for Alt Rep Data Model
76
77
'Alternate Representations' ,
77
78
'The representation of the resource that lists all other representations (profiles and Media Types)' ,
78
79
['text/html' , 'application/json' ] + self .RDF_MEDIA_TYPES ,
79
80
'text/html' ,
80
81
languages = ['en' ], # default 'en' only for now
81
- profile_uri = 'http://www.w3.org/ns/dx/conneg/altr' # the ConnegP URI for RRD Functional Profile
82
82
)
83
83
self .profile = None
84
84
@@ -105,7 +105,7 @@ def __init__(self,
105
105
# make headers only if there's no error
106
106
if self .vf_error is None :
107
107
self .headers = dict ()
108
- self .headers ['Content-Profile' ] = '<' + self .profiles [self .profile ].namespace + '>'
108
+ self .headers ['Content-Profile' ] = '<' + self .profiles [self .profile ].uri + '>'
109
109
self .headers ['Content-Type' ] = self .mediatype
110
110
self .headers ['Content-Language' ] = self .language
111
111
@@ -139,8 +139,8 @@ def _get_profiles_from_qsa(self):
139
139
for profile in pqsa .profiles :
140
140
if profile ['profile' ].startswith ('<' ):
141
141
# convert this valid URI/URN to a token
142
- for token , view in self .profiles .items ():
143
- if view . namespace == profile ['profile' ].strip ('<>' ):
142
+ for token , profile in self .profiles .items ():
143
+ if profile . uri == profile ['profile' ].strip ('<>' ):
144
144
profiles .append (token )
145
145
else :
146
146
# it's already a token so just add it
@@ -164,8 +164,8 @@ def _get_profiles_from_http(self):
164
164
profiles = []
165
165
for profile in ap .profiles :
166
166
# convert this valid URI/URN to a token
167
- for token , view in self .profiles .items ():
168
- if view . namespace == profile ['profile' ]:
167
+ for token , profile in self .profiles .items ():
168
+ if profile . uri == profile ['profile' ]:
169
169
profiles .append (token )
170
170
if len (profiles ) == 0 :
171
171
return None
@@ -175,14 +175,14 @@ def _get_profiles_from_http(self):
175
175
return None
176
176
except Exception :
177
177
msg = 'You have requested a profile using an Accept-Profile header that is incorrectly formatted.'
178
- raise ViewsFormatsException (msg )
178
+ raise ProfilesMediatypesException (msg )
179
179
else :
180
180
return None
181
181
182
182
def _get_available_profiles (self ):
183
183
uris = {}
184
- for token , view in self .profiles .items ():
185
- uris [view . namespace ] = token
184
+ for token , profile in self .profiles .items ():
185
+ uris [profile . uri ] = token
186
186
187
187
return uris
188
188
@@ -199,7 +199,7 @@ def _get_profile(self):
199
199
return self .default_profile_token
200
200
201
201
# if we have a result from QSA or HTTP, got through each in order and see if there's an available
202
- # view for that token, return first one
202
+ # profile for that token, return first one
203
203
profiles_available = self ._get_available_profiles ()
204
204
for profile in profiles_requested :
205
205
for k , v in profiles_available .items ():
@@ -254,7 +254,7 @@ def _get_mediatypes_from_http(self):
254
254
# return only the orderd list of mediatypes, not weights
255
255
return [x [1 ] for x in mediatypes ]
256
256
except Exception :
257
- raise ViewsFormatsException (
257
+ raise ProfilesMediatypesException (
258
258
'You have requested a Media Type using an Accept header that is incorrectly formatted.' )
259
259
260
260
return None
@@ -321,7 +321,7 @@ def _get_languages_from_http(self):
321
321
# return only the orderd list of languages, not weights
322
322
return [x [1 ] for x in languages ]
323
323
except Exception :
324
- raise ViewsFormatsException (
324
+ raise ProfilesMediatypesException (
325
325
'You have requested a language using an Accept-Language header that is incorrectly formatted.' )
326
326
327
327
return None
@@ -356,17 +356,17 @@ def _make_header_link_tokens(self):
356
356
individual_links = []
357
357
link_header_template = '<http://www.w3.org/ns/dx/prof/Profile>; rel="type"; token="{}"; anchor=<{}>, '
358
358
359
- for token , view in self .profiles .items ():
360
- individual_links .append (link_header_template .format (token , view . namespace ))
359
+ for token , profile in self .profiles .items ():
360
+ individual_links .append (link_header_template .format (token , profile . uri ))
361
361
362
362
return '' .join (individual_links ).rstrip (', ' )
363
363
364
364
def _make_header_link_list_profiles (self ):
365
365
individual_links = []
366
- for token , view in self .profiles .items ():
366
+ for token , profile in self .profiles .items ():
367
367
# create an individual Link statement per Media Type
368
- for mediatype in view .mediatypes :
369
- # set the rel="self" just for this view & mediatype
368
+ for mediatype in profile .mediatypes :
369
+ # set the rel="self" just for this profile & mediatype
370
370
if mediatype != '_internal' :
371
371
if token == self .default_profile_token and mediatype == self .profiles [self .profile ].default_mediatype :
372
372
rel = 'self'
@@ -380,7 +380,7 @@ def _make_header_link_list_profiles(self):
380
380
mediatype ,
381
381
rel ,
382
382
mediatype ,
383
- view . namespace )
383
+ profile . uri )
384
384
)
385
385
386
386
# append to, or create, Link header
@@ -392,31 +392,46 @@ def _make_header_link_list_profiles(self):
392
392
# making response content
393
393
#
394
394
def _generate_alt_profiles_rdf (self ):
395
+ # Alt R Data Model as per https://www.w3.org/TR/dx-prof-conneg/#altr
395
396
g = Graph ()
396
- ALT = Namespace ('http://w3id. org/profile/alt #' )
397
- g .bind ('alt ' , ALT )
397
+ ALTR = Namespace ('http://www.w3. org/ns/dx/conneg/altr #' )
398
+ g .bind ('altr ' , ALTR )
398
399
399
400
g .bind ('dct' , DCTERMS )
400
401
401
402
PROF = Namespace ('http://www.w3.org/ns/prof/' )
402
403
g .bind ('prof' , PROF )
403
404
404
- for token , v in self .profiles .items ():
405
- v_node = BNode ()
406
- g .add ((v_node , RDF .type , ALT .View ))
407
- g .add ((v_node , PROF .token , Literal (token , datatype = XSD .token )))
408
- g .add ((v_node , RDFS .label , Literal (v .label , datatype = XSD .string )))
409
- g .add ((v_node , RDFS .comment , Literal (v .comment , datatype = XSD .string )))
410
- for f in v .mediatypes :
411
- if not str (f ).startswith ('_' ): # ignore mediatypes like `_internal`
412
- g .add ((v_node , URIRef (DCTERMS + 'format' ), Literal (f )))
413
- g .add ((v_node , ALT .hasDefaultFormat , Literal (v .default_mediatype , datatype = XSD .string )))
414
- if v .namespace is not None :
415
- g .add ((v_node , DCTERMS .conformsTo , URIRef (v .namespace )))
416
- g .add ((URIRef (self .instance_uri ), ALT .view , v_node ))
417
-
418
- if self .default_profile_token == token :
419
- g .add ((URIRef (self .instance_uri ), ALT .hasDefaultView , v_node ))
405
+ instance_uri = URIRef (self .instance_uri )
406
+
407
+ # for each Profile, lis it via its URI and give annotations
408
+ for token , p in self .profiles .items ():
409
+ profile_uri = URIRef (p .uri )
410
+ g .add ((profile_uri , RDF .type , PROF .Profile ))
411
+ g .add ((profile_uri , PROF .token , Literal (token , datatype = XSD .token )))
412
+ g .add ((profile_uri , RDFS .label , Literal (p .label , datatype = XSD .string )))
413
+ g .add ((profile_uri , RDFS .comment , Literal (p .comment , datatype = XSD .string )))
414
+
415
+ # for each Profile and Media Type, create a Representation
416
+ for token , p in self .profiles .items ():
417
+ for mt in p .mediatypes :
418
+ if not str (mt ).startswith ('_' ): # ignore Media Types like `_internal`
419
+ rep = BNode ()
420
+ g .add ((rep , RDF .type , ALTR .Representation ))
421
+ g .add ((rep , DCTERMS .conformsTo , URIRef (p .uri )))
422
+ g .add ((rep , URIRef (DCTERMS + 'format' ), Literal (mt )))
423
+
424
+ # if this is the default format for the Profile, say so
425
+ if mt == p .default_mediatype :
426
+ g .add ((rep , ALTR .isProfilesDefault , Literal (True , datatype = XSD .boolean )))
427
+
428
+ # link this representation to the instances
429
+ g .add ((instance_uri , ALTR .hasRepresentation , rep ))
430
+
431
+ # if this is the default Profile and the default Media Type, set it as the instance's default Rep
432
+ if token == self .default_profile_token and mt == p .default_mediatype :
433
+ g .add ((instance_uri , ALTR .hasDefaultRepresentation , rep ))
434
+
420
435
return g
421
436
422
437
def _make_rdf_response (self , graph , mimetype = None , headers = None , delete_graph = True ):
@@ -453,14 +468,14 @@ def _make_rdf_response(self, graph, mimetype=None, headers=None, delete_graph=Tr
453
468
454
469
def _render_alt_profile_html (self , template_context = None ):
455
470
profiles = {}
456
- for token , v in self .profiles .items ():
471
+ for token , profile in self .profiles .items ():
457
472
profiles [token ] = {
458
- 'label' : str (v .label ), 'comment' : str (v .comment ),
459
- 'mediatypes' : tuple (f for f in v .mediatypes if not f .startswith ('_' )),
460
- 'default_mediatype' : str (v .default_mediatype ),
461
- 'languages' : v .languages if v .languages is not None else ['en' ],
462
- 'default_language' : str (v .default_language ),
463
- 'namespace ' : str (v . namespace )
473
+ 'label' : str (profile .label ), 'comment' : str (profile .comment ),
474
+ 'mediatypes' : tuple (f for f in profile .mediatypes if not f .startswith ('_' )),
475
+ 'default_mediatype' : str (profile .default_mediatype ),
476
+ 'languages' : profile .languages if profile .languages is not None else ['en' ],
477
+ 'default_language' : str (profile .default_language ),
478
+ 'uri ' : str (profile . uri )
464
479
}
465
480
_template_context = {
466
481
'uri' : self .instance_uri ,
@@ -485,7 +500,7 @@ def _render_alt_profile_json(self):
485
500
return Response (
486
501
json .dumps ({
487
502
'uri' : self .instance_uri ,
488
- 'views ' : list (self .profiles .keys ()),
503
+ 'profiles ' : list (self .profiles .keys ()),
489
504
'default_profile' : self .default_profile_token
490
505
}),
491
506
mimetype = 'application/json' ,
@@ -510,10 +525,10 @@ def _render_alt_profile(self):
510
525
511
526
def render (self ):
512
527
"""
513
- Use the received view and mediatype to create a response back to the client.
528
+ Use the received profile and mediatype to create a response back to the client.
514
529
515
530
TODO: Ashley, are you able to update this description with your new changes please?
516
- What is the method for rendering other views now? - Edmond
531
+ What is the method for rendering other profiles now? - Edmond
517
532
518
533
This is an abstract method.
519
534
0 commit comments