Skip to content

Commit

Permalink
Finished alpha release of RDFa Live Loop tool.
Browse files Browse the repository at this point in the history
  • Loading branch information
msporny committed Dec 15, 2010
1 parent 8dbf942 commit 519b1a3
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 11 deletions.
8 changes: 8 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
AddHandler mod_python .py
PythonDebug On
PythonHandler live-loop

<FilesMatch "(triples|git-update)">
SetHandler mod_python
</FilesMatch>

9 changes: 7 additions & 2 deletions css/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ padding-bottom: 50px;
.onblack {
background: #e9922a;
color: #fff;
padding-top: 50px;
padding-bottom: 30px;
padding-top: 10px;
padding-bottom: 10px;
}

.onblack h2 {
Expand Down Expand Up @@ -268,6 +268,11 @@ textarea {
width: 99%;
}

pre {
font-size: 1em;
line-height: 1em;
}

/* Provide higher res assets for iPhone 4 */

@media only screen and (-webkit-min-device-pixel-ratio: 2) {
Expand Down
1 change: 1 addition & 0 deletions git-update
17 changes: 8 additions & 9 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@
<link rel="stylesheet" href="css/smallerscreen.css" media="only screen and (max-width: 1023px)" />
<link rel="stylesheet" href="css/mobile.css" media="handheld, only screen and (max-width: 767px)" />
<link rel="stylesheet" href="css/layout.css" type="text/css" media="screen" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="live-loop.js"></script>
</head>
<body>
<body onload="liveloop.setupUi();">

<div class="titlebar">
<h1>Live Loop</h1>
</div>
<div class="container vspacing">
<div class="row">
<div class="twelvecol">
<h1>Play with RDFa.
<span class="subhead">Discover something new.</span></h1>
<h1>For Dave Lehn.
<span class="subhead">With love and hugs.</span></h1>
</div>
</div>
<div class="row">
Expand All @@ -42,7 +43,7 @@ <h1>Play with RDFa.
<pre id="code-prologue">&lt;html&gt;</pre>
<div class="row">
<form class="twelvecol last">
<textarea name="rdfa" rows="15"></textarea>
<textarea id="code-body" name="rdfa" rows="15">&lt;p property=&quot;dc:creator&quot;&gt;Alice&lt;/p&gt;</textarea>
</form>
</div>
<pre id="code-epilogue">&lt;/html&gt;</pre>
Expand All @@ -51,10 +52,8 @@ <h1>Play with RDFa.
<div class="container onblack">
<div class="row">
<div class="twelvecol">

<h2>Your data:</h2>
<p>
</p>
<div id="triple-data">
</div>
</div>
</div>
</div>
Expand Down
59 changes: 59 additions & 0 deletions live-loop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* All of the live-loop javascript code necessary to make live loop work.
*/
(function($)
{
// create the liveloop object
window.liveloop = window.liveloop || {};
var liveloop = window.liveloop;

liveloop.generateCodePrologue = function()
{
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML+RDFa 1.0//EN\" \"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:dc=\"http://purl.org/dc/terms/\">\n <head>\n <title>Test Snippet</title>\n </head>\n <body>";
}

liveloop.setupCodePrologue = function()
{
var e = $("#code-prologue");
var encodedPrologue = $('<div/>').text(liveloop.generateCodePrologue()).html();
e.html(encodedPrologue);
};

liveloop.generateCodeEpilogue = function()
{
return " </body>\n</html>";
}

liveloop.setupCodeEpilogue = function()
{
var e = $("#code-epilogue");
var encodedEpilogue = $('<div/>').text(liveloop.generateCodeEpilogue()).html();
e.html(encodedEpilogue);
};

liveloop.setupUi = function()
{
liveloop.setupCodePrologue();
liveloop.setupCodeEpilogue();
$("#code-body").keyup(liveloop.updateTriples);
};

liveloop.updateTriples = function(event)
{
var rdfaDocument = liveloop.generateCodePrologue() +
$("#code-body").val() + liveloop.generateCodeEpilogue();
$.ajax({
url: "triples",
type: "POST",
success: function(data)
{
$("#triple-data").html(data);
},
contentType: "application/xml+xhtml",
processData: false,
data: rdfaDocument
});
};

})(jQuery);

148 changes: 148 additions & 0 deletions live-loop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
##
# This is the web service for the Live Loop RDFa editor.
# License: LGPLv3
#
# @author Manu Sporny
import os, os.path, sys
import subprocess
import rdfa

try:
from mod_python import apache
except Exception, e:
pass

##
# Formats a triple in a very special way.
#
# @param request the HTTP request to use when writing the output.
# @param subject the subject of the triple.
# @param predicate the predicate for the triple.
# @param obj the object of the triple.
# @param object_type the type for the object in the triple.
# @param datatype the datatype for the object in the triple.
# @param language the language for the object in the triple.
def writeTriple2( \
request, subject, predicate, obj, object_type, datatype, language):
request.write("&lt;%s&gt; &lt;%s&gt; " % (subject, predicate))
if(object_type == rdfa.RDF_TYPE_IRI):
request.write("&lt;%s&gt; . " % (obj,))
else:
ostr = "&quot;%s&quot; ." % (obj,)
if(language != None):
ostr += "@%s" % (language,)
if(datatype != None):
ostr += "^^^<%s>" % (datatype,)
request.write(ostr)

##
# Called whenever a triple is generated for the default graph by the
# underlying implementation.
#
# @param request the HTTP request to use when writing the output.
# @param subject the subject of the triple.
# @param predicate the predicate for the triple.
# @param obj the object of the triple.
# @param object_type the type for the object in the triple.
# @param datatype the datatype for the object in the triple.
# @param language the language for the object in the triple.
def defaultTriple2( \
request, subject, predicate, obj, object_type, datatype, language):

request.write("<div class=\"rdfa-default-triple\">")
writeTriple2( \
request, subject, predicate, obj, object_type, datatype, language)
request.write("</div>")

##
# Called whenever a triple is generated for the processor graph by the
# underlying implementation.
#
# @param request the HTTP request to use when writing the output.
# @param subject the subject of the triple.
# @param predicate the predicate for the triple.
# @param obj the object of the triple.
# @param object_type the type for the object in the triple.
# @param datatype the datatype for the object in the triple.
# @param language the language for the object in the triple.
def processorTriple2( \
request, subject, predicate, obj, object_type, datatype, language):

request.write("<div class=\"rdfa-processor-triple\">")
if(object_type == rdfa.RDF_TYPE_NAMESPACE_PREFIX):
request.write("%s %s: %s ." % (subject, predicate, obj))
else:
writeTriple( \
request, subject, predicate, obj, object_type, datatype, language)
request.write("</div>")

##
# Called whenever the processing buffer for the C-side needs to be re-filled.
#
# @param data the entire file blob
# @param bufferSize the size of the buffer to return. Returning anything less
# than bufferSize will halt execution after the returned
# buffer has been processed.
def handleBuffer2(data, bufferSize):
return data.read()

##
# The handler function is what is called whenever an apache call is made.
#
# @param req the HTTP request.
#
# @return apache.OK if there wasn't an error, the appropriate error code if
# there was a failure.
def handler(req):
# File that runs an apache test.
status = apache.OK

puri = req.parsed_uri
service = puri[-3]
argstr = puri[-2]
args = {}

# Retrieve all of the unit tests from the W3C website
if(service.find("/live-loop/triples") != -1):
req.content_type = 'text/html'
if(req.method == "POST"):
document = req.read()
liveLoopDir = os.path.dirname(req.canonical_filename)
p = subprocess.Popen(["python", "live-loop.py"],
bufsize=4096, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True, cwd=liveLoopDir)
p.stdin.write(document)
(so, se) = p.communicate()
req.write(so)
else:
req.content_type = 'text/plain'
req.write("""
You can POST an XHTML+RDFa document to this service. The result will be an HTML snippet that can be placed inside of a <div> element in an HTML page.
For example, try the following using CURL:
curl -d "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?><\!DOCTYPE html PUBLIC \\"-//W3C//DTD XHTML+RDFa 1.1//EN\\" \\"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd\\"> <html xmlns=\\"http://www.w3.org/1999/xhtml\\" xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\"><head><title>Test Snippet</title></head><body><p>This HTML snippet was written by <span about=\\"\\" property=\\"dc:creator\\">Manu Sporny</span>.</p></body></html>" %s
""" % (req.construct_url(req.unparsed_uri),))
# Perform a git update in the current directory
elif(service.find("/live-loop/git-update") != -1):
testSuitePath = os.path.dirname(req.canonical_filename)
gitUpdatePath = os.path.join(testSuitePath, ".git")
p = subprocess.Popen(["git", "--git-dir", gitUpdatePath, "pull"],
bufsize=4096, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
close_fds=True, cwd=testSuitePath)
(so, se) = p.communicate()
req.write("GIT status: %s%s" % (so, se))
else:
req.content_type = 'text/html'
req.write("<strong>ERROR: Unknown Live Loop service: %s</strong>" % \
(service,))

return status

if __name__ == "__main__":
parser = rdfa.RdfaParser("http://example.com/sample.html")
parser.setDefaultGraphTripleHandler(defaultTriple2, sys.stdout)
parser.setProcessorGraphTripleHandler(processorTriple2, sys.stdout)
parser.setBufferHandler(handleBuffer2, sys.stdin)
parser.parse()

1 change: 1 addition & 0 deletions triples

0 comments on commit 519b1a3

Please sign in to comment.