NerdVana

Beware of computer programmers that carry screwdrivers.

Textify: Asciifying web proxy

Written by Eric Schwimmer

What was that? You are looking for a proxy that will convert any page into ascii art? Then you have come to the right place, my friend! All you will need to do is install phantomjs, fapws, and the PIL and selenium Python modules, and then run this script as a daemon:

#!/usr/bin/python

import fapws._evwsgi as evwsgi
from fapws import base
from fapws.contrib import zip, log
from selenium import webdriver
import random, sys
from PIL import Image

txtPx = "BG0O$&#@?7>!:-;.  "

def start():
    evwsgi.start('0.0.0.0', '8080')
    evwsgi.set_base_module(base)

    @log.Log()
    @zip.Gzip()

    def textfin(environ, start_response):
        start_response('200 OK', [('Content-Type','text/html')])

        targetUrl = environ['fapws.uri'][1:]
        if not targetUrl:
            return [ 'TextIt!  Usage: %s://%s/<full url to textify>' % (
                environ['wsgi.url_scheme'].lower(),
                environ['HTTP_HOST'].lower())
                ]

        outputFile = '/tmp/%032x' % random.randrange(16**32)
        driver = webdriver.PhantomJS()
        driver.set_window_size(1120, 550)

        driver.get(targetUrl)
        driver.save_screenshot(outputFile)
        driver.quit()
        maxLen = 700
        img = Image.open(outputFile)
        width, height = img.size
        rate = maxLen / float(width)
        width = int(rate * width)
        height = int(rate * height)
        img = img.resize((width, height))
        imgData = img.load()

        out = ""
        for h in xrange(height):
            for w in xrange(width):
                px = imgData[w, h]
                try:
                    if len(px) > 3:
                        out += txtPx[
                              int(max(sum(px[:2]) / 3.0, 256.0 - px[3]) / 16)]
                    else:
                        out += txtPx[int(sum(px) / 48.0)]
                except:
                    print int(max(sum(px[:2]) / 3.0, 256.0 - px[3])) / 16
            out += "\n"

        return [ '''<html>
            <head>
              <meta http-equiv="content-type" 
                content="text/html; charset=utf-8" />
              <link href='http://fonts.googleapis.com/css?family=Cousine' 
                rel='stylesheet' type='text/css'>
              <style type="text/css" media="all">
                body {
                  margin: 0 0 0 0;
                }
                pre {
                  font-family: 'Cousine';
                  line-height: 0.182vw;
                  font-size: 0.235vw;
                  font-weight: 900;
                }
              </style>
            </head>
            <body>
              <pre>%s</pre>
            </body>
            </html>''' % out ]

    evwsgi.wsgi_cb(('/', textfin))

    evwsgi.set_debug(0)
    evwsgi.run()

if __name__ == '__main__':
    start()

You'll probably want to put it behind varnish or some other sort of caching reverse proxy, because it can be pretty slow on larger pages.


comments powered by Disqus