Commits

Anonymous committed b24b39e

Addition of alt links to letters and correspondents templates. reworked rdf and partial reworking of json (to be completed) for better endpoints.

  • Participants
  • Parent commits 2f89b41

Comments (0)

Files changed (17)

openletters/cli.py

     '''Load external data into domain model.
 
         dickens: Load Dickens data.
+        
+        endpoint: create the RDF/JSON/XML endpoints
     '''
     summary = __doc__.split('\n')[0]
     usage = __doc__
             openletters.command.load_source(source_obj)
             openletters.command.load_texts(book_obj)
 
+        elif cmd == 'endpoint':
+            import openletters.command
+            openletters.command.create_endpoint()
+            
         else:
             print 'Action not recognized'
 
 
 class Index(BaseCommand):
-    '''
-       Index the letters for a Xapian powered search
+    ''' Index the letters for a Xapian powered search
     
        index dickens  - indexes the Dickens letters
     '''

openletters/command.py

-# -*- coding: latin-1 -*-
+
 '''
 Class to parse the Dickens letters and enter into a store
 '''
-import unicodedata
+import unicodedata, urllib, os
+
+from ofs.local import OFS
 from xml.dom import minidom
-import urllib, os
 
 from openletters.parse import parse_text, parse_date
 from openletters import model
 
+from openletters.transform.transform_rdf import rdf_transform
+from openletters.transform.transform_json import json_transform
+from openletters.transform.transform_xml import xml_transform
+
 def getText(nodelist):
     rc = []
     for node in nodelist:
         database.add_document(document)
         
     database.flush()
+    
+def create_endpoint ():
+    #delete any existing endpoints first before loading
+    o = OFS()
+    for b in o.list_buckets():
+        #if o.exists(b, "rdfendpoint"): o.del_stream(b, "rdfendpoint")
+        if o.exists(b, "jsonendpoint"): o.del_stream(b, "jsonendpoint")
+        if o.exists(b, "xmlendpoint"): o.del_stream(b, "xmlendpoint")
+        if o.exists(b, "simile"): o.del_stream(b, "simile")
+        
+
+
+    
+    #TODO put in the books xml
+    
+def __store (data_store, data_name):
+    
+    o = OFS()
+    store_id = o.claim_bucket(data_name)
+    o.put_stream(store_id, data_name, data_store)

openletters/controllers/book.py

         else:
             books = model.Session.query(model.Book).filter(model.Book.url == author)
             if correspondent == "rdf":
-                response.headers['Content-Type'] = 'text/xml'
+                #response.headers['Content-Type'] = 'application/rdf+xml'
                 rdf = rdf_transform()
-                return rdf.create_publication(author, "book")
+                return rdf.create_publication(author, "book")
+            if correspondent == "json":
+               # response.headers['Content-Type'] = 'application/json'
+                json = json_transform()
+                return json.book_json(author, "book")

openletters/controllers/correspondent.py

-import logging
+import logging, urllib
 
 from pylons import request, response, session, tmpl_context as c
 from pylons.controllers.util import abort, redirect_to
 
 from openletters.lib.base import BaseController, render
+from openletters import model
+from openletters.model import dbase
 
+from openletters.transform.transform_json import json_transform
+from openletters.transform.transform_xml import xml_transform
 from openletters.transform.transform_rdf import rdf_transform
 
-from openletters.model import dbase
 
 log = logging.getLogger(__name__)
 
 class CorrespondentController(BaseController):
 
     def index(self):
+        c.page_title = "Index of correspondents"
+
+        c.corres =  model.Session.query(model.Letter.correspondent).distinct().all()
+
+        return render('letters/correspondent.html')
+    
+
+    def view(self, author=None):
+        '''
+              Method to return details about a correspondent
+        '''
         c.page_title = urllib.unquote(author)
         c.author = author
         c.nicks = self.corr_dict(author)
         
         return render('letters/correspondent.html')
     
-    '''
-      Method to return details about a correspondent
-    '''
-    def view(self, author=None):
-        
-        c.page_title = urllib.unquote(author)
-        c.author = author
-        c.nicks = self.corr_dict(author)
-        
-        return render('letters/correspondent.html')
-    
-    '''
-      Method to return details about a correspondent
-    '''
+
     def resource(self, author=None, correspondent=None):
         
+        '''
+          Method to return details about a correspondent
+        '''
         if author is None:
             abort(404)
 

openletters/controllers/data.py

-import logging
+import logging, urllib
 
 from pylons import request, response, session, tmpl_context as c
 
-import urllib
-
-from openletters.lib.base import BaseController, render
+#from ofs.local import OFS
 
 from openletters import model
-
+from openletters.lib.base import BaseController, render
 from openletters.transform.transform_rdf import rdf_transform
 from openletters.transform.transform_json import json_transform
 from openletters.transform.transform_xml import xml_transform
 log = logging.getLogger(__name__)
 
 class DataController(BaseController):
-    '''
-       Return an endpoint in which ever format is requested
-    '''
+
     def endpoint (self, author = '', correspondent = ''):
         
+        '''
+          Return an endpoint in which ever format is requested
+        '''
+        #o = OFS()
+        
         if author == "rdf":
             response.headers['Content-Type'] = 'application/rdf+xml'
+            #response.headers['Content-Type'] = 'application/rdf+xml
+            #for b in o.list_buckets():
+            #    g = o.get_stream(b, "rdfendpoint")
+            #    return g.read()
+                #print "data", g.read()
             rdf = rdf_transform()
             return rdf.create_rdf_end()
         
         
         elif author == "xml":
             xml = xml_transform()
-            response.headers['Content-Type'] = 'text/xml'
+            response.headers['Content-Type'] = 'application/xml'
             if correspondent == "simile":
+                
+                #for b in o.list_buckets():
+                #    print "bucket",b
+                #    if o.exists(b, "simile"):  
+                #        g = o.get_stream(b, "simile", True)
+                #        return g.read()
+                #    else:
+                #        simile = xml.endpoint_xml("simile")
+                #        try:
+                #            store_id = o.claim_bucket("simile")
+                #            o.put_stream(store_id, "simile", simile)
+                #            g = o.get_stream(store_id, "simile", True)
+                #            return g.read()
+                #        except:
+                            
                 return xml.endpoint_xml("simile")
             else:
+                #for b in o.list_buckets():
+                #    g = o.get_stream(b, "xmlendpoint", True)
+                #    return g.read()
                 return xml.endpoint_xml()
         else:
             return render("endpoint/index.html")

openletters/controllers/letters.py

 from routes import redirect_to
 
 from openletters.lib.base import BaseController, render
+
 from openletters import model
+from openletters.model import dbase
+
 from openletters.parse import parse_text, parse_date
 
 from openletters.transform.transform_json import json_transform
 from openletters.transform.transform_xml import xml_transform
 from openletters.transform.transform_rdf import rdf_transform
 
-from openletters.model import dbase
-
 
 log = logging.getLogger(__name__)
 

openletters/controllers/magazine.py

             return render('letters/magazineindex.html')
         else:
             mag = urllib.unquote(author)
-            if mag =="Household Works":
+            if mag =="Household Words":
                 c.start = u"March 1850"
                 c.end = u"May 1859"
                 c.abstract = u"Household Words was an English weekly magazine edited by Charles Dickens in the 1850s which took its name from the line from Shakespeare 'Familiar in his mouth as household words' - Henry V"
                 
             return render('letters/magazine.html')
      
-    '''
-       Method to return a resource view of the publication
-       @param author publication name
-       @param correspondent data type - rdf, json or xml
-    '''
+
     def resource(self, author=None, correspondent=None):
+         '''
+           Method to return a resource view of the publication
+           @param author publication name
+           @param correspondent data type - rdf, json or xml
+         '''
          if author is None:
              abort(404)
          else:
              title = str(urllib.unquote(author))
              if correspondent == "rdf":
-                 response.headers['Content-Type'] = 'text/xml; charset=utf-8'
+
+                 response.headers['Content-Type'] = 'application/rdf+xml;'
+                 rdf = rdf_transform()
+                 return rdf.create_publication(author, "magazine")
+             
+             elif correspondent == "json":
+                 #response.headers['Content-Type'] = 'application/json'
                  #response.headers['Content-Type'] = 'application/rdf+xml; charset=utf-8'
-                 rdf = rdf_transform()
-                 return rdf.create_publication(title, "magazine")
+                 json = json_transform()
+                 return json.book_json(author, "magazine")
+             
+                          
+             elif correspondent == "xml":
+                 #response.headers['Content-Type'] = 'application/json'
+                 #response.headers['Content-Type'] = 'application/rdf+xml; charset=utf-8'
+                 json = json_transform()
+                 return json.book_json(author, "magazine")
             

openletters/controllers/place.py

         locations = []
         locations = list(sparql.find_places())
         c.places = sorted(locations)
-        print "locations", c.places
+        #print "locations", c.places
 
         return render('letters/magazineindex.html')
     

openletters/docs/dickens_texts.xml

         <url>Master_Humphrey's_Clock</url>
         <description></description>
     </book>
+        <book>
+        <id>26</id>
+        <title>All the Year Round</title>
+        <mag_start>1859-01-28</mag_start>
+        <mag_end>1895-03-30</mag_end>
+        <aka></aka>
+        <aka2></aka2>
+        <source></source>
+        <url>All_the_Year_Round</url>
+        <description>All the Year Round was a Victorian periodical, being a British weekly literary magazine founded and owned by Charles Dickens, published between 1859 and 1895 throughout the United Kingdom. Edited by Dickens, it was the direct successor to his previous publication Household Words, abandoned due to differences with his former publisher. It hosted the serialization of many prominent novels, including Dickens' own A Tale of Two Cities. After Dickens's death in 1870, it was owned and edited by his eldest son Charles Dickens, Jr.</description>
+    </book>
+        <book>
+        <id>27</id>
+        <title>Household Words</title>
+        <mag_start>1850-03-01</mag_start>
+        <mag_end>1859-05-01</mag_end>
+        <aka></aka>
+        <aka2></aka2>
+        <source></source>
+        <url>Household_Words</url>
+        <description>Household Words was an English weekly magazine edited by Charles Dickens in the 1850s which took its name from the line from Shakespeare 'Familiar in his mouth as household words' - Henry V</description>
+    </book>
 </opencorrespondence>

openletters/model/dbase.py

 #gets the book details
 def get_book_rdf (title):
     book_arr = {}
+    print title
     book = books.select(books.c.url == title)
     rs = book.execute()
     for row in rs:

openletters/templates/letters/correspondent.html

 <html xmlns:py="http://genshi.edgewall.org/"
   xmlns:xi="http://www.w3.org/2001/XInclude"
   py:strip="True" >
-
+  <py:if test="c.nicks">
+     <py:def function="optional_head">
+       <link rel="alt" type="application/rdf+xml" href="${url(controller='correspondent', action='resource', author=c.author, correspondent='rdf')}" title="RDF/XML version of page" /> 
+       <link rel="alt" type="application/json" href="${url(controller='correspondent', action='resource', author=c.author, correspondent='json')}" title="JSON version of page" />
+       <link rel="alt" type="text/xml" href="${url(controller='correspondent', action='resource', author=c.author, correspondent='xml')}" title="XML version of page" />  
+     </py:def>
+  </py:if>
   <py:def function="page_title">c.page_title</py:def>
 
   <div py:def="content">
     <div class="letter">
 
         <h4>${c.author}</h4>
-        <p>Also known as:</p>
+        <py:if test="c.nicks">
+        <py:def function="optional_head">
+              <link rel="alt" href="${url(controller='correspondent', action='resource', author=corr.correspondent, correspondent='rdf')}" description="RDF/XML version of page" /> 
+        </py:def>
+           <p>Also known as:</p>
+               <ul>
+         		<div py:for="nick, t in c.nicks">
+           			 <li>${nick}</li>
+         		 </div>
+          </ul>
+        </py:if>
+        <py:if test="c.corres">
           <ul>
-          <div py:for="nick, t in c.nicks">
-            <li>${nick}</li>
+          <div py:for="corr in c.corres">
+            <li><a href="${url(controller='correspondent', action='view', author=corr.correspondent)}">${corr.correspondent}</a></li>
           </div>
           </ul>
-        <!--<h5>Letters</h5>
-          <ul>
-            <li><a href="${corr.type}/${corr.correspondent}/${corr.id}">${corr.type}/${corr.correspondent}/${corr.id}</a></li>
-          </ul>-->
-
+        </py:if>
     </div>
   </div>
 

openletters/templates/letters/view.html

 <html xmlns:py="http://genshi.edgewall.org/"
   xmlns:xi="http://www.w3.org/2001/XInclude"
   py:strip = "True">
+  
+ <py:def function="optional_head">
+   <link rel="alt" type="application/rdf+xml" href="${url(controller='letters', action='resource', author='dickens', correspondent=c.correspondent, id=c.id, type='rdf')}" title="RDF/XML version of letter" /> 
+   <link rel="alt" type="application/json" href="${url(controller='letters', action='resource', author='dickens', correspondent=c.correspondent, id=c.id, type='json')}" title="JSON version of letter" />
+   <link rel="alt" type="text/xml" href="${url(controller='letters', action='resource', author='dickens', correspondent=c.correspondent, id=c.id, type='xml')}" title="XML version of letter" />  
+ </py:def>
 
   <py:def function="page_title">Letters - View</py:def>
 
   <div py:def="content">
     <div class="letter">
       ${h.literal(h.markdown(c.letter_text))}
-      <!--<a href="../../../../data/letter_rdf/${c.id}">Rdf version</a>-->
       <p>&nbsp;</p>
       <p>Source: ${getattr(c.type, 'title', '')}<br />${getattr(c.type, 'author', '')}</p>
       <p>${getattr(c.type, 'publn_data', '')} : ${getattr(c.type, 'publn_date', '')}</p>

openletters/tests/functional/test_publisher.py

 class TestPublisherController(TestController):
 
     def test_index(self):
-        #response = self.app.get(url(controller='publisher', action='index'))
-        # Test response...
-        pass
+        response = self.app.get(url(controller='publisher', action='index'))
+        assert 'Chapman' in response

openletters/transform/sparql_funcs.py

 
 geo = Namespace('http://www.w3.org/2003/01/geo/wgs84_pos#')
 dublin_core = Namespace('http://purl.org/dc/elements/1.1/')
+letter_ns = Namespace('http://www.opencorrespondence.org/schema#')
 
 class sparql_funcs():
     
         self.g.parse(self.endpoint)
 
         for s,_,n in self.g.triples((None, dublin_core['title'], None)):
-            print "sub", s
             loc_key = urllib.unquote(n.replace("http://www.opencorrespondence.org/place/resource/", ""))
             row.add(self.__tidy_location(loc_key))
-        print "row", row
+
         return row
     
     def __tidy_location (self, location):
                 location = str(location).replace("U.s", "United States")
             ret_location = str(location).replace(".", "")    
             
-        return ret_location
+        return ret_location
+    
+    def find_correspondents(self):
+        '''
+            Function to get the distinct locations mentioned in the headers of the letters. 
+            These are the locations from which Dickens wrote. 
+            TODO: Parsing the letters to get the places mentioned in them
+        '''
+        row = set()
+        self.g.parse(self.endpoint)
+
+        for s,_,n in self.g.triples((None, letter['correspondent'], None)):
+            loc_key = urllib.unquote(n.replace("http://www.opencorrespondence.org/correspondent/resource/", ""))
+            row.add(loc_key)
+
+        return row
+    

openletters/transform/transform_json.py

     '''
     Function to return the book graph
     '''
-    def book_json (self, book_query):
+    def book_json (self, title, type):
+        books_set = {}
+        start = '';
+        end = '';
+        abstract = '';
+        uri_str = '';
+        source = '';
+
+        author = "http://www.opencorrespondence.org/author/resource/Charles%20Dickens/json"
+        books = dbase.get_book_rdf(title)
+        book_items = books.items()
+        book_items.sort()
+
+        dict = '{'
         
-        dict = '{'
+        for u, book in book_items:
 
-        for b in book_query:
-            dict +=  str(b.author) + ': [ '
-            dict += '"correspondent": "' + author
-            dict += '", "nick: "' + l
-        
+            dict +=  str(title) + ': [ '
+            dict += '"title": "' + u
+            dict += '"author": "' + author
+            dict += '", "start: "' + book[0]
+            dict += '", "end: "' + book[1]
+            dict += '", "abstract: "' + book[2]
+                     
+            if type == "book":
+               dict += '", "source: http://gutenberg.org/ebooks/"' + book[4]
+            
+            dict +=   '", "sameas: "' + u"http://dbpedia.org/page/" + book[3] 
+            
             dict += '"]'
         
         dict += '}'
-        
+
         return self.jsonify(dict)
     
     def jsonify (self, output):

openletters/transform/transform_rdf.py

         
         for url, text in letter_items:
             try:
-                correspondence = base_uri + "letters/resource/dickens/" + urllib.quote(text[1]) + '/' + str(url)
+                correspondence = base_uri + "letters/resource/dickens/" + urllib.quote(str(text[1])) + '/' + str(url)
                 self.add_author(correspondence, "Charles Dickens")
                 self.add_subject(correspondence, "letter")
                 self.add_subject(correspondence, "Charles Dickens")
             end = '';
             abstract = '';
             uri_str = '';
+            source = '';
 
-            if type == "magazine":
-                if title == "Household Words":
-                     start = u"1850-03-01"
-                     end = u"1859-05-01"
-                     abstract = u"Household Words was an English weekly magazine edited by Charles Dickens in the 1850s which took its name from the line from Shakespeare 'Familiar in his mouth as household words' - Henry V"
-                     uri_str = u"Household_Words"
-                elif title =="All the Year Round":
-                     start = u"1859-01-28"
-                     end = u"1895-03-30"
-                     abstract = u"All the Year Round was a Victorian periodical, being a British weekly literary magazine founded and owned by Charles Dickens, published between 1859 and 1895 throughout the United Kingdom. Edited by Dickens, it was the direct successor to his previous publication Household Words, abandoned due to differences with his former publisher. It hosted the serialization of many prominent novels, including Dickens' own A Tale of Two Cities. After Dickens's death in 1870, it was owned and edited by his eldest son Charles Dickens, Jr." 
-                     uri_str = u"All_the_Year_Round"
-            else:
-                books = dbase.get_book_rdf(title)
-                book_items = books.items()
-                book_items.sort()
-                
-                for u, book in book_items:
+            books = dbase.get_book_rdf(title)
+            book_items = books.items()
+            book_items.sort()
 
-                    title = u
-                    start = book[0]
-                    end = book[1]
-                    abstract = book[2]
-                    uri_str = book[3]
-                    source = book[4]
-                    #create a books dictionary as a list of records to build a list of uris from
-                    # title => uri string
-                    books_set[u] = uri_str
+            for u, book in book_items:
+
+                title = u
+                start = book[0]
+                end = book[1]
+                abstract = book[2]
+                uri_str = book[3]
+                source = book[4]
+                 #create a books dictionary as a list of records to build a list of uris from
+                 # title => uri string
+                books_set[u] = uri_str
                     
-                    if ":" in u:
-                        for bk in u.split(":"):
-                            books_set[bk[0]] = uri_str
+                if ":" in u:
+                    for bk in u.split(":"):
+                        books_set[bk[0]] = uri_str
             
-                    if "The " in u or "A " in u:
-                        aka = u.replace("The ", "").replace("A ", "")
-                        books_set[aka] = uri_str
+                if "The " in u or "A " in u:
+                    aka = u.replace("The ", "").replace("A ", "")
+                    books_set[aka] = uri_str
             
             correspondence = base_uri + type + "/resource/" + title.strip().replace(" ", "_")
             self.add_subject(correspondence, type)

openletters/transform/transform_xml.py

           
         for url, utext in letter_items:
             if type == "simile":
-                event = ET.SubElement(root, "event", {"start": str(utext[3])+'T00:00:00Z', "title": utext[1] , "link": 'http://www.opencorrespondence.org/letters/view/dickens/' + urllib.quote(utext[1]) + '/' + str(url)  })
-                event.text = unicode("Letter to " + utext[1])
+                event = ET.SubElement(root, "event", {"start": str(utext[3])+'T00:00:00Z', "title": str(utext[1]) , "link": 'http://www.opencorrespondence.org/letters/view/dickens/' + urllib.quote(str(utext[1])) + '/' + str(url)  })
+                event.text = unicode("Letter to " + str(utext[1]))
             else:
                 letter = ET.SubElement(root, "letter")
                 aurl = ET.SubElement(letter, "author")
                 date = ET.SubElement(letter, "date")
                 date.text = unicode(utext[3])
                 id = ET.SubElement(letter, "id")
-                id.text = unicode('http://www.opencorrespondence.org/letters/view/dickens/' + urllib.quote(utext[1]) + '/' + str(url))
+                id.text = unicode('http://www.opencorrespondence.org/letters/view/dickens/' + urllib.quote(str(utext[1])) + '/' + str(url))
         
         doc  = ET.tostring(root, "UTF-8")
         return doc