aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--LICENSE.txt21
-rw-r--r--README.md32
-rw-r--r--api.py20
-rw-r--r--print_mutual_friends.py42
-rw-r--r--track_online.py62
6 files changed, 178 insertions, 0 deletions
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 <Egor.Tensin@gmail.com>
+
+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 <Egor.Tensin@gmail.com>
+# 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 <Egor.Tensin@gmail.com>
+# 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 <Egor.Tensin@gmail.com>
+# 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])