Commit 32dd8b4e33b27d786b51e1dc749124c5fbaf59e3

  • avatar
  • arvind
  • Thu Jul 19 08:42:51 IST 2012
Feeds are now read and made as comment/renarration, adding 'type' field to db, moved /menu to Flask
  • server/alipi.py 118 ------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  • server/templates/feeds.html 25 --------+++++++++++++++++
  • server/ui.js 176 --------------------------------------------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  • Diff rendering mode:
  • inline
  • side by side

server/alipi.py

2from flask import Flask, request, render_template, g, redirect, jsonify, make_response2from flask import Flask, request, render_template, g, redirect, jsonify, make_response
3from bson import Code3from bson import Code
4from urllib import quote_plus, unquote_plus4from urllib import quote_plus, unquote_plus
5from lxml.html import html5parser
5import urllib2, StringIO, lxml.html, pymongo, conf, oursql6import urllib2, StringIO, lxml.html, pymongo, conf, oursql
6app = Flask(__name__)7app = Flask(__name__)
7@app.before_request8@app.before_request
5050
51 elif request.args.has_key('lang') == True and request.args.has_key('interactive') == True and request.args.has_key('blog') == False:51 elif request.args.has_key('lang') == True and request.args.has_key('interactive') == True and request.args.has_key('blog') == False:
52 setScripts()52 setScripts()
53 setSocialScript()
54 g.root.body.set("onload","a11ypi.ren();a11ypi.tweet(); a11ypi.facebook(); a11ypi.loadOverlay();")
53 if request.args['interactive'] == '1':
54 setSocialScript()
55 g.root.body.set("onload","a11ypi.ren();a11ypi.tweet(); a11ypi.facebook(); a11ypi.loadOverlay();")
56 else:
57 g.root.body.set("onload","a11ypi.ren();")
55 g.root.make_links_absolute(d['foruri'], resolve_base_href = True)58 g.root.make_links_absolute(d['foruri'], resolve_base_href = True)
56 return lxml.html.tostring(g.root)59 return lxml.html.tostring(g.root)
57 60
241 collection = g.db['post']241 collection = g.db['post']
242 lang = request.args['lang']242 lang = request.args['lang']
243 url = request.args['url']243 url = request.args['url']
244 query = collection.group(
245 key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
246 condition={"about" : url, "lang" : lang,"elementtype":"text"},
247 initial={'narration': []},
248 reduce=Code('function(doc,out){out.narration.push(doc);}')
249 )
244 if request.args['type'] == 'renarration':
245 query = collection.group(
246 key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
247 condition={"about" : url, "lang" : lang,"elementtype":"text","type":"renarration"},
248 initial={'narration': []},
249 reduce=Code('function(doc,out){out.narration.push(doc);}')
250 )
250 251
251 audio_query =collection.group(
252 key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
253 condition={"about" : url, "lang" : lang, 'elementtype':"audio/ogg"},
254 initial={'narration': []},
255 reduce=Code('function(doc,out){out.narration.push(doc);}')
256 )
252 audio_query =collection.group(
253 key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
254 condition={"about" : url, "lang" : lang, 'elementtype':"audio/ogg","type":"renarration"},
255 initial={'narration': []},
256 reduce=Code('function(doc,out){out.narration.push(doc);}')
257 )
257258
258 image_query =collection.group(
259 key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
260 condition={"about" : url, "lang" : lang, 'elementtype':"image"},
261 initial={'narration': []},
262 reduce=Code('function(doc,out){out.narration.push(doc);}')
263 )
264 try:
265 for i in audio_query:
266 query.append(i)
267 except IndexError:
268 pass
269 try:
270 for i in image_query:
271 query.append(i)
272 except IndexError:
273 pass
259 image_query =collection.group(
260 key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
261 condition={"about" : url, "lang" : lang, 'elementtype':"image", "type":"renarration"},
262 initial={'narration': []},
263 reduce=Code('function(doc,out){out.narration.push(doc);}')
264 )
265 try:
266 for i in audio_query:
267 query.append(i)
268 except IndexError:
269 pass
270 try:
271 for i in image_query:
272 query.append(i)
273 except IndexError:
274 pass
274275
276 elif request.args['type'] == 'comment':
277 query = []
278 query = collection.group(
279 key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
280 condition={"about" : url, "lang" : lang,"type":"comment"},
281 initial={'narration': []},
282 reduce=Code('function(doc,out){out.narration.push(doc);}')
283 )
275 for i in query:284 for i in query:
276 for y in i['narration']:285 for y in i['narration']:
277 del(y['_id'])286 del(y['_id'])
317 d['bxpath'] = request.form['bxpath']317 d['bxpath'] = request.form['bxpath']
318 d['xpath'] = request.form['xpath']318 d['xpath'] = request.form['xpath']
319 d['author'] = request.form['author']319 d['author'] = request.form['author']
320 d['type'] = request.form['type']
321 d['lang'] = request.form['lang']
322 d['location'] = request.form['location']
320 coll.insert(d)323 coll.insert(d)
324 if d['type'] == 'comment':
325 collection = g.db['post']
326 root = html5parser.parse(d['blog']).getroot()
327 tree = root.getroottree()
328 if tree.docinfo.doctype == '':
329 lxml.html.xhtml_to_html(root)
330 d['data'] = lxml.html.tostring(root.xpath(d['bxpath'])[0]) #TODO implement a function like lxml.html.make_links_absolute
331 collection.insert(d)
321 response = make_response()332 response = make_response()
322 response.data = repr(request.form['blog'])333 response.data = repr(request.form['blog'])
323 response.headers['Access-Control-Allow-Origin'] = '*'334 response.headers['Access-Control-Allow-Origin'] = '*'
324 return response335 return response
336
337@app.route("/menu",methods=['GET'])
338def menuForDialog():
339 if request.args.has_key('option') == False:
340 collection = g.db['post']
341 c = {}
342 cntr = 0
343 for i in collection.find({"about":request.args['url']}).distinct('lang'):
344 for j in collection.find({"about":request.args['url'],'lang':i}).distinct('type'):
345 d = {}
346 d['lang'] = i
347 d['type'] = j
348 c[cntr] = d
349 cntr += 1
350 return jsonify(c)
351 else:
352 collection = g.db['post']
353 #get the ren languages for the received url
354 langForUrl = collection.group(
355 key = Code('function(doc){return {"about" : doc.about}}'),
356 condition={"about" : d['url'],"blog":{'$regex':'/'+d['option']+'.*/'}},
357 initial={'lang': []},
358 reduce=Code('function(doc, out){if (out.lang.indexOf(doc.lang) == -1) out.lang.push(doc.lang)}') #here xpath for test
359 )
360
361 #send the response
362 if (langForUrl):
363 connection.disconnect()
364 return json.dumps(langForUrl[0]['lang'])
365
366 else:
367 connection.disconnect()
368 return "empty"
369
325370
326import logging,os371import logging,os
327from logging import FileHandler372from logging import FileHandler

server/templates/feeds.html

18 </script>18 </script>
19</head>19</head>
20<body style="text-wrap:normal">20<body style="text-wrap:normal">
21 @<input type="text" id="t1" name="author" value="author" /> says <input type="text" id="t2" name="about" value="about" /> <input type="text" id="t3" name="xpath" value="xpath" /> is related to <input type="text" id="t4" name="blog" value="blog" /> <input type="text" id="t5" name="bxpath" value="bxpath" /> <input type="submit" id="post" name="alipi" value="Feed" onclick="postForm();" />
21 @<input type="text" id="t1" name="author" value="author" /> says <input type="text" id="t2" name="about" value="about" /> <input type="text" id="t3" name="xpath" value="xpath" /> has <select id="selected" ><option>re-narrations</option><option>comment</option></select> at <input type="text" id="t4" name="blog" value="blog" /> <input type="text" id="t5" name="bxpath" value="bxpath" /> in <input type="text" name="lang" value="language" id="t6" /> targetting <input type="text" name="loc" value="location" id="t7"/> <input type="submit" id="post" name="alipi" value="Feed" onclick="postForm();" />
22<div id="feeds">22<div id="feeds">
23</div>23</div>
24<script type="text/javascript">24<script type="text/javascript">
25 function postForm()25 function postForm()
26 {26 {
27 console.log("here");
28 var arr = {};
29 arr['author'] = $('#t1').val();
30 arr['about'] = $('#t2').val();
31 arr['xpath'] = $('#t3').val();
32 arr['blog'] = $('#t4').val();
33 arr['bxpath'] = $('#t5').val();
27 var arr = {};
28 arr['author'] = $('#t1').val();
29 arr['about'] = $('#t2').val();
30 arr['xpath'] = $('#t3').val();
31 arr['blog'] = $('#t4').val();
32 arr['bxpath'] = $('#t5').val();
33 arr['type'] = $("#selected").val();
34 arr['lang'] = $('#t6').val();
35 arr['location'] = $('#t7').val();
34 $.post("http://127.0.0.1:5000/feeds/write", arr, function(data)36 $.post("http://127.0.0.1:5000/feeds/write", arr, function(data)
35 {37 {
36 alert("Posted");38 alert("Posted");
37 });39 });
38}40}
41function checkVal(){
42 if($("#selected").val() == "comment")
43 $("#post").hide();
44 else
45 $("#post").show();
46}
47
39</script>48</script>
40</body>49</body>
41</html>50</html>

server/ui.js

1//-*-coding: utf-8 -*-
1var a11ypi = {2var a11ypi = {
2 auth : " ",3 auth : " ",
3 loc:" ",4 loc:" ",
34 }34 }
35 },35 },
3636
37 createMenu: function(menu_list) {
38 var xyz = document.getElementById("show-box");
37 createMenu: function(type) {
38 var xyz = '';
39 if(type == 'renarration')
40 xyz = document.getElementById("show-box");
41 else
42 xyz = document.getElementById("show-comment");
39 xyz.innerHTML = '';43 xyz.innerHTML = '';
40 a = a11ypi.getParams();44 a = a11ypi.getParams();
41 for(var i=0;i<menu_list.length;i++)
45 for(var i in a11ypi.showbox)
42 {46 {
43 var para = document.createElement("p");
44 var newel = document.createElement("a");
45 newel.textContent = menu_list[i];
46 $(newel).attr("href",config.deploy+"/?foruri="+a['foruri']+"&lang="+menu_list[i]+"&interactive=1");
47 para.appendChild(newel);
48 xyz.appendChild(para);
47 if(a11ypi.showbox[i]['type'] == type)
48 {
49 var para = document.createElement("p");
50 var newel = document.createElement("a");
51 newel.textContent = a11ypi.showbox[i]['lang'];
52 $(newel).attr("href",config.deploy+"/?foruri="+a['foruri']+"&lang="+a11ypi.showbox[i]['lang']+"&interactive=1"+"&type="+type);
53 para.appendChild(newel);
54 xyz.appendChild(para);
55 }
49 }56 }
50 },57 },
51 58
60 if(a11ypi.flag == '0')60 if(a11ypi.flag == '0')
61 {61 {
62 a11ypi.flag = 1;62 a11ypi.flag = 1;
63 var xhr = new XMLHttpRequest();
64 xhr.onreadystatechange = function()
65 {
66 if(xhr.readyState == 4)
67 {
68 if(xhr.responseText == "empty")
69 {
70 //a11ypi.clearMenu();
71 }
72 else
73 {
74 $('#see-narration').show();
75 $("#blog-filter").show(); a11ypi.blogFilter();
76 $("#go").show();
77 a11ypi.showbox = JSON.parse(xhr.responseText);
78 }
79 }
80 }
81 xhr.open("POST",config.root+"/menu",true);
82 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
83 a = a11ypi.getParams();63 a = a11ypi.getParams();
84 xhr.send('url='+a['foruri']);
64 $.getJSON(config.deploy+'/menu?', {"url":decodeURIComponent(a['foruri'])}, function(data)
65 {
66 a11ypi.showbox = data;
67 $('#see-narration').show();
68 $("#blog-filter").show(); a11ypi.blogFilter();
69 $("#go").show();
70 });
8571
86 req = {"about":decodeURIComponent(a['foruri']), "lang":a['lang']};72 req = {"about":decodeURIComponent(a['foruri']), "lang":a['lang']};
87 $.getJSON(config.deploy+'/info?', req, function(data)73 $.getJSON(config.deploy+'/info?', req, function(data)
112 a = a11ypi.getParams();112 a = a11ypi.getParams();
113 var url = decodeURIComponent(a['foruri']);113 var url = decodeURIComponent(a['foruri']);
114 var lang = a['lang'];114 var lang = a['lang'];
115 $.getJSON(config.deploy+"/replace?",{"url":url,"lang":lang},function(data)
115 var type = a['type'];
116 $.getJSON(config.deploy+"/replace?",{"url":url,"lang":lang,"type":type},function(data)
116 {117 {
117 for(var i=0;i<data['r'].length;i++)118 for(var i=0;i<data['r'].length;i++)
118 {119 {
119 for(var x in data['r'][i]['narration'])120 for(var x in data['r'][i]['narration'])
120 {121 {
121 path = data['r'][i]['narration'][x]['xpath'];
122 newContent = data['r'][i]['narration'][x]['data'];
123 elementType = data['r'][i]['narration'][x]['elementtype'];
124 a11ypi.evaluate(path,newContent,elementType);
122 // path = data['r'][i]['narration'][x]['xpath'];
123 // newContent = data['r'][i]['narration'][x]['data'];
124 // elementType = data['r'][i]['narration'][x]['elementtype'];
125 a11ypi.evaluate(data['r'][i]['narration'][x]);
125 }126 }
126 }127 }
127 });128 });
128 },129 },
129 evaluate: function()
130 evaluate: function(a)
130 {131 {
131 try{132 try{
132 var nodes = document.evaluate(path, document, null, XPathResult.ANY_TYPE,null);
133 var nodes = document.evaluate(a['xpath'], document, null, XPathResult.ANY_TYPE,null);
133134
134 }135 }
135 catch(e)136 catch(e)
136 {137 {
137 console.log(e);138 console.log(e);
138 }139 }
139 try{
140 var result = nodes.iterateNext();
141 while (result)
142 {
143 if (elementType == 'image')
140 if(a['type'] == 'renarrration')
141 {
142 try{
143 var result = nodes.iterateNext();
144 while (result)
144 {145 {
145 if(newContent != '')
146 if (a['elementtype'] == 'image')
146 {147 {
147 result.setAttribute('src',newContent.split(',')[1]); //A hack to display images properly, the size has been saved in the database.
148 width = newContent.split(',')[0].split('x')[0];
149 height = newContent.split(',')[0].split('x')[1];
150 result.setAttribute('width',width);
151 result.setAttribute('height', height);
148 if(a['data'] != '')
149 {
150 result.setAttribute('src',a['data'].split(',')[1]); //A hack to display images properly, the size has been saved in the database.
151 width = a['data'].split(',')[0].split('x')[0];
152 height = a['data'].split(',')[0].split('x')[1];
153 result.setAttribute('width',width);
154 result.setAttribute('height', height);
155 result.setAttribute('class','blink');
156 }
157 else
158 $(result).hide();
159 }
160 else if(a['elementtype'] == 'audio/ogg')
161 {
162 a['data'] = decodeURIComponent(a['data']);
163 audio = '<audio controls="controls" src="'+a['data']+'" style="display:table;"></audio>';
164 $(result).before(audio);
152 result.setAttribute('class','blink');165 result.setAttribute('class','blink');
153 }166 }
154 else
155 $(result).hide();
156 }
157 else if(elementType == 'audio/ogg')
158 {
159 newContent = decodeURIComponent(newContent);
160 audio = '<audio controls="controls" src="'+newContent+'" style="display:table;"></audio>';
161 $(result).before(audio);
162 result.setAttribute('class','blink');
167 else{
168 result.innerHTML = a['data'];
169 result.setAttribute('class','blink');
170 }
171 result=nodes.iterateNext();
163 }172 }
164 else{
165 result.innerHTML = newContent;
166 result.setAttribute('class','blink');
167 }
168 result=nodes.iterateNext();
169 }173 }
170 }
171 catch (e)174 catch (e)
172 {175 {
173 // dump( 'error: Document tree modified during iteration ' + e );176 // dump( 'error: Document tree modified during iteration ' + e );
174 }177 }
178 }
179 else if(a['type']=='comment')
180 {
181
182 try{
183 var result = nodes.iterateNext();
184 while (result)
185 {
186 result.innerHTML = a['data'];
187 result=nodes.iterateNext();
188 }
189 }
190 catch (e)
191 {
192 //dump( 'error: Document tree modified during iteration ' + e );
193 }
194 }
175 },195 },
176 filter: function()196 filter: function()
177 {197 {
299 '<button id="edit-current" class="alipi" onclick="a11ypi.editPage();" title="Allow to edit this page">Re-narrate</button> '+299 '<button id="edit-current" class="alipi" onclick="a11ypi.editPage();" title="Allow to edit this page">Re-narrate</button> '+
300 '<button id="see-narration" class="alipi" onclick="a11ypi.showBox();" title="See other renarrations, which are in same or other languages"> '+300 '<button id="see-narration" class="alipi" onclick="a11ypi.showBox();" title="See other renarrations, which are in same or other languages"> '+
301 'Re-narrations</button>'+301 'Re-narrations</button>'+
302 '<button id="see-comment" class="alipi" onclick="a11ypi.showComment();" title="Comments"> '+
303 'Comments</button>'+
302 '<button id="see-links" class="alipi" onclick="a11ypi.showBox1();" title="See other re-narrated pages of this domain">Re-narrated Pages '+304 '<button id="see-links" class="alipi" onclick="a11ypi.showBox1();" title="See other re-narrated pages of this domain">Re-narrated Pages '+
303 '</button>'+305 '</button>'+
304 '<select id="blog-filter" class="alipi" onChange="a11ypi.checkSelect();" title="Select one of the blog name"></select>'+306 '<select id="blog-filter" class="alipi" onChange="a11ypi.checkSelect();" title="Select one of the blog name"></select>'+
305 '<button id="go" class="alipi ui-icon-circle-arrow-e" onclick="a11ypi.go();" title="Filter by blog" >|Y|</button>'+307 '<button id="go" class="alipi ui-icon-circle-arrow-e" onclick="a11ypi.go();" title="Filter by blog" >|Y|</button>'+
306 '<div id="show-box" title="Choose a narration"></div> '+308 '<div id="show-box" title="Choose a narration"></div> '+
309 '<div id="show-comment" title="Comments for"></div> '+
307 '<div id="show-links" title="List of pages narrated in this domain" class="alipi"></div> '+310 '<div id="show-links" title="List of pages narrated in this domain" class="alipi"></div> '+
308 '<div id="share-box" class="alipi" title="Share this page in any following social network"></div>';311 '<div id="share-box" class="alipi" title="Share this page in any following social network"></div>';
309 312
345 $("#outter-up-button").button({icons:{primary:"ui-icon-circle-arrow-s"},text:false}); $('#outter-up-button').children().addClass('alipi');345 $("#outter-up-button").button({icons:{primary:"ui-icon-circle-arrow-s"},text:false}); $('#outter-up-button').children().addClass('alipi');
346 $("#edit-current").button({icons:{primary:"ui-icon-pencil"}}); $('#edit-current').children().addClass('alipi');346 $("#edit-current").button({icons:{primary:"ui-icon-pencil"}}); $('#edit-current').children().addClass('alipi');
347 $("#see-narration").button({icons:{primary:"ui-icon-document-b"}}); $('#see-narration').children().addClass('alipi');347 $("#see-narration").button({icons:{primary:"ui-icon-document-b"}}); $('#see-narration').children().addClass('alipi');
348 $("#see-comment").button({icons:{primary:"ui-icon-document-b"}}); $('#see-comment').children().addClass('alipi');
348 $("#see-links").button({icons:{primary:"ui-icon-link"}}); $('#see-links').children().addClass('alipi');349 $("#see-links").button({icons:{primary:"ui-icon-link"}}); $('#see-links').children().addClass('alipi');
349 /*$("#blog-filter").button({icons:{secondary:"ui-icon-triangle-1-s"}}); */ $('#blog-filter').children().addClass('alipi');350 /*$("#blog-filter").button({icons:{secondary:"ui-icon-triangle-1-s"}}); */ $('#blog-filter').children().addClass('alipi');
350 $("#go").button({icons:{primary:"ui-icon-arrowthick-1-e"},text:false}); $('#go').children().addClass('alipi');351 $("#go").button({icons:{primary:"ui-icon-arrowthick-1-e"},text:false}); $('#go').children().addClass('alipi');
573 });573 });
574 }574 }
575 },575 },
576
577 hideAll: function() {
578 var boxes = '#show-links, #show-box, #show-comment';
579 $(boxes).dialog('close');
580 },
576 581
577 showBox: function() {582 showBox: function() {
583 this.hideAll();
578 $(document).unbind('mouseover'); // Unbind the css on mouseover584 $(document).unbind('mouseover'); // Unbind the css on mouseover
579 $(document).unbind('mouseout'); // Unbind the css on mouseout585 $(document).unbind('mouseout'); // Unbind the css on mouseout
580586
594 });594 });
595 });595 });
596 d = window.location.search.split('?')[1];596 d = window.location.search.split('?')[1];
597 var a =[];
598 for (var i = 0;i<d.split('&').length;i++){
599 a[d.split('&')[i].split('=')[0]] = d.split('&')[i].split('=')[1];
600 }
597 var a = a11ypi.getParams();
601 if (a['blog'] === undefined ) {598 if (a['blog'] === undefined ) {
602 a11ypi.createMenu(a11ypi.showbox);
599 a11ypi.createMenu('renarration');
603 }600 }
604 else {601 else {
605 $('#show-box').attr('title', 'Choose a re-narration from the blog you specified.');602 $('#show-box').attr('title', 'Choose a re-narration from the blog you specified.');
606 a11ypi.ajax1();603 a11ypi.ajax1();
607 }604 }
608 },605 },
606 showComment: function() {
607 this.hideAll();
608 $(document).unbind('mouseover'); // Unbind the css on mouseover
609 $(document).unbind('mouseout'); // Unbind the css on mouseout
610
611 $(function() {
612 $( "#show-comment" ).dialog( "destroy" );
613
614 $( "#show-comment" ).dialog({
615 width: 300,
616 height: 300,
617 modal: true
618 });
619 });
620 a11ypi.createMenu('comment');
621 },
622
609 ajaxLinks1: function() {623 ajaxLinks1: function() {
610 var xhr = new XMLHttpRequest();624 var xhr = new XMLHttpRequest();
611 xhr.onreadystatechange = function()625 xhr.onreadystatechange = function()
642 xhr.send('url='+a['foruri'])642 xhr.send('url='+a['foruri'])
643 },643 },
644 showBox1: function() {644 showBox1: function() {
645 this.hideAll();
645 $(document).unbind('mouseover'); // Unbind the css on mouseover646 $(document).unbind('mouseover'); // Unbind the css on mouseover
646 $(document).unbind('mouseout'); // Unbind the css on mouseout647 $(document).unbind('mouseout'); // Unbind the css on mouseout
647648
756 });756 });
757 },757 },
758 editPage: function() {758 editPage: function() {
759 this.hideAll();
759 a11ypi.testContext();760 a11ypi.testContext();
760 $('#pub_overlay').show(); $('#pub_overlay').addClass('barOnTop'); 761 $('#pub_overlay').show(); $('#pub_overlay').addClass('barOnTop');
761 $('#icon-down').show();762 $('#icon-down').show();