From f0e1653fc09984a16a80daa8198b8d04553025a6 Mon Sep 17 00:00:00 2001 From: Johannes Löthberg Date: Sun, 21 Jun 2015 13:47:13 +0100 Subject: Move script to src --- fingerchange.py | 153 ---------------------------------------------------- src/fingerchange.py | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 153 deletions(-) delete mode 100755 fingerchange.py create mode 100755 src/fingerchange.py diff --git a/fingerchange.py b/fingerchange.py deleted file mode 100755 index b34c009..0000000 --- a/fingerchange.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python3 - -from textwrap import fill, indent -from bs4 import BeautifulSoup -import requests -import asyncio -import json - -api_url = 'https://api.stackexchange.com/2.2/users/' - - -def slice_dict(dict, slice): - s_len = len(slice) - return {key[s_len:]: value for key,value in dict.items() - if key.startswith(slice)} - - -def get_user_by_uid(site, uid): - params = { - 'site': site, - 'filter': '!9YdnSA07B', - } - res = requests.get(api_url + str(uid), params=params) - res = json.loads(res.text) - - return res['items'][0] - - -def get_users_by_name(site, name=''): - params = { - 'site': site, - 'inname': name, - 'filter': '!9YdnSA07B', - } - res = requests.get(api_url, params=params) - res = json.loads(res.text) - - return res['items'] - - -def format_url(url): - return '<{}>'.format(url) - - -def format_field(key, value=None, indent=1): - if not value: - return '{}:: {}\n'.format(' '*indent, key) - - return '{}:: {} {}\n'.format(' '*indent, key, value) - - -def format_header(header, filler): - header = str(header) - header_len = len(header) - filler_len = 80 - header_len - (3 + 2) - - msg = '{pre_fil} {header} {post_fil}\n'.format(**{ - 'pre_fil': filler * 3, - 'header': header, - 'post_fil': filler * filler_len, - }) - return msg - - -def format_rep_changes(user): - changes = slice_dict(user, 'reputation_') - msg = '' - if changes['change_day'] > 0: - msg += format_field('day', '+' + str(changes['change_day']), indent=3) - if changes['change_quarter'] > 0: - msg += format_field('quarter', '+' + str(changes['change_quarter']), indent=3) - if changes['change_year'] > 0: - msg += format_field('year', '+' + str(changes['change_year']), indent=3) - - if len(msg) > 0: - msg = format_field('reputation changes') + msg - - return msg - - -def format_user(user, long_output=True): - msg = '\n' - msg += format_header(user['account_id'], '=') - msg += format_field('uid', user['user_id']) - msg += format_field('name', user['display_name']) - msg += format_field('reputation', user['reputation']) - if 'location' in user: - msg += format_field('location', user['location']) - - msg += format_field('profile', format_url(user['link'])) - if 'website_url' in user and len(user['website_url']) > 0: - msg += format_field('website', format_url(user['website_url'])) - - msg += format_rep_changes(user) - msg += '\n' - - if long_output and 'about_me' in user and len(user['about_me']) > 0: - msg += format_header('About User', '-') + '\n' - - soup = BeautifulSoup(user['about_me']) - text = soup.get_text() - - lines = [ line for line in text.splitlines() if line.strip() ] - for line in lines: - msg += indent(fill(line), ' ') + '\n\n' - - return msg - - -@asyncio.coroutine -def handle_client(reader, writer): - line = yield from reader.readline() - line = line.decode('utf-8').strip() - - if '@' not in line: - writer.write('Error: Username or site missing\n'.encode('utf-8')) - writer.close() - return - - user, site = line.split('@') - if user.startswith('/W'): - long_output = True - user = user[3:] - else: - long_output = False - - try: - uid = int(user) - users = [get_user_by_uid(site, uid)] - except ValueError: - users = get_users_by_name(site, user) - - for user in users: - if user['user_type'] == 'unregistered': - continue - - msg = format_user(user, long_output) - writer.write(msg.encode('utf-8')) - - writer.close() - - -loop = asyncio.get_event_loop() - -coro = asyncio.start_server(handle_client, host='0.0.0.0', port=79, loop=loop) -server = loop.run_until_complete(coro) - -try: - loop.run_forever() -except KeyboardInterrupt: - server.close() - loop.run_until_complete(server.wait_closed()) - loop.close() diff --git a/src/fingerchange.py b/src/fingerchange.py new file mode 100755 index 0000000..b34c009 --- /dev/null +++ b/src/fingerchange.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 + +from textwrap import fill, indent +from bs4 import BeautifulSoup +import requests +import asyncio +import json + +api_url = 'https://api.stackexchange.com/2.2/users/' + + +def slice_dict(dict, slice): + s_len = len(slice) + return {key[s_len:]: value for key,value in dict.items() + if key.startswith(slice)} + + +def get_user_by_uid(site, uid): + params = { + 'site': site, + 'filter': '!9YdnSA07B', + } + res = requests.get(api_url + str(uid), params=params) + res = json.loads(res.text) + + return res['items'][0] + + +def get_users_by_name(site, name=''): + params = { + 'site': site, + 'inname': name, + 'filter': '!9YdnSA07B', + } + res = requests.get(api_url, params=params) + res = json.loads(res.text) + + return res['items'] + + +def format_url(url): + return '<{}>'.format(url) + + +def format_field(key, value=None, indent=1): + if not value: + return '{}:: {}\n'.format(' '*indent, key) + + return '{}:: {} {}\n'.format(' '*indent, key, value) + + +def format_header(header, filler): + header = str(header) + header_len = len(header) + filler_len = 80 - header_len - (3 + 2) + + msg = '{pre_fil} {header} {post_fil}\n'.format(**{ + 'pre_fil': filler * 3, + 'header': header, + 'post_fil': filler * filler_len, + }) + return msg + + +def format_rep_changes(user): + changes = slice_dict(user, 'reputation_') + msg = '' + if changes['change_day'] > 0: + msg += format_field('day', '+' + str(changes['change_day']), indent=3) + if changes['change_quarter'] > 0: + msg += format_field('quarter', '+' + str(changes['change_quarter']), indent=3) + if changes['change_year'] > 0: + msg += format_field('year', '+' + str(changes['change_year']), indent=3) + + if len(msg) > 0: + msg = format_field('reputation changes') + msg + + return msg + + +def format_user(user, long_output=True): + msg = '\n' + msg += format_header(user['account_id'], '=') + msg += format_field('uid', user['user_id']) + msg += format_field('name', user['display_name']) + msg += format_field('reputation', user['reputation']) + if 'location' in user: + msg += format_field('location', user['location']) + + msg += format_field('profile', format_url(user['link'])) + if 'website_url' in user and len(user['website_url']) > 0: + msg += format_field('website', format_url(user['website_url'])) + + msg += format_rep_changes(user) + msg += '\n' + + if long_output and 'about_me' in user and len(user['about_me']) > 0: + msg += format_header('About User', '-') + '\n' + + soup = BeautifulSoup(user['about_me']) + text = soup.get_text() + + lines = [ line for line in text.splitlines() if line.strip() ] + for line in lines: + msg += indent(fill(line), ' ') + '\n\n' + + return msg + + +@asyncio.coroutine +def handle_client(reader, writer): + line = yield from reader.readline() + line = line.decode('utf-8').strip() + + if '@' not in line: + writer.write('Error: Username or site missing\n'.encode('utf-8')) + writer.close() + return + + user, site = line.split('@') + if user.startswith('/W'): + long_output = True + user = user[3:] + else: + long_output = False + + try: + uid = int(user) + users = [get_user_by_uid(site, uid)] + except ValueError: + users = get_users_by_name(site, user) + + for user in users: + if user['user_type'] == 'unregistered': + continue + + msg = format_user(user, long_output) + writer.write(msg.encode('utf-8')) + + writer.close() + + +loop = asyncio.get_event_loop() + +coro = asyncio.start_server(handle_client, host='0.0.0.0', port=79, loop=loop) +server = loop.run_until_complete(coro) + +try: + loop.run_forever() +except KeyboardInterrupt: + server.close() + loop.run_until_complete(server.wait_closed()) + loop.close() -- cgit v1.2.3-54-g00ecf