1
#-*-coding: utf-8 -*-
2
from flask import Flask, request, render_template, g, redirect, jsonify, make_response
3
from bson import Code
4
from urllib import quote_plus, unquote_plus
5
import urllib2, StringIO, lxml.html, pymongo, conf, oursql
6
app = Flask(__name__)
7
@app.before_request
8
def first():
9
    g.connection = pymongo.Connection('localhost',27017) #Create the object once and use it.
10
    g.db = g.connection[conf.MONGODB[0]]
11
@app.teardown_request
12
def close(exception):
13
    g.connection.disconnect()
14
@app.route('/')
15
def start_page() :
16
    d = {}
17
    d['foruri'] = request.args['foruri']
18
    myhandler1 = urllib2.Request(d['foruri'],headers={'User-Agent':"Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"}) #A fix to send user-agents, so that sites render properly.
19
    try:
20
        a = urllib2.urlopen(myhandler1)
21
        if a.geturl() != d['foruri']:
22
            return "There was a server redirect, please click on the <a href='http://dev.a11y.in/web?foruri={0}'>link</a> to continue.".format(quote_plus(a.geturl()))
23
        else:
24
            page = a.read()
25
            a.close()
26
    except ValueError:
27
        return "The link is malformed, click <a href='http://dev.a11y.in/web?foruri={0}&lang={1}&interactive=1'>here</a> to be redirected.".format(quote_plus(unquote_plus(d['foruri'].encode('utf-8'))),request.args['lang'])
28
    except urllib2.URLError:
29
        return render_template('error.html')
30
    try:
31
        page = unicode(page,'utf-8')  #Hack to fix improperly displayed chars on wikipedia.
32
    except UnicodeDecodeError:
33
        pass #Some pages may not need be utf-8'ed
34
    try:
35
        g.root = lxml.html.parse(StringIO.StringIO(page)).getroot()
36
    except ValueError:
37
        g.root = lxml.html.parse(d['foruri']).getroot() #Sometimes creators of the page lie about the encoding, thus leading to this execption. http://lxml.de/parsing.html#python-unicode-strings
38
    if request.args.has_key('lang') == False and request.args.has_key('blog') == False:
39
        g.root.make_links_absolute(d['foruri'], resolve_base_href = True)
40
        for i in g.root.iterlinks():
41
            if i[1] == 'href' and i[0].tag != 'link':
42
                try:
43
                    i[0].attrib['href'] = 'http://{0}?foruri={1}'.format(conf.DEPLOYURL[0],quote_plus(i[0].attrib['href']))
44
                except KeyError:
45
                    i[0].attrib['href'] = '{0}?foruri={1}'.format(conf.DEPLOYURL[0],quote_plus(i[0].attrib['href'].encode('utf-8')))
46
        setScripts() 
47
        g.root.body.set("onload","a11ypi.loadOverlay();")
48
        return lxml.html.tostring(g.root)
49
50
    elif request.args.has_key('lang') == True and request.args.has_key('interactive') == True and request.args.has_key('blog') == False:
51
        setScripts()
52
        setSocialScript()
53
        g.root.body.set("onload","a11ypi.ren();a11ypi.tweet(); a11ypi.facebook(); a11ypi.loadOverlay();")
54
        g.root.make_links_absolute(d['foruri'], resolve_base_href = True)
55
        return lxml.html.tostring(g.root)
56
        
57
    elif request.args.has_key('lang') == True and request.args.has_key('blog') == False:
58
        script_jq_mini = g.root.makeelement('script')
59
        g.root.body.append(script_jq_mini)
60
        script_jq_mini.set("src", conf.JQUERYURL[0] + "/jquery-1.7.min.js")
61
        script_jq_mini.set("type", "text/javascript")
62
        d['lang'] = request.args['lang']
63
        script_test = g.root.makeelement('script')
64
        g.root.body.append(script_test)
65
        script_test.set("src", conf.APPURL[0] + "/server/ui.js")
66
        script_test.set("type", "text/javascript")
67
        g.root.body.set("onload","a11ypi.ren()");
68
        return lxml.html.tostring(g.root)
69
70
    elif request.args.has_key('interactive') == True and request.args.has_key('blog') == True and request.args.has_key('lang') == True:
71
        setScripts()
72
        setSocialScript()
73
        g.root.body.set("onload","a11ypi.filter(); a11ypi.tweet(); a11ypi.facebook(); a11ypi.loadOverlay();");
74
        g.root.make_links_absolute(d['foruri'], resolve_base_href = True)
75
        return lxml.html.tostring(g.root)
76
77
    elif request.args.has_key('interactive') == False and request.args.has_key('blog') == True:    
78
        setScripts()
79
        g.root.make_links_absolute(d['foruri'], resolve_base_href = True)
80
        g.root.body.set('onload', 'a11ypi.loadOverlay();')
81
        return lxml.html.tostring(g.root)
82
83
def setScripts():
84
    script_test = g.root.makeelement('script')
85
    script_edit = g.root.makeelement('script')
86
    g.root.body.append(script_test)
87
    g.root.body.append(script_edit)
88
    script_test.set("src", conf.APPURL[0] + "/server/ui.js")
89
    script_test.set("type", "text/javascript")
90
    script_edit.set("src", conf.APPURL[0] + "/server/wsgi/pageEditor.js")
91
    script_edit.set("type","text/javascript")
92
    script_config = g.root.makeelement('script')
93
    g.root.body.append(script_config)
94
    script_config.set("src", conf.APPURL[0] + "/server/config.js")
95
    script_config.set("type", "text/javascript")
96
97
    
98
    script_jq_mini = g.root.makeelement('script')
99
    g.root.body.append(script_jq_mini)
100
    script_jq_mini.set("src", conf.JQUERYURL[0] + "/jquery-1.7.min.js")
101
    script_jq_mini.set("type", "text/javascript")
102
    
103
    style = g.root.makeelement('link')
104
    g.root.body.append(style)
105
    style.set("rel","stylesheet")
106
    style.set("type", "text/css")
107
    style.set("href", conf.APPURL[0] + "/server/stylesheet.css")
108
109
    script_jq_cust = g.root.makeelement('script')
110
    g.root.body.append(script_jq_cust)
111
    script_jq_cust.set("src", conf.JQUERYUI[0] + "/jquery-ui.min.js")
112
    script_jq_cust.set("type", "text/javascript")
113
114
    style_cust = g.root.makeelement('link')
115
    style_cust.set("rel","stylesheet")
116
    style_cust.set("type", "text/css")
117
    style_cust.set("href", conf.JQUERYCSS[0] + "/jquery-ui.css")
118
    g.root.body.append(style_cust)
119
    
120
def setSocialScript():
121
    info_button = g.root.makeelement('button')
122
    g.root.body.append(info_button)
123
    info_button.set("id", "info")
124
    info_button.set("class", "alipi")
125
    info_button.set("onClick", "a11ypi.showInfo(a11ypi.responseJSON);")
126
    info_button.text =  "Info"
127
    info_button.set("title", "Have a look at the information of each renarrated element")
128
    
129
    share_button = g.root.makeelement('button')
130
    g.root.body.append(share_button)
131
    share_button.set("id", "share")
132
    share_button.set("class", "alipi")
133
    share_button.set("onClick", "a11ypi.share();")
134
    share_button.text =  "Share"
135
    share_button.set("title", "Share your contribution in your social network")
136
    
137
    see_orig = g.root.makeelement('button')
138
    g.root.body.append(see_orig)
139
    see_orig.set("id", "orig-button")
140
    see_orig.set("class", "alipi")
141
    see_orig.set("onClick", "a11ypi.showOriginal();")
142
    see_orig.text = "Original Page"
143
    see_orig.set("title", "Go to Original link, the original page of this renarrated")
144
    
145
    tweetroot = g.root.makeelement("div")
146
    tweetroot.set("id", "tweet-root")
147
    tweetroot.set("class", "alipi")
148
    tweetroot.set("style", "display:none;padding:10px;")
149
    g.root.body.append(tweetroot)
150
151
    tweet = g.root.makeelement("a")
152
    tweet.set("id", "tweet")
153
    tweet.set("href", "https://twitter.com/share")
154
    tweet.set("class", "alipi twitter-share-button")
155
    tweet.set("data-via", "a11ypi")
156
    tweet.set("data-lang", "en")
157
    tweet.set("data-url", "http://dev.a11y.in/web?foruri={0}&lang={1}&interactive=1".format(quote_plus(request.args['foruri']),request.args['lang']))
158
    tweet.textContent = "Tweet"
159
    tweetroot.append(tweet)
160
161
    fblike = g.root.makeelement("div")
162
    fblike.set("id", "fb-like")
163
    fblike.set("class", "alipi fb-like")
164
    fblike.set("style", "display:none;padding:10px;")
165
    fblike.set("data-href", "http://dev.a11y.in/web?foruri={0}&lang={1}&interactive=1".format(quote_plus(request.args['foruri']),request.args['lang']))
166
    fblike.set("data-send", "true")
167
    fblike.set("data-layout", "button_count")
168
    fblike.set("data-width", "50")
169
    fblike.set("data-show-faces", "true")
170
    fblike.set("data-font", "arial")
171
    g.root.body.append(fblike)
172
    
173
    style = g.root.makeelement('link')
174
    g.root.body.append(style)
175
    style.set("rel","stylesheet")
176
    style.set("type", "text/css")
177
    style.set("href", "http://dev.a11y.in/server/stylesheet.css")
178
179
    
180
@app.route('/directory')
181
def show_directory():
182
    collection = g.db['post']
183
    query = collection.group(
184
        key = Code('function(doc){return {"about" : doc.about,"lang":doc.lang}}'),
185
        condition={"about":{'$regex':'^[/\S/]'}},
186
        initial={'na': []},
187
        reduce=Code('function(doc,out){out.na.push(doc.blog)}')
188
        )
189
    query.reverse()
190
    return render_template('directory.html', name=query, mymodule = quote_plus, myset=set, mylist= list)
191
192
@app.route('/getLoc', methods=['GET'])
193
def get_loc():
194
195
    term = request.args['term']
196
    connection = oursql.Connection(conf.DBHOST[0],conf.DBUSRNAME[0],conf.DBPASSWD[0],db=conf.DBNAME[0])
197
    cursor = connection.cursor(oursql.DictCursor)
198
    cursor.execute('select l.name, c.country_name from `location` as l, `codes` as c where l.name like ? and l.code=c.code limit ?', (term+'%', 5))
199
    r = cursor.fetchall()
200
    connection.close()
201
    d = {}
202
    d['return'] = r
203
    response = jsonify(d)
204
    response.headers['Access-Control-Allow-Origin'] = '*'
205
    return response
206
@app.route('/getLang', methods=['GET'])
207
def get_lang():
208
    term = request.args['term']
209
    connection = oursql.Connection(conf.DBHOST[0],conf.DBUSRNAME[0],conf.DBPASSWD[0],db=conf.DBNAME[0])
210
    cursor = connection.cursor(oursql.DictCursor)
211
    cursor.execute('select * from `languages` as l  where l.name like ? limit ?', (term+'%',5))
212
    r = cursor.fetchall()
213
    connection.close()
214
    d = {}
215
    d['return'] = r
216
    response = jsonify(d)
217
    response.headers['Access-Control-Allow-Origin'] = '*'
218
    return response
219
@app.route('/blank', methods=['GET'])
220
def serve_blank():
221
    return render_template('blank.html')
222
223
@app.route('/info', methods=['GET'])
224
def serve_info():
225
    coll = g.db['post']
226
    d = {}
227
    cntr = 0
228
    for i in coll.find({"about":unquote_plus(request.args['about']),"lang":request.args['lang']}):
229
        i['_id'] = str(i['_id'])
230
        d[cntr] = i
231
        cntr+=1
232
    response = jsonify(d)
233
    response.headers['Access-Control-Allow-Origin'] = '*'
234
    return response
235
@app.route("/replace", methods=['GET'])
236
def replace():
237
    collection = g.db['post']
238
    lang = request.args['lang']
239
    url = request.args['url']
240
    query = collection.group(
241
        key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
242
        condition={"about" : url, "lang" : lang,"elementtype":"text"},
243
        initial={'narration': []},
244
        reduce=Code('function(doc,out){out.narration.push(doc);}') 
245
        )
246
    
247
    audio_query =collection.group(
248
        key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
249
        condition={"about" : url, "lang" : lang, 'elementtype':"audio/ogg"},
250
        initial={'narration': []},
251
        reduce=Code('function(doc,out){out.narration.push(doc);}') 
252
        )
253
254
    image_query =collection.group(
255
        key = Code('function(doc){return {"xpath" : doc.xpath, "about": doc.url}}'),
256
        condition={"about" : url, "lang" : lang, 'elementtype':"image"},
257
        initial={'narration': []},
258
        reduce=Code('function(doc,out){out.narration.push(doc);}') 
259
        )
260
    try:
261
        for i in audio_query:
262
            query.append(i)
263
    except IndexError:
264
        pass
265
    try:
266
        for i in image_query:
267
            query.append(i)
268
    except IndexError:
269
        pass
270
271
    for i in query:
272
        for y in i['narration']:
273
            del(y['_id'])
274
    d = {}
275
    d['r'] = query
276
    response = jsonify(d)
277
    response.headers['Access-Control-Allow-Origin'] = '*'
278
    return response
279
280
@app.route('/feeds', methods=['GET'])
281
def serve_feed_temp():
282
    return render_template("feeds.html")
283
284
@app.route('/feed', methods=['GET'])
285
def serve_feed():
286
    coll = g.db['post']
287
    d = {}
288
    cntr = 0
289
    for i in coll.find().sort('_id',direction=-1):
290
        if i['data'] != '<br/>':
291
            i['_id'] = str(i['_id'])
292
            d[cntr] = i
293
            cntr+=1
294
    response = jsonify(d)
295
    response.headers['Access-Control-Allow-Origin'] = '*'
296
    return response
297
298
@app.route('/feeds/write', methods=['POST'])
299
def save_feed():
300
    coll = g.db['feed']
301
    d = {}
302
    d['about'] = request.form['about']
303
    d['blog'] = request.form['blog']
304
    d['bxpath'] = request.form['bxpath']
305
    d['xpath'] = request.form['xpath']
306
    d['author'] = request.form['author']
307
    coll.insert(d)
308
    response = make_response()
309
    response.data = repr(request.form['blog'])
310
    response.headers['Access-Control-Allow-Origin'] = '*'
311
    return response
312
313
import logging,os
314
from logging import FileHandler
315
316
fil = FileHandler(os.path.join(os.path.dirname(__file__),'logme'),mode='a')
317
fil.setLevel(logging.ERROR)
318
app.logger.addHandler(fil)
319
320
if __name__ == '__main__':
321
    app.run(debug=True, host='0.0.0.0')