« December 2011 | Main | March 2012 »
February 28, 2012
Jython servlet and JSP for AJAX slide presentations
Servlet Code:
from javax.servlet.http import HttpServlet
from java.util import ArrayList
from java.util import HashMap
import re
import string
from just import just
class presentationXML(HttpServlet):
    def doGet(self,request,response):
        self.doPost (request,response)
    def doPost(self,request,response):
        response.setContentType ("text/plain")
        
        presentation_id = request.getParameter('presentation_id')
        
        presentation = self.get_presentation(presentation_id)
        
        prezs = presentation.get('rows')
        
        top_slide = prezs.get(0)
        
        request.setAttribute("top_title", top_slide['title'])
        
        request.setAttribute("top_author", top_slide['author'])
        
        request.setAttribute("top_desc", top_slide['description'])
        slides = self.get_slides(presentation_id)
        
        rows = slides.get('rows')
        
        columns = slides.get('columns')
        
        request.setAttribute("columns", columns)
        
        request.setAttribute("rows", rows)
        
        disp = request.getRequestDispatcher('presentation.xml.jsp')
        
        disp.forward(request, response)
        
    def build_slide(self, slide):
        
        title = slide['title']
        
        body = slide['body']
        slide_list = ""   
        for i in body.split("\n"):
            
            (tag, line) = i.split(':')
            
            slide_list = slide_list + "\n<" + tag + '><span class="red">»</span> ' + line + "</" + tag + ">"
        
        return {'title' : title, 'slide_list' : slide_list, 'example_url' : slide['example_url'] }
    def get_slides(self, pres_id):
        juice = just()    
        
        reply = juice.sql("select * from slides.slide where presentation_id = " + str(pres_id) + " order by sort_order asc")
        slides = []
        for row in reply['rows']:
            
            slide = self.build_slide(row)
            slides.append(slide)
        return( self.jhash(slides, ['title', 'slide_list', 'example_url' ]) )
        
    def get_presentation(self, pres_id):
        juice = just()    
        
        reply = juice.sql("select * from slides.presentation where presentation_id = " + str(pres_id) + "limit 1")
        return( self.jhash(reply['rows'], reply['columns']) )
        
    def jhash(self, rows, columns):
        
        results = HashMap()   
        
        jrows = ArrayList()
        
        jcols = ArrayList()
        
        for row in rows:
            
            res = HashMap()   
            
            for col in columns:
                
                jcols.add(col)   
                
                res.put(col, row[col])
                
            jrows.add(res)
        
        results.put('columns', jcols)
        
        results.put('rows', jrows)
            
        return results
JSP:
<?xml version="1.0" encoding="UTF-8"?>
<%@ page contentType="text/xml" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<?xml-stylesheet type="text/xsl" href="xslt/ajax-s-html.xml"?>
<ajax-s>
<pages>
<page>
<br/>
<br/>
<h2>${top_title}</h2>
    <h3>${top_desc}</h3>
    <h4><span class="red">»</span> ${top_author}</h4>
</page>
<c:forEach items="${rows}" var="row">
 <page>
    <h2>${row['title']}</h2>
    <dl>
    <c:out value="${row['slide_list']}" escapeXml="false"/>
    </dl>
    <c:if test="${row['example_url'] != ''}">
    <p style="text-align: right"><a target="__newwin" href="${row['example_url']}">e.g. <span class="red">»</span></a></p>
    </c:if>
  </page>
</c:forEach>
</pages>
</ajax-s>
DB Query Bean
import re
import string
import com.ziclix.python.sql as sql
class just:
        
    def sql(self, skewl):
        
        description, results = self.query(skewl)
        cols = []
        
        final = {}
        
        final['rows'] = []
        
        final['columns'] = []
        
        for i in description:
            
            cols.append(i[0])
        
        for i in results:
        
            row = list(i)
            
            r = {}  
            
            count = 0            
            
            for c in row:
                
                r[cols[count]] = c
                
                count = count + 1
            
            final['rows'].append(r)
        
        final['columns'] = cols
        
        return final
        
    def query(self, q):
        
        dburl, user, pw, drv = ("jdbc:postgresql://localhost:5432/roo","*****","*****","org.postgresql.Driver")
        
        db = sql.zxJDBC.connect(dburl, user, pw, drv)
        
        cursor = db.cursor()
        
        cursor.datahandler = sql.handler.PostgresqlDataHandler(cursor.datahandler)
        
        cursor.execute(q)
        columns = cursor.description
        results = cursor.fetchall()
        
        return (columns, results)
Posted by pj at 03:05 PM | Comments (0)
LOM OAI-PMH Harvester in Python
import oaipmh
import os
import re
import sys
import string
import time
import httplib
import urllib
import libxml2
from read_config import read_config
import do_sql
#from read_file import read_file
from MySQLdb.cursors import DictCursor
#from split import split
from string import split
import ConfigParser
import lom_handlers
import normalize_harvest
debug = 1
harvest = {}
repository_definitions_map = read_config('repository_definitions.ini', debug)
time.sleep(5)
# Namespaces to be stripped out from the about section and replaced with a single default one
# ie. oaiabout:
namespace_list = ['rdn_dc','dcterms','dc','meg','rdnterms']
identifier_list = []
harvest_type = ''
try:
	repository_handle =  sys.argv[1]
except:
        MissingArgumentError = "\nUsage:\n\npython %s  \n" % sys.argv[0]
        raise MissingArgumentError
try:
        harvest_type = sys.argv[2]
except:
        MissingArgumentError = "\nUsage:\n\npython %s  \n" % sys.argv[0]
        raise MissingArgumentError
def get_last_harvest_date(repository_handle):
	sql = "select max(date_format(harvest_date,'%Y-%m-%dT%H:%i:%sZ')) as last_harvest_date from harvests where harvest_type = 'daily' and repository_handle = '" + repository_handle + "'"
	response = do_sql.do_sql_query('ltsn01_harvester',sql,debug)
	do_sql.check_status(response, debug)
	results = response['results']
	return results[0]['last_harvest_date']
def get_xpath_map():
	sql = 'select * from xpath_map'
	response = do_sql.do_sql_query('ltsn01_harvester',sql,debug)
        
	do_sql.check_status(response, debug)
	results = response['results']
	return results
def do_xpath_query(xml, xpath, label, identifier):
	# We need to strip out namespaces from the about section
	# for our xpath to work, as we will be adding ones back in
	for ns in namespace_list:
		xml = string.replace(xml, ns + ':','')
		label = string.replace(label, ns + ':','')
		
		xpath = string.replace(xpath, ns + ':','oaiabout:')
	xpath = string.replace(xpath, '//about','//oaiabout:about')
	final_dict = {}
	parsed_doc = libxml2.parseDoc(xml)
	if string.find(xpath, 'oaiabout') == -1:
		#xpath_elements = split('/', xpath)
		xpath_elements = split(xpath,'/')
		xpath = ''
		del xpath_elements[0]
		del xpath_elements[0]
		nspace = '/lom:'
		for el in xpath_elements:
			xpath = xpath + nspace + el
		xpath = '/' + xpath
		xpath = string.replace(xpath, 'lom:@','@')
		xpath = string.replace(xpath, 'about:@','@')
	if debug == 1: 
		print xpath
	ctx = parsed_doc.xpathNewContext() 
	ctx.xpathRegisterNs("lom", "http://ltsc.ieee.org/xsd/LOMv1p0")
	ctx.xpathRegisterNs("oaiabout", "http://www.openarchives.org/OAI/2.0/")
	final_dict[label] = [node.content for node in ctx.xpathEval(xpath)] 
	parsed_doc.freeDoc()
	if debug == 1: 
		print final_dict
	return final_dict
def classification_parser(xml, debug):
	# Special parser for the horribly nested classification section.
	# In order to get the proper nesting we need three passes:
	# 1) Grab the classification nodes
	# 2) For each classification node parse the taxonPaths
	# 3) For each taxonPath parse out the taxons
	parsed_doc = libxml2.parseDoc(xml)
	ctx = parsed_doc.xpathNewContext()
                
	ctx.xpathRegisterNs("lom", "http://ltsc.ieee.org/xsd/LOMv1p0")
	ctx.xpathRegisterNs("xsi", "http://www.w3.org/2001/XMLSchema-instance")
	xpath="//lom:lom/lom:classification"
	class_list = [ node for node in ctx.xpathEval(xpath)]
	count = 0
	node_values = []
	for snode in class_list:
		if debug == 1: print snode.serialize()
		node_dict = {}
		new_doc = libxml2.parseDoc(snode.serialize())
		ctx = new_doc.xpathNewContext()
		xpath="//classification/purpose/source"
		node_dict['classification_purpose_source'] = [ node.content for node in ctx.xpathEval(xpath)]
		xpath="//classification/purpose/value"
		node_dict['classification_purpose_value'] = [ node.content for node in ctx.xpathEval(xpath)]
		xpath="//classification/taxonPath"
		# Serialize the node back into XML for parse once again :)
		xml_path_list = [ node.serialize() for node in ctx.xpathEval(xpath)]
		node_dict['classification_taxonPaths'] = []
		for xml_path in xml_path_list:
			path = {}
			new_new_doc = libxml2.parseDoc(xml_path)
			ctx = new_new_doc.xpathNewContext()
			xpath="//taxonPath/source/string"
			path['source_string'] = [ node.content for node in ctx.xpathEval(xpath)]
			xpath="//taxonPath/taxon/id"
			path['taxon_id'] = [ node.content for node in ctx.xpathEval(xpath)]
			xpath="//taxonPath/taxon/entry/string"
			path['taxon_entry_string'] = [ node.content for node in ctx.xpathEval(xpath)]
			node_dict['classification_taxonPaths'].append(path)		
		node_values.append(node_dict)
		count = count + 1
	return node_values
if harvest_type == 'daily':
	harvest_from = get_last_harvest_date(repository_handle)
else:
	harvest_from = '2003-01-01T00:00:00Z'
lom_handlers.clear_tables(debug)
print "\n##Going to harvest the %s repository##\n" % repository_handle
try:
	repository_definition = repository_definitions_map[repository_handle]
except:
	BadHandleExceptionMessage = "Sorry there's no such repository definition as " + repository_handle + " in repository_definitions.ini:\n" + str(repository_defs.keys())
	raise BadHandleExceptionMessage
repository_domain = repository_definition['repository_domain']
uri_path = repository_definition['uri_path']
repository_uri = "http://%s%s" % (repository_domain,uri_path)
sesh = oaipmh.ServerProxy(repository_uri)
server_id = sesh.identify()
print server_id.repositoryName()
print server_id.adminEmails()
metadata_formats = sesh.listMetadataFormats()
if debug == 1:
	for format in metadata_formats:
		print format
all_identifiers = sesh.listIdentifiers(metadataPrefix='oai_dc', from_='2003-01-01T00:00:00Z')
all_ids_list = []
for header in all_identifiers:
	this_id = header.identifier()
        all_ids_list.append(this_id)
identifiers = sesh.listIdentifiers(metadataPrefix='oai_dc', from_=harvest_from)
xpath_map = get_xpath_map()
print xpath_map
sys.exit
xpath_query_list = {}
for map in xpath_map:
	xpath_query_list[map['xpath_query']] = 1
for header in identifiers:
	this_record = {}
	print "\n\n"
	this_id = header.identifier()
	identifier_list.append(this_id)
	print "\n %s" % this_id
	time.sleep(2)
	#sesh = httplib.HTTPConnection(repository_domain)
	#sesh.connect()
	#sesh.request('GET',uri_path + '?verb=GetRecord&metadataPrefix=lom&identifier=' + this_id)
	#response = sesh.getresponse()
	response = urllib.urlopen(repository_uri + '?verb=GetRecord&metadataPrefix=lom&identifier=' + this_id)
	xml = response.read()	
	# Fix for Nik's dodgy classification section
	xml = string.replace(xml, 'taxonpath', 'taxonPath')
	neat_xml = lom_handlers.mysql_tidy(xml)
	reply = do_xpath_query(xml, '//lom/general/title/string', 'main_title', this_id)
	main_title = lom_handlers.mysql_tidy(reply['main_title'][0])
	sql = "insert into xml_store(oai_identifier,xml_document,record_main_title) values('%s','%s','%s')" % (this_id,neat_xml,main_title)
	if debug == 1: print sql
	response = do_sql.do_sql('ltsn01_harvester',sql,debug)
        
	do_sql.check_status(response, debug)
	for query in xpath_query_list.keys():
		label = query
		label = string.replace(label,'//','')
		label = string.replace(label,'oaiabout:','')
		label = string.replace(label,'/','_')
		label = string.replace(label,'@','_')
		reply = do_xpath_query(xml, query, label, this_id)
		for ns in namespace_list:
			label = string.replace(label, ns + ':','')
		this_record[label] = reply[label]
	if debug == 1: 
		print "\nThis record:\n", this_record
		time.sleep(5)
	lom_resource_id = lom_handlers.add_main_title(this_id, debug, this_record)
	lom_handlers.add_title_added_entries(lom_resource_id, debug, this_record)
	lom_handlers.add_keywords(lom_resource_id, debug, this_record)
	lom_handlers.add_ISBNs(lom_resource_id, debug, this_record)
	lom_handlers.store_poi(lom_resource_id, debug, this_record)
	lom_handlers.lom_extra_languages(lom_resource_id, debug, this_record)
	lom_handlers.add_general_value(lom_resource_id, debug, 'lom_general_description_string', 'general_description', this_record)
	lom_handlers.add_general_value(lom_resource_id, debug, 'lom_general_coverage_string', 'general_coverage', this_record)
	lom_handlers.add_general_value(lom_resource_id, debug, 'lom_technical_otherPlatformRequirements_string', 'technical_otherPlatformRequirements', this_record)
	lom_handlers.add_authors(lom_resource_id, debug, this_record)
	lom_handlers.add_about(lom_resource_id, debug, this_record)
	lom_handlers.add_publishers(lom_resource_id, debug, this_record)
	lom_handlers.add_locations(lom_resource_id, debug, this_record)
	lom_handlers.add_formats(lom_resource_id, debug, this_record)
	lom_handlers.add_lr_types(lom_resource_id, debug, this_record)
	lom_handlers.add_educational_contexts(lom_resource_id, debug, this_record)
	lom_handlers.add_general_value(lom_resource_id, debug, 'lom_educational_description_string', 'educational_description', this_record)
	lom_handlers.add_general_value(lom_resource_id, debug, 'lom_rights_description_string', 'rights_description', this_record)
	if this_record['lom_rights_copyrightAndOtherRestrictions_value']:
		if this_record['lom_rights_copyrightAndOtherRestrictions_value'][0] == 'Yes' or this_record['lom_rights_copyrightAndOtherRestrictions_value'][0] == 'yes':
			lom_handlers.add_set_value(lom_resource_id, debug, 1, 'rights_restricted')
	lom_handlers.add_relations(lom_resource_id, debug, this_record)
	class_list = []
	class_list = classification_parser(xml, debug)
	this_record['lom_classification'] = class_list
	harvest[this_id] = this_record
	if debug == 1: 
		print class_list
		time.sleep(3)
	lom_handlers.add_classification(lom_resource_id, debug, class_list)
# Put the entry in the harvests logging table
harvest_identifiers = string.join(identifier_list, '::')
all_ids = string.join(all_ids_list, '::')
if harvest_type == 'daily':
	pass
else: harvest_type = 'complete'
sql = "insert into harvests(harvest_identifiers, all_identifiers, harvest_dictionary, harvest_type, repository_handle) values('" + harvest_identifiers + "','" + all_ids + "','" + lom_handlers.mysql_tidy(str(harvest)) + "','" + harvest_type + "','" + repository_handle  + "')"
response = do_sql.do_sql('ltsn01_harvester',sql,debug)
do_sql.check_status(response, debug)
normalize_harvest.normalize_data(debug)
normalize_harvest.handle_deletions(repository_handle, debug)
    
Posted by pj at 02:54 PM | Comments (0)
Example OOP PHP Code
<?php
abstract class pid_entity{
    
    function details(){
        
        global $r;
        
        $r['dbname'] = 'uebs';
        
        $r['schema'] = 'pid';
    
        if(!$this->id){ return false; }
        
        if(!$this->table){ return false; }
    
        $reply = just::sql(sprintf('select * from %s.%s where %s_id = %d',$r['schema'] , $this->table, $this->table, $this->id));
        
        $this->details = $reply['first_row'];
        
        $this->row = $this->details;
        
        }
        
    function create(){
        
        if(!$this->table){ return false; }
        
        global $r;
        
        $r['dbname'] = 'uebs';
        
        $r['schema'] = 'pid';
        $this->id = just::add($this->table);
        
        }
    
    function set(){
        
        if(!$this->table){ return false; }
        
        global $r;
        
        $r['dbname'] = 'uebs';
        
        $r['schema'] = 'pid';
        
        if(!$this->id){ $this->create(); }
        
        $reply = just::update($this->table, $r, $this->id);
        
        $_SESSION['pid_set'] = $reply;
        
        $this->details();
        
        $this->row = $this->details;
        
        return $reply['status'];
        
        }
        
    function annotate(){
    
        global $r;
        
        $r['dbname'] = 'uebs';
        
        $r['schema'] = 'pid';
    
        $id = just::add('note');
        
        $r[$this->table.'_id'] = $this->id;
        
        $reply = just::update('note', $r, $id);
        
        return $reply['status'];
        
        }
        
    function get_notes(){
        
        global $r;
        
        $r['dbname'] = 'uebs';
        
        $r['schema'] = 'pid';
        
        $reply = just::sql(sprintf('select notes, to_timestamp(insert_date) as ts, insert_date from %s.note where expired_date is null and %s_id = %d order by insert_date desc', $r['schema'],  $this->table, $this->id ));
        
        return $reply['rows'];
        
        }
    
    }
interface pid_entity_if{
    function details();
    
    function create();
    
    function set();
    
    function add_child($object);
    
    function get_children();
    
    function calculate_start();
    
    function calculate_end();
    
    function annotate();
    
    function get_notes();
    
    }
class project extends pid_entity implements pid_entity_if{
    public $id;
    public $title;
    
    public $percent_complete;
    
    public $start_date;
    
    public $end_date;
    
    public $children;
    
    public $table = 'project';
    
    function __construct($key){
        
        if($key > 0){
            
            $this->id = $key; 
        
            $this->details();
            
            }
        
        }
    
    function add_child($object){}
        
    function get_children(){}
    
    function calculate_start(){}
    
    function calculate_end(){}
    
    }
class phase extends project{
    
    public $id;
    public $title;
    
    public $percent_complete;
    
    public $start_date;
    
    public $end_date;
    
    public $children;
    
    public $table = 'phase';
    
    function __construct($phase_id){
        
        parent::__construct($phase_id); 
        
        }
    
    }
class work_package extends project{
    
    public $id;
    public $title;
    
    public $percent_complete;
    
    public $start_date;
    
    public $end_date;
    
    public $children;
    
    public $table = 'work_package';
    
    function __construct($wp_id){
        
        parent::__construct($wp_id); 
        
        }
    
    }
class deliverable extends project{
    
    public $id;
    public $title;
    
    public $percent_complete;
    
    public $start_date;
    
    public $end_date;
    
    public $children;
    
    public $table = 'deliverable';
    
    function __construct($del_id){
        
        parent::__construct($del_id); 
        
        }
    
    }
/* End of /waf/classes/project_initiation.php */
DB Model:
    drop table if exists pid.project;
    create table pid.project
    (
    project_id serial unique not null, 
    project_type_id integer null,    
	name text null,
	purpose text null,
	background text null,
	assumptions text null,
	constraints text null,
	risks text null,
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (project_id)
    );
alter table pid.project drop project_type_id;
    drop table if exists pid.phase;
    create table pid.phase
    (
    phase_id serial unique not null, 
    phase_type_id integer null,    
	project_id integer null,
	phase_sort decimal null,
	name text null,
	description text null,
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (phase_id)
    );
alter table pid.phase drop phase_type_id;
    drop table if exists pid.work_package;
    create table pid.work_package
    (
    work_package_id serial unique not null, 
    work_package_type_id integer null,    
	phase_id integer null,
	dependent_on_package_id integer null,
	name text null,
	package_sort decimal null,
	description text null,
	start_date bigint null,
	length_days decimal null,
	completion_date bigint null,
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (work_package_id)
    );
alter table pid.work_package drop work_package_type_id;
    drop table if exists pid.staff;
    create table pid.staff
    (
    staff_id serial unique not null, 
    staff_type_id integer null,    
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (staff_id)
    );
alter table pid.staff drop staff_type_id;
    drop table if exists pid.note;
    create table pid.note
    (
    note_id serial unique not null, 
    note_type_id integer null,    
	project_id integer null,
	phase_id integer null,
	work_package_id integer null,
	notes text null,
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (note_id)
    );
alter table pid.note drop note_type_id;
    drop table if exists pid.deliverable;
    create table pid.deliverable
    (
    deliverable_id serial unique not null, 
    deliverable_type_id integer null,    
	work_package_id integer null,
	name text null,
	delivery_date bigint null,
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (deliverable_id)
    );
alter table pid.deliverable drop deliverable_type_id;
    drop table if exists pid.work_package_status;
    create table pid.work_package_status
    (
    work_package_status_id serial unique not null, 
    work_package_status_type_id integer null,    
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (work_package_status_id)
    );
        drop table if exists pid.work_package_status_type;
        create table pid.work_package_status_type
        (
        work_package_status_type_id serial unique not null,
        name text null,
        description text, 
        insert_by integer null,
        insert_date bigint null,
        update_by integer null,
        update_date bigint null,
        non_deletable boolean not null default true,
        expired_date bigint null,
        primary key (work_package_status_type_id) );
    drop table if exists pid.upload_file;
    create table pid.upload_file
    (
    upload_file_id serial unique not null, 
    upload_file_type_id integer null,    
	project_id integer null,
	phase_id integer null,
	work_package_id integer null,
	file_name text null,
	file_mime_type text null,
	file_length bigint null,
	file_data bytea null,
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key (upload_file_id)
    );
alter table pid.upload_file drop upload_file_type_id;
    drop table if exists pid.project_staff_link;   
    create table pid.project_staff_link
    (
    project_staff_link_id serial unique not null,
    project_id integer null,
    staff_id integer null,
    insert_by integer null,
    insert_date bigint null,
    update_by integer null,
    update_date bigint null,
    expired_date bigint null,
    primary key(project_staff_link_id) 
    );
Windows .ini file:
[schema] default = pid [table_list] project = 0 phase = 0 work_package = 0 staff = 0 note = 0 deliverable = 0 work_package_status = 1 upload_file = 0 [upload_file] project_id = integer phase_id = integer work_package_id = integer file_name = text file_mime_type = text file_length = bigint file_data = bytea [work_package_status] work_package_id [note] project_id = integer phase_id = integer work_package_id = integer notes = text [deliverable] work_package_id = integer name = text delivery_date = bigint [work_package] phase_id = integer dependent_on_package_id = integer name = text package_sort = decimal name = text description = text start_date = bigint length_days = decimal completion_date = bigint [project] name = text purpose = text background = text assumptions = text constraints = text risks = text [phase] project_id = integer phase_sort = decimal name = text description = text [staff] [link_tables] project:staff = 0 ;programme:course = 0
Posted by pj at 02:37 PM | Comments (0)
February 22, 2012
Request forwarding to JSP from Jython
Using JSP for HTML layout for a Jython ServletPosted by pj at 04:35 PM | Comments (0)