Full Code of new92/InstaTools for AI

main 71fa53f2cf75 cached
48 files
1.5 MB
582.1k tokens
94 symbols
1 requests
Download .txt
Showing preview only (1,587K chars total). Download the full file or copy to clipboard to get everything.
Repository: new92/InstaTools
Branch: main
Commit: 71fa53f2cf75
Files: 48
Total size: 1.5 MB

Directory structure:
gitextract_fj5qyne7/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── dependabot.yml
│   └── workflows/
│       └── codeql.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Chronos/
│   ├── README.md
│   └── chronos.py
├── Delta/
│   ├── README.md
│   ├── delta.py
│   └── shortcodes.txt
├── Hermes/
│   ├── README.md
│   └── hermes.py
├── Hunter/
│   ├── README.md
│   └── hunter.py
├── IsVer/
│   ├── README.md
│   └── isver.py
├── LICENSE
├── Mutuals/
│   ├── README.md
│   └── mutuals.py
├── Poirot/
│   ├── README.md
│   └── poirot.py
├── README.md
├── Researcher/
│   ├── README.md
│   ├── files/
│   │   ├── cities.txt
│   │   └── countries.txt
│   └── researcher.py
├── SECURITY.md
├── Spammer/
│   ├── README.md
│   ├── spammer.py
│   └── targets.txt
├── Sphinx/
│   ├── README.md
│   ├── profanity.txt
│   ├── shortcodes.txt
│   └── sphinx.py
├── Spider/
│   ├── README.md
│   └── spider.py
├── ToolZ/
│   ├── README.md
│   └── toolz.py
├── Tracker/
│   ├── README.md
│   └── tracker.py
├── Zeus/
│   ├── README.md
│   ├── shortcodes.txt
│   └── zeus.py
├── cookies.py
├── requirements.txt
└── update.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "" 
    directory: "/"
    schedule:
      interval: "weekly"


================================================
FILE: .github/workflows/codeql.yml
================================================
name: "CodeQL"

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  schedule:
    - cron: '26 10 * * 4'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3
      
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}

    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2
      with:
        category: "/language:${{matrix.language}}"


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct - InstaTools

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
advances
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that they deem
inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at .
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version
[1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and
[2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md),
and was generated by [contributing-gen](https://github.com/bttger/contributing-gen).

================================================
FILE: CONTRIBUTING.md
================================================
<!-- omit in toc -->
# Contributing to InstaTools

First off, thanks for taking the time to contribute! ❤️

All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉

> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
> - Star the project
> - Tweet about it
> - Refer this project in your project's readme
> - Mention the project at local meetups and tell your friends/colleagues

<!-- omit in toc -->
## Table of Contents

- [Code of Conduct](#code-of-conduct)
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)
- [Improving The Documentation](#improving-the-documentation)
- [Styleguides](#styleguides)
- [Commit Messages](#commit-messages)
- [Join The Project Team](#join-the-project-team)


## Code of Conduct

This project and everyone participating in it is governed by the
[InstaTools Code of Conduct](https://github.com/new92/InstaToolsblob/master/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable behavior
to .


## I Have a Question

> If you want to ask a question, we assume that you have read the available [Documentation]().

Before you ask a question, it is best to search for existing [Issues](https://github.com/new92/InstaTools/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.

If you then still feel the need to ask a question and need clarification, we recommend the following:

- Open an [Issue](https://github.com/new92/InstaTools/issues/new).
- Provide as much context as you can about what you're running into.
- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant.

We will then take care of the issue as soon as possible.

<!--
You might want to create a separate issue tag for questions and include it in this description. People should then tag their issues accordingly.

Depending on how large the project is, you may want to outsource the questioning, e.g. to Stack Overflow or Gitter. You may add additional contact and information possibilities:
- IRC
- Slack
- Gitter
- Stack Overflow tag
- Blog
- FAQ
- Roadmap
- E-Mail List
- Forum
-->

## I Want To Contribute

> ### Legal Notice <!-- omit in toc -->
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.

### Reporting Bugs

<!-- omit in toc -->
#### Before Submitting a Bug Report

A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.

- Make sure that you are using the latest version.
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](). If you are looking for support, you might want to check [this section](#i-have-a-question)).
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/new92/InstaToolsissues?q=label%3Abug).
- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
- Collect information about the bug:
- Stack trace (Traceback)
- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
- Possibly your input and the output
- Can you reliably reproduce the issue? And can you also reproduce it with older versions?

<!-- omit in toc -->
#### How Do I Submit a Good Bug Report?

> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to .
<!-- You may add a PGP key to allow the messages to be sent encrypted as well. -->

We use GitHub issues to track bugs and errors. If you run into an issue with the project:

- Open an [Issue](https://github.com/new92/InstaTools/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
- Explain the behavior you would expect and the actual behavior.
- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
- Provide the information you collected in the previous section.

Once it's filed:

- The project team will label the issue accordingly.
- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced.
- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be [implemented by someone](#your-first-code-contribution).

<!-- You might want to create an issue template for bugs and errors that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->


### Suggesting Enhancements

This section guides you through submitting an enhancement suggestion for InstaTools, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.

<!-- omit in toc -->
#### Before Submitting an Enhancement

- Make sure that you are using the latest version.
- Read the [documentation]() carefully and find out if the functionality is already covered, maybe by an individual configuration.
- Perform a [search](https://github.com/new92/InstaTools/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.

<!-- omit in toc -->
#### How Do I Submit a Good Enhancement Suggestion?

Enhancement suggestions are tracked as [GitHub issues](https://github.com/new92/InstaTools/issues).

- Use a **clear and descriptive title** for the issue to identify the suggestion.
- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. <!-- this should only be included if the project has a GUI -->
- **Explain why this enhancement would be useful** to most InstaTools users. You may also want to point out the other projects that solved it better and which could serve as inspiration.

<!-- You might want to create an issue template for enhancement suggestions that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->

### Your First Code Contribution
<!-- TODO
include Setup of env, IDE and typical getting started instructions?

-->

### Improving The Documentation
<!-- TODO
Updating, improving and correcting the documentation

-->

## Styleguides
### Commit Messages
<!-- TODO

-->

## Join The Project Team
<!-- TODO -->

<!-- omit in toc -->
## Attribution
This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)!

================================================
FILE: Chronos/README.md
================================================
# Chronos ⌛

**Short description:** Chronos is a tool that analyzes how often a user posts on Instagram.

**Long description:** Chronos is a Python tool crafted to analyze a user's post frequency. It offers a straightforward way to understand posting habits on the platform, ideal for marketers, influencers, and curious users alike. With its intuitive interface and powerful functionality, Chronos empowers users to make informed decisions about their posting schedule to maximize engagement and reach. Whether you're a social media enthusiast or a data-driven strategist, Chronos provides the tools to unlock the secrets of Instagram posting frequency and optimize your online presence effectively. **Chronos works perfectly with both public & private accounts.**

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

## Set up and run Chronos 🚀

```bash
python3 cookies.py
python3 update.py # if you want to check for updates else skip it.
cd Chronos
python3 chronos.py -u <your_username> -t <target> -s <path_to_session_file>
```

## Why Chronos 😶‍🌫️

1. **Insightful Analytics:** Chronos provides detailed insights into an Instagram account's posting frequency, allowing users to understand their own or competitors' posting habits. By visualizing posting patterns over time, users can optimize their content strategy for maximum engagement and reach.
2. **Competitive Advantage:** By analyzing competitors' posting frequency and timing, users can gain a competitive advantage in the social media landscape. Chronos enables users to stay ahead of the curve by identifying trends and adjusting their own posting strategy accordingly, leading to increased visibility and engagement.

## Features 🪄

- ~~Colored~~ ✅
- ~~Fixed bugs~~ ✅

## Expected files 📂

1) `consent.txt`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/8261999d-152a-4be0-88d1-df01243083ce)

![output](https://github.com/new92/InstaTools/assets/94779840/86c27637-5f25-4a30-aff7-2302116d2f09)


================================================
FILE: Chronos/chronos.py
================================================
# -*- coding: utf-8 -*-
"""
Author: new92
Github: @new92
Leetcode: @new92
PyPI: @new92
Contributors: [@Itsfizziks, @ProgramR4732]

Chronos is a python tool used for calculating the posts's frequency for an Instagram account.

For analysis example >>> ./Photos/output.png

{*********IMPORTANT*********}
User's login credentials (such as: username, session file) won't be stored ! 
Will be used only for the purpose of Chronos.
"""
try:
    import sys
    from time import sleep
    if sys.version_info[0] < 3:
        print("[✘] Error ! Chronos requires Python 3 ! ")
        sleep(1.3)
        print("""[+] Instructions to download Python 3: 
        Linux: apt install python3
        Windows: https://www.python.org/downloads/
        MacOS: https://docs.python-guide.org/starting/install3/osx/""")
        sleep(3)
        print("[+] Please install Python3 and then use Chronos ✅")
        sleep(1)
        print("[+] Exiting...")
        sleep(0.8)
        sys.exit()
    import platform
    from rich.align import Align
    from rich.table import Table
    from rich.live import Live
    from rich.console import Console
    console = Console()
    mods = ('sys', 'time', 'platform', 'os', 'colorama', 'rich', 'logging', 'requests', 'instaloader', 'ctypes', 'argparse', 'datetime')
    with console.status('[bold dark_orange]Loading module...[/]') as status:
        for mod in mods:
            sleep(0.85)
            console.log(f'[[bold red]{mod}[/]] => [bold green]okay ✔[/]')
    import instaloader
    import argparse
    import ctypes
    import logging
    import requests
    import os
    from os import system
    from datetime import datetime
    from colorama import init, Fore
except (ImportError, ModuleNotFoundError):
    print("[!] WARNING: Not all packages used in Chronos have been installed !")
    sleep(1.5)
    print("[+] Ignoring warning...")
    sleep(0.6)
    if sys.platform.startswith('linux') or sys.platform == 'darwin':
        if os.geteuid():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            os.execvp("sudo", ["sudo", sys.executable] + sys.argv)
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("sudo pip install -r ./../requirements.txt" if sys.platform.startswith('linux') else "python -m pip install ./../requirements.txt")
    elif platform.system() == 'Windows':
        if not ctypes.windll.shell32.IsUserAnAdmin():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
            if not ctypes.windll.shell32.IsUserAnAdmin():
                print("[+] Root user permission denied.")
                sleep(1)
                print("[+] Exiting...")
                sys.exit()
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("pip install -r ./../requirements.txt")

init(autoreset=True)
GREEN = Fore.GREEN
RED = Fore.RED
YELLOW = Fore.LIGHTYELLOW_EX
CYAN = Fore.LIGHTBLUE_EX

def clear():
    system('cls' if platform.system() == 'Windows' else 'clear')

sleep(0.8)
clear()
console.print("[bold green][✔] Successfully loaded modules.[/]")
sleep(0.8)
clear()

ANS = ('yes', 'no')
EMPTY = ('', ' ')

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}
js = ''
resp = requests.get('https://api.github.com/repos/new92/InstaTools', headers=headers)
if resp.status_code == 200:
    js = resp.json()

def fpath(fname: str):
    for root, dirs, files in os.walk('/'):
        if fname in files:
            return os.path.abspath(os.path.join(root, fname))

def ScriptInfo():
    rest = requests.get('https://api.github.com/repos/new92/InstaTools/contributors', headers=headers)
    contribs = []
    if rest.status_code == 200:
        jsn = rest.json()
        contribs = [jsn[i]['login'] for i in range(len(jsn))]
    lang = requests.get('https://api.github.com/repos/new92/InstaTools/languages', headers=headers)
    languages = list(lang.json().keys()) if lang.status_code == 200 else []
    print(f"{YELLOW}[+] Author | {js['owner']['login']}")
    print(f"{YELLOW}[+] Github | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Leetcode | @{js['owner']['login']}")
    print(f"{YELLOW}[+] PyPI | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Contributors | {contribs}")
    print(f"{YELLOW}[+] License | {js['license']['spdx_id']}")
    print(f"{YELLOW}[+] Programming language(s) used | {languages}")
    print(f"{YELLOW}[+] Script's name | {js['name']}")
    print(f"{YELLOW}[+] Latest update | {js['updated_at']}")
    print(f"{YELLOW}[+] File size | {os.stat(__file__).st_size} bytes")
    print(f"{YELLOW}[+] File path | {os.path.abspath(__file__)}")
    print(f"{YELLOW}[+] Directory path | {os.path.dirname(os.path.abspath(__file__))}")
    print(f"{YELLOW}|======|GITHUB REPO INFO|======|")
    print(f"{YELLOW}[+] Repo name | {js['name']}")
    print(f"{YELLOW}[+] Description | {js['description']}")
    print(f"{YELLOW}[+] Repo URL | {js['html_url']}")
    print(f"{YELLOW}[+] Stars | {js['stargazers_count']}")
    print(f"{YELLOW}[+] Forks | {js['forks']}")
    print(f"{YELLOW}[+] Watchers | {js['subscribers_count']}")
    print(f"{YELLOW}[+] Open issues | {js['open_issues_count']}")

def banner() -> str:
    console.print("""[bold green]
          █████                                                    
         ░░███                                                     
  ██████  ░███████   ████████   ██████  ████████    ██████   █████ 
 ███░░███ ░███░░███ ░░███░░███ ███░░███░░███░░███  ███░░███ ███░░  
░███ ░░░  ░███ ░███  ░███ ░░░ ░███ ░███ ░███ ░███ ░███ ░███░░█████ 
░███  ███ ░███ ░███  ░███     ░███ ░███ ░███ ░███ ░███ ░███ ░░░░███
░░██████  ████ █████ █████    ░░██████  ████ █████░░██████  ██████ 
 ░░░░░░  ░░░░ ░░░░░ ░░░░░      ░░░░░░  ░░░░ ░░░░░  ░░░░░░  ░░░░░░   
[/]""", justify='center')

TABLE = (
    (
        "[b white]Author[/]: [i light_green]new92[/]",
        "[green]https://new92.github.io/[/]"
    ),
    (
        "[b white]Github[/]: [i light_green]@new92[/]",
        "[green]https://github.com/new92[/]"
    ),
    (
        "[b white]Leetcode[/]: [i light_green]@new92[/]",
        "[green]https://leetcode.com/new92[/]"
    ),
    (
        "[b white]PyPI[/]: [i light_green]@new92[/]",
        "[green]https://pypi.org/user/new92[/]"
    )
)

def calculate(posts: int, period: int) -> float:
    return round(float(posts / period), 3)

def Uninstall() -> str:
    def rmdir(dire):
        for root, dirs, files in os.walk(dire):
            for file in files:
                os.remove(os.path.join(root,file))
            DIRS = (os.path.join(root, dir) for dir in dirs)
        for i in DIRS:
            os.rmdir(i)
        os.rmdir(dire)
    rmdir(fpath('InstaTools'))
    return f"{GREEN}[✔] Files and dependencies uninstalled successfully !"

def main(username: str, session: str, target: str):
    console = Console()
    table = Table(show_footer=False)
    centered = Align.center(table)
    clear()
    banner()
    print("\n")
    with Live(centered, console=console, screen=False):
        table.add_column('Socials', no_wrap=False)
        table.add_column('Url', no_wrap=False)
        for row in TABLE:
            table.add_row(*row)
    print("\n")
    console.print("[bold yellow][+] Chronos is a python tool used for calculating the posts's frequency for an Instagram account.[/]")
    print("\n")
    console.print("[bold yellow][1] Find the frequency of posts[/]")
    console.print("[bold yellow][2] Show Chronos's info[/]")
    console.print("[bold yellow][3] Uninstall InstaTools[/]")
    console.print("[bold yellow][4] Exit[/]")
    num=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while num not in range(1,5):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1-4]")
        sleep(0.8)
        num=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if num == 1:
        clear()
        if not os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'consent.txt')):
            sleep(0.4)
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").strip().lower()
            while con not in ANS or con in EMPTY:
                print(f"{RED}[✘] Invalid answer !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                sleep(1)
                con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").strip().lower()
            if con == ANS[0]:
                logging.basicConfig(
                    filename='consent.txt',
                    level=logging.INFO,
                    format='%(asctime)s [%(levelname)s]: %(message)s',
                    datefmt='%d-%m-%Y | %H:%M:%S'
                )
                logging.info('Yes I consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given Instagram account.')
            else:
                print(f"{YELLOW}[OK]")
                sleep(1)
                print(f"{YELLOW}[1] Exit")
                print(f"{YELLOW}[2] Uninstall Chronos and exit")
                num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                valErr = num in (1, 2)
                while not valErr:
                    try:
                        print(f"{YELLOW}[1] Exit")
                        print(f"{YELLOW}[2] Uninstall Chronos and exit")
                        sleep(1)
                        num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                        valErr = num in (1,2)
                    except ValueError:
                        print(f"{RED}[✘] Invalid number.")
                        sleep(1)
                        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                        sleep(1)
                if num == 1:
                    clear()
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    sys.exit()
                else:
                    clear()
                    print(Uninstall())
                    sleep(2)
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    print(f"{YELLOW}[+] Thank you for using Chronos 🫡")
                    sleep(0.8)
                    print(f"{YELLOW}[+] Until we meet again 👋")
                    sleep(0.8)
                    sys.exit()
        loader = instaloader.Instaloader()
        sleep(1.4)
        clear()
        sleep(0.5)
        print(f"{GREEN}[*] Using session file >>> {session}...")
        sleep(1.3)
        try:
            with open(session, 'rb') as sessionfile:
                loader.context.load_session_from_file(username, sessionfile)
        except instaloader.exceptions.ConnectionException as ex:
            print(f"{RED}[✘] Error loading session file !")
            sleep(1)
            print(f"{YELLOW}[+] Error message >>> {ex}")
            sleep(0.8)
            print(f"{RED}[+] Exiting...")
            sys.exit()
        sleep(0.5)
        print(f"{GREEN}[✔] Session loaded successfully !")
        sleep(1.4)
        print(f"{GREEN}[✔] Login successfull !")
        sleep(0.85)
        clear()
        sleep(0.4)
        print(f"{CYAN}[*] Loading profile...")
        sleep(0.4)
        profile = instaloader.Profile.from_username(loader.context, target)
        sleep(0.7)
        print(f"{GREEN}[✔] Success.")
        sleep(0.4)
        clear()
        sleep(0.4)
        print(f"{CYAN}[*] Loading posts from @{profile.username}...")
        sleep(1)
        if profile.mediacount:
            sleep(0.5)
            print(f"{GREEN}[✔] Done. Successfully loaded {profile.mediacount} posts.")
            sleep(1)
            clear()
            sleep(0.5)
            print(f"{CYAN}[*] Analyzing...")
            sleep(0.3)
            last = ''
            for post in profile.get_posts():
                last = post
            now = datetime.now()
            years = int(now.strftime('%Y')) - last.date_utc.year
            months = abs(int(now.strftime('%m')) - last.date_utc.month)
            days = abs(int(now.strftime('%d')) - last.date_utc.day)
            hours = abs(int(now.strftime('%H')) - last.date_utc.hour)
            period = years * 365 + months * 30 + days + hours / 24
            frequency = calculate(int(profile.mediacount), period)
            sleep(0.7)
            print(f"{GREEN}[✔] Success !")
            sleep(0.4)
            clear()
            sleep(0.5)
            print(f"{GREEN}[→] @{target} posts every {frequency} day(s)." if frequency > 1 else f"{GREEN}[→] @{target} posts every {int(frequency * 24)} hour(s).")
            sleep(1.2)
        else:
            print(f"{RED}[✘] Error: No posts found on @{target} !")
            sleep(0.5)
    
    elif num == 2:
        clear()
        ScriptInfo()
        sleep(5)
    
    elif num == 3:
        clear()
        print(Uninstall())
        sleep(1)
        print(f"{GREEN}[+] Thank you for using Chronos 😁")
        sleep(0.8)
        print(f"{GREEN}[+] Until next time 👋")
        sleep(0.8)
        sys.exit()
    
    else:
        clear()
        print(f"{GREEN}[+] Thank you for using Chronos 😁")
        sleep(0.8)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.8)
        sys.exit()
    
    print(f"\n\n{YELLOW}[1] Return to menu\n{YELLOW}[2] Exit")
    number=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while number not in range(1,3):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
        sleep(1)
        number=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if number == 1:
        clear()
        main(username, session, target)
    else:
        clear()
        print(f"{RED}[+] Exiting...")
        sleep(1)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(1)
        sys.exit()

try:
    if __name__ == '__main__':
        sleep(2)
        clear()
        parser = argparse.ArgumentParser(description="Chronos is a python tool used for calculating the posts's frequency for an Instagram account.")
        parser.add_argument('-u', '--username', help='Your instagram username.')
        parser.add_argument('-t', '--target', help='The target username.')
        parser.add_argument('-s', '--session', help='The session file to use. To generate it >> python3 cookies.py')
        args = parser.parse_args()
        if len(sys.argv) < 4:
            print(f"{RED}[✘] Error: Missing arguments.")
            sleep(0.7)
            print(f"{GREEN}[+] Usage >>> python3 chronos.py -u <your_username> -t <target_username> -s <path_to_session_file>")
            sleep(1.5)
            args.username=input(f"{YELLOW}[::] Please enter your username >>> ") if not args.username else args.username
            args.target=input(f"{YELLOW}[::] Please enter the target username >>> ") if not args.target else args.target
            args.session=input(f"{YELLOW}[::] Please enter the session file >>> ") if not args.session else args.session
        main(args.username.strip().lower(), args.session.strip().replace('\\', '/'), args.target.strip().lower())
except (KeyboardInterrupt, EOFError):
    print(f"\n\n{RED}[*] <Ctrl + C> detected. Exiting safely...")
    sys.exit()


================================================
FILE: Delta/README.md
================================================
# Delta 📡

**Short description:** Delta efficiently extracts reels from Instagram accounts, simplifying content gathering for creators, marketers, and enthusiasts by using post shortcodes from a text file.

**Long description:** Delta is a powerful Python tool designed specifically for extracting reels from Instagram accounts with ease and efficiency. With its intuitive interface and robust functionality, Delta simplifies the process of gathering reels, making it an invaluable resource for content creators, marketers, and social media enthusiasts alike. By inputting the shortcodes of the desired Instagram posts contained within a text file, Delta swiftly retrieves and extracts reels, providing users with a comprehensive collection for further analysis or repurposing. Whether you're looking to stay updated on industry trends, gather inspiration for your own content, or monitor competitor activity, Delta streamlines the process, saving you time and effort. **Delta works for both public and private profiles (for private accounts its a requirement that the user follows them).**

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

## Set up and run Delta 🚀

```bash
python3 cookies.py
python3 update.py # if you want to check for updates else skip it.
cd Delta
python3 delta.py -u <your_username> -s <path_to_session_file>
```

## Why Delta 😶‍🌫️

1. **Efficient Reel Extraction:** Delta simplifies the process of extracting reels from Instagram accounts by allowing users to input shortcodes of desired posts contained within a text file. This feature streamlines the retrieval process, saving users time and effort compared to manual extraction methods.
2. **Inspiration and Content Curation:** Delta provides users with a diverse collection of reels, making it an ideal tool for gathering inspiration and curating content. Whether you're a content creator seeking fresh ideas or a marketer looking for engaging content to share, Delta's extraction capabilities enable you to discover compelling reels that resonate with your audience.
3. **Competitive Advantage:**  By using Delta to monitor competitors' reels, users can gain valuable insights into their strategies and stay ahead of the competition. Analyzing competitors' content allows users to identify trends, understand audience preferences, and refine their own content strategy for improved engagement and visibility.

## Features 🪄

- ~~Speed~~ ✅
- ~~Colored~~ ✅
- ~~Fixed bugs~~ ✅

## Expected files 📂

- `consent.txt`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/da0a585a-7643-4f2f-bf52-dc1422b5cb8a)

![output](https://github.com/new92/InstaTools/assets/94779840/4294e6b2-ab64-4865-9c7b-8804336a34ef)




================================================
FILE: Delta/delta.py
================================================
"""
Author: new92
Github: @new92
Leetcode: @new92
PyPI: @new92
Contributors: [@Itsfizziks, @ProgramR4732]

Delta is a python tool used for extracting reel(s) from Instagram.

For short code example >>> ./Photos/short_code_example.png

For output example >>> ./Photos/output.png

{*********IMPORTANT*********}
User's login credentials (such as: username, session file) won't be stored ! 
Will be used only for the purpose of Delta.
"""
try:
    import sys
    from time import sleep
    if sys.version_info[0] < 3:
        print("[✘] Error ! Delta requires Python 3 ! ")
        sleep(1.3)
        print("""[+] Instructions to download Python 3 : 
        Linux: apt install python3
        Windows: https://www.python.org/downloads/
        MacOS: https://docs.python-guide.org/starting/install3/osx/""")
        sleep(3)
        print("[+] Please install Python 3 and then use Delta ✅")
        sleep(1)
        print("[+] Exiting...")
        sleep(0.8)
        sys.exit()
    from rich.align import Align
    from rich.table import Table
    from rich.live import Live
    from rich.console import Console
    console = Console()
    mods = ('sys', 'time', 'platform', 'os', 'colorama', 'rich', 'logging', 'requests', 'ctypes', 'argparse')
    with console.status('[bold dark_orange]Loading module...[/]') as status:
        for mod in mods:
            sleep(0.85)
            console.log(f'[[bold red]{mod}[/]] => [bold green]okay ✔[/]')
    import platform
    from os import system
    import os
    import requests
    import ctypes
    import argparse
    import instaloader
    import logging
    from colorama import init, Fore
except (ImportError, ModuleNotFoundError):
    print("[!] WARNING: Not all packages used in Delta have been installed !")
    sleep(1.5)
    print("[+] Ignoring warning...")
    sleep(0.6)
    if sys.platform.startswith('linux') or sys.platform == 'darwin':
        if os.geteuid():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            os.execvp("sudo", ["sudo", sys.executable] + sys.argv)
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("sudo pip install -r ./../requirements.txt" if sys.platform.startswith('linux') else "python -m pip install ./../requirements.txt")
    elif platform.system() == 'Windows':
        if not ctypes.windll.shell32.IsUserAnAdmin():
            print("[✘] Root user not detected !")
            sleep(2)
            print("[+] Attempting to enable root user...")
            sleep(1)
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
            if not ctypes.windll.shell32.IsUserAnAdmin():
                print("[+] Root user permission denied.")
                sleep(1)
                print("[+] Exiting...")
                sys.exit()
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("pip install -r ./../requirements.txt")

init(autoreset=True)
GREEN = Fore.GREEN
YELLOW = Fore.LIGHTYELLOW_EX
RED = Fore.RED
CYAN = Fore.LIGHTBLUE_EX

def clear():
    system('cls' if platform.system() == 'Windows' else 'clear')

sleep(0.8)
clear()
console.print("[bold green][✔] Successfully loaded modules.[/]")
sleep(0.8)
clear()

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}
js = ''
resp = requests.get('https://api.github.com/repos/new92/InstaTools', headers=headers)
if resp.status_code == 200:
    js = resp.json()

ANS = ('yes', 'no')
EMPTY = ('', ' ')

def fpath(fname: str):
    for root, dirs, files in os.walk('/'):
        if fname in files:
            return os.path.abspath(os.path.join(root, fname))

TABLE = (
    (
        "[b white]Author[/]: [i light_green]new92[/]",
        "[green]https://new92.github.io/[/]"
    ),
    (
        "[b white]Github[/]: [i light_green]@new92[/]",
        "[green]https://github.com/new92[/]"
    ),
    (
        "[b white]Leetcode[/]: [i light_green]@new92[/]",
        "[green]https://leetcode.com/new92[/]"
    ),
    (
        "[b white]PyPI[/]: [i light_green]@new92[/]",
        "[green]https://pypi.org/user/new92[/]"
    )
)

def ScriptInfo():
    rest = requests.get('https://api.github.com/repos/new92/InstaTools/contributors', headers=headers)
    contribs = []
    if rest.status_code == 200:
        jsn = rest.json()
        contribs = [jsn[i]['login'] for i in range(len(jsn))]
    lang = requests.get('https://api.github.com/repos/new92/InstaTools/languages', headers=headers)
    languages = list(lang.json().keys()) if lang.status_code == 200 else []
    print(f"{YELLOW}[+] Author | {js['owner']['login']}")
    print(f"{YELLOW}[+] Github | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Leetcode | @{js['owner']['login']}")
    print(f"{YELLOW}[+] PyPI | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Contributors | {contribs}")
    print(f"{YELLOW}[+] License | {js['license']['spdx_id']}")
    print(f"{YELLOW}[+] Programming language(s) used | {languages}")
    print(f"{YELLOW}[+] Script's name | {js['name']}")
    print(f"{YELLOW}[+] Latest update | {js['updated_at']}")
    print(f"{YELLOW}[+] File size | {os.stat(__file__).st_size} bytes")
    print(f"{YELLOW}[+] File path | {os.path.abspath(__file__)}")
    print(f"{YELLOW}[+] Directory path | {os.path.dirname(os.path.abspath(__file__))}")
    print(f"{YELLOW}|======|GITHUB REPO INFO|======|")
    print(f"{YELLOW}[+] Repo name | {js['name']}")
    print(f"{YELLOW}[+] Description | {js['description']}")
    print(f"{YELLOW}[+] Repo URL | {js['html_url']}")
    print(f"{YELLOW}[+] Stars | {js['stargazers_count']}")
    print(f"{YELLOW}[+] Forks | {js['forks']}")
    print(f"{YELLOW}[+] Watchers | {js['subscribers_count']}")
    print(f"{YELLOW}[+] Open issues | {js['open_issues_count']}")

def Uninstall() -> str:
    def rmdir(dire):
        DIRS = []
        for root, dirs, files in os.walk(dire):
            for file in files:
                os.remove(os.path.join(root,file))
            for dir in dirs:
                DIRS.append(os.path.join(root,dir))
        for i in range(len(DIRS)):
            os.rmdir(DIRS[i])
        os.rmdir(dire)
    rmdir(fpath('InstaTools'))
    return f"{GREEN}[✔] Files and dependencies removed successfully !"

def count() -> int:
    return len([directory for directory in os.listdir('.') if os.path.isdir(directory)])

def banner() -> str:
    console.print("""[bold green]
________   ___________.____   ___________ _____    
\______ \  \_   _____/|    |  \__    ___//  _  \   
 |    |  \  |    __)_ |    |    |    |  /  /_\  \  
 |    `   \ |        \|    |___ |    | /    |    \ 
/_______  //_______  /|_______ \|____| \____|__  / 
        \/         \/         \/               \/  
[/]""", justify='center')
    
def main(username: str, session: str):
    console = Console()
    table = Table(show_footer=False)
    centered = Align.center(table)
    clear()
    banner()
    print("\n")
    with Live(centered, console=console, screen=False):
        table.add_column('Socials', no_wrap=False)
        table.add_column('Url', no_wrap=False)
        for row in TABLE:
            table.add_row(*row)
    print("\n")
    console.print("[bold yellow][+] Delta is a python tool used for extracting reel(s) from Instagram.[/]")
    print("\n")
    console.print("[bold yellow][1] Download reel(s)[/]")
    console.print("[bold yellow][2] Show Delta's info[/]")
    console.print("[bold yellow][3] Uninstall InstaTools[/]")
    console.print("[bold yellow][4] Exit[/]")
    num=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while num not in range(1,5):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1-4]")
        sleep(1)
        num=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if num == 1:
        clear()
        loader = instaloader.Instaloader()
        if not os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'consent.txt')):
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").lower()
            while con not in ANS:
                print(f"{RED}[✘] Invalid answer !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                sleep(1)
                con= input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").lower()
            if con == ANS[0]:
                logging.basicConfig(
                    filename='consent.txt',
                    level=logging.INFO,
                    format='%(asctime)s [%(levelname)s]: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S'
                )
                logging.info('Yes I consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given Instagram account.')
            else:
                print(f"{YELLOW}[OK]")
                sleep(1)
                print(f"{YELLOW}[1] Exit")
                print(f"{YELLOW}[2] Uninstall Delta and exit")
                num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                valErr = num in (1, 2)
                while not valErr:
                    try:
                        print(f"{YELLOW}[1] Exit")
                        print(f"{YELLOW}[2] Uninstall Delta and exit")
                        sleep(1)
                        num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                        valErr = num in (1,2)
                    except ValueError:
                        print(f"{RED}[✘] Invalid number !")
                        sleep(1)
                        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                        sleep(1)
                if num == 1:
                    clear()
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    sys.exit()
                else:
                    clear()
                    print(Uninstall())
                    sleep(2)
                    print(f"{RED}[+] Exiting...")
                    sleep(0.8)
                    print(f"{YELLOW}[+] Thank you for using Delta 🫡")
                    sleep(0.8)
                    print(f"{YELLOW}[+] Until we meet again 👋")
                    sleep(0.8)
                    sys.exit()
        sleep(2)
        clear()
        print(f"{CYAN}[*] Using session file >>> {session}...")
        sleep(1.3)
        try:
            with open(session, 'rb') as sessionfile:
                loader.context.load_session_from_file(username, sessionfile)
        except instaloader.exceptions.ConnectionException as ex:
            print(f"{RED}[✘] Error loading session file !")
            sleep(0.8)
            print(f"{YELLOW}[+] Error message >>> {ex}")
            sleep(1.5)
            print(f"{RED}[+] Exiting...")
            sys.exit()
        print(f"{GREEN}[✔] Session loaded successfully !")
        sleep(0.8)
        print(f"{GREEN}[✔] Login successfull !")
        sleep(0.85)
        clear()
        print(f"{CYAN}[*] Loading shortcodes...")
        sleep(0.7)
        with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'shortcodes.txt'), 'r') as shortcodes:
            codes = [shortcode.strip().replace('\n', '') for shortcode in shortcodes]
        sleep(0.7)
        print(f"{GREEN}[✔] Success ! Loaded {len(codes)} shortcodes.")
        sleep(1)
        clear()
        before = count()
        print(f"{CYAN}[*] Downloading reels...")
        sleep(0.5)
        for i in range(len(codes)):
            try:
                post = instaloader.Post.from_shortcode(loader.context, codes[i])
                target_directory = os.path.join(os.getcwd(), f'reel_{i}')
                loader.download_post(post, target=target_directory)
                print(f"{GREEN}[✔] Downloaded {codes[i]} reel.")
            except Exception as e:
                print(f"{RED}[✘] Failed to download {codes[i]} reel.")
                sleep(0.8)
                print(f"{CYAN}[*] Error message >>> {e}")
                sleep(0.8)
                print(f"{CYAN}[*] Skipping to the next reel...")
                sleep(0.4)
        sleep(0.7)
        print(f"\n\n{GREEN}[✔] Done. Successfully downloaded {abs(before - count())}/{len(codes)} reels.")
    
    elif num == 2:
        clear()
        ScriptInfo()
        sleep(5)

    elif num == 3:
        clear()
        print(Uninstall())
        sleep(1)
        print(f"{GREEN}[+] Thank you for using Delta 😁")
        sleep(0.8)
        print(f"{GREEN}[+] Until next time 👋")
        sleep(0.8)
        sys.exit()
    
    else:
        clear()
        print(f"{GREEN}[+] Thank you for using Delta 😁")
        sleep(0.8)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.8)
        sys.exit()
    
    print(f"\n\n{YELLOW}[1] Return to menu\n{YELLOW}[2] Exit")
    number=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while number not in range(1,3):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
        sleep(1)
        number=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if number == 1:
        clear()
        main(username, session)
    else:
        clear()
        print(f"{RED}[+] Exiting...")
        sleep(1)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(1)
        sys.exit()

try:  
    if __name__ == '__main__':
        sleep(2)
        clear()
        parser = argparse.ArgumentParser(description='Delta is a python tool used for extracting reel(s) from Instagram.')
        parser.add_argument('-u', '--username', help='Your instagram username.')
        parser.add_argument('-s', '--session', help='The session file to use. To generate it >> python3 cookies.py')
        args = parser.parse_args()
        if len(sys.argv) < 3:
            print(f"{RED}[✘] Error: Missing arguments.")
            sleep(0.7)
            print(f"{GREEN}[+] Usage >>> python3 delta.py -u <your_username> -s <path_to_session_file>")
            sleep(1.5)
            args.username=input(f"{YELLOW}[::] Please enter your username >>> ") if not args.username else args.username
            args.session=input(f"{YELLOW}[::] Please enter the session file >>> ") if not args.session else args.session
        main(args.username.strip().lower(), args.session.strip().replace('\\', '/'))
except (KeyboardInterrupt, EOFError):
    print(f"\n\n{RED}[*] <Ctrl + C> detected. Exiting safely...")
    sys.exit()

================================================
FILE: Delta/shortcodes.txt
================================================


================================================
FILE: Hermes/README.md
================================================
# Hermes 🪽

**Short description:** Hermes analyzes Instagram likes for a specific post, extracting and analyzing user profiles based on their engagement.

**Long description:** Hermes is a powerful Python script designed to delve into the world of Instagram likes and provide insightful data about the users who have engaged with a specific post. This script takes an Instagram post URL as input and extracts information about the likers, offering a comprehensive analysis of their profiles. **Hermes functions well with posts from verified accounts, but when dealing with a large number of likes, the execution time may be prolonged.**

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

## Set up and run Hermes 🚀

```bash
python3 cookies.py
python3 update.py # if you want to check for updates else skip it.
cd Hermes
python3 hermes.py -u <your_username> -p <posts_shortcode> -s <path_to_session_file>
```

## Why Hermes 😶‍🌫️

1. **User type breakdown:** Hermes categorizes likers into public and private accounts, providing a quick overview of the post's engagement dynamics.
2. **Effortless Data Storage and Analysis:** With Hermes, the process of data storage is streamlined. The script automatically saves all relevant information in a CSV file at the end of its execution. This feature not only ensures data integrity but also facilitates seamless integration with data analysis tools. Users can effortlessly conduct further analysis and draw meaningful conclusions from the stored data, making Hermes an efficient choice for those prioritizing ease of use and post-analysis activities.
3. **Privacy-Respecting Functionality:** Hermes prioritizes user privacy and adheres to ethical data extraction practices. The script solely focuses on publicly available data and does not access or store any sensitive information. This commitment to privacy ensures that users can utilize Hermes for Instagram analytics without compromising the security and privacy of user data. Choosing Hermes reflects a commitment to responsible data handling practices in the realm of social media analysis.

## Features 🪄

- ~~Data storage~~ ✅
- ~~Data visualization (prettytable usage)~~ ✅
- ~~Colored~~ ✅
- ~~Fixed bugs~~ ✅

## Expected files 📂

1) `Hermes.csv`
2) `consent.txt`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/8bd81157-37ef-4256-857a-13da83043aaf)

![output](https://github.com/new92/InstaTools/assets/94779840/f3207703-e76a-46e3-8e27-867076616014)


================================================
FILE: Hermes/hermes.py
================================================
# -*- coding: utf-8 -*-
"""
Author: new92
Github: @new92
Leetcode: @new92
PyPI: @new92
Contributors: [@Itsfizziks, @ProgramR4732]

Hermes is a python script which analyzes a post and categorises its likers.

For short code example >>> ./Photos/short_code_example.png

For analysis example >>> ./Photos/output.png

{*********IMPORTANT*********}
User's login credentials (such as: username, session file) won't be stored ! 
Will be used only for the purpose of Hermes.
"""

try:
    import sys
    from time import sleep
    if sys.version_info[0] < 3:
        print("[✘] Error ! Hermes requires Python 3 ! ")
        sleep(1.3)
        print("""[+] Instructions to download Python 3: 
        Linux: apt install python3
        Windows: https://www.python.org/downloads/
        MacOS: https://docs.python-guide.org/starting/install3/osx/""")
        sleep(3)
        print("[+] Please install Python 3 and then use Hermes ✅")
        sleep(1)
        print("[+] Exiting...")
        sleep(0.8)
        sys.exit()
    import platform
    from rich.align import Align
    from rich.table import Table
    from rich.live import Live
    from rich.console import Console
    console = Console()
    mods = ('sys', 'time', 'platform', 'os', 'colorama', 'rich', 'logging', 'requests', 'instaloader', 'csv', 'prettytable', 'argparse', 'ctypes')
    with console.status('[bold dark_orange]Loading module...[/]') as status:
        for mod in mods:
            sleep(0.85)
            console.log(f'[[bold red]{mod}[/]] => [bold green]okay ✔[/]')
    import instaloader
    import csv
    import logging
    import requests
    import ctypes
    import os
    import argparse
    from os import system
    from colorama import init, Fore
    from prettytable import PrettyTable
except (ImportError, ModuleNotFoundError):
    print("[!] WARNING: Not all packages used in Hermes have been installed !")
    sleep(1.5)
    print("[+] Ignoring warning...")
    sleep(0.6)
    if sys.platform.startswith('linux') or sys.platform == 'darwin':
        if os.geteuid():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            os.execvp("sudo", ["sudo", sys.executable] + sys.argv)
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("sudo pip install -r ./../requirements.txt" if sys.platform.startswith('linux') else "python -m pip install ./../requirements.txt")
    elif platform.system() == 'Windows':
        if not ctypes.windll.shell32.IsUserAnAdmin():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
            if not ctypes.windll.shell32.IsUserAnAdmin():
                print("[+] Root user permission denied.")
                sleep(1)
                print("[+] Exiting...")
                sys.exit()
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("pip install -r ./../requirements.txt")

init(autoreset=True)
GREEN = Fore.GREEN
RED = Fore.RED
YELLOW = Fore.LIGHTYELLOW_EX

def clear():
    system('cls' if platform.system() == 'Windows' else 'clear')

sleep(0.8)
clear()
console.print("[bold green][✔] Successfully loaded modules.[/]")
sleep(0.8)
clear()

ANS = ('yes', 'no')
EMPTY = ('', ' ')

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}
js = ''
resp = requests.get('https://api.github.com/repos/new92/InstaTools', headers=headers)
if resp.status_code == 200:
    js = resp.json()

def fpath(fname: str):
    for root, dirs, files in os.walk('/'):
        if fname in files:
            return os.path.abspath(os.path.join(root, fname))

def ScriptInfo():
    rest = requests.get('https://api.github.com/repos/new92/InstaTools/contributors', headers=headers)
    contribs = []
    if rest.status_code == 200:
        jsn = rest.json()
        contribs = [jsn[i]['login'] for i in range(len(jsn))]
    lang = requests.get('https://api.github.com/repos/new92/InstaTools/languages', headers=headers)
    languages = list(lang.json().keys()) if lang.status_code == 200 else []
    print(f"{YELLOW}[+] Author | {js['owner']['login']}")
    print(f"{YELLOW}[+] Github | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Leetcode | @{js['owner']['login']}")
    print(f"{YELLOW}[+] PyPI | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Contributors | {contribs}")
    print(f"{YELLOW}[+] License | {js['license']['spdx_id']}")
    print(f"{YELLOW}[+] Programming language(s) used | {languages}")
    print(f"{YELLOW}[+] Script's name | {js['name']}")
    print(f"{YELLOW}[+] Latest update | {js['updated_at']}")
    print(f"{YELLOW}[+] File size | {os.stat(__file__).st_size} bytes")
    print(f"{YELLOW}[+] File path | {os.path.abspath(__file__)}")
    print(f"{YELLOW}[+] Directory path | {os.path.dirname(os.path.abspath(__file__))}")
    print(f"{YELLOW}|======|GITHUB REPO INFO|======|")
    print(f"{YELLOW}[+] Repo name | {js['name']}")
    print(f"{YELLOW}[+] Description | {js['description']}")
    print(f"{YELLOW}[+] Repo URL | {js['html_url']}")
    print(f"{YELLOW}[+] Stars | {js['stargazers_count']}")
    print(f"{YELLOW}[+] Forks | {js['forks']}")
    print(f"{YELLOW}[+] Watchers | {js['subscribers_count']}")
    print(f"{YELLOW}[+] Open issues | {js['open_issues_count']}")

def banner() -> str:
    console.log("""[bold green]
                             __ __    ___  ____   ___ ___    ___   _____
                            |  T  T  /  _]|    \ |   T   T  /  _] / ___/
                            |  l  | /  [_ |  D  )| _   _ | /  [_ (   \_ 
                            |  _  |Y    _]|    / |  \_/  |Y    _] \__  T
                            |  |  ||   [_ |    \ |   |   ||   [_  /  \ |
                            |  |  ||     T|  .  Y|   |   ||     T \    |
                            l__j__jl_____jl__j\_jl___j___jl_____j  \___j
[/]""", justify='center')

TABLE = (
    (
        "[b white]Author[/]: [i light_green]new92[/]",
        "[green]https://new92.github.io/[/]"
    ),
    (
        "[b white]Github[/]: [i light_green]@new92[/]",
        "[green]https://github.com/new92[/]"
    ),
    (
        "[b white]Leetcode[/]: [i light_green]@new92[/]",
        "[green]https://leetcode.com/new92[/]"
    ),
    (
        "[b white]PyPI[/]: [i light_green]@new92[/]",
        "[green]https://pypi.org/user/new92[/]"
    )
)

output = (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Hermes.csv')).replace('\\', '/')

def Uninstall() -> str:
    def rmdir(dire):
        for root, dirs, files in os.walk(dire):
            for file in files:
                os.remove(os.path.join(root,file))
            DIRS = (os.path.join(root, dir) for dir in dirs)
        for i in DIRS:
            os.rmdir(i)
        os.rmdir(dire)
    rmdir(fpath('InstaTools'))
    return f"{GREEN}[✔] Files and dependencies removed successfully !"

global username, session, code

def main(username: str, session: str, code: str):
    console = Console()
    table = Table(show_footer=False)
    centered = Align.center(table)
    clear()
    banner()
    print("\n")
    with Live(centered, console=console, screen=False):
        table.add_column('Socials', no_wrap=False)
        table.add_column('Url', no_wrap=False)
        for row in TABLE:
            table.add_row(*row)
    print("\n")
    console.print("[bold yellow][+] Use Hermes to analyze a post and categorise its likers.[/]")
    print("\n")
    console.print("[bold yellow][1] Analyze post[/]")
    console.print("[bold yellow][2] Show Hermes's info[/]")
    console.print("[bold yellow][3] Clear csv file[/]")
    console.print("[bold yellow][4] Uninstall InstaTools[/]")
    console.print("[bold yellow][5] Exit[/]")
    num=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while num not in range(1,6):
        print(f"{RED}[✘] Invalid number !")
        sleep(0.8)
        print(f"{GREEN}[+] Acceptable numbers >>> [1-5]")
        sleep(0.8)
        num=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if num == 1:
        clear()
        loader = instaloader.Instaloader()
        if not os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'consent.txt')):
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").lower()
            while con not in ANS:
                print(f"{RED}[✘] Invalid answer !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                sleep(1)
                con= input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").lower()
            if con == ANS[0]:
                logging.basicConfig(
                    filename='consent.txt',
                    level=logging.INFO,
                    format='%(asctime)s [%(levelname)s]: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S'
                )
                logging.info('Yes I consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given Instagram account.')
            else:
                print(f"{YELLOW}[OK]")
                sleep(1)
                print(f"{YELLOW}[1] Exit")
                print(f"{YELLOW}[2] Uninstall Hermes and exit")
                num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                valErr = num in (1, 2)
                while not valErr:
                    try:
                        print(f"{YELLOW}[1] Exit")
                        print(f"{YELLOW}[2] Uninstall Hermes and exit")
                        sleep(1)
                        num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                        valErr = num in (1,2)
                    except ValueError:
                        print(f"{RED}[✘] Invalid number !")
                        sleep(1)
                        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                        sleep(1)
                if num == 1:
                    clear()
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    sys.exit()
                else:
                    clear()
                    print(Uninstall())
                    sleep(2)
                    print(f"{RED}[+] Exiting...")
                    sleep(0.8)
                    print(f"{YELLOW}[+] Thank you for using Hermes 🫡")
                    sleep(0.8)
                    print(f"{YELLOW}[+] Until we meet again 👋")
                    sleep(0.8)
                    sys.exit()
        sleep(2)
        clear()
        print(f"{GREEN}[*] Using session file >>> {session}...")
        sleep(1.3)
        try:
            with open(session, 'rb') as sessionfile:
                loader.context.load_session_from_file(username, sessionfile)
        except instaloader.exceptions.ConnectionException as ex:
            print(f"{RED}[✘] Error loading session file !")
            sleep(0.8)
            print(f"{YELLOW}[+] Error message >>> {ex}")
            sleep(1.5)
            print(f"{RED}[+] Exiting...")
            sys.exit()
        print(f"{GREEN}[✔] Session loaded successfully !")
        sleep(0.8)
        print(f"{GREEN}[✔] Login successfull !")
        sleep(0.85)
        clear()
        sleep(0.7)
        print(f"{GREEN}[+] Analyzing....")
        sleep(0.5)
        post = instaloader.Post.from_shortcode(loader.context, code)
        likers = post.get_likes()
        LIKERS = [liker.username for liker in likers]
        if LIKERS:
            PUBS, PRIVS, VERS, POSTS, FOLLS, STATUS = [], [], [], [], [], []
            for liker in LIKERS:
                profile = instaloader.Profile.from_username(loader.context, liker)
                posts = profile.mediacount
                followers = profile.followers
                if profile.is_private:
                    PRIVS.append(liker)
                    STATUS.append('boring 🥱')
                else:
                    VERS.append(liker) if profile.is_verified else PUBS.append(liker)
                    if profile.is_verified:
                        STATUS.append('verified ✅')
                    elif posts > 49 or followers > 9999:
                        STATUS.append('interesting 🤔')
                    elif posts > 40:
                        STATUS.append('captivating 📸')
                    elif followers > 5000:
                        STATUS.append('famous 🌍')
                    else:
                        STATUS.append('ordinary 🤖')
                POSTS.append(posts)
                FOLLS.append(followers)
            lks = len(LIKERS)
            privs = len(PRIVS)
            vers = len(VERS)
            pubs = len(PUBS)
            posts = sum(POSTS)
            folls = sum(FOLLS)
            PRIVS.extend([''] * (len(LIKERS) - len(PRIVS)))
            PUBS.extend([''] * (len(LIKERS) - len(PUBS)))
            VERS.extend([''] * (len(LIKERS) - len(VERS)))
            table = PrettyTable()
            table.field_names = ['Likers', 'Publics', 'Privates', 'Verified', 'Posts', 'Followers', 'Status']
            for i in range(len(LIKERS)):
                table.add_row(row=[LIKERS[i], PUBS[i], PRIVS[i], VERS[i], POSTS[i], FOLLS[i], STATUS[i]])
            sleep(0.5)
            print(f"{GREEN}[✔] Success.")
            sleep(0.5)
            print(f"{YELLOW}[+] Total likers >>> {lks}")
            sleep(0.4)
            print(f"{YELLOW}[+] Total privates >>> {privs}")
            sleep(0.4)
            print(f"{YELLOW}[+] Total publics >>> {pubs}")
            sleep(0.4)
            print(f"{YELLOW}[+] Total verified >>> {vers}")
            sleep(0.4)
            print(f"{YELLOW}[+] Total posts >>> {posts}")
            sleep(0.4)
            print(f"{YELLOW}[+] Total followers >>> {folls}")
            sleep(1.3)
            clear()
            print(f"{YELLOW}{table}")
            sleep(4)
            print(f"\n\n{GREEN}[*] Writing results to csv file...")
            sleep(0.4)
            L = [
                ['Total likers', 'Total privates', 'Total publics', 'Total verified', 'Total posts', 'Total followers'],
                [lks, privs, pubs, vers, posts, folls],
                ['Likers', 'Private', 'Public', 'Verified', 'Posts', 'Followers', 'Status']
            ]
            for i in range(len(LIKERS)):
                L.append([LIKERS[i], PRIVS[i], PUBS[i], VERS[i], POSTS[i], FOLLS[i]])
            with open(output, 'w', newline='') as file:
                writer = csv.writer(file)
                writer.writerows(L)
            print(f"{GREEN}[✔] Done. Saved data at >>> {output}")
        else:
            print(f"{RED}[✘] Error: No likers found.")
            sleep(0.5)
            print(f"{RED}[+] Exiting...")
            sys.exit()

    elif num == 2:
        clear()
        ScriptInfo()
        sleep(5)

    elif num == 3:
        clear()
        if os.path.exists(output):
            with open(output, 'w') as file:
                pass
            print(f"{GREEN}[✔] CSV file cleared successfully !")
            sleep(0.8)
        else:
            print(f"{RED}[✘] Unable to locate csv file.")
            sleep(0.8)

    elif num == 4:
        clear()
        print(Uninstall())
        sleep(1)
        print(f"{GREEN}[+] Thank you for using Hermes 😁")
        sleep(0.8)
        print(f"{GREEN}[+] Until next time 👋")
        sleep(0.8)
        sys.exit()
    
    else:
        clear()
        print(f"{GREEN}[+] Thank you for using Hermes 😁")
        sleep(0.8)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.8)
        sys.exit()
    
    print(f"\n\n{YELLOW}[1] Return to menu\n{YELLOW}[2] Exit")
    number=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while number not in range(1,3):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
        sleep(1)
        number=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if number == 1:
        clear()
        main(username, session, code)
    else:
        clear()
        print(f"{RED}[+] Exiting...")
        sleep(1)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(1)
        sys.exit()
try:
    if __name__ == '__main__':
        sleep(2)
        clear()
        parser = argparse.ArgumentParser(description='Hermes is a python script which analyzes a post and categorises its likers.')
        parser.add_argument('-u', '--username', help='Your instagram username.')
        parser.add_argument('-p', '--code', help='The shortcode of the post to use. For exampe >> /Hermes/Photos/short_code_example.png')
        parser.add_argument('-s', '--session', help='The session file to use. To generate it >> python3 cookies.py')
        args = parser.parse_args()
        if len(sys.argv) < 4:
            print(f"{RED}[✘] Error: Missing arguments.")
            sleep(0.7)
            print(f"{GREEN}[+] Usage >>> python3 hermes.py -u <your_username> -p <posts_shortcode> -s <path_to_session_file>")
            sleep(1.5)
            args.username=input(f"{YELLOW}[::] Please enter your username >>> ") if not args.username else args.username
            args.code=input(f"{YELLOW}[::] Please enter the post's shortcode >>> ") if not args.code else args.code
            args.session=input(f"{YELLOW}[::] Please enter the session file >>> ") if not args.session else args.session
        main(args.username.strip().lower(), args.session.strip().replace('\\', '/'), args.code.strip())
except (KeyboardInterrupt, EOFError):
    print(f"\n\n{RED}[*] <Ctrl + C> detected. Exiting safely...")
    sys.exit()


================================================
FILE: Hunter/README.md
================================================
# Hunter 🔫

**Short description:** Hunter tracks ghost followers on Instagram accounts, identifying users who follow but don't engage with content.

**Long description:** Hunter is a multifunctional Python script primarily designed for Instagram users. It serves as a tool for tracking ghost followers on Instagram accounts. Ghost followers are those who follow an account but don't engage with its content, such as liking or commenting. **Hunter works well with small accounts (500 followers or lower) but when dealing with larger numbers the execution time might increase.**

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

## Set up and run Hunter 🚀

```bash
python3 cookies.py
python3 update.py # if you want to check for updates else skip it.
cd Hunter
python3 hunter.py -u <your_username> -s <path_to_session_file>
```

## Why Hunter 😶‍🌫️

1. **Privacy-Respecting Functionality:** Hunter prioritizes user privacy and adheres to ethical data extraction practices. The script solely focuses on publicly available data and does not access or store any sensitive information. This commitment to privacy ensures that users can utilize Hunter for Instagram analytics without compromising the security and privacy of user data. Choosing Hunter reflects a commitment to responsible data handling practices in the realm of social media analysis.

2. **Ghost Follower Tracking:** Hunter offers a reliable solution for tracking ghost followers on Instagram, helping users identify and manage inactive or unengaged followers effectively. By providing detailed insights into follower activity and engagement, Hunter empowers users to optimize their follower base and enhance their social media presence.

3. **Convenient and Customizable Analysis:** Hunter provides a user-friendly interface and customizable analysis options, allowing users to tailor their ghost follower tracking experience to suit their specific needs. With features such as session file support and flexible filtering, Hunter streamlines the process of analyzing follower data, enabling users to make informed decisions about their Instagram account management strategy.

## Features 🪄

- ~~Data storage~~ ✅
- ~~Data visualization (prettytable usage)~~ ✅
- ~~Colored~~ ✅
- ~~Fixed bugs~~ ✅

## Expected files 📂

1) `Hunter.csv`
2) `consent.txt`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/38d96388-6bd2-4a44-b2ab-354b38213d7c)

![output](https://github.com/new92/InstaTools/assets/94779840/0cb5d58e-5ac3-41f5-9672-08eddde691d5)



================================================
FILE: Hunter/hunter.py
================================================
# -*- coding: utf-8 -*-
"""
Author: new92
Github: @new92
Leetcode: @new92
Contributors: [@Itsfizziks, @ProgramR4732]

Hunter is a python script used for tracking the ghost followers of your instagram account.

For results example >>> ./Photos/output.jpg

{*********IMPORTANT*********}
User's login credentials (such as: username, session file) won't be stored ! 
Will be used only for the purpose of Hunter.
"""
try:
    import sys
    from time import sleep
    if sys.version_info[0] < 3:
        print("[✘] Error ! Hunter requires Python version 3.X ! ")
        sleep(1.3)
        print("""[+] Instructions to download Python 3.x : 
        Linux: apt install python3
        Windows: https://www.python.org/downloads/
        MacOS: https://docs.python-guide.org/starting/install3/osx/""")
        sleep(3)
        print("[+] Please install Python 3 and then use Hunter ✅")
        sleep(1)
        print("[+] Exiting...")
        sleep(1)
        sys.exit()
    import platform
    from os import system
    from rich.align import Align
    from rich.table import Table
    from rich.live import Live
    from rich.console import Console
    console = Console()
    mods = ('sys', 'time', 'platform', 'os', 'colorama', 'rich', 'logging', 'requests', 'instaloader', 'csv', 'prettytable', 'argparse', 'ctypes')
    with console.status('[bold dark_orange]Loading module...[/]') as status:
        for mod in mods:
            sleep(0.85)
            console.log(f'[[bold red]{mod}[/]] => [bold green]okay ✔[/]')
    import requests
    import os
    import ctypes
    import instaloader
    import logging
    import csv
    import argparse
    from colorama import init, Fore
    from prettytable import PrettyTable
except ImportError or ModuleNotFoundError:
    print("[!] WARNING: Not all packages used in Hunter have been installed !")
    sleep(1.5)
    print("[+] Ignoring warning...")
    sleep(0.6)
    if sys.platform.startswith('linux') or sys.platform == 'darwin':
        if os.geteuid():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            os.execvp("sudo", ["sudo", sys.executable] + sys.argv)
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("sudo pip install -r ./../requirements.txt" if sys.platform.startswith('linux') else "python -m pip install ./../requirements.txt")
    elif platform.system() == 'Windows':
        if not ctypes.windll.shell32.IsUserAnAdmin():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
            if not ctypes.windll.shell32.IsUserAnAdmin():
                print("[+] Root user permission denied.")
                sleep(1)
                print("[+] Exiting...")
                sys.exit()
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("pip install -r ./../requirements.txt")

init(autoreset=True)
GREEN = Fore.GREEN
YELLOW = Fore.LIGHTYELLOW_EX
RED = Fore.RED

def clear():
    system('cls' if platform.system() == 'Windows' else 'clear')

sleep(0.8)
clear()
console.print("[bold green][✔] Successfully loaded modules.[/]")
sleep(0.8)
clear()

ANS = ('yes', 'no')
EMPTY = ('', ' ')

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}
js = ''
resp = requests.get('https://api.github.com/repos/new92/InstaTools', headers=headers)
if resp.status_code == 200:
    js = resp.json()

def fpath(fname: str):
    for root, dirs, files in os.walk('/'):
        if fname in files:
            return os.path.abspath(os.path.join(root, fname))

def ScriptInfo():
    rest = requests.get('https://api.github.com/repos/new92/InstaTools/contributors', headers=headers)
    contribs = []
    if rest.status_code == 200:
        jsn = rest.json()
        contribs = [jsn[i]['login'] for i in range(len(jsn))]
    lang = requests.get('https://api.github.com/repos/new92/InstaTools/languages', headers=headers)
    languages = list(lang.json().keys()) if lang.status_code == 200 else []
    print(f"{YELLOW}[+] Author | {js['owner']['login']}")
    print(f"{YELLOW}[+] Github | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Leetcode | @{js['owner']['login']}")
    print(f"{YELLOW}[+] PyPI | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Contributors | {contribs}")
    print(f"{YELLOW}[+] License | {js['license']['spdx_id']}")
    print(f"{YELLOW}[+] Programming language(s) used | {languages}")
    print(f"{YELLOW}[+] Script's name | {js['name']}")
    print(f"{YELLOW}[+] Latest update | {js['updated_at']}")
    print(f"{YELLOW}[+] File size | {os.stat(__file__).st_size} bytes")
    print(f"{YELLOW}[+] File path | {os.path.abspath(__file__)}")
    print(f"{YELLOW}[+] Directory path | {os.path.dirname(os.path.abspath(__file__))}")
    print(f"{YELLOW}|======|GITHUB REPO INFO|======|")
    print(f"{YELLOW}[+] Repo name | {js['name']}")
    print(f"{YELLOW}[+] Description | {js['description']}")
    print(f"{YELLOW}[+] Repo URL | {js['html_url']}")
    print(f"{YELLOW}[+] Stars | {js['stargazers_count']}")
    print(f"{YELLOW}[+] Forks | {js['forks']}")
    print(f"{YELLOW}[+] Watchers | {js['subscribers_count']}")
    print(f"{YELLOW}[+] Open issues | {js['open_issues_count']}")

def banner() -> str:
    console.log("""[bold green]
   ▄█    █▄    ███    █▄  ███▄▄▄▄       ███        ▄████████    ▄████████ 
  ███    ███   ███    ███ ███▀▀▀██▄ ▀█████████▄   ███    ███   ███    ███ 
  ███    ███   ███    ███ ███   ███    ▀███▀▀██   ███    █▀    ███    ███ 
 ▄███▄▄▄▄███▄▄ ███    ███ ███   ███     ███   ▀  ▄███▄▄▄      ▄███▄▄▄▄██▀ 
▀▀███▀▀▀▀███▀  ███    ███ ███   ███     ███     ▀▀███▀▀▀     ▀▀███▀▀▀▀▀   
  ███    ███   ███    ███ ███   ███     ███       ███    █▄  ▀███████████ 
  ███    ███   ███    ███ ███   ███     ███       ███    ███   ███    ███ 
  ███    █▀    ████████▀   ▀█   █▀     ▄████▀     ██████████   ███    ███ 
                                                               ███    ███ 
[/]""", justify='center')

TABLE = (
    (
        "[b white]Author[/]: [i light_green]new92[/]",
        "[green]https://new92.github.io/[/]"
    ),
    (
        "[b white]Github[/]: [i light_green]@new92[/]",
        "[green]https://github.com/new92[/]"
    ),
    (
        "[b white]Leetcode[/]: [i light_green]@new92[/]",
        "[green]https://leetcode.com/new92[/]"
    ),
    (
        "[b white]PyPI[/]: [i light_green]@new92[/]",
        "[green]https://pypi.org/user/new92[/]"
    )
)

def Uninstall() -> str:
    def rmdir(dire):
        DIRS = []
        for root, dirs, files in os.walk(dire):
            for file in files:
                os.remove(os.path.join(root,file))
            for dir in dirs:
                DIRS.append(os.path.join(root,dir))
        for i in range(len(DIRS)):
            os.rmdir(DIRS[i])
        os.rmdir(dire)
    rmdir(fpath('InstaTools'))
    return f"{GREEN}[✓] Files and dependencies removed successfully !"

output = (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Hunter.csv')).replace('\\', '/')

def main(username: str, session: str):
    console = Console()
    table = Table(show_footer=False)
    centered = Align.center(table)
    banner()
    print('\n')
    with Live(centered, console=console, screen=False):
        table.add_column('Socials', no_wrap=False)
        table.add_column('Url', no_wrap=False)
        for row in TABLE:
            table.add_row(*row)
    print('\n')
    console.print("[bold yellow][+] Hunter is a python script used for tracking the ghost followers of a user.[/]")
    print('\n')
    console.print("[bold yellow][1] Track ghost followers[/]")
    console.print("[bold yellow][2] Shows Hunter's info[/]")
    console.print("[bold yellow][3] Clear csv file[/]")
    console.print("[bold yellow][4] Uninstall InstaTools[/]")
    console.print("[bold yellow][5] Exit[/]")
    print('\n')
    num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones) >>> "))
    while num not in range(1,6):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1-5]")
        sleep(1)
        num=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if num == 1:
        clear()
        loader = instaloader.Instaloader()
        if not os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'consent.txt')):
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").lower()
            while con not in ANS:
                print(f"{RED}[✘] Invalid answer !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                sleep(1)
                con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").lower()
            if con == ANS[0]:
                logging.basicConfig(
                    filename='consent.txt',
                    level=logging.INFO,
                    format='%(asctime)s [%(levelname)s]: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S'
                )
                logging.info('Yes I consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given Instagram account.')
            else:
                print(f"{YELLOW}[OK]")
                sleep(1)
                print(f"{YELLOW}[1] Exit")
                print(f"{YELLOW}[2] Uninstall Hunter and exit")
                num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                valErr = num in (1, 2)
                while not valErr:
                    try:
                        print(f"{YELLOW}[1] Exit")
                        print(f"{YELLOW}[2] Uninstall Hunter and exit")
                        sleep(1)
                        num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones): "))
                        valErr = num in (1,2)
                    except ValueError:
                        print(f"{RED}[✘] Invalid number !")
                        sleep(1)
                        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                        sleep(1)
                if num == 1:
                    clear()
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    sys.exit()
                else:
                    clear()
                    print(Uninstall())
                    sleep(2)
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    print(f"{YELLOW}[+] Thank you for using Hunter 🫡")
                    sleep(0.8)
                    print(f"{YELLOW}[+] Until we meet again 👋")
                    sleep(1)
                    sys.exit()
        sleep(2)
        clear()
        print(f"{GREEN}[*] Using session file >>> {session}...")
        sleep(1.3)
        try:
            with open(session, 'rb') as sessionfile:
                loader.context.load_session_from_file(username, sessionfile)
                print(f"{GREEN}[✔] Session loaded successfully !")
                sleep(0.8)
        except instaloader.exceptions.ConnectionException as ex:
            print(f"{RED}[✘] Error loading session file !")
            sleep(0.8)
            print(f"{YELLOW}[+] Error message >>> {ex}")
            sleep(1.5)
            print(f"{RED}[+] Exiting...")
            sys.exit()
        print(f"{GREEN}[✔] Login successfull !")
        sleep(0.85)
        clear()
        sleep(0.7)
        print(f"{GREEN}[+] Analyzing....")
        sleep(0.5)
        profile = instaloader.Profile.from_username(loader.context, username)
        print(f"{YELLOW}[+] Gathering likes from posts...")
        sleep(0.8)
        if not profile.mediacount or not profile.followers:
            print(f"{RED}[✘] No posts detected ! Working with 0 posts will result to false analysis." if not profile.mediacount else f"{RED}[✘] No followers detected ! Working with 0 followers will result to false analysis. ")
            sleep(0.8)
            print(f"{RED}[+] Exiting...")
            sys.exit()
        likes = set()
        for post in profile.get_posts():
            likes = likes | set(post.get_likes())
        sleep(0.8)
        print(f"{YELLOW}[+] Fetching followers...")
        sleep(0.8)
        followers = set(profile.get_followers())
        ghosts = followers - likes
        pubs, privs, vers, posts, folls, fols = [], [], [], [], [], []
        for ghost in ghosts:
            if ghost.is_private:
                privs.append(ghost.username)
            elif ghost.is_verified:
                vers.append(ghost.username)
            else:
                pubs.append(ghost.username)
            posts.append(ghost.mediacount)
            folls.append(ghost.followers)
            fols.append(ghost.followees)
        ghosts = [ghost.username for ghost in ghosts]
        pubs.extend([''] * (len(ghosts) - len(pubs)))
        privs.extend([''] * (len(ghosts) - len(privs)))
        vers.extend([''] * (len(ghosts) - len(vers)))
        table = PrettyTable()
        table.field_names = ['Ghosts', 'Publics', 'Privates', 'Verified', 'Posts', 'Followers', 'Followings']
        for i in range(len(ghosts)):
            table.add_row(row=[ghosts[i], pubs[i], privs[i], vers[i], posts[i], folls[i], fols[i]])
        sleep(0.5)
        print(f"{GREEN}[✔] Success." if table else f"{RED}[✘] Unable to create the table !")
        ghsts = len(ghosts)
        prvs = len(privs)
        pbs = len(pubs)
        vrs = len(vers)
        sleep(0.5)
        print(f"[+] Total ghosts >>> {ghsts}")
        sleep(0.4)
        print(f"[+] Total privates >>> {prvs}")
        sleep(0.4)
        print(f"[+] Total publics >>> {pbs}")
        sleep(0.4)
        print(f"[+] Total verified >>> {vrs}")
        sleep(0.4)
        clear()
        print(f"{YELLOW}{table}")
        L = [
            ['Total ghosts', 'Total privates', 'Total publics', 'Total verified'],
            [ghsts, prvs, pbs, vrs],
            ['Ghosts', 'Private', 'Public', 'Verified', 'Posts', 'Followers', 'Followings']
        ]
        for i in range(len(pubs)):
            L.append([ghosts[i], privs[i], pubs[i], vers[i], posts[i], folls[i], fols[i]])
        with open(output, mode='w', newline='\n') as file:
            writer = csv.writer(file)
            writer.writerows(L)
        out = (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'consent.txt')).replace('\\', '/')
        sleep(5)
        print("\n\n\n")
        print(f"{GREEN}[+] CSV file location >>> {out}")
    
    elif num == 2:
        clear()
        ScriptInfo()
        sleep(5)
    
    elif num == 3:
        clear()
        if os.path.exists(output):
            with open(output, 'w') as file:
                pass
            print(f"{GREEN}[✔] CSV file cleared successfully !")
            sleep(0.8)
        else:
            print(f"{RED}[✘] Unable to locate CSV file.")
            sleep(0.8)
    
    elif num == 4:
        clear()
        print(Uninstall())
        sleep(2)
        print(f"{GREEN}[+] Thank you for using Hunter 😁")
        sleep(0.8)
        print(f"{GREEN}[+] Until next time 👋")
        sleep(0.8)
        sys.exit()

    elif num == 5:
        clear()
        print(f"{GREEN}[+] Thank you for using Hunter 😁")
        sleep(0.8)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.8)
        sys.exit()

    print(f"\n\n{YELLOW}[1] Return to menu\n{YELLOW}[2] Exit")
    number=int(input(f"{YELLOW}[::] Please enter a number (from the above ones): "))
    while number not in range(1,3):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
        sleep(1)
        number=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones): "))
    if number == 1:
        clear()
        main(username, session)
    else:
        clear()
        print(f"{RED}[+] Exiting...")
        sleep(1)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(1)
        sys.exit()
try:
    if __name__ == '__main__':
        sleep(2)
        clear()
        parser = argparse.ArgumentParser(description='Hunter is a python script used for tracking the ghost followers of your instagram account.')
        parser.add_argument('-u', '--username', help='Your username on Instagram.')
        parser.add_argument('-s', '--session', help='The session file to use. To generate it >> python3 cookies.py')
        args = parser.parse_args()
        if len(sys.argv) < 3:
            print(f"{RED}[✘] Error: Missing arguments.")
            sleep(0.7)
            print(f"{GREEN}[+] Usage >>> python3 hunter.py -u <your_username> -s <path_to_session_file>")
            sleep(1.5)
            args.username=input(f"{YELLOW}[::] Please enter your username >>> ") if not args.username else args.username
            args.session=input(f"{YELLOW}[::] Please enter the session file >>> ") if not args.session else args.session
        main(args.username.strip().lower(), args.session.strip().replace('\\', '/'))
except (KeyboardInterrupt, EOFError):
    print(f"\n\n{RED}[*] <Ctrl + C> detected. Exiting safely...")
    sys.exit()

================================================
FILE: IsVer/README.md
================================================
# IsVer 🔭

**Short description:** IsVer attempts to identify verified accounts a user follows, offering insights into their network.

**Long description:** IsVer is a handy Python script designed to analyze and report on the Instagram followings of a user. With IsVer, you can effortlessly identify and keep track of the verified accounts that a user follows on Instagram, providing valuable insights into their network. Stay informed about the presence of verified users in your Instagram connections with this user-friendly script. **Works for both public and private accounts**

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like this one.

## Set up and run IsVer 🚀

```bash
python3 cookies.py
python3 update.py # if you want to check for updates else skip it.
cd IsVer
python3 isver.py -u <your_username> -t <target_username> -s <path_to_session_file>
```

## Why IsVer ? 😶‍🌫️

1. **Verification Status Identification:** The script can identify and flag verified accounts among the user's Instagram followings. It helps users quickly spot which of their followed accounts have the blue verification badge.
2. **List of Verified Accounts:** IsVer generates a list of the verified accounts within the user's followings, making it easy for users to see who they are following that holds a verified status.
3. **User-Friendly Interface:** The script provides a user-friendly report that displays the verified accounts in a clear and organized manner, making it easy for users to digest the information.
4. **Automation:** Depending on the script's design, it may automate the process of identifying verified accounts among a user's followings, saving users time and effort compared to manually checking each account.
5. **Customization:** Some versions of IsVer may allow users to customize the script's behavior, such as specifying which accounts to scan or which actions to take based on the verification status.

## Features 🚀

- ~~Log file~~ ✅
- ~~Colored~~ ✅
- Data visualization
- Categorize the verified accounts (sports, lifestyle, companies etc.)

## Expected files 📂

1) `IsVer__Log.txt`
2) `consent.txt`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/8bcb5040-4b87-4293-9be5-2ca0683ecc50)

![output](https://github.com/new92/InstaTools/assets/94779840/9b2a0a9a-3848-489a-9c7e-0d2f6324a9a5)

![output_](https://github.com/new92/InstaTools/assets/94779840/6788b6b9-1d5f-4dde-9aa6-0db99c96b596)


================================================
FILE: IsVer/isver.py
================================================
# -*- coding: utf-8 -*-
"""
Author: new92
Github: @new92
Leetcode: @new92
PyPI: @new92
Contributors: [@Itsfizziks, @ProgramR4732]

IsVer finds and displays the usernames of the verified users followed by a user on Instagram.

For results example >>> ./Photos/output.png   &   ./Photos/output_.png

{*********IMPORTANT*********}
User's login credentials (such as: username, session file) won't be stored ! 
Will be used only for the purpose of IsVer.
"""
try:
    import sys
    from time import sleep
    if sys.version_info[0] < 3:
        print("[✘] Error ! IsVer requires Python 3 ! ")
        sleep(1.3)
        print("""[+] Instructions to download Python 3 : 
        Linux: apt install python3
        Windows: https://www.python.org/downloads/
        MacOS: https://docs.python-guide.org/starting/install3/osx/""")
        sleep(3)
        print("[+] Please install Python 3 and then use IsVer ✅")
        sleep(1)
        print("[+] Exiting...")
        sleep(0.8)
        sys.exit()
    import platform
    from rich.align import Align
    from rich.table import Table
    from rich.live import Live
    from rich.console import Console
    console = Console()
    mods = ('sys', 'time', 'rich', 'platform', 'os', 'requests', 'instaloader', 'logging', 'prettytable', 'colorama', 'ctypes', 'argparse')
    with console.status('[bold dark_orange]Loading module...[/]') as status:
        for mod in mods:
            sleep(0.85)
            console.log(f'[[bold red]{mod}[/]] => [bold green]okay ✔[/]')
    import os
    from os import system
    import instaloader
    import requests
    import logging
    import ctypes
    import argparse
    from prettytable import PrettyTable
    from colorama import init, Fore
except (ImportError, ModuleNotFoundError):
    print("[!] WARNING: Not all packages used in IsVer have been installed !")
    sleep(1.5)
    print("[+] Ignoring warning...")
    sleep(0.6)
    if sys.platform.startswith('linux') or sys.platform == 'darwin':
        if os.geteuid():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            os.execvp("sudo", ["sudo", sys.executable] + sys.argv)
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("sudo pip install -r ./../requirements.txt" if sys.platform.startswith('linux') else "python -m pip install ./../requirements.txt")
    elif platform.system() == 'Windows':
        if not ctypes.windll.shell32.IsUserAnAdmin():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
            if not ctypes.windll.shell32.IsUserAnAdmin():
                print("[+] Root user permission denied.")
                sleep(1)
                print("[+] Exiting...")
                sys.exit()
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("pip install -r ./../requirements.txt")

init(autoreset=True)
GREEN = Fore.GREEN
RED = Fore.RED
YELLOW = Fore.LIGHTYELLOW_EX

def clear():
    system('cls' if platform.system() == 'Windows' else 'clear')

sleep(0.8)
clear()
console.print("[bold green][✔] Successfully loaded modules.[/]")
sleep(0.8)
clear()

ANS = ('yes', 'no')
EMPTY = ('', ' ')

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}
js = ''
resp = requests.get('https://api.github.com/repos/new92/InstaTools', headers=headers)
if resp.status_code == 200:
    js = resp.json()

def fpath(fname: str):
    for root, dirs, files in os.walk('/'):
        if fname in files:
            return os.path.abspath(os.path.join(root, fname))

def ScriptInfo():
    rest = requests.get('https://api.github.com/repos/new92/InstaTools/contributors', headers=headers)
    contribs = []
    if rest.status_code == 200:
        jsn = rest.json()
        contribs = [jsn[i]['login'] for i in range(len(jsn))]
    lang = requests.get('https://api.github.com/repos/new92/InstaTools/languages', headers=headers)
    languages = list(lang.json().keys()) if lang.status_code == 200 else []
    print(f"{YELLOW}[+] Author | {js['owner']['login']}")
    print(f"{YELLOW}[+] Github | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Leetcode | @{js['owner']['login']}")
    print(f"{YELLOW}[+] PyPI | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Contributors | {contribs}")
    print(f"{YELLOW}[+] License | {js['license']['spdx_id']}")
    print(f"{YELLOW}[+] Programming language(s) used | {languages}")
    print(f"{YELLOW}[+] Script's name | {js['name']}")
    print(f"{YELLOW}[+] Latest update | {js['updated_at']}")
    print(f"{YELLOW}[+] File size | {os.stat(__file__).st_size} bytes")
    print(f"{YELLOW}[+] File path | {os.path.abspath(__file__)}")
    print(f"{YELLOW}[+] Directory path | {os.path.dirname(os.path.abspath(__file__))}")
    print(f"{YELLOW}|======|GITHUB REPO INFO|======|")
    print(f"{YELLOW}[+] Repo name | {js['name']}")
    print(f"{YELLOW}[+] Description | {js['description']}")
    print(f"{YELLOW}[+] Repo URL | {js['html_url']}")
    print(f"{YELLOW}[+] Stars | {js['stargazers_count']}")
    print(f"{YELLOW}[+] Forks | {js['forks']}")
    print(f"{YELLOW}[+] Watchers | {js['subscribers_count']}")
    print(f"{YELLOW}[+] Open issues | {js['open_issues_count']}")
    
def banner() -> str:
    console.log("""[bold green]
 /$$$$$$  /$$$$$$        /$$    /$$ /$$$$$$$$ /$$$$$$$ 
|_  $$_/ /$$__  $$      | $$   | $$| $$_____/| $$__  $$
  | $$  | $$  \__/      | $$   | $$| $$      | $$  \ $$
  | $$  |  $$$$$$       |  $$ / $$/| $$$$$   | $$$$$$$/
  | $$   \____  $$       \  $$ $$/ | $$__/   | $$__  $$
  | $$   /$$  \ $$        \  $$$/  | $$      | $$  \ $$
 /$$$$$$|  $$$$$$/         \  $/   | $$$$$$$$| $$  | $$
|______/ \______/           \_/    |________/|__/  |__/
[/]""", justify='center')

TABLE = (
    (
        "[b white]Author[/]: [i light_green]new92[/]",
        "[green]https://new92.github.io/[/]"
    ),
    (
        "[b white]Github[/]: [i light_green]@new92[/]",
        "[green]https://github.com/new92[/]"
    ),
    (
        "[b white]Leetcode[/]: [i light_green]@new92[/]",
        "[green]https://leetcode.com/new92[/]"
    ),
    (
        "[b white]PyPI[/]: [i light_green]@new92[/]",
        "[green]https://pypi.org/user/new92[/]"
    )
)

name = 'IsVer__Log.txt'

def Uninstall() -> str:
    def rmdir(dire):
        for root, dirs, files in os.walk(dire):
            for file in files:
                os.remove(os.path.join(root,file))
            DIRS = (os.path.join(root, dir) for dir in dirs)
        for i in DIRS:
            os.rmdir(i)
        os.rmdir(dire)
    rmdir(fpath('InstaTools'))
    return f"{GREEN}[✔] Files and dependencies removed successfully !"

def main(username: str, target: str, session: str):
    console = Console()
    table = Table(show_footer=False)
    centered = Align.center(table)
    banner()
    print("\n")
    with Live(centered, console=console, screen=False):
        table.add_column('Socials', no_wrap=False)
        table.add_column('Url', no_wrap=False)
        for row in TABLE:
            table.add_row(*row)
    print("\n")
    console.print("[bold yellow][+] Use IsVer to track down the verified users a user follows on Instagram.[/]")
    print("\n")
    console.print("[bold yellow][1] Initiate IsVer[/]")
    console.print("[bold yellow][2] Show IsVer's info[/]")
    console.print("[bold yellow][3] Clear log file[/]")
    console.print("[bold yellow][4] Uninstall InstaTools[/]")
    console.print("[bold yellow][5] Exit[/]")
    num=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while num not in range(1,6):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1-5]")
        sleep(1)
        num=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if num == 1:
        clear()
        loader = instaloader.Instaloader()
        if not os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'consent.txt')):
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").strip().lower()
            while con not in ANS or con in EMPTY:
                print(f"{RED}[✘] Invalid answer !")
                sleep(0.8)
                print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                sleep(0.8)
                con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").strip().lower()
            if con == ANS[0]:
                logging.basicConfig(
                    filename='consent.txt',
                    level=logging.INFO,
                    format='%(asctime)s [%(levelname)s]: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S'
                )
                logging.info('Yes I consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given Instagram account.')
            else:
                print(f"{YELLOW}[OK]")
                sleep(1)
                print(f"{YELLOW}[1] Exit")
                print(f"{YELLOW}[2] Uninstall IsVer and exit")
                num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones) >>> "))
                valErr = num in (1,2)
                while not valErr:
                    try:
                        print(f"{YELLOW}[1] Exit")
                        print(f"{YELLOW}[2] Uninstall IsVer and exit")
                        sleep(1)
                        num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones) >>> "))
                        valErr = num in (1,2)
                    except ValueError:
                        print(f"{RED}[✘] Invalid number !")
                        sleep(1)
                        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                        sleep(1)
                if num == 1:
                    clear()
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    sys.exit()
                else:
                    clear()
                    print(Uninstall())
                    sleep(2)
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    print(f"{YELLOW}[+] Thank you for using IsVer 🫡")
                    sleep(0.8)
                    print(f"{YELLOW}[+] Until we meet again 👋")
                    sleep(0.8)
                    sys.exit()
        sleep(2)
        clear()
        sleep(0.5)
        print(f"{GREEN}[*] Using session file >>> {session}...")
        sleep(1.3)
        try:
            with open(session, 'rb') as sessionfile:
                loader.context.load_session_from_file(username, sessionfile)
        except instaloader.exceptions.ConnectionException as ex:
            print(f"{RED}[✘] Error loading session file !")
            sleep(1)
            print(f"{YELLOW}[+] Error message >>> {ex}")
            sleep(0.8)
            print(f"{RED}[+] Exiting...")
            sys.exit()
        print(f"{GREEN}[✔] Session loaded successfully !")
        sleep(1.4)
        print(f"{GREEN}[✔] Login successfull !")
        sleep(0.85)
        clear()
        sleep(0.4)
        print(f"{YELLOW}[+] Loading profile...")
        sleep(0.6)
        profile = None
        try:
            profile = instaloader.Profile.from_username(loader.context, target)
        except instaloader.ProfileNotExistsException:
            print(f"{RED}[✘] Profile not found")
            sleep(1)
            print("[1] Return to menu")
            print("[2] Exit")
            num=int(input("[::] Please enter a number (from the above ones) >>> "))
            while num not in range(1,3):
                print(f"{RED}[✘] Invalid number !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                sleep(1)
                num=int(input("[::] Please enter again a number (from the above ones) >>> "))
            if num == 1:
                clear()
                main(username, target, session)
            else:
                clear()
                print(f"{RED}[+] Exiting...")
                sleep(1)
                print(f"{GREEN}[+] See you next time 👋")
                sleep(1)
                sys.exit()
        if profile:
            print(f"{GREEN}[✔] Profile loaded successfully !")
            sleep(0.85)
            clear()
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            keep=input(f"{YELLOW}[?] Keep log ? ").strip().lower()
            while keep not in ANS or keep in EMPTY:
                print(f"{RED}[✘] Invalid answer !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                sleep(1)
                keep=input(f"{YELLOW}[?] Keep log ? ").strip().lower()
            keep = keep == ANS[0]
            sleep(0.8)
            clear()
            print(f"{YELLOW}[+] Fetching {target}'s followings...")
            sleep(0.8)
            FOLLOWINGS = [following.username for following in profile.get_followees()]
            VERS, FOLS, FOLLS = [], [], []
            if not FOLLOWINGS:
                print(f"{RED}[✘] Fail. 0 followers detected. IsVer can't work without followers.")
                sleep(0.9)
                print(f"{RED}[+] Exiting...")
                sys.exit()
            print(f"{GREEN}[✔] Done.")
            sleep(1)
            print(f"{YELLOW}[+] Extracting verified followings...")
            sleep(0.8)
            for it in FOLLOWINGS:
                prof = instaloader.Profile.from_username(loader.context, it)
                if prof.is_verified:
                    VERS.append(prof.username)
                    FOLS.append(prof.followees)
                    FOLLS.append(prof.followers)
            followees = profile.followees
            fol = len(VERS) > 0
            print(f"{GREEN}[✔] Done." if fol else f"{RED}[✘] Fail.")
            sleep(0.8)
            print(f"{YELLOW}[+] Is {target} following verified accounts ? {GREEN}{fol}" if fol else f"{YELLOW}[+] Is {target} following verified accounts ? {RED}{fol}")
            sleep(0.6)
            if fol:
                print(f"{YELLOW}[+] {target} follows {len(VERS)} verified accounts.")
                sleep(1)
                table = PrettyTable()
                table.field_names = ['usernames', 'followers', 'followings']
                for i in range(len(VERS)):
                    table.add_row(row=[VERS[i], FOLLS[i], FOLS[i]])
                print(f"{YELLOW}{table}")
                sleep(5)
                print(f"{GREEN}[+] Percentage of verified accounts followed by {target} ==> {round((float(len(VERS)) / len(FOLLOWINGS)*100), 2)}%")
                sleep(0.8)
                print(f"{GREEN}[+] Verified followings ==> {len(VERS)}/{followees}")
                if keep:
                    with open(name, 'w', encoding='utf-8') as fp:
                        fp.write(str(table))
                    print(f"{GREEN}[✔] Successfully saved log !")
                    sleep(1.2)
                    path = fpath(name)
                    print(f"{GREEN}[↪] Name >>> {name}", f"{GREEN}[↪] Path >>> {path}", f"{GREEN}[↪] Size >>> {os.stat(path).st_size} bytes", sep='\n')
                    sleep(1.5)
                    
    elif num == 2:
        clear()
        ScriptInfo()
        sleep(5)

    elif num == 3:
        clear()
        location = os.path.join(os.path.dirname(os.path.abspath(__file__)), name)
        if os.path.exists(location):
            with open(location.replace('\\', '/'), 'w') as f:
                pass
            print(f"{GREEN}[✔] Log file cleared successfully !")
            sleep(0.8)
            print(f"{GREEN}[↪] Name >>> {name}", f"{GREEN}[↪] Location >>> {location}", f"{GREEN}[↪] Size >>> 0 bytes", sep="\n")
            sleep(3)
        else:
            print(f"{RED}[✘] Unable to locate log file.")
            sleep(0.8)

    elif num == 4:
        clear()
        print(Uninstall())
        sleep(2)
        print(f"{GREEN}[+] Thank you for using IsVer 😁")
        sleep(0.8)
        print(f"{GREEN}[+] Until next time 👋")
        sleep(0.8)
        sys.exit()

    else:
        clear()
        print(f"{GREEN}[+] Thank you for using IsVer 😁")
        sleep(0.8)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.8)
        sys.exit()
    
    print(f"\n\n{YELLOW}[1] Return to menu\n{YELLOW}[2] Exit")
    number=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while number not in range(1,3):
        print(f"{RED}[✘] Invalid number !")
        sleep(0.8)
        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
        sleep(1)
        number=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if number == 1:
        clear()
        main(username, target, session)
    else:
        clear()
        print(f"{RED}[+] Exiting...")
        sleep(0.8)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.8)
        sys.exit()
try:
    if __name__ == '__main__':
        sleep(2)
        clear()
        parser = argparse.ArgumentParser(description='IsVer traces the usernames of the verified users followed by a user on Instagram.')
        parser.add_argument('-u', '--username', help='Your username on Instagram.')
        parser.add_argument('-t', '--target', help='The target username.')
        parser.add_argument('-s', '--session', help='The session file to use. To generate it >> python3 cookies.py')
        args = parser.parse_args()
        if len(sys.argv) < 4:
            print(f"{RED}[✘] Error: Missing arguments.")
            sleep(0.7)
            print(f"{GREEN}[+] Usage >>> python3 isver.py -u <username> -t <target_username> -s <path_to_session_file>")
            sleep(1.5)
            args.username=input(f"{YELLOW}[::] Please enter your username >>> ") if not args.username else args.username
            args.target=input(f"{YELLOW}[::] Please enter the target username >>> ") if not args.target else args.target
            args.session=input(f"{YELLOW}[::] Please enter the session file >>> ") if not args.session else args.session
        main(args.username.strip().lower(), args.target.strip().lower(), args.session.strip().replace('\\', '/'))
except (KeyboardInterrupt, EOFError):
    print(f"\n\n{RED}[*] <Ctrl + C> detected. Exiting safely...")
    sys.exit()

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2023 new92

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.


================================================
FILE: Mutuals/README.md
================================================
# Mutuals 🧙

**Short description:** Mutuals identifies mutual followers and followings between 2 Instagram accounts, facilitating connection and insight into shared networks effortlessly.

**Long description:** Mutuals is a powerful Python script designed to discover and display mutual followers and followings between two Instagram accounts. Whether you're looking to strengthen connections or gain insights into shared networks, Mutuals simplifies the process, allowing users to identify and connect with those who share mutual interests and connections on Instagram. **Mutuals works for both public and private accounts**.

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

## Set up and run Mutuals 🚀

```bash
python3 cookies.py
python3 update.py # if you want to check for updates else skip it.
cd Mutuals
python3 mutuals.py -u <your_username> -u1 <user_1> -u2 <user_2> -s <path_to_session_file>
```

## Why Mutuals ? 🧐

1. **Mutual Followers and Followings:** The script identifies and displays the accounts that both users A and B (the two Instagram accounts being compared) follow and are followed by. This helps users see who they have in common within their network.
2. **User-Friendly Interface:** Mutuals often provides a user-friendly interface or report that lists the mutual followers and followings in a clear and organized manner, making it easy for users to view and interact with this information.
3. **Comparison Metrics:** Some versions of Mutuals may offer additional metrics, such as the number of mutual followers, the number of mutual followings, and a list of these mutual accounts, allowing for a detailed analysis of the overlap in their Instagram networks.
4. **Filtering and Sorting:** Users may have the option to filter and sort the list of mutual followers and followings based on various criteria, such as engagement, account type, or recent activity.
5. **Exporting Data:** Mutuals exports the data and saves them into a text file.
6. **Notifications:** Mutuals provides notifications to users when new mutual followers or followings are identified or when changes occur in the mutual connections.

## Features 🪄

- Data visualization
- ~~Data storage (output is stored in log file)~~ ✅
- ~~Fix bugs~~ ✅
- ~~Colored~~ ✅
- ~~Option to retrieve both mutual followers and followings between 2 accounts~~ ✅

## Expected files 📁
1) `mutuals.txt`
2) `consent.txt`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/57a03890-bd3e-4699-a2a0-6f88a00294a2)

![output](https://github.com/new92/InstaTools/assets/94779840/e82c5c25-c256-470f-8408-de5341a552f3)

![output_](https://github.com/new92/InstaTools/assets/94779840/7e5195e5-d116-4ab7-84f4-171bcef9581f)



================================================
FILE: Mutuals/mutuals.py
================================================
# -*- coding: utf-8 -*-
"""
Author: new92
Github: @new92
Leetcode: @new92
PyPI: @new92
Contributors: [@Itsfizziks, @ProgramR4732]

Mutuals is a powerful Python script designed to discover and display mutual followers and followings between two Instagram accounts. Whether you're looking to strengthen connections or gain insights into shared networks, Mutuals simplifies the process, allowing users to identify and connect with those who share mutual interests and connections on Instagram.

For output example >>> ./Photos/output.png

{*********IMPORTANT*********}
User's login credentials (such as: username, session file) won't be stored ! 
Will be used only for the purpose of Mutuals.
"""
try:
    import sys
    from time import sleep
    if sys.version_info[0] < 3:
        print("[✘] Error ! IsVer requires Python 3 ! ")
        sleep(1.3)
        print("""[+] Instructions to download Python 3 : 
        Linux: apt install python3
        Windows: https://www.python.org/downloads/
        MacOS: https://docs.python-guide.org/starting/install3/osx/""")
        sleep(3)
        print("[+] Please install Python 3 and then use IsVer ✅")
        sleep(1.2)
        print("[+] Exiting...")
        sleep(0.8)
        sys.exit()
    from rich.align import Align
    from rich.table import Table
    from rich.live import Live
    from rich.console import Console
    console = Console()
    mods = ('sys', 'time', 'platform', 'os', 'colorama', 'rich', 'logging', 'requests', 'instaloader', 'ctypes', 'csv', 'argparse')
    with console.status('[bold dark_orange]Loading module...[/]') as status:
        for mod in mods:
            sleep(0.85)
            console.log(f'[[bold red]{mod}[/]] => [bold green]okay ✔[/]')
    import platform
    from os import system
    import instaloader
    import os
    import logging
    import requests
    import argparse
    import ctypes
    from colorama import init, Fore
except (ImportError, ModuleNotFoundError):
    print("[!] WARNING: Not all packages used in Mutuals have been installed !")
    sleep(1.5)
    print("[+] Ignoring warning...")
    sleep(0.6)
    if sys.platform.startswith('linux') or sys.platform == 'darwin':
        if os.geteuid():
            print("[✘] Root user not detected !")
            sleep(2)
            print("[+] Attempting to enable root user...")
            sleep(1)
            os.execvp("sudo", ["sudo", sys.executable] + sys.argv)
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("sudo pip install -r ./../requirements.txt" if sys.platform.startswith('linux') else "python -m pip install ./../requirements.txt")
    elif platform.system() == 'Windows':
        if not ctypes.windll.shell32.IsUserAnAdmin():
            print("[✘] Root user not detected !")
            sleep(2)
            print("[+] Attempting to enable root user...")
            sleep(1)
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
            if not ctypes.windll.shell32.IsUserAnAdmin():
                print("[+] Root user permission denied.")
                sleep(1)
                print("[+] Exiting...")
                sys.exit()
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("pip install -r ./../requirements.txt")

init(autoreset=True)
GREEN = Fore.GREEN
RED = Fore.RED
YELLOW = Fore.LIGHTYELLOW_EX

def clear():
    system('cls' if platform.system() == 'Windows' else 'clear')

sleep(0.8)
clear()
console.print("[bold green][✔] Successfully loaded modules.[/]")
sleep(0.8)
clear()

ANS = ('yes','no')
EMPTY = ('', ' ')

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}
js = ''
resp = requests.get('https://api.github.com/repos/new92/InstaTools', headers=headers)
if resp.status_code == 200:
    js = resp.json()

def fpath(fname: str):
    for root, dirs, files in os.walk('/'):
        if fname in files:
            return os.path.abspath(os.path.join(root, fname))

def ScriptInfo():
    rest = requests.get('https://api.github.com/repos/new92/InstaTools/contributors', headers=headers)
    contribs = []
    if rest.status_code == 200:
        jsn = rest.json()
        contribs = [jsn[i]['login'] for i in range(len(jsn))]
    lang = requests.get('https://api.github.com/repos/new92/InstaTools/languages', headers=headers)
    languages = list(lang.json().keys()) if lang.status_code == 200 else []
    print(f"{YELLOW}[+] Author | {js['owner']['login']}")
    print(f"{YELLOW}[+] Github | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Leetcode | @{js['owner']['login']}")
    print(f"{YELLOW}[+] PyPI | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Contributors | {contribs}")
    print(f"{YELLOW}[+] License | {js['license']['spdx_id']}")
    print(f"{YELLOW}[+] Programming language(s) used | {languages}")
    print(f"{YELLOW}[+] Script's name | {js['name']}")
    print(f"{YELLOW}[+] Latest update | {js['updated_at']}")
    print(f"{YELLOW}[+] File size | {os.stat(__file__).st_size} bytes")
    print(f"{YELLOW}[+] File path | {os.path.abspath(__file__)}")
    print(f"{YELLOW}[+] Directory path | {os.path.dirname(os.path.abspath(__file__))}")
    print(f"{YELLOW}|======|GITHUB REPO INFO|======|")
    print(f"{YELLOW}[+] Repo name | {js['name']}")
    print(f"{YELLOW}[+] Description | {js['description']}")
    print(f"{YELLOW}[+] Repo URL | {js['html_url']}")
    print(f"{YELLOW}[+] Stars | {js['stargazers_count']}")
    print(f"{YELLOW}[+] Forks | {js['forks']}")
    print(f"{YELLOW}[+] Watchers | {js['subscribers_count']}")
    print(f"{YELLOW}[+] Open issues | {js['open_issues_count']}")

TABLE = (
    (
        "[b white]Author[/]: [i light_green]new92[/]",
        "[green]https://new92.github.io/[/]"
    ),
    (
        "[b white]Github[/]: [i light_green]@new92[/]",
        "[green]https://github.com/new92[/]"
    ),
    (
        "[b white]Leetcode[/]: [i light_green]@new92[/]",
        "[green]https://leetcode.com/new92[/]"
    ),
    (
        "[b white]PyPI[/]: [i light_green]@new92[/]",
        "[green]https://pypi.org/user/new92[/]"
    )
)

def banner() -> str:
    console.log("""[bold green]
   _____    ____ ___ ___________ ____ ___   _____   .____       _________ 
  /     \  |    |   \\__    ___/|    |   \ /  _  \  |    |     /   _____/ 
 /  \ /  \ |    |   /  |    |   |    |   //  /_\  \ |    |     \_____  \  
/    Y    \|    |  /   |    |   |    |  //    |    \|    |___  /        \ 
\____|__  /|______/    |____|   |______/ \____|__  /|_______ \/_______  / 
        \/                                       \/         \/        \/  
[/]""", justify='center')

def Uninstall() -> str:
    def rmdir(dire):
        for root, dirs, files in os.walk(dire):
            for file in files:
                os.remove(os.path.join(root,file))
            DIRS = (os.path.join(root,dir) for dir in dirs)
        for i in DIRS:
            os.rmdir(i)
        os.rmdir(dire)
    rmdir(fpath('InstaTools'))
    return f'{GREEN}[✔] Files and dependencies removed successfully !'

name = 'mutuals.txt'

def main(username: str, session: str, user1: str, user2: str):
    console = Console()
    table = Table(show_footer=False)
    centered = Align.center(table)
    banner()
    print("\n")
    with Live(centered, console=console, screen=False):
        table.add_column('Socials', no_wrap=False)
        table.add_column('Url', no_wrap=False)
        for row in TABLE:
            table.add_row(*row)
    print("\n")
    console.print("[bold yellow][+] Python script to retrieve the mutual followers/followings between 2 accounts.[/]")
    print("\n")
    console.print("[bold yellow][1] Find mutuals[/]")
    console.print("[bold yellow][2] Show Mutuals's info[/]")
    console.print("[bold yellow][3] Uninstall InstaTools[/]")
    console.print("[bold yellow][4] Exit[/]")
    num=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while num not in range(1,5):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1-5]")
        sleep(2)
        num=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if num == 1:
        clear()
        loader = instaloader.Instaloader()
        if not os.path.exists('./consent.txt'):
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").strip().lower()
            while con not in ANS or con in EMPTY:
                if con in EMPTY:
                    print(f"{RED}[✘] This field can't be blank !")
                else:
                    print(f"{RED}[✘] Invalid answer !")
                    sleep(1)
                    print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                sleep(1)
                con=input(f"{YELLOW}[>] Do you consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given (Instagram) account ? ").strip().lower()
            if con == ANS[0]:
                logging.basicConfig(
                    filename='consent.txt',
                    level=logging.INFO,
                    format='%(asctime)s [%(levelname)s]: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S'
                )
                logging.info('Yes I consent that the author (new92) has no responsibility for any loss or damage may the script cause to the given Instagram account.')
            else:
                print(f"{YELLOW}[OK]")
                sleep(1)
                print(f"{YELLOW}[1] Exit")
                print(f"{YELLOW}[2] Uninstall Mutuals and exit")
                num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones) >>> "))
                valErr = num in (1, 2)
                while not valErr:
                    try:
                        print(f"{YELLOW}[1] Exit")
                        print(f"{YELLOW}[2] Uninstall Mutuals and exit")
                        sleep(1)
                        num=int(input(f"{YELLOW}[>] Please enter a number (from the above ones) >>> "))
                        valErr = num in (1,2)
                    except ValueError:
                        print(f"{RED}[!] Please enter a valid number.")
                        sleep(1)
                        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                        sleep(1)
                if num == 1:
                    clear()
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    sys.exit()
                else:
                    clear()
                    print(Uninstall())
                    sleep(2)
                    print(f"{RED}[+] Exiting...")
                    sleep(1)
                    print(f"{YELLOW}[+] Thank you for using Mutuals 🫡")
                    sleep(2)
                    print(f"{YELLOW}[+] Until we meet again 👋")
                    sleep(1)
                    sys.exit()
        sleep(2)
        clear()
        sleep(0.5)
        print(f"{GREEN}[*] Using session file >>> {session}...")
        sleep(1.3)
        try:
            with open(session, 'rb') as sessionfile:
                loader.context.load_session_from_file(username, sessionfile)
        except instaloader.exceptions.ConnectionException as ex:
            print(f"{RED}[✘] Error loading session file !")
            sleep(1)
            print(f"{YELLOW}[+] Error message >>> {ex}")
            sleep(0.8)
            print(f"{RED}[+] Exiting...")
            sys.exit()
        print(f"{GREEN}[✔] Session loaded successfully !")
        sleep(1.4)
        print(f"{GREEN}[✔] Login successfull !")
        sleep(0.85)
        clear()
        sleep(0.4)
        print(f"{YELLOW}[+] Loading profile...")
        sleep(0.6)
        profile = None
        try:
            profile = instaloader.Profile.from_username(loader.context, username)
        except instaloader.ProfileNotExistsException:
            print(f"{RED}[✘] Profile not found")
            sleep(1)
            print("[1] Return to menu")
            print("[2] Exit")
            num=int(input("[::] Please enter a number (from the above ones) >>> "))
            while num not in range(1,3):
                print(f"{RED}[✘] Invalid number !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                sleep(1)
                num=int(input("[::] Please enter again a number (from the above ones) >>> "))
            if num == 1:
                clear()
                main(username, session, user1, user2)
            else:
                clear()
                print(f"{RED}[+] Exiting...")
                sleep(1)
                print(f"{GREEN}[+] See you next time 👋")
                sleep(0.8)
                sys.exit()
        if profile:
            sleep(0.5)
            print(f"{GREEN}[✔] Profile loaded successfully !")
            sleep(0.85)
            clear()
            print(f"{YELLOW}[1] Find the mutual followers")
            print(f"{YELLOW}[2] Find the mutual followees")
            print(f"{YELLOW}[3] Find the mutual followers & followees")
            t=int(input(f"{YELLOW}[::] Number >>> "))
            while t not in range(1,4):
                print(f"{RED}[✘] Invalid number !")
                sleep(1)
                print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
                sleep(2)
                print(f"{YELLOW}[1] Find mutual followers")
                print(f"{YELLOW}[2] Find mutual followees")
                print(f"{YELLOW}[3] Find the mutual followers & followees between 2 accounts")
                t=int(input(f"{YELLOW}[::] Number >>> "))
            profilef=instaloader.Profile.from_username(loader.context, user1)
            profiles=instaloader.Profile.from_username(loader.context, user2)
            if t == 1:
                clear()
                print(f"{GREEN}[*] Extracting mutual followers...")
                sleep(0.5)
                FOLLOWERSF=[follower.username for follower in profilef.get_followers()]
                FOLLOWERSS=[follower.username for follower in profiles.get_followers()]
                if FOLLOWERSF and FOLLOWERSS:
                    sumf = len(FOLLOWERSF) + len(FOLLOWERSS)
                    MUTUALS = [mutual for mutual in FOLLOWERSF if mutual in FOLLOWERSS] + [mutual for mutual in FOLLOWERSS if mutual in FOLLOWERSF]
                    if not MUTUALS:
                        print(f"{RED}[✘] No mutual followers found between {user1} & {user2}")
                        sleep(0.8)
                        print(f"{RED}[+] Exiting...")
                        sleep(1)
                        print(f"{GREEN}[+] Thank you for using Mutuals 😁")
                        sys.exit()
                    else:
                        print(f"{GREEN}[✔] Extracted {len(MUTUALS)} mutual followers from {user1} & {user2}")
                        sleep(1)
                        print(f"{YELLOW}[+] Percentage of mutual followers >>> {'{:.2f}'.format((len(MUTUALS) / float(sumf))*100)}%")
                        sleep(1)
                        print(f"{YELLOW}[+] Mutual followers betweeen {user1} & {user2}\n")
                        print('-' * 30 + '\n')
                        for counter, username in enumerate(MUTUALS):
                            print(f"{YELLOW}[{counter+1}] >>> https://www.instagram.com/{username}/")
                        sleep(3)
                        print("\n\n")
                        print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                        sleep(1)
                        savem=input(f"{YELLOW}[?] Save mutual followers ? ").strip().lower()
                        while savem not in ANS:
                            print(f"{RED}[✘] Invalid answer !")
                            sleep(1)
                            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                            sleep(1)
                            savem=input(f"{YELLOW}[?] Save mutual followers ? ").strip().lower()
                else:
                    print("\n\n")
                    print(f"{RED}[✘] No followers found on >>> {user1}" if not len(FOLLOWERSF) else f"{RED}[✘] No followers found on >>> {user2}")
                    sleep(0.6)
                    print(f"{RED}[+] Exiting...")
                    sleep(0.7)
                    print(f"{GREEN}[+] Thank you for using Mutuals 😁")
                    sleep(0.8)
                    sys.exit()
            elif t == 2:
                clear()
                print(f"{GREEN}[*] Extracting mutual followees...")
                sleep(0.5)
                FOLLOWINGSF=[following.username for following in profilef.get_followees()]
                FOLLOWINGSS=[following.username for following in profiles.get_followees()]
                if FOLLOWINGSF and FOLLOWINGSS:
                    sumf = len(FOLLOWINGSF) + len(FOLLOWINGSS)
                    MUTUALS = [mutual for mutual in FOLLOWINGSF if mutual in FOLLOWINGSS] + [mutual for mutual in FOLLOWINGSS if mutual in FOLLOWINGSF]
                    if not MUTUALS:
                        print(f"{RED}[✘] No mutual followees found !")
                        sleep(0.8)
                        print(f"{GREEN}[+] Thank you for using Mutuals 😁")
                        sleep(0.8)
                        print(f"{RED}[+] Exiting...")
                        sleep(0.8)
                        sys.exit()
                    else:
                        print(f"{GREEN}[✔] Extracted {len(MUTUALS)} mutual followees from {user1} & {user2}")
                        sleep(0.8)
                        print(f"{YELLOW}[+] Percentage of mutual followees >>> {'{:.2f}'.format(len(MUTUALS) / float(sumf))*100}%")
                        sleep(0.8)
                        print(f"{YELLOW}[+] Mutual followees betweeen {user1} & {user2}\n")
                        print('-' * 30 + '\n')
                        for counter, username in enumerate(MUTUALS):
                            print(f"{YELLOW}[{counter+1}] https://www.instagram.com/{username}/")
                        sleep(3)
                        print("\n\n")
                        print(f'{GREEN}[+] Acceptable answers >>> {ANS}')
                        sleep(1)
                        savem=input(f"{YELLOW}[?] Save mutual followees ? ").strip().lower()
                        while savem not in ANS:
                            print(f"{RED}[✘] Invalid answer !")
                            sleep(1)
                            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                            sleep(1)
                            savem=input(f"{YELLOW}[?] Save mutual followees ? ").strip().lower()
                else:
                    print("\n\n")
                    print(f"{RED}[✘] No followees found on >>> {user1}" if not len(FOLLOWINGSF) else f"{RED}[✘] No followees found on >>> {user2}")
                    sleep(0.6)
                    print(f"{RED}[+] Exiting...")
                    sleep(0.7)
                    print(f"{GREEN}[+] Thank you for using Mutuals 😁")
                    sleep(0.8)
                    sys.exit()
            else:
                clear()
                print(f"{GREEN}[*] Extracting both mutual followers & followees...")
                sleep(0.5)
                FOLLOWERSF=[follower.username for follower in profilef.get_followers()]
                FOLLOWERSS=[follower.username for follower in profiles.get_followers()]
                FOLLOWINGSF=[following.username for following in profilef.get_followees()]
                FOLLOWINGSS=[following.username for following in profiles.get_followees()]
                if FOLLOWERSF and FOLLOWERSS and FOLLOWINGSF and FOLLOWINGSS:
                    sumf = len(FOLLOWERSF) + len(FOLLOWERSS) + len(FOLLOWINGSF) + len(FOLLOWINGSS)
                    MUTUALS = [mutual + '| follower' for mutual in FOLLOWERSF if mutual in FOLLOWERSS] + [mutual + '| follower' for mutual in FOLLOWERSS if mutual in FOLLOWERSF] + [mutual + '| followee' for mutual in FOLLOWINGSF if mutual in FOLLOWINGSS] + [mutual + '| followee' for mutual in FOLLOWINGSS if mutual in FOLLOWINGSF]
                    if not MUTUALS:
                        print(f"{RED}[✘] No mutuals found !")
                        sleep(0.8)
                        print(f"{GREEN}[+] Thank you for using Mutuals 😁")
                        sleep(0.8)
                        print(f"{RED}[+] Exiting...")
                        sleep(0.8)
                        sys.exit()
                    else:
                        print(f"{GREEN}[✔] Extracted {len(MUTUALS)} mutual followees from {user1} & {user2}")
                        sleep(0.8)
                        print(f"{YELLOW}[+] Percentage of mutuals >>> {'{:.2f}'.format(len(MUTUALS) / float(sumf))*100}%")
                        sleep(0.8)
                        print(f"{YELLOW}[+] Mutual followers / followees betweeen {user1} & {user2}\n")
                        print('-' * 30 + '\n')
                        for counter, username in enumerate(MUTUALS):
                            print(f"{YELLOW}[{counter+1}] https://www.instagram.com/{username[:username.find('|')]}/ {username[username.find('|'):]}")
                        sleep(3)
                        print("\n\n")
                        print(f'{GREEN}[+] Acceptable answers >>> {ANS}')
                        sleep(1)
                        savem=input(f"{YELLOW}[?] Save mutuals ? ").strip().lower()
                        while savem not in ANS:
                            print(f"{RED}[✘] Invalid answer !")
                            sleep(1)
                            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
                            sleep(1)
                            savem=input(f"{YELLOW}[?] Save mutuals ? ").strip().lower()
                        with open(f'./{name}', 'w', encoding='utf-8') as f:
                            for counter, username in enumerate(MUTUALS):
                                f.write(f"{YELLOW}[{counter+1}] https://www.instagram.com/{username[:username.find('|')]}/ {username[username.find('|'):]}")
                else:
                    print("\n\n")
                    print(f"{RED}[✘] Error: Unable to gather enough data for extraction !")
                    sleep(0.6)
                    print(f"{RED}[+] Exiting...")
                    sleep(0.7)
                    sys.exit()
            if savem == ANS[0] and MUTUALS and num != 3:
                print(f"{YELLOW}[*] Writing mutuals in {name}...")
                with open(f'./{name}', 'w', encoding='utf-8') as f:
                    for counter, username in enumerate(MUTUALS):
                        f.write(f"[{counter+1}] https://www.instagram.com/{username}/\n")
            sleep(0.8)
            print(f"{GREEN}[✔] Successfully saved mutuals !")
            sleep(0.8)
            print(f"{YELLOW}[↪] Name >>> {name}", f"{YELLOW}[↪] Location >>> ./{name}", f"{YELLOW}[↪] Size >>> {os.stat(('./' + name)).st_size}", sep='\n')

    elif num == 2:
        clear()
        ScriptInfo()
        sleep(5)

    elif num == 3:
        clear()
        print(Uninstall())
        sleep(2)
        print(f"{GREEN}[+] Thank you for using Mutuals 😁")
        sleep(1.5)
        print(f"{GREEN}[+] Until we meet again 🫡")
        sleep(0.8)
        sys.exit()

    else:
        clear()
        print(f"{GREEN}[+] Thank you for using Mutuals 😁")
        sleep(1)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.8)
        sys.exit()

    print(f"\n\n{YELLOW}[1] Return to menu\n{YELLOW}[2] Exit")
    number=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while number not in range(1, 3):
        print(f"{RED}[✘] Invalid number !")
        sleep(0.8)
        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
        sleep(1)
        number=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>> "))
    if number == 1:
        clear()
        main(username, session, user1, user2)
    else:
        print(f"{RED}[+] Exiting...")
        sleep(1)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(2)
        sys.exit()
try:
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(description='Mutuals is a python script used to find the mutual followers and/or followings between 2 accounts on Instagram.')
        parser.add_argument('-u', '--username', help='Your Instagram username.')
        parser.add_argument('-u1', '--user1', help='The first username for the mutuals retrieval')
        parser.add_argument('-u2', '--user2', help='The second username for the mutuals retrieval')
        parser.add_argument('-s', '--session', help='The session file to use. To generate it >>> python3 cookies.py')
        args = parser.parse_args()
        if len(sys.argv) < 5:
            print(f"{RED}[✘] Error: Missing arguments.")
            sleep(0.7)
            print(f"{GREEN}[+] Usage >>> python3 mutuals.py -u <username> -u1 <user_1> -u2 <user_2> -s <path_to_session_file>")
            sleep(1.5)
            args.username=input(f"{YELLOW}[::] Please enter your username >>> ") if not args.username else args.username
            args.session=input(f"{YELLOW}[::] Please enter the session file >>> ") if not args.session else args.session
            args.u1=input(f"{YELLOW}[::] Please enter the first username for the mutuals retrieval >>> ") if not args.u1 else args.u1
            args.u2=input(f"{YELLOW}[::] Please enter the second username for the mutuals retrieval >>> ") if not args.u2 else args.u2
        main(args.username.strip().lower(), args.session.strip().replace('\\', '/'), args.user1.strip().lower(), args.user2.strip().lower())
except (KeyboardInterrupt, EOFError):
    print(f"\n\n{RED}[*] <Ctrl + C> detected. Exiting safely...")
    sys.exit()


================================================
FILE: Poirot/README.md
================================================
# Poirot 🕵️

**Short description:** Poirot elegantly extracts valuable information from Instagram accounts using Instagram's GraphQL data query language.

**Long description:** Poirot is a Python script designed to elegantly extract data from Instagram accounts. With its sophisticated algorithms, Poirot allows users to effortlessly gather valuable insights and information from Instagram profiles, empowering businesses and individuals to make data-driven decisions and enhance their online strategies. **Works for both public & private accounts without requiring any form of login or verification !**

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

## Set up and run Poirot 🚀

```bash
python3 update.py # if you want to check for updates else skip it.
cd Poirot
python3 poirot.py -u <target_username>
```

## Why Poirot ? 🧐

- **No login or additional information is required for the information gathering process.**
- Anonymity
- Fast results
- Poirot extracts valuable data (such as: emails, telephones, addresses etc.)

## Features 🚀

- ~~Log file~~ ✅
- ~~Colored~~ ✅
- ~~Pretty output~~ ✅

## Expected files 📂

1) `poirotLog.txt`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/02bf61c9-3676-47d3-8852-49b9432fe631)

![output](https://github.com/new92/InstaTools/assets/94779840/934689c9-5bd0-458c-bed7-9fc27171c5e1)


================================================
FILE: Poirot/poirot.py
================================================
# -*- coding: utf-8 -*-
"""
Author: new92
Github: @new92
Leetcode: @new92
PyPI: @new92
Contributors: [@Itsfizziks, @ProgramR4732]

Poirot is a python script used to extract information from Instagram accounts. Without login or any type of credentials required.

For output example >>> ./Photos/output.png
"""
try:
    import sys
    from time import sleep
    if sys.version_info[0] < 3:
        print("[✘] Error ! Poirot requires Python 3 ! ")
        sleep(1.3)
        print("""[+] Instructions to download Python 3: 
        Linux: apt install python3
        Windows: https://www.python.org/downloads/
        MacOS: https://docs.python-guide.org/starting/install3/osx/""")
        sleep(3)
        print("[+] Please install Python3 and then use Poirot ✅")
        sleep(1)
        print("[+] Exiting...")
        sleep(0.8)
        sys.exit()
    from rich.align import Align
    from rich.table import Table
    from rich.live import Live
    from rich.console import Console
    console = Console()
    mods = ('sys', 'time', 'platform', 'os', 'colorama', 'rich', 'logging', 'requests', 'instaloader', 'ctypes', 'argparse')
    with console.status('[bold dark_orange]Loading module...[/]') as status:
        for mod in mods:
            sleep(0.85)
            console.log(f'[[bold red]{mod}[/]] => [bold green]okay ✔[/]')
    import platform
    import ctypes
    import requests
    import os
    import argparse
    from os import system
    from colorama import init, Fore
except (ImportError, ModuleNotFoundError):
    print(f"[!] WARNING: Not all packages used in Poirot have been installed !")
    sleep(1.5)
    print(f"[+] Ignoring warning...")
    sleep(0.6)
    if sys.platform.startswith('linux') or sys.platform == 'darwin':
        if os.geteuid():
            print("[✘] Root user not detected !")
            sleep(1)
            print("[+] Attempting to enable root user...")
            sleep(1)
            os.execvp("sudo", ["sudo", sys.executable] + sys.argv)
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("sudo pip install -r ./../requirements.txt" if sys.platform.startswith('linux') else "python -m pip install ./../requirements.txt")
    elif platform.system() == 'Windows':
        if not ctypes.windll.shell32.IsUserAnAdmin():
            print("[✘] Root user not detected !")
            sleep(2)
            print("[+] Attempting to enable root user...")
            sleep(1)
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
            if not ctypes.windll.shell32.IsUserAnAdmin():
                print("[+] Root user permission denied.")
                sleep(1)
                print("[+] Exiting...")
                sys.exit()
            print("[✔] Done.")
            sleep(0.6)
            print("[+] Loading required modules...")
            sleep(0.4)
        system("pip install -r ./../requirements.txt")

init(autoreset=True)
GREEN = Fore.GREEN
RED = Fore.RED
YELLOW = Fore.LIGHTYELLOW_EX

def clear():
    system('cls' if platform.system() == 'Windows' else 'clear')

sleep(0.8)
clear()
console.print("[bold green][✔] Successfully loaded modules.[/]")
sleep(0.8)
clear()

ANS = ('yes', 'no')
EMPTY = ('', ' ')

def fpath(fname: str):
    for root, dirs, files in os.walk('/'):
        if fname in files:
            return os.path.abspath(os.path.join(root, fname))

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}
js = ''
resp = requests.get('https://api.github.com/repos/new92/InstaTools', headers=headers)
if resp.status_code == 200:
    js = resp.json()

def ScriptInfo():
    rest = requests.get('https://api.github.com/repos/new92/InstaTools/contributors', headers=headers)
    contribs = []
    if rest.status_code == 200:
        jsn = rest.json()
        contribs = [jsn[i]['login'] for i in range(len(jsn))]
    lang = requests.get('https://api.github.com/repos/new92/InstaTools/languages', headers=headers)
    languages = list(lang.json().keys()) if lang.status_code == 200 else []
    print(f"{YELLOW}[+] Author | {js['owner']['login']}")
    print(f"{YELLOW}[+] Github | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Leetcode | @{js['owner']['login']}")
    print(f"{YELLOW}[+] PyPI | @{js['owner']['login']}")
    print(f"{YELLOW}[+] Contributors | {contribs}")
    print(f"{YELLOW}[+] License | {js['license']['spdx_id']}")
    print(f"{YELLOW}[+] Programming language(s) used | {languages}")
    print(f"{YELLOW}[+] Script's name | {js['name']}")
    print(f"{YELLOW}[+] Latest update | {js['updated_at']}")
    print(f"{YELLOW}[+] File size | {os.stat(__file__).st_size} bytes")
    print(f"{YELLOW}[+] File path | {os.path.abspath(__file__)}")
    print(f"{YELLOW}[+] Directory path | {os.path.dirname(os.path.abspath(__file__))}")
    print(f"{YELLOW}|======|GITHUB REPO INFO|======|")
    print(f"{YELLOW}[+] Repo name | {js['name']}")
    print(f"{YELLOW}[+] Description | {js['description']}")
    print(f"{YELLOW}[+] Repo URL | {js['html_url']}")
    print(f"{YELLOW}[+] Stars | {js['stargazers_count']}")
    print(f"{YELLOW}[+] Forks | {js['forks']}")
    print(f"{YELLOW}[+] Watchers | {js['subscribers_count']}")
    print(f"{YELLOW}[+] Open issues | {js['open_issues_count']}")

def banner() -> str:
    console.print("""[bold green]
                           _               _   
                          (_)             | |  
             _ __    ___   _  _ __   ___  | |_ 
            | '_ \  / _ \ | || '__| / _ \ | __|
            | |_) || (_) || || |   | (_) || |_ 
            | .__/  \___/ |_||_|    \___/  \__|
            | |
            |_|
""", justify='center')

def Uninstall() -> str:
    def rmdir(dire):
        for root, dirs, files in os.walk(dire):
            for file in files:
                os.remove(os.path.join(root,file))
            DIRS = (os.path.join(root, dir) for dir in dirs)
        for i in DIRS:
            os.rmdir(i)
        os.rmdir(dire)
    rmdir(fpath('InstaTools'))
    return f'{GREEN}[✔] Files and dependencies removed successfully !'

TABLE = (
    (
        "[b white]Author[/]: [i light_green]new92[/]",
        "[green]https://new92.github.io/[/]"
    ),
    (
        "[b white]Github[/]: [i light_green]@new92[/]",
        "[green]https://github.com/new92[/]"
    ),
    (
        "[b white]Leetcode[/]: [i light_green]@new92[/]",
        "[green]https://leetcode.com/new92[/]"
    ),
    (
        "[b white]PyPI[/]: [i light_green]@new92[/]",
        "[green]https://pypi.org/user/new92[/]"
    )
)

def fetch(username: str):
    headers = {
        'User-Agent': 'Instagram 64.0.0.14.96'
    }
    request = requests.get(f'https://www.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers)
    js = request.json()
    if request.status_code != 200:
        return js['message']
    return {
        'bio': js['data']['user']['biography'],
        'posts': js['data']['user']['edge_owner_to_timeline_media']['count'],
        'links': [js['data']['user']['bio_links'][i]['url'] for i in range(len(js['data']['user']['bio_links']))],
        'fb': js['data']['user']['fb_profile_biolink'],
        'users': [js['data']['user']['biography_with_entities']['entities'][i]['user']['username'] for i in range(len(js['data']['user']['biography_with_entities']['entities'])) if js['data']['user']['biography_with_entities']['entities'][i]['user'] != None],
        'hashtags': [js['data']['user']['biography_with_entities']['entities'][i]['hashtag']['name'] for i in range(len(js['data']['user']['biography_with_entities']['entities'])) if js['data']['user']['biography_with_entities']['entities'][i]['hashtag'] != None],
        'followers': js['data']['user']['edge_followed_by']['count'],
        'followings': js['data']['user']['edge_follow']['count'],
        'fbid': js['data']['user']['fbid'],
        'name': js['data']['user']['full_name'],
        'id': js['data']['user']['id'],
        'hide': js['data']['user']['hide_like_and_view_counts'],
        'business': js['data']['user']['is_business_account'],
        'professional': js['data']['user']['is_professional_account'],
        'supervision': js['data']['user']['is_supervision_enabled'],
        'join': js['data']['user']['is_joined_recently'],
        'email': js['data']['user']['business_email'],
        'tel': js['data']['user']['business_phone_number'],
        'private': js['data']['user']['is_private'],
        'verified': js['data']['user']['is_verified'],
        'pic': js['data']['user']['profile_pic_url_hd'],
        'category': js['data']['user']['category_name']
    }

name = 'poirotLog.txt'
    
def main(target: str):
    console = Console()
    table = Table(show_footer=False)
    centered = Align.center(table)
    banner()
    print("\n")
    with Live(centered, console=console, screen=False):
        table.add_column('Socials', no_wrap=False)
        table.add_column('Url', no_wrap=False)
        for row in TABLE:
            table.add_row(*row)
    print("\n")
    console.print("[bold yellow][+] Poirot is a python script for extracting info from a user's Instagram account.[/]")
    print("\n")
    console.print(f"[bold yellow][1] Extract {target}'s info[/]")
    console.print("[bold yellow][2] Show Poirot's info[/]")
    console.print("[bold yellow][3] Clear log[/]")
    console.print("[bold yellow][4] Uninstall InstaTools[/]")
    console.print("[bold yellow][5] Exit[/]")
    print("\n")
    num=int(input(f"{YELLOW}[::] Please enter a number (from the above ones) >>> "))
    while num not in range(1,6):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1-5]")
        sleep(2)
        num=int(input(f"{YELLOW}[::] Please enter again a number (from the above ones) >>>   "))
    if num == 1:
        clear()
        sleep(1)
        print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
        sleep(1)
        keep=input(f"{YELLOW}[?] Keep log ? ").strip().lower()
        while keep not in ANS:
            print(f"{RED}[✘] Invalid answer !")
            sleep(1)
            print(f"{GREEN}[+] Acceptable answers >>> {ANS}")
            sleep(1)
            keep=input(f"{YELLOW}[?] Keep log ? ").strip().lower()
        keep = keep == ANS[0]
        sleep(1.2)
        clear()
        sleep(0.5)
        print(f"{GREEN}[+] Username -> OK")
        sleep(1.3)
        print(f"{GREEN}[*] Starting information extraction...")
        sleep(1.3)
        dict = fetch(target)
        if type(dict) is not str:
            sleep(1.3)
            print(f"{GREEN}[✔] Success !")
            sleep(1.1)
            clear()
            print(
                f"{GREEN}{'-' * (len(target) + 15)}", f"{GREEN}[>] Name | {dict['name']}",
                f"{GREEN}[>] Bio | {dict['bio']}", f"{GREEN}[>] Posts {dict['posts']}", f"{GREEN}[>] Followers | {dict['followers']}",
                f"{GREEN}[>] Followings | {dict['followings']}", f"{GREEN}[>] Email | {dict['email']}",
                f"{GREEN}[>] Tel | {dict['tel']}", f"{GREEN}[>] Profile pic | {dict['pic']}",
                f"{GREEN}[>] ID | {dict['id']}", f"{GREEN}[>] External links | {dict['links']}",
                f"{GREEN}[>] Users in bio | {dict['users']}", f"{GREEN}[>] Hashtags in bio | {dict['hashtags']}",
                f"{GREEN}[>] fb | {dict['fb']}", f"{GREEN}[>] fb ID | {dict['fbid']}", f"{GREEN}[>] Category | {dict['category']}",
                f"{GREEN}[>] Joined recently | {dict['join']}", f"{GREEN}[>] Private | {dict['private']}",
                f"{GREEN}[>] Verified | {dict['verified']}", f"{GREEN}[>] Business | {dict['business']}",
                f"{GREEN}[>] Professional | {dict['professional']}", f"{GREEN}[>] Supervised | {dict['supervision']}",
                f"{GREEN}[>] Hide likes & views | {dict['hide']}", f"{GREEN}{'-' * (len(str(dict['hide'])) + 25)}", sep="\n")
            sleep(2)
            if keep:
                with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), name), 'a', encoding='utf-8') as f:
                    f.write('\n\n')
                    f.write('-' * (len(target) + 15))
                    f.write(str(dict))
                    f.write(f"\n{'-' * (len(str(dict['hide'])) + 25)}")
                location = os.path.join(os.path.dirname(os.path.abspath(__file__)), name)
                print(f"\n{GREEN}[✔] Successfully saved log !")
                sleep(1)
                print(f"{YELLOW}[↪] Name >>> {name}",  f"{YELLOW}[↪] Path >>> {location}", f"{YELLOW}[↪] Size >>> {os.stat(name).st_size} bytes", sep='\n')
        else:
            print(f"{RED}[✘] Information gathering unsuccessfull !")
            sleep(1)
            print(f"{GREEN}[+] Error message => {dict}")
            sleep(2)

    elif num == 2:
        clear()
        ScriptInfo()
        sleep(5)

    elif num == 3:
        clear()
        location = os.path.join(os.path.dirname(os.path.abspath(__file__)), name)
        if os.path.exists(location):
            with open(name, 'w', encoding='utf-8') as f:
                pass
            sleep(0.5)
            print(f"{GREEN}[✔] Successfully cleared log !")
            sleep(1)
            print(f"{GREEN}[↪] Name >>> {name}", f"{GREEN}[↪] Location >>> {location.replace('\\', '/')}", f"{GREEN}[↪] Size >>> 0 bytes", sep="\n")
            sleep(3)
        else:
            clear()
            print(f"{RED}[✘] Log file not found !")
            sleep(0.8)
            print(f"{YELLOW}[+] Searched log file using name >>> {name}")
            sleep(0.8)
            print(f"{GREEN}[*] Please first create the log file and then use this option.")
            sleep(1)
            print(f"""{YELLOW}[+] Instructions: 
            1) Return to menu and enter the option number 1
            2) Enter <yes> in the keep log question
            """)
            sleep(3)
    
    elif num == 4:
        clear() 
        print(Uninstall())
        sleep(2)
        print(f"{GREEN}[+] Thank you for using Poirot 😁")
        sleep(0.8)
        print(f"{GREEN}[+] Until we meet again 🫡")
        sleep(0.7)
        sys.exit()

    else:
        clear()
        print(f"{YELLOW}[+] Thank you for using Poirot 😁")
        sleep(0.8)
        print(f"{YELLOW}[+] See you next time 👋")
        sleep(0.9)
        sys.exit()
    
    print(f"\n\n{YELLOW}[1] Return to menu\n{YELLOW}[2] Exit")
    opt=int(input(f"{YELLOW}[>] Please enter a number (from the above ones) >>> "))
    while opt not in range(1, 3):
        print(f"{RED}[✘] Invalid number !")
        sleep(1)
        print(f"{GREEN}[+] Acceptable numbers >>> [1,2]")
        sleep(2)
        opt=int(input(f"{YELLOW}[>] Please enter again a number (from the above ones) >>> "))
    if opt == 1:
        clear()
        main(target)
    else:
        clear()
        print(f"{GREEN}[+] Thank you for using Poirot 😁")
        sleep(0.8)
        print(f"{GREEN}[+] See you next time 👋")
        sleep(0.9)
        sys.exit()
try:
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(description='Poirot is a python script used for extracting information from accounts on Instagram. Without login or any type of credentials required!')
        parser.add_argument('-u', '--target', help='The target username to extract the info from.')
        args = parser.parse_args()
        if len(sys.argv) < 2:
            print(f"{RED}[✘] Error: Missing arguments.")
            sleep(0.7)
            print(f"{GREEN}[+] Usage >>> python3 poirot.py -u <target_username>")
            sleep(1.5)
            args.target=input(f"{YELLOW}[::] Please enter the target username >>> ")
        main(args.target.strip().lower())
except (KeyboardInterrupt, EOFError):
    print(f"\n\n{RED}[*] <Ctrl + C> detected. Exiting safely...")
    sys.exit()

================================================
FILE: README.md
================================================
![logo-no-background](https://github.com/new92/InstaTools/assets/94779840/6b147b66-c439-4ef8-bded-4d77909c9fe7)

[![Codacy grade](https://img.shields.io/codacy/grade/187dba28735848868b7f8615e0e45597?style=for-the-badge&logo=codacy)](https://img.shields.io/codacy/grade/187dba28735848868b7f8615e0e45597?style=for-the-badge&logo=codacy) [![Open issues](https://img.shields.io/github/issues/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/issues/new92/InstaTools?style=for-the-badge&logo=github) [![Closed issues](https://img.shields.io/github/issues-closed/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/issues-closed/new92/InstaTools?style=for-the-badge&logo=github) [![Open pull requests](https://img.shields.io/github/issues-pr/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/issues-pr/new92/InstaTools?style=for-the-badge&logo=github) [![Closed pull requests](https://img.shields.io/github/issues-pr-closed/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/issues-pr-closed/new92/InstaTools?style=for-the-badge&logo=github) [![Discussions](https://img.shields.io/github/discussions/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/discussions/new92/InstaTools?style=for-the-badge&logo=github) [![Code size in bytes](https://img.shields.io/github/languages/code-size/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/languages/code-size/new92/InstaTools?style=for-the-badge&logo=github) [![File count](https://img.shields.io/github/directory-file-count/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/directory-file-count/new92/InstaTools?style=for-the-badge&logo=github) [![Repo size](https://img.shields.io/github/repo-size/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/repo-size/new92/InstaTools?style=for-the-badge&logo=github) [![Followers](https://img.shields.io/github/followers/new92?style=for-the-badge&logo=github)](https://img.shields.io/github/followers/new92?style=for-the-badge&logo=github) [![Stars](https://img.shields.io/github/stars/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/stars/new92/InstaTools?style=for-the-badge&logo=github) [![Forks](https://img.shields.io/github/forks/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/forks/new92/InstaTools?style=for-the-badge&logo=github) [![Watchers](https://img.shields.io/github/watchers/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/watchers/new92/InstaTools?style=for-the-badge&logo=github) [![Language count](https://img.shields.io/github/languages/count/new92/InstaTools?style=for-the-badge&logo=github)](https://img.shields.io/github/languages/count/new92/InstaTools?style=for-the-badge&logo=github) [![Top language used](https://img.shields.io/github/languages/top/new92/InstaTools?style=for-the-badge&logo=python&logoColor=white)](https://img.shields.io/github/languages/top/new92/InstaTools?style=for-the-badge&logo=python&logoColor=white)

InstaTools offers a suite of powerful automation tools designed specifically for Instagram users. From automating time-consuming tasks to conducting in-depth research, InstaTools streamlines processes that would otherwise demand significant time and effort, particularly for users with large followings. Whether you're managing a high-profile account or conducting market research, these tools provide valuable insights and efficiency. However, it's important to use InstaTools judiciously to avoid risking account suspension or even permanent blocking. Exercise caution and use responsibly to maximize benefits without jeopardizing your account's integrity.

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

If you didn't like it and/or found a bug or you have a suggestion please feel free to contact me at anytime at <a href='mailto:new92github@gmail.com'>this email address</a>. Or create a <a href="https://github.com/new92/InstaTools/discussions">discussion</a>. Or open an <a href="https://github.com/new92/InstaTools/issues">issue</a>.
Any type of feedback is welcome and appreciated. (Please do not use any vulgar vocabulary)

## Urls 🔗

- [License](https://github.com/new92/InstaTools/blob/main/LICENSE)
- [Contributing](https://github.com/new92/InstaTools/blob/main/CONTRIBUTING.md)
- [Code of conduct](https://github.com/new92/InstaTools/blob/main/CODE_OF_CONDUCT.md)
- [You may also find interesting](https://github.com/new92?tab=repositories)

## Author(s) ✍️

- [@new92](https://www.github.com/new92)

## What's new 🚀

- Addition of more tools (<a href="https://github.com/new92/InstaTools/tree/main/Chronos">Chronos</a>, <a href="https://github.com/new92/InstaTools/tree/main/Delta">Delta</a>, <a href="https://github.com/new92/InstaTools/tree/main/Hunter">Hunter</a>, <a href="https://github.com/new92/InstaTools/tree/main/Sphinx">Sphinx</a>, <a href="https://github.com/new92/InstaTools/tree/main/Spider">Spider</a>)

- Fixed bugs

- Fixed README.md file

- Enhanced UI

- Added the "save to CSV" option to most tools


## Installation 📥

### Linux 🐧

```bash
sudo su
git clone https://github.com/new92/InstaTools
cd InstaTools
sudo pip install -r requirements.txt
python3 cookies.py
cd <THE FOLDER IN WHICH IS LOCATED THE SCRIPT YOU WANT TO USE. Example: cd Mutuals>
python3 <THE NAME OF THE SCRIPT. Example: python3 mutuals.py>.py <additional parameters>
```

### Windows 🪟

```bash
git clone https://github.com/new92/InstaTools
cd InstaTools
pip install -r requirements.txt
python3 cookies.py
cd <THE FOLDER IN WHICH IS LOCATED THE SCRIPT YOU WANT TO USE. Example: cd Mutuals>
python3 <THE NAME OF THE SCRIPT. Example: python3 mutuals.py>.py
```

### MacOS 🍎

```bash
sudo su
git clone https://github.com/new92/InstaTools
cd InstaTools
python -m pip install -r requirements.txt
python3 cookies.py
cd <THE FOLDER IN WHICH IS LOCATED THE SCRIPT YOU WANT TO USE. Example: cd Mutuals>
python3 <THE NAME OF THE SCRIPT. Example: python3 mutuals.py>.py
```

## Update 🔄️

```bash
python3 update.py
```

## Contributing 🤝

Contributions are always welcome!

See `contributing.md` for ways to get started.

Please adhere to this project's `code of conduct`. For more info please check the `CODE_OF_CONDUCT.md` file.

## Special thanks to 🫡

<p align="center">
<a href="https://github.com/new92/InstaTools/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=new92/InstaTools">
</a>
</p>

## Feedback 💭

If you have any feedback, please reach out to us at <a href="mailto:new92github@gmail.com">this email address</a>.

**Feel free to contact us anytime ! You'll get a reply within a day. Please avoid using abusive or offensive language.
If you are reporting a bug or making a suggestion please make sure your report/suggestion is as much detailed as possible.**


## Features 🆕

- [ ] New tools
- [ ] Enhanced UI
- [ ] UX improvements
- [ ] Interactive menu mode
- [ ] Config support
- [ ] Safety & Account protection
- [ ] Documentation

## FAQ 🤔

#### Question 1

- Can my account get banned by using InstaTools ?

Answer ➡️ Absolutely not. InstaTools strictly adheres to Instagram's guidelines, and it does not violate any privacy-related rules. Therefore, there is no reason for Instagram to block your account.

#### Question 2

- Encountering error while attempting to log in ?

Answer ➡️ This error can be resolved simply by logging in to your account from your browser, completing Instagram's verification tests and executing the script again.
    
## License 📜

[![License](https://img.shields.io/github/license/new92/IGFollowersIncreaser?style=for-the-badge)](https://github.com/new92/IGFollowersIncreaser/blob/main/LICENSE)

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=new92/InstaTools&type=Date)](https://star-history.com/#new92/InstaTools&Date)


================================================
FILE: Researcher/README.md
================================================
# Researcher 🔍

**Short description:** Researcher uncovers the possible geographic locations of a user's followers on Instagram, providing valuable insights into audience demographics for marketers, influencers, and curious users.

**Long description:** Researcher is an innovative Python script designed to uncover the possible geographic locations of a user's Instagram followers. With Researcher, you can gain valuable insights into the global reach of your Instagram audience. Whether you're a marketer, influencer, or simply curious about your followers' demographics, this script simplifies the process of researching and visualizing the potential locations of your Instagram fanbase.
**Works for both public and private accounts**.

> If you find value in this repository, please consider giving it a star and/or forking it. Your support greatly encourages me to create more repositories like InstaTools.

## Set up and run Researcher 🚀

```bash
python3 cookies.py
python3 update.py # if you want to check for updates else skip it.
cd Researcher
python3 researcher.py -u <your_username> -t <target_username> -s <path_to_session_file>
```

## Why Researcher ? 🧐

Researcher offers **high speed**, **data storage**, **automatic uninstallation** and combines **data analysis** in order to provide as much information as possible to the user. Plus, soon will have some interesting features such as: The user will have the choice to either set a specific country to search or the script will search automatically the followers of a user (which the user will specify) and separate them to categories in proportion to the country.

## Features 🚀

- ~~Data storage~~ ✅
- ~~Log file~~ ✅
- ~~Colored~~ ✅
- ~~Pretty and organised output (prettytable usage)~~ ✅

## Expected files 📂

1) `ResearcherLog.txt`
2) `consent.txt`
3) `Researcher.csv`

## Photos 📸

![menu](https://github.com/new92/InstaTools/assets/94779840/25a97fc9-d462-453a-893b-d54333f5f877)

![output](https://github.com/new92/InstaTools/assets/94779840/094c2fb9-0c81-4c06-b34c-659c71eab532)



================================================
FILE: Researcher/files/cities.txt
================================================
ashkasham
fayzabad
jurm
khandud
raghistan
wakhan
ghormach
baghlan
nahrin
balkh
dowlatabad
khulm
lab-sar
mazar-e sharif
qarchi gak
bamyan
panjab
nili
farah
andkhoy
maymana
ghazni
fayroz koh
shahrak
gereshk
lashkar gah
sangin
chahar burj
ghoriyan
herat
kafir qala
karukh
kuhsan
kushk
qarah bagh
shindand
tir pul
zindah jan
aqchah
darzab
qarqin
shibirghan
kabul
paghman
kandahar
sidqabad
khost
asadabad
asmar
imam sahib
khanabad
kunduz
qarawul
mehtar lam
baraki barak
hukumati azrah
basawul
jalalabad
khash
mirabad
rudbar
zaranj
parun
gardez
sarobi
zarah sharan
zarghun shahr
bazarak
charikar
aibak
chiras
larkird
sar-e pul
tagaw-bay
tukzar
art khwajah
taloqan
tarinkot
uruzgan
qalat
banaj
bashkia berat
bashkia kucove
bashkia polican
bashkia skrapar
berat
corovode
kucove
polican
ura vajgurore
bashkia klos
bashkia mat
bulqize
burrel
klos
peshkopi
ulez
bashkia durres
bashkia kruje
bashkia shijak
durres
fushe-kruje
kruje
shijak
sukth
ballsh
bashkia divjake
bashkia fier
bashkia mallakaster
bashkia patos
divjake
fier
fier-cifci
lushnje
patos
patos fshat
roskovec
bashkia dropull
bashkia kelcyre
bashkia libohove
bashkia memaliaj
bashkia permet
bashkia tepelene
gjinkar
gjirokaster
kelcyre
lazarat
libohove
memaliaj
permet
tepelene
bashkia devoll
bashkia kolonje
bashkia maliq
bashkia pustec
bilisht
erseke
korce
leskovik
libonik
maliq
mborje
pogradec
velcan
voskopoje
bajram curri
krume
kukes
bashkia kurbin
bashkia lezhe
bashkia mirdite
kurbnesh
lac
lezhe
mamurras
milot
rreshen
rubik
shengjin
bashkia puke
fushe-arrez
koplik
puke
shkoder
vukatane
bashkia kavaje
bashkia vore
kamez
kavaje
krrabe
rrogozhine
sinaballaj
tirana
vore
bashkia finiq
bashkia himare
bashkia konispol
bashkia selenice
bashkia vlore
delvine
himare
konispol
ksamil
orikum
sarande
selenice
vlore
adrar
aoulef
reggane
timimoun
ain defla
el abadia
el attaf
khemis miliana
ain temouchent
beni saf
el amria
el malah
ain taya
algiers
bab ezzouar
birkhadem
rouiba
annaba
berrahal
drean
el hadjar
ain touta
arris
barika
batna
boumagueur
merouana
tazoult-lambese
bechar
akbou
amizour
barbacha
bejaia
el hed
el kseur
feraoun
seddouk
biskra
oumache
sidi khaled
sidi okba
tolga
beni mered
blida
bou arfa
boufarik
bougara
bouinan
chebli
chiffa
larbaa
meftah
sidi moussa
souma
bordj ghdir
bordj zemoura
el achir
mansourah
melouza
ain bessem
bouira
chorfa
lakhdaria
arbatache
beni amrane
boudouaou
boumerdas
dellys
makouda
naciria
ouled moussa
reghaia
tadmait
thenia
tizi gheniff
boukadir
chlef
ech chettia
oued fodda
oued sly
sidi akkacha
ain smara
constantine
didouche mourad
el khroub
hamma bouziane
ain oussera
birine
charef
dar chioukh
djelfa
el idrissia
messaad
brezina
el bayadh
debila
el oued
reguiba
robbah
ben mehidi
besbes
el kala
el tarf
berriane
ghardaia
metlili chaamba
boumahra ahmed
guelma
heliopolis
illizi
jijel
khenchela
aflou
laghouat
m’sila
sidi aissa
mascara
sig
berrouaghia
medea
mila
rouached
sidi merouane
telerghma
mostaganem
ain sefra
naama
bou tlelis
es senia
oran
djamaa
el hadjira
hassi messaoud
megarine
ouargla
rouissat
sidi amrane
tebesbest
touggourt
ain beida
ain fakroun
ain kercha
el aouinet
meskiana
ammi moussa
djidiouia
mazouna
oued rhiou
relizane
smala
zemoura
saida
ain arnat
bougaa
el eulma
salah bey
setif
balidat ameur
belarbi
el bour
lamtar
marhoum
merine
mezaourou
moggar
moulay slissen
n'goussa
sfissef
sidi brahim
sidi hamadouche
sidi slimane
sidi yacoub
sidi yahia
taibet
tamellaht
tamerna djedida
teghalimet
telagh
tenezara
tenira
tessala
zerouala
azzaba
karkira
skikda
tamalous
sedrata
souk ahras
i-n-salah
tamanrasset
cheria
hammamet
tebessa
’ain deheb
djebilet rosfa
frenda
ksar chellala
sougueur
tiaret
tindouf
’ain benian
baraki
bou ismail
cheraga
douera
el affroun
hadjout
kolea
mouzaia
saoula
tipasa
zeralda
lardjem
tissemsilt
arhribs
azazga
beni douala
boghni
boudjima
chemini
freha
ighram
mekla
timizart
tirmitine
tizi ouzou
tizi rached
tizi-n-tleta
beni mester
bensekrane
chetouane
hennaya
mansoura
nedroma
ouled mimoun
remchi
sebdou
sidi abdelli
tlemcen
canillo
el tarter
encamp
les escaldes
arinsal
la massana
ordino
ambriz
bula atumba
caxito
dande
muxima
nambuangongo
pango aluquem
ucua
baia farta
balombo
benguela
bocoio
caimbambo
catumbela
chongoroi
cubal
ganda
lobito
sumbe
camacupa
catabola
chissamba
cuito
cabinda
menongue
camabatela
n’dalatando
quibala
uacu cungo
ondjiva
caala
chela
huambo
longonjo
caconda
caluquembe
chibia
chicomba
chipindo
cuvango
gambos
humpata
jamba
lubango
matala
quilengues
quipungo
belas
cacuaco
cazenga
luanda
talatona
viana
lucapa
cazaji
saurimo
malanje
leua
luau
luena
lumeje
uige
mbanza congo
n'zeto
soio
codrington
piggotts
potters village
saint john’s
bolands
falmouth
liberta
all saints
parham
balvanera
barracas
belgrano
boedo
buenos aires
colegiales
retiro
villa lugano
villa ortuzar
ancasti
andalgala
capayan
el rodeo
fiambala
hualfin
huillapima
icano
londres
los altos
los varela
mutquin
poman
recreo
san antonio
santa maria
tinogasta
avia terai
barranqueras
basail
campo largo
capitan solari
castelli
charadai
charata
chorotis
ciervo petiso
colonia benitez
colonia elisa
colonias unidas
corzuela
cote-lai
fontana
gancedo
general pinedo
general vedia
hermoso campo
la clotilde
la eduvigis
la escondida
la leonesa
la tigra
la verde
laguna limpia
lapachito
las brenas
las garcitas
los frentones
machagai
makalle
margarita belen
napenay
pampa almiron
presidencia roca
puerto bermejo
puerto tirol
puerto vilelas
quitilipi
resistencia
samuhu
san bernardo
santa sylvina
taco pozo
tres isletas
villa angela
villa berthet
camarones
comodoro rivadavia
dolavon
el maiten
esquel
gaiman
gastre
gobernador costa
lago puelo
las plumas
puerto madryn
rada tilly
rawson
rio mayo
rio pico
sarmiento
tecka
trelew
trevelin
achiras
adelia maria
alejandro roca
alejo ledesma
almafuerte
alta gracia
arias
arroyito
arroyo cabral
balnearia
bell ville
berrotaran
brinkmann
buchardo
camilo aldao
canals
carnerillo
carrilobo
cavanagh
charras
chazon
cintra
cordoba
coronel baigorria
coronel moldes
corralito
cosquin
costa sacate
cruz alta
cuesta blanca
dean funes
del campillo
despenaderos
devoto
el aranado
el tio
elena
embalse
etruria
general baldissera
general cabrera
general levalle
general roca
guatimozin
hernando
huanchillas
huerta grande
huinca renanco
idiazabal
inriville
isla verde
italo
james craik
jesus maria
justiniano posse
la calera
la carlota
la cesira
la cumbre
la falda
la francia
la granja
la para
la playosa
laborde
laboulaye
laguna larga
las acequias
las higueras
las junturas
las perdices
las varas
las varillas
leones
los cocos
los condores
los surgentes
malagueno
malvinas argentinas
marcos juarez
marull
mattaldi
mendiolaza
mina clavero
miramar
monte buey
monte cristo
monte maiz
morrison
morteros
noetinger
obispo trejo
oliva
oncativo
ordonez
pascanas
pasco
pilar
piquillin
portena
quilino
rio ceballos
rio cuarto
rio segundo
rio tercero
sacanta
saldan
salsacate
salsipuedes
sampacho
san agustin
san basilio
san carlos
san francisco
santa eufemia
santa magdalena
santiago temple
sebastian elcano
serrano
serrezuela
tancacha
ticino
tio pujio
toledo
ucacha
unquillo
valle hermoso
viamonte
vicuna mackenna
villa allende
villa ascasubi
villa berna
villa dolores
villa giardino
villa huidobro
villa maria
villa nueva
villa reduccion
villa rumipal
villa tulumba
villa valeria
wenceslao escalante
alvear
bonpland
chavarria
concepcion
corrientes
curuzu cuatia
empedrado
esquina
felipe yofre
garruchos
gobernador virasora
goya
herlitzka
ita ibate
itati
ituzaingo
juan pujol
la cruz
libertad
loreto
mburucuya
mercedes
mocoreta
monte caseros
palmar grande
perugorria
pueblo libertador
riachuelo
saladas
san cosme
san lorenzo
san miguel
santa lucia
santa rosa
santo tome
yapeyu
yataity calle
aranguren
bovril
caseros
ceibas
chajari
colon
colonia elia
concordia
conscripto bernardi
crespo
diamante
dominguez
federacion
federal
general campos
general galarza
general ramirez
gobernador mansilla
gualeguay
gualeguaychu
hasenkamp
hernandez
herrera
la criolla
la paz
larroque
los charruas
los conquistadores
lucas gonzalez
macia
nogoya
oro verde
parana
piedras blancas
pronunciamiento
puerto ibicuy
puerto yerua
san benito
san gustavo
san justo
san salvador
santa ana
santa anita
santa elena
segui
tabossi
ubajay
urdinarrain
viale
victoria
villa elisa
villa hernandarias
villa mantero
villa paranacito
villa urquiza
villaguay
clorinda
comandante fontana
el colorado
formosa
herradura
ibarreta
laguna naick-neck
laguna yema
las lomitas
palo santo
pirane
riacho eh-eh
villa escolar
abra pampa
caimancito
calilegua
el aguilar
fraile pintado
humahuaca
la mendieta
la quiaca
maimara
palma sola
palpala
santa clara
tilcara
yuto
alpachiri
alta italia
anguil
arata
bernardo larroude
bernasconi
caleufu
catrilo
colonia baron
doblas
eduardo castex
embajador martini
general acha
general pico
guatrache
ingeniero luiggi
intendente alvear
jacinto arauz
la adela
la maruja
lonquimay
macachin
miguel riglos
parera
quemu quemu
rancul
realico
santa isabel
telen
trenel
uriburu
victorica
winifreda
arauco
castro barros
chamical
chilecito
la rioja
villa bustos
vinchina
godoy cruz
las heras
mendoza
san martin
san rafael
alba posse
azara
campo grande
campo ramon
campo viera
candelaria
capiovi
caraguatay
cerro azul
cerro cora
colonia aurora
dos arroyos
el alcazar
el soberbio
florentino ameghino
garuhape
garupa
general alvear
gobernador roca
guarani
jardin america
los helechos
martires
mojon grande
montecarlo
obera
panambi
posadas
puerto eldorado
puerto esperanza
puerto iguazu
puerto leoni
puerto libertad
puerto piray
puerto rico
san jose
san pedro
san vicente
santo pipo
tres capones
wanda
alumine
andacollo
anelo
barrancas
buta ranquil
centenario
chos malal
cutral-co
el huecu
las coloradas
las lajas
las ovejas
loncopue
mariano moreno
neuquen
picun leufu
plaza huincul
plottier
senillosa
vista alegre
zapala
allen
catriel
cervantes
chichinales
chimpay
choele choel
cinco saltos
cipolletti
comallo
contraalmirante cordero
coronel belisle
darwin
el bolson
el cuy
general conesa
ingeniero jacobacci
lamarque
los menucos
mainque
maquinchao
norquinco
pilcaniyeu
rio colorado
sierra colorada
sierra grande
valcheta
viedma
villa regina
apolinario saravia
cachi
cafayate
campo quijano
chicoana
departamento capital
el carril
el galpon
el quebrachal
embarcacion
la caldera
las lajitas
salta
tartagal
albardon
calingasta
caucete
chimbas
pocito
san juan
buena esperanza
concaran
justo daract
la punta
la toma
lujan
merlo
naschel
san luis
tilisarao
union
villa mercedes
caleta olivia
el calafate
gobernador gregores
los antiguos
perito moreno
pico truncado
puerto deseado
rio gallegos
rio turbio
san julian
armstrong
arroyo seco
arrufo
avellaneda
bella italia
calchaqui
capitan bermudez
carcarana
casilda
ceres
chanar ladeado
coronda
el trebol
esperanza
firmat
funes
galvez
gato colorado
gobernador galvez
granadero baigorria
helvecia
hersilia
iriondo department
laguna paiva
las parejas
las rosas
las toscas
los laureles
malabrigo
melincue
perez
rafaela
reconquista
roldan
rosario
rufino
san cristobal
san javier
san jorge
santa fe
sastre
sunchales
tacuarendi
tostado
totoras
venado tuerto
vera
villa canas
villa constitucion
villa mugueta
villa ocampo
villa trinidad
anatuya
beltran
campo gallo
clodomira
colonia dora
el hoyo
la banda
los juries
los telares
quimili
sumampa
suncho corral
tintina
villa atamisqui
rio grande
tolhuin
ushuaia
aguilares
alderetes
bella vista
burruyacu
famailla
graneros
la cocha
monteros
simoca
tafi viejo
trancas
yerba buena
agarakavan
aparan
aragats
arteni
ashnak
ashtarak
byurakan
hnaberd
karbi
kasakh
kosh
nor yerznka
oshakan
sasunik
shenavan
t’alin
tsaghkahovit
ushi
voskevaz
zovuni
abovyan
aralez
ararat
arevabuyr
arevshat
armash
artashat
avshar
aygavan
aygepat
aygestan
aygezard
bardzrashen
berk’anush
burastan
byuravan
dalar
darakert
dashtavan
dimitrov
dvin
getazat
ghukasavan
goravan
hayanist
hovtashat
hovtashen
jrahovit
lusarrat
marmarashen
masis
mrganush
mrgavan
mrgavet
nizami
norabats’
noramarg
norashen
noyakert
nshavan
sayat’-nova
shahumyan
sis
sisavan
surenavan
vedi
verin artashat
verin dvin
vosketap’
vostan
yeghegnavan
zangakatun
zorak
aghavnatun
aknalich
aknashen
alashkert
apaga
arak’s
arazap’
arbat’
arevashat
arevik
argavand
armavir
arshaluys
artimet
aygek
aygeshat
baghramyan
bambakashat
dalarik
doghs
gay
geghakert
geghanist
getashen
gmbet’
griboyedov
haykashen
hovtamej
janfida
khoronk’
lenughi
lukashin
margara
mayisyan
merdzavan
metsamor
mrgashat
musalerr
myasnikyan
nalbandyan
nor armavir
norakert
p’shatavan
ptghunk’
sardarapat
tandzut
taronik
tsaghkunk’
tsiatsan
vagharshapat
voskehat
yeghegnut
yeraskhahun
akunk’
astghadzor
chambarak
ddmashen
drakhtik
dzoragyugh
gagarin
gandzak
gavarr
geghamasar
geghamavan
karanlukh
karchaghbyur
lanjaghbyur
lchap’
lchashen
lichk’
madina
martuni
mets masrik
nerk’in getashen
noratus
sarukhan
sevan
tsovagyugh
tsovak
tsovasar
tsovazard
tsovinar
vaghashen
vahan
vardenik
vardenis
varser
verin getashen
yeranos
aghavnadzor
aramus
argel
arzakan
arzni
balahovit
bjni
buzhakan
byureghavan
dzoraghbyur
fantan
garrni
goght’
hrazdan
kaputan
kotayk’
lerrnanist
mayakovski
meghradzor
mrgashen
nor geghi
nor gyugh
prroshyan
ptghni
solak
tsaghkadzor
yeghvard
zarr
zoravan
zovaber
agarak
akht’ala
alaverdi
arevashogh
bazum
chochkan
darpas
dsegh
fioletovo
gogaran
gugark’
gyulagarak
jrashen
lerrnants’k’
lerrnapat
lerrnavan
lorut
margahovit
mets parni
metsavan
odzun
sarahart’
saramej
shirakamut
shnogh
spitak
step’anavan
tashir
tsaghkaber
urrut
vahagni
vanadzor
vardablur
akhuryan
amasia
anushavan
arrap’i
azatan
basen
dzit’hank’ov
gyumri
haykavan
horrom
kamo
lerrnakert
maralik
marmashen
meghrashen
mets mant’ash
p’ok’r mant’ash
pemzashen
saratak
shirak
spandaryan
voskehask
yerazgavors
akner
angeghakot’
brrnakot’
dzorastan
goris
hats’avan
kapan
khndzoresk
meghri
shaghat
shinuhayr
tegh
verishen
archis
artsvaberd
aygehovit
azatamut
bagratashen
berd
berdavan
dilijan
haghartsin
ijevan
khasht’arrak
mosesgegh
navur
noyemberyan
parravak’ar
sarigyugh
voskevan
agarakadzor
areni
getap’
gladzor
jermuk
malishka
rrind
shatin
vayk’
vernashen
yeghegis
yeghegnadzor
zarrit’ap’
arabkir
k’anak’erravan
vardadzor
yerevan
acton
ainslie
amaroo
aranda
banks
barton
belconnen
bonner
bonython
braddon
bruce
calwell
campbell
canberra
casey
chapman
charnwood
chifley
chisholm
city
conder
cook
coombs
crace
curtin
deakin
dickson
downer
duffy
dunlop
evatt
fadden
farrer
fisher
florey
flynn
forde
forrest
franklin
fraser
garran
gilmore
giralang
gordon
gowrie
greenway
griffith
gungahlin
hackett
harrison
hawker
higgins
holder
holt
hughes
isaacs
isabella plains
kaleen
kambah
kingston
latham
lyneham
lyons
macarthur
macgregor
macquarie
mawson
mckellar
melba
monash
narrabundah
ngunnawal
nicholls
o'connor
oxley
page
palmerston
pearce
phillip
red hill
reid
richardson
rivett
scullin
spence
stirling
theodore
torrens
turner
wanniassa
waramanga
watson
weetangera
weston
wright
yarralumla
abbotsbury
abbotsford
abercrombie
aberdare
aberdeen
aberglasslyn
abermain
acacia gardens
adamstown
adamstown heights
airds
albion park
albury
aldavilla
alexandria
alfords point
allambie heights
allawah
alstonville
ambarvale
anna bay
annandale
annangrove
appin
arcadia
arcadia vale
argenton
armidale
arncliffe
artarmon
ashbury
ashcroft
ashfield
ashmont
ashtonfield
asquith
auburn
austinmer
austral
avoca beach
avondale
balgowlah
balgowlah heights
balgownie
ballina
balmain
balmain east
balranald
bangalow
bangor
banksia
banksmeadow
bankstown
banora point
bar beach
barden ridge
bardia
bardwell park
bardwell valley
bargo
barham
barnsley
barooga
barraba
barrack heights
basin view
bass hill
bateau bay
batehaven
batemans bay
bathurst
bathurst regional
batlow
baulkham hills
bay view
beacon hill
beaumont hills
beecroft
bega
bega valley
belfield
bellambi
bellbird
bellevue hill
bellingen
belmont
belmont north
belmont south
belmore
belrose
bensville
berala
beresfield
berkeley
berkeley vale
berkshire park
bermagui
berowra
berowra heights
berridale
berrigan
berry
beverley park
beverly hills
bexley
bexley north
bidwill
bilambil heights
bilgola plateau
bingara
birchgrove
birmingham gardens
birrong
blackalls park
blackbutt
blackett
blackheath
blacksmiths
blacktown
blackwall
blair athol
blakehurst
bland
blaxland
blayney
bligh park
blue bay
blue haven
boambee
boambee east
bogan
bogangar
boggabri
bolton point
bolwarra heights
bomaderry
bombala
bondi
bondi beach
bondi junction
bonnells bay
bonnet bay
bonny hills
bonnyrigg
bonnyrigg heights
bonville
booker bay
booragul
boorowa
bossley park
botany
botany bay
bourke
bourkelands
bow bowing
bowen mountain
bowenfels
bowral
bowraville
bradbury
braidwood
branxton
breakfast point
brewarrina
brighton-le-sands
bringelly
broadmeadow
broken hill
bronte
brookvale
broulee
brunswick heads
budgewoi
buff point
bulahdelah
bullaburra
bulli
bundanoon
bundeena
bungarribee
bungendore
buronga
burradoo
burraneer
burrill lake
burwood
busby
buttaba
buxton
byron bay
byron shire
bywong
cabarita
cabonne
cabramatta
cabramatta west
caddens
calala
callaghan
callala bay
cambewarra village
cambridge gardens
cambridge park
camden
camden haven
camden south
cameron park
cammeray
campbelltown
camperdown
campsie
canada bay
canley heights
canley vale
canowindra
canterbury
canton beach
cardiff
cardiff heights
cardiff south
caringbah
caringbah south
carlingford
carlton
carnes hill
carramar
carrathool
carrington
carss park
cartwright
carwoola
casino
castle cove
castle hill
castlecrag
castlereagh
casuarina
casula
catalina
catherine field
caves beach
cecil hills
centennial park
central darling
cessnock
charlestown
charmhaven
chatswood
chatswood west
cherrybrook
chester hill
chinderah
chippendale
chipping norton
chiswick
chittaway bay
claremont meadows
clarence town
clarence valley
claymore
clemton park
clontarf
clovelly
coal point
cobar
cobbitty
coffs harbour
coleambally
colebee
coledale
collaroy
collaroy plateau
colo vale
colyton
como
concord
concord west
condell park
condobolin
coniston
connells point
constitution hill
coogee
cooks hill
coolah
coolamon
cooma
coonabarabran
coonamble
cooranbong
cootamundra
copacabana
coraki
cordeaux heights
corindi beach
corlette
corowa
corrimal
coutts crossing
cowra
cranebrook
cremorne
cremorne point
crescent head
crestwood
cringila
cromer
cronulla
crookwell
crows nest
croydon
culburra beach
culcairn
cumbalum
cundletown
curl curl
currans hill
daceyville
dalmeny
dapto
darling point
darlinghurst
darlington
darlington point
davidson
davistown
dean park
dee why
denham court
deniliquin
denistone
denistone east
denman
dharruk
dolls point
doonside
dora creek
dorrigo
double bay
douglas park
dover heights
drummoyne
dubbo
dudley
dulwich hill
dundas valley
dunedoo
dungog
dural
eagle vale
earlwood
east albury
east ballina
east branxton
east corrimal
east gosford
east hills
east jindabyne
east kempsey
east killara
east kurrajong
east lindfield
east lismore
east maitland
east ryde
east tamworth
eastlakes
eastwood
eden
edensor park
edgecliff
edgeworth
edmondson park
eglinton
elanora heights
elderslie
eleebana
elermore vale
elizabeth bay
elizabeth hills
ellalong
emerald beach
emerton
empire bay
emu heights
emu plains
engadine
enmore
epping
erina
ermington
erskine park
erskineville
eschol park
estella
ettalong
ettalong beach
eulomogo
eurobodalla
evans head
fairfield
fairfield east
fairfield heights
fairfield west
fairlight
fairy meadow
farmborough heights
faulconbridge
fennell bay
fern bay
fern hill
figtree
fingal bay
finley
five dock
fletcher
flinders
floraville
forbes
forest hill
forest lodge
forestville
forresters beach
forster
frederickton
freemans reach
frenchs forest
freshwater
galston
garden suburb
gateshead
georges hall
georgetown
gerringong
gilgandra
gillieston heights
girards hill
girraween
gladesville
glebe
glen alpine
glen innes
glenbrook
glendale
glendenning
glenfield
glenfield park
glenhaven
glenmore park
glenning valley
glenorie
glenroy
glenwood
glossodia
gloucester
gol gol
googong
goonellabah
gorokan
gosford
goulburn
goulburn mulwaree
grafton
granville
grasmere
grays point
green valley
greenacre
greenfield park
greenwell point
greenwich
gregory hills
grenfell
greta
greystanes
grose vale
guildford west
gulgong
gulmarrad
gundagai
gundaroo
gunnedah
guyra
gwandalan
gwydir
gwynneville
gymea
gymea bay
haberfield
halekulani
hamilton
hamlyn terrace
hammondville
hanwood
harrington
harrington park
harris park
hassall grove
hawkesbury
hawks nest
hay
haymarket
hazelbrook
heathcote
hebersham
heckenberg
heddon greta
helensburgh
henty
hill top
hillsdale
hillston
hillvue
hinchinbrook
hobartville
holbrook
holmesville
holroyd
holsworthy
homebush
homebush west
horningsea park
hornsby
hornsby heights
hornsby shire
horsley
horsley park
howlong
hoxton park
hunters hill
hunterview
huntingwood
hurlstone park
hurstville
hurstville grove
illawong
iluka
ingleburn
inverell
islington
jamberoo
jamisontown
jannali
jerilderie
jerrabomberra
jesmond
jewells
jilliby
jindabyne
jindera
jordan springs
junction hill
junee
kahibah
kanahooka
kandos
kanwal
kapooka
karabar
kareela
kariong
karuah
katoomba
kearns
keiraville
kellyville
kellyville ridge
kelso
kemps creek
kempsey
kendall
kensington
kenthurst
kew
kiama
kiama downs
kilaben bay
killara
killarney heights
killarney vale
king creek
kings langley
kings park
kingscliff
kingsford
kingsgrove
kingswood park
kirrawee
kirribilli
kogarah
kogarah bay
koonawarra
kooringal
kootingal
korora
kotara
kotara south
ku-ring-gai
kurnell
kurraba point
kurrajong heights
kurri kurri
kyle bay
kyogle
lachlan
lake albert
lake cargelligo
lake cathie
lake haven
lake heights
lake illawarra
lake munmorah
lakelands
lakemba
lakewood
lalor park
lambton
lane cove
lansvale
largs
lavington
lawrence
lawson
leeton
leichhardt
lennox head
leonay
leppington
lethbridge park
leumeah
leura
lewisham
liberty grove
lidcombe
lightning ridge
lilli pilli
Download .txt
gitextract_fj5qyne7/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── dependabot.yml
│   └── workflows/
│       └── codeql.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Chronos/
│   ├── README.md
│   └── chronos.py
├── Delta/
│   ├── README.md
│   ├── delta.py
│   └── shortcodes.txt
├── Hermes/
│   ├── README.md
│   └── hermes.py
├── Hunter/
│   ├── README.md
│   └── hunter.py
├── IsVer/
│   ├── README.md
│   └── isver.py
├── LICENSE
├── Mutuals/
│   ├── README.md
│   └── mutuals.py
├── Poirot/
│   ├── README.md
│   └── poirot.py
├── README.md
├── Researcher/
│   ├── README.md
│   ├── files/
│   │   ├── cities.txt
│   │   └── countries.txt
│   └── researcher.py
├── SECURITY.md
├── Spammer/
│   ├── README.md
│   ├── spammer.py
│   └── targets.txt
├── Sphinx/
│   ├── README.md
│   ├── profanity.txt
│   ├── shortcodes.txt
│   └── sphinx.py
├── Spider/
│   ├── README.md
│   └── spider.py
├── ToolZ/
│   ├── README.md
│   └── toolz.py
├── Tracker/
│   ├── README.md
│   └── tracker.py
├── Zeus/
│   ├── README.md
│   ├── shortcodes.txt
│   └── zeus.py
├── cookies.py
├── requirements.txt
└── update.py
Download .txt
SYMBOL INDEX (94 symbols across 16 files)

FILE: Chronos/chronos.py
  function clear (line 94) | def clear():
  function fpath (line 114) | def fpath(fname: str):
  function ScriptInfo (line 119) | def ScriptInfo():
  function banner (line 148) | def banner() -> str:
  function calculate (line 179) | def calculate(posts: int, period: int) -> float:
  function Uninstall (line 182) | def Uninstall() -> str:
  function main (line 194) | def main(username: str, session: str, target: str):

FILE: Delta/delta.py
  function clear (line 94) | def clear():
  function fpath (line 114) | def fpath(fname: str):
  function ScriptInfo (line 138) | def ScriptInfo():
  function Uninstall (line 167) | def Uninstall() -> str:
  function count (line 181) | def count() -> int:
  function banner (line 184) | def banner() -> str:
  function main (line 194) | def main(username: str, session: str):

FILE: Hermes/hermes.py
  function clear (line 97) | def clear():
  function fpath (line 117) | def fpath(fname: str):
  function ScriptInfo (line 122) | def ScriptInfo():
  function banner (line 151) | def banner() -> str:
  function Uninstall (line 183) | def Uninstall() -> str:
  function main (line 197) | def main(username: str, session: str, code: str):

FILE: Hunter/hunter.py
  function clear (line 93) | def clear():
  function fpath (line 113) | def fpath(fname: str):
  function ScriptInfo (line 118) | def ScriptInfo():
  function banner (line 147) | def banner() -> str:
  function Uninstall (line 179) | def Uninstall() -> str:
  function main (line 195) | def main(username: str, session: str):

FILE: IsVer/isver.py
  function clear (line 93) | def clear():
  function fpath (line 113) | def fpath(fname: str):
  function ScriptInfo (line 118) | def ScriptInfo():
  function banner (line 147) | def banner() -> str:
  function Uninstall (line 180) | def Uninstall() -> str:
  function main (line 192) | def main(username: str, target: str, session: str):

FILE: Mutuals/mutuals.py
  function clear (line 92) | def clear():
  function fpath (line 112) | def fpath(fname: str):
  function ScriptInfo (line 117) | def ScriptInfo():
  function banner (line 165) | def banner() -> str:
  function Uninstall (line 175) | def Uninstall() -> str:
  function main (line 189) | def main(username: str, session: str, user1: str, user2: str):

FILE: Poirot/poirot.py
  function clear (line 86) | def clear():
  function fpath (line 98) | def fpath(fname: str):
  function ScriptInfo (line 111) | def ScriptInfo():
  function banner (line 140) | def banner() -> str:
  function Uninstall (line 152) | def Uninstall() -> str:
  function fetch (line 183) | def fetch(username: str):
  function main (line 218) | def main(target: str):

FILE: Researcher/researcher.py
  function clear (line 95) | def clear():
  function fpath (line 112) | def fpath(fname: str):
  function ScriptInfo (line 117) | def ScriptInfo():
  function filter (line 168) | def filter(spaces: list, followers: list, bios: list) -> tuple:
  function Uninstall (line 184) | def Uninstall() -> str:
  function banner (line 200) | def banner():
  function main (line 210) | def main(username: str, target: str, session: str):

FILE: Spammer/spammer.py
  function clear (line 99) | def clear():
  function fpath (line 116) | def fpath(fname: str):
  function ScriptInfo (line 121) | def ScriptInfo():
  function Uninstall (line 150) | def Uninstall() -> str:
  function banner (line 181) | def banner() -> str:
  function main (line 191) | def main(username: str, password: str):

FILE: Sphinx/sphinx.py
  function clear (line 100) | def clear():
  function fpath (line 112) | def fpath(fname: str):
  function ScriptInfo (line 125) | def ScriptInfo():
  function banner (line 154) | def banner() -> str:
  function filter (line 185) | def filter(COMS, COMES):
  function Uninstall (line 195) | def Uninstall() -> str:
  function main (line 207) | def main(username: str, session: str):

FILE: Spider/spider.py
  function clear (line 97) | def clear():
  function fpath (line 117) | def fpath(fname: str):
  function ScriptInfo (line 122) | def ScriptInfo():
  function banner (line 151) | def banner() -> str:
  function Uninstall (line 185) | def Uninstall() -> str:
  function crawl (line 202) | def crawl(target: str, counter: int):
  function main (line 226) | def main(username: str, session: str, target: str, counter: int):

FILE: ToolZ/toolz.py
  function clear (line 92) | def clear():
  function fpath (line 104) | def fpath(fname: str):
  function Uninstall (line 109) | def Uninstall() -> str:
  function ScriptInfo (line 148) | def ScriptInfo():
  function banner (line 177) | def banner() -> str:
  function main (line 199) | def main(username: str, target: str, session: str):

FILE: Tracker/tracker.py
  function clear (line 95) | def clear():
  function fpath (line 104) | def fpath(fname: str):
  function Uninstall (line 109) | def Uninstall() -> str:
  function ScriptInfo (line 148) | def ScriptInfo():
  function banner (line 177) | def banner() -> str:
  function main (line 190) | def main(username: str, target: str, session: str):

FILE: Zeus/zeus.py
  function clear (line 100) | def clear():
  function fpath (line 117) | def fpath(fname: str):
  function ScriptInfo (line 122) | def ScriptInfo():
  function banner (line 151) | def banner() -> str:
  function filter (line 180) | def filter(L: list) -> list:
  function Uninstall (line 198) | def Uninstall() -> str:
  function main (line 210) | def main(username: str, session: str):

FILE: cookies.py
  function get_cookiefile (line 13) | def get_cookiefile():
  function import_session (line 24) | def import_session(cookiefile, sessionfile):

FILE: update.py
  function update (line 5) | def update():
Condensed preview — 48 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,712K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 834,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 105,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"\" \n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 878,
    "preview": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n  schedule:\n    - cron: '2"
  },
  {
    "path": ".gitignore",
    "chars": 1799,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3098,
    "preview": "# Code of Conduct - InstaTools\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncon"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 9517,
    "preview": "<!-- omit in toc -->\n# Contributing to InstaTools\n\nFirst off, thanks for taking the time to contribute! ❤️\n\nAll types of"
  },
  {
    "path": "Chronos/README.md",
    "chars": 2109,
    "preview": "# Chronos ⌛\n\n**Short description:** Chronos is a tool that analyzes how often a user posts on Instagram.\n\n**Long descrip"
  },
  {
    "path": "Chronos/chronos.py",
    "chars": 16215,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @Prog"
  },
  {
    "path": "Delta/README.md",
    "chars": 2831,
    "preview": "# Delta 📡\n\n**Short description:** Delta efficiently extracts reels from Instagram accounts, simplifying content gatherin"
  },
  {
    "path": "Delta/delta.py",
    "chars": 15221,
    "preview": "\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @ProgramR4732]\n\nDelta is a py"
  },
  {
    "path": "Delta/shortcodes.txt",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "Hermes/README.md",
    "chars": 2601,
    "preview": "# Hermes 🪽\n\n**Short description:** Hermes analyzes Instagram likes for a specific post, extracting and analyzing user pr"
  },
  {
    "path": "Hermes/hermes.py",
    "chars": 18417,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @Prog"
  },
  {
    "path": "Hunter/README.md",
    "chars": 2648,
    "preview": "# Hunter 🔫\n\n**Short description:** Hunter tracks ghost followers on Instagram accounts, identifying users who follow but"
  },
  {
    "path": "Hunter/hunter.py",
    "chars": 17887,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nContributors: [@Itsfizziks, @ProgramR4732]\n\nHu"
  },
  {
    "path": "IsVer/README.md",
    "chars": 2540,
    "preview": "# IsVer 🔭\n\n**Short description:** IsVer attempts to identify verified accounts a user follows, offering insights into th"
  },
  {
    "path": "IsVer/isver.py",
    "chars": 19583,
    "preview": "# -*- coding: utf-8 -*-\r\n\"\"\"\r\nAuthor: new92\r\nGithub: @new92\r\nLeetcode: @new92\r\nPyPI: @new92\r\nContributors: [@Itsfizziks,"
  },
  {
    "path": "LICENSE",
    "chars": 1062,
    "preview": "MIT License\n\nCopyright (c) 2023 new92\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
  },
  {
    "path": "Mutuals/README.md",
    "chars": 2833,
    "preview": "# Mutuals 🧙\n\n**Short description:** Mutuals identifies mutual followers and followings between 2 Instagram accounts, fac"
  },
  {
    "path": "Mutuals/mutuals.py",
    "chars": 26331,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @Prog"
  },
  {
    "path": "Poirot/README.md",
    "chars": 1476,
    "preview": "# Poirot 🕵️\n\n**Short description:** Poirot elegantly extracts valuable information from Instagram accounts using Instagr"
  },
  {
    "path": "Poirot/poirot.py",
    "chars": 16347,
    "preview": "# -*- coding: utf-8 -*-\r\n\"\"\"\r\nAuthor: new92\r\nGithub: @new92\r\nLeetcode: @new92\r\nPyPI: @new92\r\nContributors: [@Itsfizziks,"
  },
  {
    "path": "README.md",
    "chars": 8126,
    "preview": "![logo-no-background](https://github.com/new92/InstaTools/assets/94779840/6b147b66-c439-4ef8-bded-4d77909c9fe7)\n\n[![Coda"
  },
  {
    "path": "Researcher/README.md",
    "chars": 2053,
    "preview": "# Researcher 🔍\n\n**Short description:** Researcher uncovers the possible geographic locations of a user's followers on In"
  },
  {
    "path": "Researcher/files/cities.txt",
    "chars": 1205383,
    "preview": "ashkasham\nfayzabad\njurm\nkhandud\nraghistan\nwakhan\nghormach\nbaghlan\nnahrin\nbalkh\ndowlatabad\nkhulm\nlab-sar\nmazar-e sharif\nq"
  },
  {
    "path": "Researcher/files/countries.txt",
    "chars": 1454,
    "preview": "🇦🇫 afghanistan afg\n🇦🇱 albania alb\n🇩🇿 algeria dz\n🇦🇩 andorra and\n🇦🇴 angola ao\n🇦🇬 antigua and barbuda ag\n🇦🇷 argentina arg\n🇦"
  },
  {
    "path": "Researcher/researcher.py",
    "chars": 23701,
    "preview": "# -*- coding: utf-8 -*-\r\n\"\"\"\r\nAuthor: new92\r\nGithub: @new92\r\nLeetcode: @new92\r\nPyPI: @new92\r\nContributors: [@Itsfizziks,"
  },
  {
    "path": "SECURITY.md",
    "chars": 350,
    "preview": "# Security Policy\n\n## Supported Versions\n\n| Version | Supported          |\n| ------- | ------------------ |\n| 1.0     | "
  },
  {
    "path": "Spammer/README.md",
    "chars": 3517,
    "preview": "# Spammer 🧨\n\n**Short description:** Spammer automates sending multiple messages to another user's Instagram inbox.\n\n**Lo"
  },
  {
    "path": "Spammer/spammer.py",
    "chars": 15837,
    "preview": "# -*- coding: utf-8 -*-\r\n\"\"\"\r\nAuthor: new92\r\nGithub: @new92\r\nLeetcode: @new92\r\nPyPI: @new92\r\nContributors: [@Itsfizziks,"
  },
  {
    "path": "Spammer/targets.txt",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "Sphinx/README.md",
    "chars": 3040,
    "preview": "# Sphinx 🔬\n\n**Short description:** Sphinx swiftly identifies and extracts offensive comments from Instagram posts using "
  },
  {
    "path": "Sphinx/profanity.txt",
    "chars": 17896,
    "preview": "2g1c\n2girls1cup\n5h1t\n5hit\nJesus\na$$\na$$hole\na2m\na55\na55hole\nabortion\nabuse\nacrotomophilia\naddict\naddicts\nahole\nalabamaho"
  },
  {
    "path": "Sphinx/shortcodes.txt",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "Sphinx/sphinx.py",
    "chars": 20014,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @Prog"
  },
  {
    "path": "Spider/README.md",
    "chars": 2843,
    "preview": "# Spider 🕸️\n\n**Short description:** Spider gathers URLs from Instagram users by scanning captions, user bios, and other "
  },
  {
    "path": "Spider/spider.py",
    "chars": 18089,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @Prog"
  },
  {
    "path": "ToolZ/README.md",
    "chars": 2613,
    "preview": "# ToolZ 🕵\n\n**Short description:** Toolz helps monitor the unfollowers of a user on Instagram, keeping the user informed "
  },
  {
    "path": "ToolZ/toolz.py",
    "chars": 18383,
    "preview": "\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @ProgramR4732]\n\nToolZ is a py"
  },
  {
    "path": "Tracker/README.md",
    "chars": 2692,
    "preview": "# Tracker 👻\n\n**Short description:** Tracker monitors and records changes in Instagram followers and followings, providin"
  },
  {
    "path": "Tracker/tracker.py",
    "chars": 34126,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @Prog"
  },
  {
    "path": "Zeus/README.md",
    "chars": 2400,
    "preview": "# Zeus ⚡\n\n**Short description:** Zeus identifies mutual likers, commenters, and comments across specified Instagram post"
  },
  {
    "path": "Zeus/shortcodes.txt",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "Zeus/zeus.py",
    "chars": 17559,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nAuthor: new92\nGithub: @new92\nLeetcode: @new92\nPyPI: @new92\nContributors: [@Itsfizziks, @Prog"
  },
  {
    "path": "cookies.py",
    "chars": 2085,
    "preview": "from argparse import ArgumentParser\r\nfrom glob import glob\r\nfrom os.path import expanduser\r\nfrom platform import system\r"
  },
  {
    "path": "requirements.txt",
    "chars": 132,
    "preview": "instaloader == 4.10\nrequests == 2.33.0\ncolorama == 0.4.6\nprettytable == 3.8.0\ninstagrapi == 1.16.30\nrich == 12.6.0\ntabul"
  },
  {
    "path": "update.py",
    "chars": 610,
    "preview": "import subprocess, os\nfrom time import sleep\nfrom colorama import init, Fore\n\ndef update():\n    init(autoreset=True)\n   "
  }
]

About this extraction

This page contains the full source code of the new92/InstaTools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 48 files (1.5 MB), approximately 582.1k tokens, and a symbol index with 94 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!