From 0651896fa9dd3afc42f0080c58e7aa97308e9c96 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Wed, 6 May 2015 06:02:02 +0300 Subject: initial commit --- .gitignore | 1 + LICENSE.txt | 21 +++++++++++++++++ README.md | 32 +++++++++++++++++++++++++ api.py | 20 ++++++++++++++++ print_mutual_friends.py | 42 +++++++++++++++++++++++++++++++++ track_online.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 178 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 api.py create mode 100644 print_mutual_friends.py create mode 100644 track_online.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..fbbdd68 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Egor Tensin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5d40a48 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# VK scripts + +A collection of scripts abusing VK.com API. + +## Usage + +To use this software, you need to be able to run Python 3 scripts. + +### track_online.py + +Track when people go online/offline: + + track_online.py [SCREEN_NAME...] + +For example, + + track_online.py egor.tensin id5245998 + +### print_mutual_friends.py + +Learn who your ex and her new boyfriend are both friends with: + + print_mutual_friends.py [SCREEN_NAME...] + +For example, + + print_mutual_friends.py egor.tensin durov + +## Licensing + +This project, including all of the files and their contents, is licensed under the terms of the MIT License. +See LICENSE.txt for details. diff --git a/api.py b/api.py new file mode 100644 index 0000000..d584c2b --- /dev/null +++ b/api.py @@ -0,0 +1,20 @@ +# Copyright 2015 Egor Tensin +# This file is licensed under the terms of the MIT License. +# See LICENSE.txt for details. + +import json, sys, urllib.request + +def call_method(method_name, **kwargs): + get_args = '&'.join(map(lambda k: '{}={}'.format(k, kwargs[k]), kwargs)) + url = 'https://api.vk.com/method/{}?{}'.format(method_name, get_args) + response = json.loads(urllib.request.urlopen(url).read().decode()) + if 'response' not in response: + print(response, file=sys.stderr) + sys.exit(-1) + return response['response'] + +def users_get(**kwargs): + return call_method('users.get', **kwargs) + +def friends_get(**kwargs): + return call_method('friends.get', **kwargs) diff --git a/print_mutual_friends.py b/print_mutual_friends.py new file mode 100644 index 0000000..fdc195a --- /dev/null +++ b/print_mutual_friends.py @@ -0,0 +1,42 @@ +# Copyright 2015 Egor Tensin +# This file is licensed under the terms of the MIT License. +# See LICENSE.txt for details. + +import api + +def users_get(user_ids): + return api.users_get(user_ids=','.join(user_ids)) + +def friends_get(user_id): + return api.friends_get(user_id=user_id) + +def format_user_name(user): + return '{} {}'.format(user['last_name'], user['first_name']) + +def join_user_names(user_names): + return '{} and {}'.format(', '.join(user_names[:-1]), user_names[-1]) + +def print_mutual_friends(users, mutual_friends): + user_names = list(map(format_user_name, users)) + user_names = join_user_names(user_names) + if not mutual_friends: + print('{} don\'t have any mutual friends'.format(user_names)) + else: + print('{} are friends with these guys:'.format(user_names)) + for friend in mutual_friends: + print('\t{}'.format(format_user_name(friend))) + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument(metavar='UID', dest='user_ids', nargs='+', + help='user IDs or "screen names"') + args = parser.parse_args() + users = users_get(args.user_ids) + user_ids = map(lambda user: user['uid'], users) + friend_lists = map(friends_get, user_ids) + friend_lists = map(frozenset, friend_lists) + mutual_friends = frozenset.intersection(*friend_lists) + if mutual_friends: + mutual_friends = users_get(map(str, mutual_friends)) + print_mutual_friends(users, mutual_friends) diff --git a/track_online.py b/track_online.py new file mode 100644 index 0000000..c1bae37 --- /dev/null +++ b/track_online.py @@ -0,0 +1,62 @@ +# Copyright 2015 Egor Tensin +# This file is licensed under the terms of the MIT License. +# See LICENSE.txt for details. + +from datetime import datetime +import time + +import api + +def users_get(user_ids): + return api.users_get(user_ids=','.join(user_ids), + fields='online,last_seen') + +def log(s): + print('[{}] {}'.format(datetime.now().replace(microsecond=0), s)) + +def format_user_name(user): + return '{} {}'.format(user['last_name'], user['first_name']) + +def user_is_online(user): + log('{} is ONLINE'.format(format_user_name(user))) + +def user_is_offline(user): + user_name = format_user_name(user) + log('{} is OFFLINE'.format(user_name)) + last_seen = datetime.fromtimestamp(user['last_seen']['time']) + log('{} was last seen at {}'.format(user_name, last_seen)) + +def user_went_online(user): + log('{} went ONLINE'.format(format_user_name(user))) + +def user_went_offline(user): + log('{} went OFFLINE'.format(format_user_name(user))) + +def print_user(status): + if status['online']: + user_is_online(status) + else: + user_is_offline(status) + +def print_user_update(status): + if status['online']: + user_went_online(status) + else: + user_went_offline(status) + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument(metavar='UID', dest='user_ids', nargs='+', + help='user IDs or "screen names"') + args = parser.parse_args() + users = users_get(args.user_ids) + for user in users: + print_user(user) + while True: + time.sleep(5) + updated_users = users_get(args.user_ids) + for i in range(len(updated_users)): + if users[i]['online'] != updated_users[i]['online']: + users[i] = updated_users[i] + print_user_update(updated_users[i]) -- cgit v1.2.3