From 65eb41f44205ad767b9e0c59836e27abf32d5b9b Mon Sep 17 00:00:00 2001 From: Datalux Date: Wed, 16 Sep 2020 12:11:36 +0200 Subject: [PATCH 1/9] feat: set itself as target --- src/Osintgram.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Osintgram.py b/src/Osintgram.py index 8eb6fb75..9f760e16 100644 --- a/src/Osintgram.py +++ b/src/Osintgram.py @@ -1044,6 +1044,8 @@ def onlogin_callback(self, api, new_settings_file): # print('SAVED: {0!s}'.format(new_settings_file)) def check_following(self): + if self.target_id == self.api.authenticated_user_id: + return True endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target_id}) return self.api._call_api(endpoint)['user_detail']['user']['friendship_status']['following'] From dddcbf57638a5800b2cac21cb3bca85bfbf15079 Mon Sep 17 00:00:00 2001 From: AboDa7aM Date: Wed, 16 Sep 2020 13:30:34 +0200 Subject: [PATCH 2/9] fixed an error while saving non-utf8 followers output while FILE=y when saving a non-utf8 language an error will be thrown. file.write() python UnicodeEncodeError: 'charmap' codec can't encode characters this commit fixes this issue at line 315 --- src/Osintgram.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Osintgram.py b/src/Osintgram.py index 8eb6fb75..14442e28 100644 --- a/src/Osintgram.py +++ b/src/Osintgram.py @@ -311,9 +311,9 @@ def get_followers(self): if self.writeFile: file_name = "output/" + self.target + "_followers.txt" - file = open(file_name, "w") - file.write(str(t)) - file.close() + with open(file_name, 'w', encoding='utf-8') as f: + f.write(str(t)) + f.close() if self.jsonDump: json_data['followers'] = followers From e223ecf04fa5e1e547c702766f3e8aad0d4283b5 Mon Sep 17 00:00:00 2001 From: Datalux Date: Sun, 20 Sep 2020 12:01:51 +0200 Subject: [PATCH 3/9] fix: issue #58 --- src/Osintgram.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Osintgram.py b/src/Osintgram.py index 8eb6fb75..d848fcea 100644 --- a/src/Osintgram.py +++ b/src/Osintgram.py @@ -1023,6 +1023,8 @@ def login(self, u, p): # pc.printout('ClientError {0!s} (Code: {1:d}, Response: {2!s})'.format(e.msg, e.code, e.error_response), pc.RED) error = json.loads(e.error_response) pc.printout(error['message'], pc.RED) + pc.printout(": ", pc.RED) + pc.printout(e.msg, pc.RED) pc.printout("\n") exit(9) From 13211236442bb7f27273e65653a2dedff3a3adeb Mon Sep 17 00:00:00 2001 From: Datalux Date: Tue, 22 Sep 2020 09:46:53 +0200 Subject: [PATCH 4/9] chore: update version --- README.md | 4 ++-- main.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1f89a5de..79eaac34 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![](https://img.shields.io/badge/version-0.9-green)](https://github.com/Datalux/Osintgram/releases/tag/0.9) +[![](https://img.shields.io/badge/version-1.0-green)](https://github.com/Datalux/Osintgram/releases/tag/1.0) [![](https://img.shields.io/badge/license-GPLv3-blue)](https://img.shields.io/badge/license-GPLv3-blue) [![](https://img.shields.io/badge/language-Python3-red)](https://img.shields.io/badge/language-Python3-red) @@ -32,7 +32,7 @@ Osintgram offers an interactive shell to perform analysis on Instagram account o ``` You can find detailed commands usage [here](doc/COMMANDS.md). -[**Latest version**](https://github.com/Datalux/Osintgram/releases/tag/0.9) | +[**Latest version**](https://github.com/Datalux/Osintgram/releases/tag/1.0) | [CHANGELOG](doc/CHANGELOG.md) ## Tools diff --git a/main.py b/main.py index 67cf3ba7..95fa79b0 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ def printlogo(): pc.printout("\_______ /____ >__|___| /__| \___ /|__| (____ /__|_| /\n", pc.YELLOW) pc.printout(" \/ \/ \/ /_____/ \/ \/ \n", pc.YELLOW) print('\n') - pc.printout("Version 0.9 - Developed by Giuseppe Criscione - 2019\n\n", pc.YELLOW) + pc.printout("Version 1.0 - Developed by Giuseppe Criscione\n\n", pc.YELLOW) pc.printout("Type 'list' to show all allowed commands\n") pc.printout("Type 'FILE=y' to save results to files like '_.txt (deafult is disabled)'\n") pc.printout("Type 'FILE=n' to disable saving to files'\n") From 1bb84ed4c23f37b9a1dd23b6afaf02a09265806b Mon Sep 17 00:00:00 2001 From: Giuseppe Criscione Date: Fri, 2 Oct 2020 17:44:32 +0200 Subject: [PATCH 5/9] Revert "fixed an error while saving non-utf8 followers output" --- src/Osintgram.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Osintgram.py b/src/Osintgram.py index 74c6ca13..41905bb9 100644 --- a/src/Osintgram.py +++ b/src/Osintgram.py @@ -311,9 +311,9 @@ def get_followers(self): if self.writeFile: file_name = "output/" + self.target + "_followers.txt" - with open(file_name, 'w', encoding='utf-8') as f: - f.write(str(t)) - f.close() + file = open(file_name, "w") + file.write(str(t)) + file.close() if self.jsonDump: json_data['followers'] = followers From c9b068f78c1d33de012366d69b3b9bfe13bd79a0 Mon Sep 17 00:00:00 2001 From: Datalux Date: Sat, 10 Oct 2020 14:38:02 +0200 Subject: [PATCH 6/9] chore: update requirements --- requirements.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 62e51139..19e848c3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ requests==2.24.0 requests-toolbelt==0.9.1 -geopy==1.11 +geopy>=2.0.0 prettytable==0.7.2 -instagram-private-api==1.6.0 \ No newline at end of file +instagram-private-api==1.6.0 +readline>=6.2.4 \ No newline at end of file From d749c0bcd558a4f7c1019f0ffe77777a5c711583 Mon Sep 17 00:00:00 2001 From: Datalux Date: Sat, 10 Oct 2020 14:38:23 +0200 Subject: [PATCH 7/9] fix: geolocator --- src/Osintgram.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Osintgram.py b/src/Osintgram.py index 41905bb9..979d9de0 100644 --- a/src/Osintgram.py +++ b/src/Osintgram.py @@ -19,7 +19,7 @@ class Osintgram: api = None api2 = None - geolocator = Nominatim() + geolocator = Nominatim(user_agent="user-agent") user_id = None target_id = None is_private = True From c8c59ba34d26f1239285b87a54fddd82fe8bb454 Mon Sep 17 00:00:00 2001 From: Datalux Date: Mon, 15 Mar 2021 12:41:28 +0100 Subject: [PATCH 8/9] fix: login issue --- src/Osintgram.py | 196 +++++++++++++++++++++++++++-------------------- 1 file changed, 113 insertions(+), 83 deletions(-) diff --git a/src/Osintgram.py b/src/Osintgram.py index b2060865..139eae32 100644 --- a/src/Osintgram.py +++ b/src/Osintgram.py @@ -442,60 +442,83 @@ def get_hashtags(self): pc.printout("Sorry! No results found :-(\n", pc.RED) def get_user_info(self): - content = requests.get("https://www.instagram.com/" + str(self.target) + "/?__a=1") - - if content.status_code == 404: - print("Oops... " + str(self.target) + " non exist, please enter a valid username.") - sys.exit(2) - - data = content.json() - data = data['graphql']['user'] - - pc.printout("[ID] ", pc.GREEN) - pc.printout(str(data['id']) + '\n') - pc.printout("[FULL NAME] ", pc.RED) - pc.printout(str(data['full_name']) + '\n') - pc.printout("[BIOGRAPHY] ", pc.CYAN) - pc.printout(str(data['biography']) + '\n') - pc.printout("[FOLLOWED] ", pc.BLUE) - pc.printout(str(data['edge_followed_by']['count']) + '\n') - pc.printout("[FOLLOW] ", pc.GREEN) - pc.printout(str(data['edge_follow']['count']) + '\n') - pc.printout("[BUSINESS ACCOUNT] ", pc.RED) - pc.printout(str(data['is_business_account']) + '\n') - if data['is_business_account']: - pc.printout("[BUSINESS CATEGORY] ") - pc.printout(str(data['business_category_name']) + '\n') - pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN) - pc.printout(str(data['is_verified']) + '\n') - if 'business_email' in data: - pc.printout("[BUSINESS EMAIL] ", pc.BLUE) - pc.printout(str(data['business_email']) + '\n') - pc.printout("[HD PROFILE PIC] ", pc.GREEN) - pc.printout(str(data['profile_pic_url_hd']) + '\n') - if data['connected_fb_page']: - pc.printout("[FB PAGE] ", pc.RED) - pc.printout(str(data['connected_fb_page']) + '\n') + try: + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target}) + content = self.api._call_api(endpoint) + + data = content['user_detail']['user'] + + pc.printout("[ID] ", pc.GREEN) + pc.printout(str(data['pk']) + '\n') + pc.printout("[FULL NAME] ", pc.RED) + pc.printout(str(data['full_name']) + '\n') + pc.printout("[BIOGRAPHY] ", pc.CYAN) + pc.printout(str(data['biography']) + '\n') + pc.printout("[FOLLOWED] ", pc.BLUE) + pc.printout(str(data['follower_count']) + '\n') + pc.printout("[FOLLOW] ", pc.GREEN) + pc.printout(str(data['following_count']) + '\n') + pc.printout("[BUSINESS ACCOUNT] ", pc.RED) + pc.printout(str(data['is_business']) + '\n') + if data['is_business']: + if not data['can_hide_category']: + pc.printout("[BUSINESS CATEGORY] ") + pc.printout(str(data['category']) + '\n') + pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN) + pc.printout(str(data['is_verified']) + '\n') + if 'public_email' in data and data['public_email']: + pc.printout("[EMAIL] ", pc.BLUE) + pc.printout(str(data['public_email']) + '\n') + pc.printout("[HD PROFILE PIC] ", pc.GREEN) + pc.printout(str(data['hd_profile_pic_url_info']['url']) + '\n') + if 'fb_page_call_to_action_id' in data and data['fb_page_call_to_action_id']: + pc.printout("[FB PAGE] ", pc.RED) + pc.printout(str(data['connected_fb_page']) + '\n') + if 'whatsapp_number' in data and data['whatsapp_number']: + pc.printout("[WHATSAPP NUMBER] ", pc.GREEN) + pc.printout(str(data['whatsapp_number']) + '\n') + if 'city_name' in data and data['city_name']: + pc.printout("[CITY] ", pc.YELLOW) + pc.printout(str(data['city_name']) + '\n') + if 'address_street' in data and data['address_street']: + pc.printout("[ADDRESS STREET] ", pc.RED) + pc.printout(str(data['address_street']) + '\n') + if 'contact_phone_number' in data and data['contact_phone_number']: + pc.printout("[CONTACT PHONE NUMBER] ", pc.CYAN) + pc.printout(str(data['contact_phone_number']) + '\n') - if self.jsonDump: - user = { - 'id': data['id'], - 'full_name': data['full_name'], - 'biography': data['biography'], - 'edge_followed_by': data['edge_followed_by']['count'], - 'edge_follow': data['edge_follow']['count'], - 'is_business_account': data['is_business_account'], - 'is_verified': data['is_verified'], - 'profile_pic_url_hd': data['profile_pic_url_hd'] - } - if 'business_email' in data: - user['business_email'] = data['business_email'] - if data['connected_fb_page']: - user['connected_fb_page'] = data['connected_fb_page'] + if self.jsonDump: + user = { + 'id': data['pk'], + 'full_name': data['full_name'], + 'biography': data['biography'], + 'edge_followed_by': data['follower_count'], + 'edge_follow': data['following_count'], + 'is_business_account': data['is_business_account'], + 'is_verified': data['is_business'], + 'profile_pic_url_hd': data['hd_profile_pic_url_info']['url'] + } + if 'public_email' in data and data['public_email']: + user['email'] = data['public_email'] + if 'fb_page_call_to_action_id' in data and data['fb_page_call_to_action_id']: + user['connected_fb_page'] = data['fb_page_call_to_action_id'] + if 'whatsapp_number' in data and data['whatsapp_number']: + user['whatsapp_number'] = data['whatsapp_number'] + if 'city_name' in data and data['city_name']: + user['city_name'] = data['city_name'] + if 'address_street' in data and data['address_street']: + user['address_street'] = data['address_street'] + if 'contact_phone_number' in data and data['contact_phone_number']: + user['contact_phone_number'] = data['contact_phone_number'] + + json_file_name = "output/" + self.target + "_info.json" + with open(json_file_name, 'w') as f: + json.dump(user, f) - json_file_name = "output/" + self.target + "_info.json" - with open(json_file_name, 'w') as f: - json.dump(user, f) + except ClientError as e: + pc.printout("Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED) + pc.printout("\n") + exit(2) def get_total_likes(self): if self.check_private_profile(): @@ -821,27 +844,32 @@ def get_user_photo(self): pc.printout("\nWoohoo! We downloaded " + str(counter) + " photos (saved in output/ folder) \n", pc.GREEN) def get_user_propic(self): - content = requests.get("https://www.instagram.com/" + str(self.target) + "/?__a=1") - if content.status_code == 404: - print("Oops... " + str(self.target) + " non exist, please enter a valid username.") - sys.exit(2) + try: + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target}) + content = self.api._call_api(endpoint) - data = content.json() + data = content['user_detail']['user'] - uurl = data["graphql"]["user"] - if "profile_pic_url_hd" in uurl: - URL = data["graphql"]["user"]["profile_pic_url_hd"] - else: - URL = data["graphql"]["user"]["profile_pic_url"] + if "hd_profile_pic_url_info" in data: + URL = data["hd_profile_pic_url_info"]['url'] + else: + #get better quality photo + items = len(data['hd_profile_pic_versions']) + URL = data["hd_profile_pic_versions"][items-1]['url'] - if URL != "": - end = "output/" + self.target + "_propic.jpg" - urllib.request.urlretrieve(URL, end) - pc.printout("Target propic saved in output folder\n", pc.GREEN) + if URL != "": + end = "output/" + self.target + "_propic.jpg" + urllib.request.urlretrieve(URL, end) + pc.printout("Target propic saved in output folder\n", pc.GREEN) - else: - pc.printout("Sorry! No results found :-(\n", pc.RED) + else: + pc.printout("Sorry! No results found :-(\n", pc.RED) + + except ClientError as e: + print(e) + print("An error occured... exit") + exit(2) def get_user_stories(self): if self.check_private_profile(): @@ -946,25 +974,27 @@ def get_people_tagged_by_user(self): pc.printout("Sorry! No results found :-(\n", pc.RED) def get_user(self, username): - content = requests.get("https://www.instagram.com/" + username + "/?__a=1") - - if content.status_code == 404: - print("Oops... " + str(self.target) + " non exist, please enter a valid username.") - sys.exit(2) + try: + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target}) + content = self.api._call_api(endpoint) - data = content.json() + if self.writeFile: + file_name = "output/" + self.target + "_user_id.txt" + file = open(file_name, "w") + file.write(str(content['user_detail']['user']['pk'])) + file.close() - if self.writeFile: - file_name = "output/" + self.target + "_user_id.txt" - file = open(file_name, "w") - file.write(str(data['graphql']['user']['id'])) - file.close() + user = dict() + user['id'] = content['user_detail']['user']['pk'] + user['is_private'] = content['user_detail']['user']['is_private'] - user = dict() - user['id'] = data['graphql']['user']['id'] - user['is_private'] = data['graphql']['user']['is_private'] + return user + except ClientError as e: + pc.printout("Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED) + pc.printout("\n") + exit(2) - return user + def set_write_file(self, flag): if flag: From b75147cb0c1aee62ed8329dd3a84924deae3e3ac Mon Sep 17 00:00:00 2001 From: Datalux Date: Mon, 15 Mar 2021 12:57:25 +0100 Subject: [PATCH 9/9] doc: new release --- doc/CHANGELOG.md | 12 ++++++++++++ doc/COMMANDS.md | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 4dcabd0f..3b4379ce 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [1.0](https://github.com/Datalux/Osintgram/releases/tag/1.0) +**Enhancements** +- Set itself as target (#53) +- Get others info from user (`info` command): + - Whats'App number (if avaible) + - City Name (if avaible) + - Address Street (if avaible) + - Contact phone number (if avaible) + +**Bug fixes** +- Fix login issue (#79, #80, #81) + ## [0.9](https://github.com/Datalux/Osintgram/releases/tag/0.9) **Enhancements** diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index ccdae6ba..37336530 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -68,6 +68,10 @@ Show target info like: - business email (if available) - HD profile picture url - connected Facebook page (if available) +- Whats'App number (if avaible) +- City Name (if avaible) +- Address Street (if avaible) +- Contact phone number (if avaible) ### JSON Can set preference to export commands output as JSON in output folder. It save output in `_.JSON` file.