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