Created
September 1, 2015 20:40
-
-
Save prokoptsev/66d78997e12e1d11b0d5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
# coding: utf-8 | |
from __future__ import unicode_literals | |
import sys | |
import string | |
import textwrap | |
import webbrowser | |
from urlparse import urlparse | |
from argparse import ArgumentParser, RawDescriptionHelpFormatter | |
import requests | |
from lxml import html | |
from bottle import Bottle, Response | |
__version__ = '1.0.0' | |
COOL_LENGTH = 6 | |
PROXY_FEATURE = "™" | |
INVIOLABLE = ["pre", "code", "script", "style"] | |
_EXCLUDE_SYMBOLS = string.punctuation + string.whitespace | |
def split_url(url): | |
url = urlparse(url) | |
host = "{}://{}".format(url.scheme, url.netloc) | |
path = "{path}{query}{fragment}".format( | |
path=url.path, | |
query="?{}".format(url.query) if url.query else '', | |
fragment="#{}".format(url.fragment) if url.fragment else '') | |
return host, path | |
def get_needed_words(data): | |
target = set() | |
for word in data.split(): | |
word = word.strip(_EXCLUDE_SYMBOLS) | |
if word.isalpha() and len(word) == COOL_LENGTH: | |
target.add(word) | |
return target | |
def upgrade_text(text): | |
for word in get_needed_words(text): | |
text = text.replace(word, "{}{}".format(word, PROXY_FEATURE)) | |
return text | |
app = Bottle() | |
@app.route("<path:path>") | |
def proxy(path): | |
resp = requests.get("{}{}".format(app.config.base_on, path)) | |
tree = html.fromstring(resp.text) | |
for block in tree.iter(): | |
if block.tag in INVIOLABLE or isinstance(block, html.HtmlComment): | |
continue | |
if block.text and block.text.strip(_EXCLUDE_SYMBOLS): | |
block.text = upgrade_text(block.text) | |
if block.tail and block.tail.strip(_EXCLUDE_SYMBOLS): | |
block.tail = upgrade_text(block.tail) | |
content = html.tostring(tree, pretty_print=True) | |
return Response(content) | |
if __name__ == '__main__': | |
parser = ArgumentParser( | |
description=""" | |
%(prog)s — это простейший http-прокси-сервер, запускаемый локально. | |
Этот прокси-сервер показывает содержимое страниц, c одним | |
исключением: после каждого слова из шести букв должен стоять | |
значок «™». | |
""", | |
epilog=textwrap.dedent(""" | |
Пример использования: | |
%(prog)s http://habrahabr.ru/company/yandex/blog/258673/ | |
"""), | |
formatter_class=RawDescriptionHelpFormatter, | |
version=__version__) | |
parser.add_argument("url", | |
help="URL адрес который необходимо открыть", | |
nargs='?') | |
parser.add_argument("--host", | |
help="хост сервера", | |
type=str, | |
default="127.0.0.1") | |
parser.add_argument("--port", | |
help="порт сервера", | |
type=int, | |
default=5000) | |
opts = parser.parse_args() | |
if opts.url is not None: | |
try: | |
resp = requests.head(opts.url) | |
except requests.RequestException as e: | |
sys.exit( | |
"Не удалось выполнить запрос " | |
"по url адресу: {!r}".format(opts.url)) | |
base_on, path = split_url(opts.url) | |
app.config.base_on = base_on | |
webbrowser.open("http://{}:{}{}".format(opts.host, opts.port, path)) | |
app.run(host=opts.host, port=opts.port, debug=False) | |
else: | |
parser.print_help() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment