Ejemplo n.º 1
0
def run(environ):
    status = '200 OK'
    headers = []
    path = environ['module_path']
    if path == '':
        responseBody = html.getHead(title='Catalogue des torrents')
        responseBody += render.fullList("""
                ORDER BY submit_time DESC
                LIMIT 0, 10""")
        responseBody += html.getFoot()
        return status, headers, responseBody
    parsed = detailsMatch.match(path)
    if parsed is not None:
        t_id = parsed.group('t_id')
        torrent = db.conn.cursor()
        torrent.execute("SELECT name FROM torrents WHERE t_id=%s", (t_id,))
        if torrent.rowcount == 0:
            raise exceptions.Error404()
        assert torrent.rowcount == 1
        torrent = torrent.fetchone()
        responseBody = html.getHead(title='%s (torrent)' % torrent[0])
        responseBody += render.details(t_id)
        reponseBody += html.getFoot()
        return status, headers, responseBody

    raise exceptions.Error404()
Ejemplo n.º 2
0
def run(environ):
    global body
    status = '200 OK'
    headers = []
    responseBody = html.getHead(title=u'À propos')
    responseBody += body
    responseBody += html.getFoot()
    return status, headers, responseBody
Ejemplo n.º 3
0
def error404(environ):
    status = '404 Not Found'
    headers = []
    responseBody = '<h1>Not Found</h1>'
    head, foot = '', ''
    try:
        head, foot = (html.getHead(title='Error 404'), html.getFoot())
    except:
        pass
    return  status, headers, head + responseBody + foot
Ejemplo n.º 4
0
def run(environ):
    headers = []
    if environ["module_path"] == "":
        status = "200 OK"
        responseBody = html.getHead(title="Accueil")
        responseBody += "Bienvenue sur Freetorrent.fr"
        responseBody += html.getFoot()
        return status, headers, responseBody
    else:
        raise exceptions.Error404()
Ejemplo n.º 5
0
def error500(environ, e):
    status = '500 Internal Server Error'
    headers = []
    responseBody = '<h1>Internal Error</h1>'
    responseBody += '<h2>%s</h2>' % e.__class__.__name__
    exceptionTraceback = StringIO()
    traceback.print_exc(file=exceptionTraceback)
    exceptionTraceback.seek(0)
    responseBody += '<pre>%s</pre>' % exceptionTraceback.read()
    head, foot = '', ''
    try:
        head, foot = html.getHead(title='Error 500'), html.getFoot()
    except:
        pass
    return  status, headers, unicode(responseBody, errors='replace')
Ejemplo n.º 6
0
def run(environ):
    status = '200 OK'
    headers = []
    responseBody = html.getHead(title='Se connecter')
    path = environ['module_path']
    if path == '':
        responseBody += u"""
        <form action="submit.htm" method="POST">
            <table>
                <tr>
                    <td><label for="name">Nom :</label></td>
                    <td><input type="text" id="name" name="name" /></td>
                </tr>
                <tr>
                    <td><label for="passwd">Mot de passe :</label></td>
                    <td>
                        <input type="password" id="passwd" name="passwd" />
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="Se connecter" />
                    </td>
                </tr>
            </table>
        </form>"""
    elif path == 'submit.htm':
        data = parsers.http_query(environ, 'POST')
        assert all((key in data) for key in ('name', 'passwd'))
        currentUser = user.User(data['name'],
                                hashlib.md5(data['passwd']).hexdigest())
        def getCookie(name, value):
            return cookie.Cookie(name=name,
                                 value=value,
                                 expires=2592000,
                                 path='/')
        nameCookie = getCookie('name', currentUser.name)
        passwdCookie = getCookie('passwdhash', currentUser.passwdhash)
        headers.append(('Set-Cookie', str(nameCookie)))
        headers.append(('Set-Cookie', str(passwdCookie)))
        headers.append(('Location', '/'))
        status = '302 Found'
        responseBody += 'Bienvenue %s !' % str(nameCookie.value)
    else:
        raise exceptions.Error404()
    responseBody += html.getFoot()
    return status, headers, responseBody
Ejemplo n.º 7
0
def run(environ):
    status = '200 OK'
    headers = []
    responseBody = html.getHead(title=u'Déconnexion')
    path = environ['module_path']
    if path == '':
        responseBody += u'<p>Vous avez été déconnecté(e)</p>'
        headers += [('Set-Cookie',
                     str(cookie.expire_cookie('name', path='/')))]
        headers += [('Set-Cookie',
                     str(cookie.expire_cookie('passwdhash', path='/')))]
        headers.append(('Location', '/'))
        status = '302 Found'
        responseBody += u'À bientôt !'
    else:
        raise errors.Error404()
    responseBody += html.getFoot()
    return status, headers, responseBody
Ejemplo n.º 8
0
def run(environ):
    headers = []
    status = '200 OK'
    tiny = environ['module_path'].split('/')[0]
    try:
        assert tiny != ''
    except:
        raise exceptions.Error404()
    cursor = db.conn.cursor()
    cursor.execute('SELECT `full` FROM `tiny2full` WHERE tiny=?', (tiny,))
    result = cursor.fetchone()
    if result is None:
        raise exceptions.Error404()
    longurl = result[0]
    results = []

    for start, end in [(x-HOUR,x) for x in
                       [int(x)+time.time() for x in
                        range(0, 12*HOUR, HOUR)]]:
        cursor.execute("""SELECT COUNT(*) FROM `clicks`
                          WHERE `tiny`=? AND `time`>? AND `time`<?""",
                       (tiny, start, end))
        results.append(cursor.fetchone()[0])

    max_ = max(results)
    min_ = min(results)

    table = '<table>'
    for ago, number in zip(range(1, 12), results):
        if ago >= 2:
            ago = 'Il y a %i heures' % ago
        elif ago == 1:
            ago = u'La dernière heure'
        table += '<tr><td>%s</td><td>%i</td></tr>' % (ago, number)
    table += '</table>'

    responseBody = html.getHead(title='Statistiques sur %s' % tiny)
    responseBody += u'Statistiques de clics pour l\'URL raccourcie.'
    responseBody += table
    responseBody += html.getFoot()

    return status, headers, responseBody
Ejemplo n.º 9
0
def run(environ):
    status = "200 OK"
    headers = []
    path = environ["module_path"]
    responseBody = html.getHead(title="Soumission d'un torrent")
    if path == "":
        categoriesHtml = ""
        categories = db.conn.cursor()
        categories.execute("SELECT c_id, name FROM categories")
        for category in categories:
            categoriesHtml += '<option value="%s">%s</option>' % (category[0], category[1])

        responseBody += form % {"categories": categoriesHtml}
        responseBody += html.getFoot()
    elif path == "submit.htm":
        data = parsers.http_query(environ, "POST")
        assert all(
            (key in data)
            for key in ("name", "license", "url", "description", "category", "audio", "video", "file", "icon")
        )
    else:
        raise exceptions.Error404()

    return status, headers, responseBody
Ejemplo n.º 10
0
def run(environ):
    status = '200 OK'
    headers = []
    responseBody = html.getHead(title=u'Créer un compte')
    path = environ['module_path']
    if path == '':
        responseBody += u"""
        <form action="submit.htm" method="POST">
            <table>
                <tr>
                    <td><label for="name">Nom :</label></td>
                    <td><input type="text" id="name" name="name" /></td>
                </tr>
                <tr>
                    <td><label for="passwd1">Mot de passe :</label></td>
                    <td>
                        <input type="password" id="passwd1" name="passwd1" />
                    </td>
                </tr>
                <tr>
                    <td><label for="passwd2">
                        Mot de passe (confirmation) :
                    </label></td>
                    <td>
                        <input type="password" id="passwd2" name="passwd2" />
                    </td>
                </tr>
                <tr>
                    <td><label for="email">Adresse de courriel :</label></td>
                    <td><input type="text" id="email" name="email" /></td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="S'inscrire" />
                    </td>
                </tr>
            </table>
        </form>"""
    elif path == 'submit.htm':
        data = parsers.http_query(environ, 'POST')
        assert all((key in data) for key in
                   ('name', 'passwd1', 'passwd2', 'email'))
        cursor = db.conn.cursor()
        cursor.execute("SELECT name FROM users WHERE name=%s",
                       (data['name'],))
        row = cursor.fetchone()
        anyError = False
        if row is not None:
            responseBody += u"""<p>Il y a déjà un utilisateur ayant ce nom.
                               Veuillez en choisir un autre.</p>"""
            anyError = True
        if data['passwd1'] != data['passwd2']:
            responseBody += u"""<p>Le mot de passe et sa confirmation ne sont
                               pas identiques.</p>"""
            anyError = True
        if not testName.match(data['name']):
            responseBody += u"""<p>Le nom d'utilisateur est incorrect.
                               Taille : de 2 à 36, et ne peux contenir que
                               des caractères alphanumériques, des
                               underscores et des tirets.</p>"""
            anyError = True
        if not testEmail.match(data['email']):
            responseBody += u"""<p>L'adresse de courriel est invalide.</p>"""
            anyError = True

        if not anyError:
            ##DB#users
            cursor.execute("""INSERT INTO users VALUES
                            (NULL,%s,%s,%s,'','','')""", (
                            data['name'],
                            hashlib.md5(data['passwd1']).hexdigest(),
                            data['email']))
            db.conn.commit()
            responseBody += u"""Votre compte a été créé."""
    else:
        raise exceptions.Error404()

    responseBody += html.getFoot()
    return status, headers, responseBody
Ejemplo n.º 11
0
def run(environ):
    return "200 OK", [], html.getHead(title=u"À propos") + body + html.getFoot()
Ejemplo n.º 12
0
def run(environ):
    status = '200 OK'
    headers = []
    path = environ['module_path']
    if path == '':
        status = '302 Found'
        headers.append(('Location', 'search-0-50.htm'))
        responseBody = html.getHead(title='Redirection')
        responseBody += u"""<p>Si vous voyez cette page, c'est que votre
                navigateur ne supporte pas les redirections. Veuillez cliquer
                sur <a href="list-1-50.htm">ce lien</a> pour voir la liste des
                utilisateurs.</p>"""
        responseBody += html.getFoot()
        return status, headers, responseBody
    parsed = searchMatch.match(path)
    if parsed is not None:
        args = {}
        if parsed.group('args') != '':
            assert parsed.group('args')[0] == '?'
            args = cgi.parse_qsl(parsed.group('args'))
        sqlQuery = "SELECT u_id, name FROM users WHERE u_id!=0 "
        sqlArgs = tuple()
        if args.has_key('orderby'):
            orderby == args['orderby']
            assert orderby in ('u_id', 'name')
            sqlQuery += "ORDER BY %s " % orderby
            if args.has_key('desc'):
                sqlQuery += "DESC "
        sqlQuery += "LIMIT %i, %i" % (int(parsed.group('from')), int(parsed.group('count')))
        users = db.conn.cursor()
        users.execute(sqlQuery, sqlArgs)
        rows = ''
        for user in users:
            cursor = db.conn.cursor()
            cursor.execute("SELECT COUNT(*) FROM messages WHERE u_id=%s" % (user[0],))
            messages = cursor.fetchone()[0]
            rows += usersListRowTemplate % {'id': user[0],
                                            'name': user[1],
                                            'messages': messages}
        responseBody = html.getHead(title=u"Recherche d'utilisateurs")
        responseBody += usersListTemplate % rows
        responseBody += html.getFoot()
        return status, headers, responseBody
    else:
        username = path.split('/')[0]
        user = db.conn.cursor()
        user.execute("SELECT u_id, email, avatar FROM users WHERE name=%s",
                     (username,))
        if user.rowcount == 0:
            raise exceptions.Error404()
        assert user.rowcount == 1
        user = user.fetchone()
        responseBody = html.getHead(title=u"%s (membre)" % username)
        cached = cache.getUserCache(user[0])
        responseBody += userProfileTemplate % {'name': username,
                                              'u_id': user[0],
                                              'email': user[1].replace('@', '(4R0B4S3)'),
                                              'avatar': user[2],
                                              'messages': cached['messages']}
        responseBody += html.getFoot()
        return status, headers, responseBody

    raise exceptions.Error404()
Ejemplo n.º 13
0
def run(environ):
    status = '200 OK'
    headers = []
    path = environ['module_path']
    if path == '':
        forums = db.conn.cursor()
        forums.execute("SELECT f_id, name, description FROM forums;")
        responseBody = html.getHead(title='Liste des forums')
        forumRows = ''
        for forum in forums:
            lastMessage = db.conn.cursor()
            lastMessage.execute("""SELECT messages.m_id, topics.t_id,
                        topics.title, users.name
                    FROM messages, topics, users
                    WHERE f_id=%s
                        AND topics.t_id=messages.t_id
                        AND users.u_id=messages.u_id
                    ORDER BY messages.last_update DESC
                    LIMIT 0,1;""", (forum[0],))
            lastMessage = lastMessage.fetchone()
            if lastMessage is None:
                lastMessage = 'aucun'
            else:
                lastMessage = lastForumMessageTemplate % \
                        {'url': getTopicUrl(lastMessage[1]),
                        'msg_id': lastMessage[0],
                        'topic_name': lastMessage[2],
                        'user_name': lastMessage[3]}
            if user.currentUser.id != 0:
                topics = db.conn.cursor()
                topics.execute("SELECT t_id FROM topics WHERE f_id=%s", (forum[0],))
                notRead = 0
                for topic in topics:
                    lastRead = db.conn.cursor()
                    lastRead.execute("""
                            SELECT time FROM last_read
                            WHERE u_id=%s AND t_id=%s""",
                            (user.currentUser.id, topic[0]))
                    if lastRead.rowcount == 0:
                        lastRead = 0
                    else:
                        lastRead = lastRead.fetchone()[0]
                    counter = db.conn.cursor()
                    counter.execute("""
                            SELECT COUNT(*) FROM messages
                            WHERE t_id=%s AND UNIX_TIMESTAMP(last_update)>%s""",
                            (topic[0], lastRead))
                    row = counter.fetchone()
                    notRead += row[0]
            else:
                notRead = 0
            if notRead == 0:
                prefix = 'no'
            else:
                prefix = ''
            forumRow = forumRowTemplate % \
                    {'newmsg_prefix': prefix,
                    'newmsg': notRead,
                    'url': getForumUrl(forum[0]),
                    'forum_name': forum[1],
                    'forum_desc': forum[2],
                    'topics': getForumTopicsCount(forum[0]),
                    'posts': getForumPostsCount(forum[0]),
                    'lastmessage': lastMessage}
            forumRows += forumRow
        responseBody += forumsListTemplate % forumRows
        responseBody += html.getFoot()
        return status, headers, responseBody
    parsed = forumMatch.match(path)
    if parsed is not None:
        f_id = parsed.group('f_id')
        forum = db.conn.cursor()
        forum.execute("SELECT name FROM forums WHERE f_id = %s", f_id)
        if forum.rowcount < 1:
            raise exceptions.Error404()
        forum = forum.fetchone()
        responseBody = html.getHead(title=u"%s (forum)" % forum[0])
        topicRows = u''
        topics = db.conn.cursor()
        topics.execute("SELECT t_id, title FROM topics WHERE f_id=%s", (f_id,))
        for topic in topics:
            lastMessage = db.conn.cursor()
            lastMessage.execute("""SELECT messages.m_id, users.name
                    FROM messages, users
                    WHERE t_id=%s
                        AND users.u_id=messages.u_id
                    ORDER BY messages.last_update DESC
                    LIMIT 0,1;""", (topic[0],))
            lastMessage = lastMessage.fetchone()
            if lastMessage is None:
                lastMessage = 'aucun'
            else:
                lastMessage = lastTopicMessageTemplate % \
                        {'url': getTopicUrl(topic[0]),
                        'msg_id': lastMessage[0],
                        'user_name': lastMessage[1]}
            if user.currentUser.id != 0:
                lastRead = db.conn.cursor()
                lastRead.execute("""
                        SELECT time FROM last_read
                        WHERE t_id=%s AND last_read.u_id=%s""",
                                 (topic[0], user.currentUser.id))
                row = lastRead.fetchone()
                if row is None:
                    lastRead = 0
                else:
                    lastRead = row[0]
                notRead = db.conn.cursor()
                notRead.execute("""
                        SELECT COUNT(*) FROM messages
                        WHERE UNIX_TIMESTAMP(last_update)>%s AND t_id=%s""",
                        (lastRead,topic[0]))
                notRead = notRead.fetchone()[0]
            else:
                notRead = 0
            if notRead == 0:
                prefix = 'no'
            else:
                prefix = ''
            topicRow = topicRowTemplate % \
                    {'newmsg_prefix': prefix,
                    'newmsg': notRead,
                    'url': getTopicUrl(topic[0]),
                    'topic_name': topic[1],
                    'posts': getTopicPostsCount(topic[0]),
                    'lastmessage': lastMessage}
            topicRows += topicRow
        responseBody += topicsListTemplate % (forum[0], topicRows)
        responseBody += html.getFoot()
        return status, headers, responseBody
    parsed = topicMatch.match(path)
    if parsed is not None:
        f_id = parsed.group('f_id')
        t_id = parsed.group('t_id')
        topic = db.conn.cursor()
        topic.execute("SELECT title FROM topics WHERE t_id=%s", (t_id,))
        if topic.rowcount == 0:
            raise exceptions.Error404()
        topic = topic.fetchone()
        updateLastRead = db.conn.cursor()
        args = (t_id, user.currentUser.id)
        updateLastRead.execute("""
                DELETE FROM last_read
                WHERE t_id=%s AND u_id=%s""", args)
        updateLastRead.execute("INSERT INTO last_read VALUES(%s, %s, %s)",
                               args + (time.time(),))
        messages = db.conn.cursor()
        messages.execute("""
                SELECT m_id, content, created_on, users.u_id, users.name, avatar
                FROM messages
                INNER JOIN users USING (u_id)
                WHERE t_id=%s""", (t_id,))
        responseBody = html.getHead(title=u"%s (sujet)" % topic[0])
        messageRows = u''
        for message in messages:
            def getAvatarHtml(avatarUrl):
                if avatarUrl != '':
                    return '<img src="%s" alt="avatar" />' % avatarUrl
                else:
                    return ''
            messageRow = messageRowTemplate % \
                    {'user_url': '/users/%s/' % message[4],
                    'user_name': message[4],
                    'avatar': getAvatarHtml(message[5]),
                    'message_content': render.forum(message[1]),
                    'id': message[0]}
            messageRows += messageRow
        responseBody += topicBodyTemplate % (topic[0], messageRows)
        responseBody += html.getFoot()
        return status, headers, responseBody
    parsed = newTopicMatch.match(path)
    if parsed is not None:
        f_id = parsed.group('f_id')
        responseBody = html.getHead(title='Nouveau sujet')
        if user.currentUser.id == 0:
            responseBody += notAllowedTemplate
        elif path.endswith('submit.htm'):
            data = parsers.http_query(environ, 'POST')
            assert all((key in data) for key in ('title', 'content'))
            cursor = db.conn.cursor()
            cursor.execute("SELECT COUNT(*) FROM forums WHERE f_id=%s", (f_id,))
            try:
                assert cursor.fetchone()[0] == 1
                cursor.execute("INSERT INTO topics VALUES('', %s, %s)",
                               (f_id, data['title']))
                cursor.execute("""
                        INSERT INTO messages
                        VALUES('', %s, %s, %s, CURRENT_TIMESTAMP, '')""",
                        (cursor.lastrowid,user.currentUser.id,data['content']))
                responseBody += u"<p>Le sujet a été créé avec succès.</p>"
                status = '302 Found'
                headers.append(('Location', '../'))
            except Exception, e:
                print repr(e)
                responseBody += failedSubmitionTemplate % \
                        {'content': data['content']}
        else:
            responseBody += newTopicTemplate
        responseBody += html.getFoot()
        return status, headers, responseBody
Ejemplo n.º 14
0
                     (cursor.lastrowid,user.currentUser.id,data['content']))
             responseBody += u"<p>Le sujet a été créé avec succès.</p>"
             status = '302 Found'
             headers.append(('Location', '../'))
         except Exception, e:
             print repr(e)
             responseBody += failedSubmitionTemplate % \
                     {'content': data['content']}
     else:
         responseBody += newTopicTemplate
     responseBody += html.getFoot()
     return status, headers, responseBody
 parsed = newMessageMatch.match(path)
 if parsed is not None:
     t_id = parsed.group('t_id')
     responseBody = html.getHead(title=u'Réponse au sujet')
     if user.currentUser.id == 0:
         responseBody += notAllowedTemplate
     elif path.endswith('submit.htm'):
         data = parsers.http_query(environ, 'POST')
         assert all((key in data) for key in ('content'))
         cursor = db.conn.cursor()
         cursor.execute("SELECT COUNT(*) FROM topics WHERE t_id=%s", (f_id,))
         try:
             assert cursor.fetchone()[0] == 1
             cursor.execute("""
                     INSERT INTO messages
                     VALUES('', %s, %s, %s, CURRENT_TIMESTAMP, '')""",
                     (t_id, user.currentUser.id, data['content']))
             responseBody += u"<p>La réponse a été envoyée avec succès.</p>"
             status = '302 Found'
Ejemplo n.º 15
0
def run(environ):
    headers = []
    status = '200 OK'
    if environ['module_path'] == '':
        responseBody = html.getHead(title='Accueil')


        cursor = db.conn.cursor()
        cursor.execute("""SELECT `tiny`, `full` FROM `tiny2full`
                          WHERE `u_id`=?
                          ORDER BY `submit_time` DESC
                          LIMIT 0,20""", (user.currentUser.id,))
        older = time.time() - 60*60
        string = ''
        for tiny, full in cursor:
            string += '<li><a href="/%s">%s</a> ' % (tiny, full)
            string += '<a href="/stats/%s">Stats</a></li>' % tiny
        responseBody += rootTemplate % {'last_tiny': string}


        cursor = db.conn.cursor()
        cursor.execute('SELECT `full` FROM `tiny2full`')


        responseBody += html.getFoot()
        return status, headers, responseBody
    elif environ['module_path'] == 'submiturl.htm':
        errormsg = ''

        data = parsers.http_query(environ, 'POST')
        assert all((key in data) for key in ('longurl','size'))

        longurl, size = data['longurl'], data['size']

        if matchUrl1.match(longurl):
            longurl = 'http://' + longurl
        elif not matchUrl2.match(longurl):
            errormsg += u'<p>Votre URL longue ne correspond pas à notre ' + \
                        u'expression régulière.</p>'
        try:
            size = int(size)
            assert 2 <= size <= 7
        except:
            errormsg += u'<p>La taille ne peut être qu\'un entier ' + \
                        u'positif compris entre 2 et 7 (inclus)</pre>'
        if errormsg != '':
            responseBody = html.getHead(title='Nouvelle URL - Erreur')
            responseBody += errormsg
            responseBody += html.getFoot()
            return status, headers, responseBody

        hash_ = hashlib.md5(longurl)
        tiny = ''
        timeout = time.time() + 0.5
        cursor = db.conn.cursor()
        while tiny == '' and time.time() < timeout:
            digest = hash_.hexdigest()
            while len(digest) >= size:
                cursor.execute("""SELECT `full`, `expiry` FROM `tiny2full`
                                  WHERE `tiny`=?""", (digest[0:size],))
                result = cursor.fetchone()
                if result is None or (result[1]!=0 and result[1]<time.time()):
                    tiny=digest[0:size]
                    if result is not None:
                        cursor.execute("""DELETE FROM `tiny2full`
                                          WHERE `tiny`=?""", (tiny,))
                    cursor.execute('INSERT INTO `tiny2full` VALUES(?,?,?,?,?)',
                                   (tiny, user.currentUser.id, longurl,
                                    getExpiry(size), time.time()))
                    db.conn.commit()
                    break
                if result[0] == longurl:
                    tiny = digest[0:size]
                    break
                digest = digest[1:] # Strip the first character
            hash_.update(chr(random.randrange(255)))

        assert tiny != '', ('Impossible de calculer une URL raccourcie,'
                            'veuillez réessayer (un facteur aléatoire '
                            'intervient dans le calcul)')

        responseBody = u'<a href="/">Cliquez sur ce lien si vous n\'êtes ' + \
                       u'pas redirigé(e)</a>'
        headers.append(('Location', '/'))
        status = '302 Found'
    else:
        cursor = db.conn.cursor()
        cursor.execute('SELECT `full` FROM `tiny2full` WHERE `tiny`=?',
                       (environ['module_path'],))
        result = cursor.fetchone()
        if result is None:
            raise exceptions.Error404()

        cursor = db.conn.cursor()
        cursor.execute("""INSERT INTO `clicks` VALUES(?,?,?)""",
                       (environ['module_path'], user.currentUser.id, int(time.time())))
        db.conn.commit()
        cursor.execute('SELECT * FROM `clicks`')

        responseBody = (u'<a href="%s">Cliquez sur ce lien si vous n\'êtes '
                       u'pas redirigé(e)</a>') % result[0]
        headers.append(('Location', str(result[0])))
        status = '302 Found'


    return status, headers, responseBody