Commit 3a2f8347c150a3605ef627fba9c20c5e7a6d31e8
Many changes
- now the app sweets to sweet store
- also displays related web annotations on the web view
| | | | 1 | *.png | 1 | *.png |
---|
2 | *.*~ | 2 | *.*~ |
---|
3 | *.xml | 3 | *.xml |
---|
| | 4 | conf.py |
---|
| | | | | | 1 | SWEET_STORE_URL = 'your sweet store url here' |
---|
| | | | 13 | import json | 13 | import json |
---|
14 | import urllib | 14 | import urllib |
---|
15 | | 15 | |
---|
| | 16 | import conf |
---|
| | 17 | import sweetmaker |
---|
| | 18 | |
---|
16 | app = Flask(__name__) | 19 | app = Flask(__name__) |
---|
17 | | 20 | |
---|
| | 21 | SWEET_STORE_URL = conf.SWEET_STORE_URL |
---|
18 | | 22 | |
---|
| | 23 | |
---|
19 | @app.route('/', methods=['GET']) | 24 | @app.route('/', methods=['GET']) |
---|
20 | def index(): | 25 | def index(): |
---|
21 | if request.args.has_key('url'): | 26 | if request.args.has_key('url'): |
---|
… | | … | |
---|
65 | ret = {} | 65 | ret = {} |
---|
66 | keywords_dict = json.loads(request.args['data']) | 66 | keywords_dict = json.loads(request.args['data']) |
---|
67 | #keywords = json.loads(keywords_dict)['data'] | 67 | #keywords = json.loads(keywords_dict)['data'] |
---|
68 | for i in collection.find(): | | for i in collection.find(): |
---|
69 | for keyword in keywords_dict: | | for keyword in keywords_dict: |
---|
| | 68 | if 'nodes' in keywords_dict: | | | 69 | for i in collection.find(): |
---|
70 | try: | 70 | try: |
---|
71 | if keyword in i['nodes']: | | if keyword in i['nodes']: |
---|
72 | del(i['_id']) | | del(i['_id']) |
---|
73 | ret[y] = i | | ret[y] = i |
---|
74 | y = y + 1 | | y = y + 1 |
---|
| | 71 | if 'how' in i: | | | 72 | i['nodes'] = i['how'] |
---|
75 | except: | 73 | except: |
---|
76 | pass | 74 | pass |
---|
| | 75 | for node in keywords_dict['nodes']: |
---|
| | 76 | try: |
---|
| | 77 | if node in i['nodes']: |
---|
| | 78 | del(i['_id']) |
---|
| | 79 | ret[y] = i |
---|
| | 80 | y = y + 1 |
---|
| | 81 | except: |
---|
| | 82 | pass |
---|
| | 83 | elif 'where' in keywords_dict: |
---|
| | 84 | for i in collection.find({'uri': keywords_dict['where']}): |
---|
| | 85 | del(i['_id']) |
---|
| | 86 | ret[y] = i |
---|
| | 87 | y = y + 1 |
---|
| | 88 | for i in collection.find({'where': {'$regex':\ |
---|
| | 89 | keywords_dict['where']}}): |
---|
| | 90 | del(i['_id']) |
---|
| | 91 | ret[y] = i |
---|
| | 92 | y = y + 1 |
---|
| | 93 | |
---|
77 | return render_template('blank.html', content = ret) | 94 | return render_template('blank.html', content = ret) |
---|
78 | | 95 | |
---|
79 | | 96 | |
---|
… | | … | |
---|
103 | try: | 103 | try: |
---|
104 | for i in requestData: | 104 | for i in requestData: |
---|
105 | coll.insert(i) | 105 | coll.insert(i) |
---|
| | 106 | print 'inserted' |
---|
| | 107 | print requestData |
---|
106 | response = make_response() | 108 | response = make_response() |
---|
107 | response.headers['Access-Control-Allow-Origin'] = '*' | 109 | response.headers['Access-Control-Allow-Origin'] = '*' |
---|
108 | response.status = '200 OK' | | response.status = '200 OK' |
---|
109 | response.status_code = 200 | 110 | response.status_code = 200 |
---|
110 | return response | | return response |
---|
| | 111 | for i in requestData: | | | 112 | del(i['_id']) |
---|
| | 113 | i['how'] = '{concepts: ' + ', '.join(i['how']) + '}' |
---|
| | 114 | #i['how'] = attribs |
---|
| | 115 | print 'payload for sweet' |
---|
| | 116 | print requestData |
---|
| | 117 | sweetmaker.sweet(SWEET_STORE_URL, requestData) |
---|
111 | except: | 118 | except: |
---|
112 | response = make_response() | 119 | response = make_response() |
---|
113 | response.status = "500" | | response.status = "500" |
---|
| | 120 | response.status_code = 500 | 114 | response.data = "Your post could not be saved. Try posting again." | 121 | response.data = "Your post could not be saved. Try posting again." |
---|
115 | return response | | return response |
---|
116 | | 122 | |
---|
| | 123 | return response |
---|
| | 124 | |
---|
| | 125 | |
---|
117 | @app.route('/web/', methods=['GET']) | 126 | @app.route('/web/', methods=['GET']) |
---|
118 | def web(): | 127 | def web(): |
---|
119 | return render_template('web.html') | 128 | return render_template('web.html') |
---|
… | | … | |
---|
147 | | 147 | |
---|
148 | # inject the JS toolbar to annotate text | 148 | # inject the JS toolbar to annotate text |
---|
149 | jq = root.makeelement('script') | 149 | jq = root.makeelement('script') |
---|
150 | jq.set('src', 'static/jquery-1.9.1.min.js') | | jq.set('src', 'static/jquery-1.9.1.min.js') |
---|
| | 150 | jq.set('src', '/static/jquery-1.9.1.min.js') | 151 | | 151 | |
---|
152 | script = root.makeelement('script') | 152 | script = root.makeelement('script') |
---|
153 | script.set('src', 'static/text-annotation.js') | | script.set('src', 'static/text-annotation.js') |
---|
| | 153 | script.set('src', '/static/text-annotation.js') | 154 | | 154 | |
---|
155 | tree = root.makeelement('script') | 155 | tree = root.makeelement('script') |
---|
156 | tree.set('src', 'static/tree.js') | | tree.set('src', 'static/tree.js') |
---|
| | 156 | tree.set('src', '/static/tree.js') | 157 | | 157 | |
---|
158 | bs_js = root.makeelement('script') | 158 | bs_js = root.makeelement('script') |
---|
159 | bs_js.set('src', 'static/bootstrap.js') | | bs_js.set('src', 'static/bootstrap.js') |
---|
| | 159 | bs_js.set('src', '/static/bootstrap.js') | 160 | | 160 | |
---|
161 | jit = root.makeelement('script') | 161 | jit = root.makeelement('script') |
---|
162 | jit.set('src', 'static/jit.js') | | jit.set('src', 'static/jit.js') |
---|
| | 162 | jit.set('src', '/static/jit.js') | 163 | | 163 | |
---|
164 | us = root.makeelement('script') | 164 | us = root.makeelement('script') |
---|
165 | us.set('src', 'static/underscore-min-1.4.4.js') | | us.set('src', 'static/underscore-min-1.4.4.js') |
---|
| | 165 | us.set('src', '/static/underscore-min-1.4.4.js') | 166 | | 166 | |
---|
167 | link = root.makeelement('link') | 167 | link = root.makeelement('link') |
---|
168 | link.set('href', 'static/text-annotation.css') | | link.set('href', 'static/text-annotation.css') |
---|
| | 168 | link.set('href', '/static/text-annotation.css') | 169 | link.set('type', 'text/css') | 169 | link.set('type', 'text/css') |
---|
170 | link.set('rel', 'stylesheet') | 170 | link.set('rel', 'stylesheet') |
---|
171 | | 171 | |
---|
172 | bs = root.makeelement('link') | 172 | bs = root.makeelement('link') |
---|
173 | bs.set('href', 'static/bootstrap.css') | | bs.set('href', 'static/bootstrap.css') |
---|
| | 173 | bs.set('href', '/static/bootstrap.css') | 174 | bs.set('type', 'text/css') | 174 | bs.set('type', 'text/css') |
---|
175 | bs.set('rel', 'stylesheet') | 175 | bs.set('rel', 'stylesheet') |
---|
176 | | 176 | |
---|
177 | tree_css = root.makeelement('link') | 177 | tree_css = root.makeelement('link') |
---|
178 | tree_css.set('href', 'static/tree.css') | | tree_css.set('href', 'static/tree.css') |
---|
| | 178 | tree_css.set('href', '/static/tree.css') | 179 | tree_css.set('type', 'text/css') | 179 | tree_css.set('type', 'text/css') |
---|
180 | tree_css.set('rel', 'stylesheet') | 180 | tree_css.set('rel', 'stylesheet') |
---|
181 | | 181 | |
---|
| | | | 77 | "test", | 77 | "test", |
---|
78 | feature.geometry.getBounds().getCenterLonLat(), | 78 | feature.geometry.getBounds().getCenterLonLat(), |
---|
79 | new OpenLayers.Size(640,480), | 79 | new OpenLayers.Size(640,480), |
---|
80 | '<iframe src='+config.indexer+"/search?data="+JSON.stringify(ans.ans[i]["nodes"])+" ></iframe>",null,true); | | '<iframe src='+config.indexer+"/search?data="+JSON.stringify(ans.ans[i]["nodes"])+" ></iframe>",null,true); |
---|
| | 80 | '<iframe src='+config.indexer+"/search?data="+JSON.stringify({'nodes': ans.ans[i]["nodes"]})+" ></iframe>",null,true); | 81 | feature.popup = z; | 81 | feature.popup = z; |
---|
82 | z.panMapIfOutOfView = true; | 82 | z.panMapIfOutOfView = true; |
---|
83 | map.addPopup(z); | 83 | map.addPopup(z); |
---|
| | | | 35 | //$(document).mouseover(onHover); | 35 | //$(document).mouseover(onHover); |
---|
36 | //$(document).mouseout(onHoverOut); | 36 | //$(document).mouseout(onHoverOut); |
---|
37 | }; | 37 | }; |
---|
| | 38 | window.listAnno = function() { // list annotations of current page |
---|
| | 39 | console.log('listing annotations'); |
---|
| | 40 | $.get(config.indexer + '/search?data=' + |
---|
| | 41 | JSON.stringify({'where': window.location.search.split('url=')[1]}), |
---|
| | 42 | function(data) { |
---|
| | 43 | //console.log(data); |
---|
| | 44 | $('#list-anno .modal-body').html(data); |
---|
| | 45 | $('#list-anno').modal(); |
---|
| | 46 | }); |
---|
| | 47 | }; |
---|
| | 48 | |
---|
38 | var removeSelect = function() { | 49 | var removeSelect = function() { |
---|
39 | var nodes = document.getElementsByTagName('*'); | 50 | var nodes = document.getElementsByTagName('*'); |
---|
40 | var bar = document.getElementById('annotate-bar'); | 51 | var bar = document.getElementById('annotate-bar'); |
---|
… | | … | |
---|
67 | '<li><a></a></li>'+ | 67 | '<li><a></a></li>'+ |
---|
68 | '<li><button class="btn" id="anno-btn" onclick="initSelect();">Annotate</button></li>' + | 68 | '<li><button class="btn" id="anno-btn" onclick="initSelect();">Annotate</button></li>' + |
---|
69 | '<li><a></a></li>'+ | 69 | '<li><a></a></li>'+ |
---|
| | 70 | '<li><button class="btn" id="list-anno-btn" onclick="listAnno();">Annotations</button></li>' + |
---|
| | 71 | '<li><a></a></li>'+ |
---|
70 | '<li><button class="btn" id="publish">Publish</button></li>' + | 72 | '<li><button class="btn" id="publish">Publish</button></li>' + |
---|
71 | '</ul></div></div>' + | 73 | '</ul></div></div>' + |
---|
72 | '<div id="sweeted"></div> <div id="posted"></div> <div id="fail-posting"></div>'; | | '<div id="sweeted"></div> <div id="posted"></div> <div id="fail-posting"></div>'; |
---|
| | 74 | '<div id="sweeted"></div> <div id="posted"></div> <div id="fail-posting"></div>'+ | | | 75 | '<div id="list-anno" class="modal hide fade" role="dialog" aria-labelledby="list-anno-label" aria-hidden="true">'+ |
---|
| | 76 | ' <div class="modal-header">'+ |
---|
| | 77 | ' <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'+ |
---|
| | 78 | ' <h3>Annotations</h3>'+ |
---|
| | 79 | ' </div>'+ |
---|
| | 80 | ' <div class="modal-body">'+ |
---|
| | 81 | ' </div>'+ |
---|
| | 82 | ' <div class="modal-footer">'+ |
---|
| | 83 | ' <a href="#" class="btn" data-dismiss="modal" aria-hidden="true">Close</a>'+ |
---|
| | 84 | ' </div>'+ |
---|
| | 85 | '</div>'; |
---|
73 | }; | 86 | }; |
---|
74 | | 87 | |
---|
75 | var modal_template = function() { | 88 | var modal_template = function() { |
---|
| | | | 162 | window.location.href; | 162 | window.location.href; |
---|
163 | resource = decodeURIComponent(resource).replace('"', '', 'gi'); | 163 | resource = decodeURIComponent(resource).replace('"', '', 'gi'); |
---|
164 | var data = { | 164 | var data = { |
---|
165 | user: user, | | user: user, |
---|
166 | type: this.type, | | type: this.type, |
---|
167 | uri: resource, | | uri: resource, |
---|
168 | nodes: this.nodes, | | nodes: this.nodes, |
---|
| | 165 | who: user, | | | 166 | what: this.type, |
---|
| | 167 | where: resource, |
---|
| | 168 | how: this.nodes, |
---|
169 | name: attribs.name | 169 | name: attribs.name |
---|
170 | }; | 170 | }; |
---|
171 | if(attribs.hasOwnProperty('top') && | 171 | if(attribs.hasOwnProperty('top') && |
---|
172 | attribs.hasOwnProperty('bottom') && | 172 | attribs.hasOwnProperty('bottom') && |
---|
173 | attribs.hasOwnProperty('right') && | 173 | attribs.hasOwnProperty('right') && |
---|
174 | attribs.hasOwnProperty('left')) { | 174 | attribs.hasOwnProperty('left')) { |
---|
175 | data.top = attribs.top; | | data.top = attribs.top; |
---|
176 | data.bottom = attribs.bottom; | | data.bottom = attribs.bottom; |
---|
177 | data.left = attribs.left; | | data.left = attribs.left; |
---|
178 | data.right = attribs.right; | | data.right = attribs.right; |
---|
| | 175 | | | | 176 | data.where += '#[' + attribs.top + |
---|
| | 177 | ',' + attribs.bottom + |
---|
| | 178 | ',' + attribs.left + |
---|
| | 179 | ',' + attribs.right + ']'; |
---|
179 | } | 180 | } |
---|
180 | if(attribs.hasOwnProperty('xpath')) { | 181 | if(attribs.hasOwnProperty('xpath')) { |
---|
181 | data.xpath = attribs.xpath; | | data.xpath = attribs.xpath; |
---|
| | 182 | data.where += '#' + attribs.xpath; | 182 | } | 183 | } |
---|
183 | this.swts.push(data); | 184 | this.swts.push(data); |
---|
184 | this.nodes = []; | 185 | this.nodes = []; |
---|
… | | … | |
---|
194 | url: config.indexer + '/submit', | 194 | url: config.indexer + '/submit', |
---|
195 | data: {'data': JSON.stringify(this.swts)}, | 195 | data: {'data': JSON.stringify(this.swts)}, |
---|
196 | success: function() { | 196 | success: function() { |
---|
197 | /*$.ajax({ | | /*$.ajax({ |
---|
198 | type: 'POST', | | type: 'POST', |
---|
199 | url: config.postTweetUrl, | | url: config.postTweetUrl, |
---|
200 | data: {'data': JSON.stringify(this.swts)}, | | data: {'data': JSON.stringify(this.swts)}, |
---|
201 | success: function() { | | success: function() { |
---|
202 | $('#posted').show(); | | $('#posted').show(); |
---|
203 | this.swts = []; | | this.swts = []; |
---|
204 | }, | | }, |
---|
205 | error: function() { | | error: function() { |
---|
206 | $('#fail-posting').show(); | | $('#fail-posting').show(); |
---|
207 | } | | } |
---|
208 | });*/ | | });*/ |
---|
209 | //$('#posted').html(posted_template()); | | //$('#posted').html(posted_template()); |
---|
210 | //$('#posted').show(); | | //$('#posted').show(); |
---|
211 | var swts = ''; | 197 | var swts = ''; |
---|
212 | for(var i in sweet.swts) { | 198 | for(var i in sweet.swts) { |
---|
213 | var data = sweet.swts[i]; | 199 | var data = sweet.swts[i]; |
---|
214 | console.log(data); | 200 | console.log(data); |
---|
215 | var swt = '@'+data.user+' '+data.type+' '+data.uri; | | var swt = '@'+data.user+' '+data.type+' '+data.uri; |
---|
216 | if(data.hasOwnProperty('xpath')) { | | if(data.hasOwnProperty('xpath')) { |
---|
217 | swt += ' xpath: '+data.xpath; | | swt += ' xpath: '+data.xpath; |
---|
218 | } | | } |
---|
219 | if(data.hasOwnProperty('top')) { | | if(data.hasOwnProperty('top')) { |
---|
220 | swt += ' #['+data.top+','+data.right+','+data.bottom+','+data.left+']'; | | swt += ' #['+data.top+','+data.right+','+data.bottom+','+data.left+']'; |
---|
221 | } | | } |
---|
222 | swt += ' ' + data.nodes.join(); | | swt += ' ' + data.nodes.join(); |
---|
| | 201 | var swt = '@'+data.who+' #'+data.what+' / '+data.where; | | | 202 | swt += ' {' + data.how.join() + ' }'; |
---|
223 | swts += swt + '\n'; | 203 | swts += swt + '\n'; |
---|
224 | } | 204 | } |
---|
225 | console.log(swts); | 205 | console.log(swts); |
---|
| | | | | | 1 | # SwtMaker |
---|
| | 2 | # ------- |
---|
| | 3 | # Server-side component to make sweets and post them to specified |
---|
| | 4 | # sweet store |
---|
| | 5 | # |
---|
| | 6 | # License: BSD, see LICENSE for more details. |
---|
| | 7 | # Servelots 2013 |
---|
| | 8 | # Authors: |
---|
| | 9 | # Arvind Khadri <arvind@servelots.com> |
---|
| | 10 | # Anon Ray <rayanon@servelots.com> |
---|
| | 11 | |
---|
| | 12 | import requests |
---|
| | 13 | import json |
---|
| | 14 | from datetime import datetime |
---|
| | 15 | |
---|
| | 16 | TIMESTAMP_FORMAT = '%d-%m-%Y %H:%M:%S' |
---|
| | 17 | |
---|
| | 18 | def sweet(sweet_url, sweet_list): |
---|
| | 19 | sweets = makeSweet(sweet_list) |
---|
| | 20 | if not sweets: |
---|
| | 21 | return False |
---|
| | 22 | else: |
---|
| | 23 | request = requests.api.post(sweet_url, {'data': json.dumps(sweets)}) |
---|
| | 24 | if request.status_code == 200: |
---|
| | 25 | return True |
---|
| | 26 | else: |
---|
| | 27 | return False |
---|
| | 28 | |
---|
| | 29 | def makeSweet(sweet_list): |
---|
| | 30 | for sweet in sweet_list: |
---|
| | 31 | if len(sweet['who']) and len(sweet['what']) and len(sweet['where'])\ |
---|
| | 32 | and len(sweet['how']): |
---|
| | 33 | sweet['created'] = datetime.utcnow().strftime(TIMESTAMP_FORMAT) |
---|
| | 34 | else: |
---|
| | 35 | return False |
---|
| | 36 | return sweet_list |
---|
| | | | 1 | {% for obj in content %} | 1 | {% for obj in content %} |
---|
2 | <div> | | <div> |
---|
| | 2 | <div class="well"> | 3 | {% for key in content[obj].keys() %} | 3 | {% for key in content[obj].keys() %} |
---|
4 | <p>{{ key }}: {{ content[obj][key] }}</p> | | <p>{{ key }}: {{ content[obj][key] }}</p> |
---|
| | 4 | <p><b>{{ key }}</b>: {{ content[obj][key] }}</p> | 5 | {% endfor %} | 5 | {% endfor %} |
---|
6 | </div> | 6 | </div> |
---|
7 | {% endfor %} | 7 | {% endfor %} |
---|
| | | | 4 | <meta charset="utf-8"> | 4 | <meta charset="utf-8"> |
---|
5 | <meta http-equiv='imagetoolbar' content='no'/> | 5 | <meta http-equiv='imagetoolbar' content='no'/> |
---|
6 | <title> Web Annotation </title> | 6 | <title> Web Annotation </title> |
---|
7 | <link rel="stylesheet" type="text/css" href="static/bootstrap.css"></link> | | <link rel="stylesheet" type="text/css" href="static/bootstrap.css"></link> |
---|
8 | <script type="text/javascript" src="static/jquery-1.9.1.min.js"></script> | | <script type="text/javascript" src="static/jquery-1.9.1.min.js"></script> |
---|
9 | <script type="text/javascript" src="static/bootstrap.js"></script> | | <script type="text/javascript" src="static/bootstrap.js"></script> |
---|
| | 7 | <link rel="stylesheet" type="text/css" href="/static/bootstrap.css"></link> | | | 8 | <script type="text/javascript" src="/static/jquery-1.9.1.min.js"></script> |
---|
| | 9 | <script type="text/javascript" src="/static/bootstrap.js"></script> |
---|
10 | <style type="text/css"> | 10 | <style type="text/css"> |
---|
11 | .container { | 11 | .container { |
---|
12 | margin-top: 30px; | 12 | margin-top: 30px; |
---|