user-scanner 1.1.0.2__tar.gz → 1.1.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/PKG-INFO +33 -5
  2. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/README.md +32 -4
  3. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/pyproject.toml +1 -1
  4. user_scanner-1.1.0.3/user_scanner/.ruff_cache/0.14.10/12603567674167520802 +0 -0
  5. user_scanner-1.1.0.3/user_scanner/.ruff_cache/0.14.10/12688104075811904861 +0 -0
  6. user_scanner-1.1.0.3/user_scanner/.ruff_cache/0.14.10/15694509833576274574 +0 -0
  7. user_scanner-1.1.0.3/user_scanner/.ruff_cache/0.14.10/301008395129872757 +0 -0
  8. user_scanner-1.1.0.3/user_scanner/.ruff_cache/0.14.10/4908403194175060721 +0 -0
  9. user_scanner-1.1.0.3/user_scanner/.ruff_cache/0.14.10/572980360641624523 +0 -0
  10. user_scanner-1.1.0.3/user_scanner/.ruff_cache/0.14.10/5935143038219898089 +0 -0
  11. user_scanner-1.1.0.3/user_scanner/config.json +3 -0
  12. user_scanner-1.1.0.3/user_scanner/email_scan/community/.ruff_cache/.gitignore +2 -0
  13. user_scanner-1.1.0.3/user_scanner/email_scan/community/.ruff_cache/0.14.10/3933329632096143294 +0 -0
  14. user_scanner-1.1.0.3/user_scanner/email_scan/community/.ruff_cache/CACHEDIR.TAG +1 -0
  15. user_scanner-1.1.0.3/user_scanner/email_scan/community/quora.py +112 -0
  16. user_scanner-1.1.0.3/user_scanner/email_scan/dev/.ruff_cache/.gitignore +2 -0
  17. user_scanner-1.1.0.3/user_scanner/email_scan/dev/.ruff_cache/0.14.10/10328336453267387919 +0 -0
  18. user_scanner-1.1.0.3/user_scanner/email_scan/dev/.ruff_cache/CACHEDIR.TAG +1 -0
  19. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/dev/bitbucket.py +2 -0
  20. user_scanner-1.1.0.3/user_scanner/email_scan/dev/codecademy.py +49 -0
  21. user_scanner-1.1.0.3/user_scanner/email_scan/dev/codepen.py +54 -0
  22. user_scanner-1.1.0.3/user_scanner/email_scan/dev/devrant.py +49 -0
  23. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/dev/github.py +2 -0
  24. user_scanner-1.1.0.3/user_scanner/email_scan/dev/wordpress.py +52 -0
  25. user_scanner-1.1.0.3/user_scanner/email_scan/hosting/.ruff_cache/.gitignore +2 -0
  26. user_scanner-1.1.0.3/user_scanner/email_scan/hosting/.ruff_cache/0.14.10/6358275293999347997 +0 -0
  27. user_scanner-1.1.0.3/user_scanner/email_scan/hosting/.ruff_cache/CACHEDIR.TAG +1 -0
  28. user_scanner-1.1.0.3/user_scanner/email_scan/hosting/render.py +60 -0
  29. user_scanner-1.1.0.3/user_scanner/email_scan/music/.ruff_cache/.gitignore +2 -0
  30. user_scanner-1.1.0.3/user_scanner/email_scan/music/.ruff_cache/0.14.10/7544735312652879689 +0 -0
  31. user_scanner-1.1.0.3/user_scanner/email_scan/music/.ruff_cache/CACHEDIR.TAG +1 -0
  32. user_scanner-1.1.0.3/user_scanner/email_scan/music/lastfm.py +60 -0
  33. user_scanner-1.1.0.3/user_scanner/email_scan/shopping/envato.py +41 -0
  34. user_scanner-1.1.0.3/user_scanner/email_scan/shopping/naturabuy.py +46 -0
  35. user_scanner-1.1.0.3/user_scanner/email_scan/shopping/vivino.py +49 -0
  36. user_scanner-1.1.0.3/user_scanner/user_scan/gaming/battlenet.py +65 -0
  37. user_scanner-1.1.0.3/user_scanner/utils/__init__.py +0 -0
  38. user_scanner-1.1.0.2/user_scanner/config.json +0 -1
  39. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/LICENSE +0 -0
  40. {user_scanner-1.1.0.2/user_scanner/email_scan/entertainment → user_scanner-1.1.0.3/user_scanner}/.ruff_cache/.gitignore +0 -0
  41. {user_scanner-1.1.0.2/user_scanner/email_scan/entertainment → user_scanner-1.1.0.3/user_scanner}/.ruff_cache/CACHEDIR.TAG +0 -0
  42. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/__init__.py +0 -0
  43. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/__main__.py +0 -0
  44. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/cli/__init__.py +0 -0
  45. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/cli/banner.py +0 -0
  46. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/core/__init__.py +0 -0
  47. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/core/email_orchestrator.py +0 -0
  48. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/core/formatter.py +0 -0
  49. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/core/helpers.py +0 -0
  50. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/core/orchestrator.py +0 -0
  51. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/core/result.py +0 -0
  52. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/core/version.py +0 -0
  53. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/__init__.py +0 -0
  54. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/adult/__init__.py +0 -0
  55. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/adult/pornhub.py +0 -0
  56. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/adult/sexvid.py +0 -0
  57. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/adult/xnxx.py +0 -0
  58. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/adult/xvideos.py +0 -0
  59. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/community/__init__.py +0 -0
  60. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/community/stackoverflow.py +0 -0
  61. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/creator/__init__.py +0 -0
  62. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/creator/gumroad.py +0 -0
  63. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/creator/patreon.py +0 -0
  64. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/dev/__init__.py +0 -0
  65. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/dev/huggingface.py +0 -0
  66. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/dev/replit.py +0 -0
  67. {user_scanner-1.1.0.2/user_scanner/email_scan/entertainment → user_scanner-1.1.0.3/user_scanner/email_scan/gaming}/__init__.py +0 -0
  68. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/gaming/chess_com.py +0 -0
  69. {user_scanner-1.1.0.2/user_scanner/email_scan/gaming → user_scanner-1.1.0.3/user_scanner/email_scan/hosting}/__init__.py +0 -0
  70. {user_scanner-1.1.0.2/user_scanner/email_scan/entertainment → user_scanner-1.1.0.3/user_scanner/email_scan/music}/.ruff_cache/0.14.10/14677874048998292530 +0 -0
  71. {user_scanner-1.1.0.2/user_scanner/email_scan/shopping → user_scanner-1.1.0.3/user_scanner/email_scan/music}/__init__.py +0 -0
  72. {user_scanner-1.1.0.2/user_scanner/email_scan/entertainment → user_scanner-1.1.0.3/user_scanner/email_scan/music}/spotify.py +0 -0
  73. {user_scanner-1.1.0.2/user_scanner/email_scan/social → user_scanner-1.1.0.3/user_scanner/email_scan/shopping}/__init__.py +0 -0
  74. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/shopping/flipkart.py +0 -0
  75. {user_scanner-1.1.0.2/user_scanner/user_scan/creator → user_scanner-1.1.0.3/user_scanner/email_scan/social}/__init__.py +0 -0
  76. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/social/facebook.py +0 -0
  77. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/social/instagram.py +0 -0
  78. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/social/mastodon.py +0 -0
  79. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/email_scan/social/x.py +0 -0
  80. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/community/__init__.py +0 -0
  81. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/community/coderlegion.py +0 -0
  82. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/community/hackernews.py +0 -0
  83. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/community/lemmy.py +0 -0
  84. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/community/stackoverflow.py +0 -0
  85. {user_scanner-1.1.0.2/user_scanner/user_scan/donation → user_scanner-1.1.0.3/user_scanner/user_scan/creator}/__init__.py +0 -0
  86. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/devto.py +0 -0
  87. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/gumroad.py +0 -0
  88. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/hashnode.py +0 -0
  89. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/itch_io.py +0 -0
  90. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/kaggle.py +0 -0
  91. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/medium.py +0 -0
  92. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/patreon.py +0 -0
  93. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/producthunt.py +0 -0
  94. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/substack.py +0 -0
  95. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/creator/twitch.py +0 -0
  96. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/__init__.py +0 -0
  97. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/bitbucket.py +0 -0
  98. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/codeberg.py +0 -0
  99. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/cratesio.py +0 -0
  100. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/dockerhub.py +0 -0
  101. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/github.py +0 -0
  102. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/gitlab.py +0 -0
  103. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/huggingface.py +0 -0
  104. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/launchpad.py +0 -0
  105. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/leetcode.py +0 -0
  106. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/npmjs.py +0 -0
  107. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/replit.py +0 -0
  108. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/dev/sourceforge.py +0 -0
  109. {user_scanner-1.1.0.2/user_scanner/user_scan/gaming → user_scanner-1.1.0.3/user_scanner/user_scan/donation}/__init__.py +0 -0
  110. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/donation/buymeacoffee.py +0 -0
  111. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/donation/liberapay.py +0 -0
  112. {user_scanner-1.1.0.2/user_scanner/user_scan/shopping → user_scanner-1.1.0.3/user_scanner/user_scan/gaming}/__init__.py +0 -0
  113. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/gaming/chess_com.py +0 -0
  114. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/gaming/lichess.py +0 -0
  115. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/gaming/minecraft.py +0 -0
  116. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/gaming/monkeytype.py +0 -0
  117. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/gaming/osu.py +0 -0
  118. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/gaming/roblox.py +0 -0
  119. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/gaming/steam.py +0 -0
  120. {user_scanner-1.1.0.2/user_scanner/utils → user_scanner-1.1.0.3/user_scanner/user_scan/shopping}/__init__.py +0 -0
  121. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/shopping/vinted.py +0 -0
  122. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/__init__.py +0 -0
  123. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/bluesky.py +0 -0
  124. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/discord.py +0 -0
  125. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/instagram.py +0 -0
  126. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/mastodon.py +0 -0
  127. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/pinterest.py +0 -0
  128. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/reddit.py +0 -0
  129. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/snapchat.py +0 -0
  130. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/soundcloud.py +0 -0
  131. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/telegram.py +0 -0
  132. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/threads.py +0 -0
  133. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/tiktok.py +0 -0
  134. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/x.py +0 -0
  135. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/user_scan/social/youtube.py +0 -0
  136. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/utils/update.py +0 -0
  137. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/utils/updater_logic.py +0 -0
  138. {user_scanner-1.1.0.2 → user_scanner-1.1.0.3}/user_scanner/version.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: user-scanner
3
- Version: 1.1.0.2
3
+ Version: 1.1.0.3
4
4
  Summary: Check username availability across multiple popular platforms
5
5
  Keywords: username,checker,availability,social,tech,python,user-scanner
6
6
  Author-email: Kaif <kafcodec@gmail.com>
@@ -16,7 +16,7 @@ Project-URL: Homepage, https://github.com/kaifcodec/user-scanner
16
16
 
17
17
  ![User Scanner Logo](https://github.com/user-attachments/assets/49ec8d24-665b-4115-8525-01a8d0ca2ef4)
18
18
  <p align="center">
19
- <img src="https://img.shields.io/badge/Version-1.1.0.2-blueviolet?style=for-the-badge&logo=github" />
19
+ <img src="https://img.shields.io/badge/Version-1.1.0.3-blueviolet?style=for-the-badge&logo=github" />
20
20
  <img src="https://img.shields.io/github/issues/kaifcodec/user-scanner?style=for-the-badge&logo=github" />
21
21
  <img src="https://img.shields.io/badge/Tested%20on-Termux-black?style=for-the-badge&logo=termux" />
22
22
  <img src="https://img.shields.io/badge/Tested%20on-Windows-cyan?style=for-the-badge&logo=Windows" />
@@ -52,12 +52,28 @@ Perfect for finding a **unique username** across GitHub, Twitter, Reddit, Instag
52
52
  - ✅ **Bulk email scanning** from file support for checking multiple emails at once
53
53
  ---
54
54
 
55
- ## Installation
55
+ ## Virtual Environment (optional but recommended)
56
56
 
57
57
  ```bash
58
- pip install user-scanner
58
+ # create venv
59
+ python -m venv .venv
60
+ ````
61
+ ## Activate venv
62
+ ```bash
63
+ # Linux / macOS
64
+ source .venv/bin/activate
65
+
66
+ # Windows (PowerShell)
67
+ .venv\Scripts\Activate.ps1
59
68
  ```
69
+ ## Installation
70
+ ```bash
71
+ # upgrade pip
72
+ python -m pip install --upgrade pip
60
73
 
74
+ # install
75
+ pip install user-scanner
76
+ ```
61
77
  ---
62
78
 
63
79
  ## Important Flags
@@ -167,9 +183,11 @@ user-scanner -U
167
183
 
168
184
  - Note*: New modules are constantly getting added so this might have only limited, outdated output:
169
185
 
170
- <img width="1072" height="848" alt="user-scanner's main usage screenshot" src="https://github.com/user-attachments/assets/34e44ca6-e314-419e-9035-d951b493b47f" />
186
+ <img width="1080" height="656" alt="1000146096" src="https://github.com/user-attachments/assets/1101e2f8-18ea-45a4-9492-92e237ecc670" />
171
187
 
188
+ ---
172
189
 
190
+ <img width="1072" height="848" alt="user-scanner's main usage screenshot" src="https://github.com/user-attachments/assets/34e44ca6-e314-419e-9035-d951b493b47f" />
173
191
 
174
192
  ---
175
193
 
@@ -222,6 +240,16 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for examples.
222
240
 
223
241
  This project is licensed under the **MIT License**. See [LICENSE](LICENSE) for details.
224
242
 
243
+ ---
244
+
245
+ ## ⚠️ Disclaimer
246
+
247
+ This tool is provided for **educational purposes** and **authorized security research** only.
248
+
249
+ - **User Responsibility:** Users are solely responsible for ensuring their usage complies with all applicable laws and the Terms of Service (ToS) of any third-party providers.
250
+ - **Methodology:** The tool interacts only with **publicly accessible, unauthenticated web endpoints**. It does not bypass authentication, security controls, or access private user data.
251
+ - **No Profiling:** This software performs only basic **yes/no availability checks**. It does not collect, store, aggregate, or analyze user data, behavior, or identities.
252
+ - **Limitation of Liability:** The software is provided **“as is”**, without warranty of any kind. The developers assume no liability for misuse or any resulting damage or legal consequences.
225
253
 
226
254
  ---
227
255
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![User Scanner Logo](https://github.com/user-attachments/assets/49ec8d24-665b-4115-8525-01a8d0ca2ef4)
4
4
  <p align="center">
5
- <img src="https://img.shields.io/badge/Version-1.1.0.2-blueviolet?style=for-the-badge&logo=github" />
5
+ <img src="https://img.shields.io/badge/Version-1.1.0.3-blueviolet?style=for-the-badge&logo=github" />
6
6
  <img src="https://img.shields.io/github/issues/kaifcodec/user-scanner?style=for-the-badge&logo=github" />
7
7
  <img src="https://img.shields.io/badge/Tested%20on-Termux-black?style=for-the-badge&logo=termux" />
8
8
  <img src="https://img.shields.io/badge/Tested%20on-Windows-cyan?style=for-the-badge&logo=Windows" />
@@ -38,12 +38,28 @@ Perfect for finding a **unique username** across GitHub, Twitter, Reddit, Instag
38
38
  - ✅ **Bulk email scanning** from file support for checking multiple emails at once
39
39
  ---
40
40
 
41
- ## Installation
41
+ ## Virtual Environment (optional but recommended)
42
42
 
43
43
  ```bash
44
- pip install user-scanner
44
+ # create venv
45
+ python -m venv .venv
46
+ ````
47
+ ## Activate venv
48
+ ```bash
49
+ # Linux / macOS
50
+ source .venv/bin/activate
51
+
52
+ # Windows (PowerShell)
53
+ .venv\Scripts\Activate.ps1
45
54
  ```
55
+ ## Installation
56
+ ```bash
57
+ # upgrade pip
58
+ python -m pip install --upgrade pip
46
59
 
60
+ # install
61
+ pip install user-scanner
62
+ ```
47
63
  ---
48
64
 
49
65
  ## Important Flags
@@ -153,9 +169,11 @@ user-scanner -U
153
169
 
154
170
  - Note*: New modules are constantly getting added so this might have only limited, outdated output:
155
171
 
156
- <img width="1072" height="848" alt="user-scanner's main usage screenshot" src="https://github.com/user-attachments/assets/34e44ca6-e314-419e-9035-d951b493b47f" />
172
+ <img width="1080" height="656" alt="1000146096" src="https://github.com/user-attachments/assets/1101e2f8-18ea-45a4-9492-92e237ecc670" />
157
173
 
174
+ ---
158
175
 
176
+ <img width="1072" height="848" alt="user-scanner's main usage screenshot" src="https://github.com/user-attachments/assets/34e44ca6-e314-419e-9035-d951b493b47f" />
159
177
 
160
178
  ---
161
179
 
@@ -208,6 +226,16 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for examples.
208
226
 
209
227
  This project is licensed under the **MIT License**. See [LICENSE](LICENSE) for details.
210
228
 
229
+ ---
230
+
231
+ ## ⚠️ Disclaimer
232
+
233
+ This tool is provided for **educational purposes** and **authorized security research** only.
234
+
235
+ - **User Responsibility:** Users are solely responsible for ensuring their usage complies with all applicable laws and the Terms of Service (ToS) of any third-party providers.
236
+ - **Methodology:** The tool interacts only with **publicly accessible, unauthenticated web endpoints**. It does not bypass authentication, security controls, or access private user data.
237
+ - **No Profiling:** This software performs only basic **yes/no availability checks**. It does not collect, store, aggregate, or analyze user data, behavior, or identities.
238
+ - **Limitation of Liability:** The software is provided **“as is”**, without warranty of any kind. The developers assume no liability for misuse or any resulting damage or legal consequences.
211
239
 
212
240
  ---
213
241
 
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "user-scanner"
7
- version = "1.1.0.2"
7
+ version = "1.1.0.3"
8
8
  description = "Check username availability across multiple popular platforms"
9
9
  readme = "README.md"
10
10
  license = {file = "LICENSE"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "auto_update_status": true
3
+ }
@@ -0,0 +1,2 @@
1
+ # Automatically created by ruff.
2
+ *
@@ -0,0 +1 @@
1
+ Signature: 8a477f597d28d172789f06886806bc55
@@ -0,0 +1,112 @@
1
+ import asyncio
2
+ import json
3
+ import re
4
+ import os
5
+ import shutil
6
+ from user_scanner.core.result import Result
7
+
8
+
9
+ async def _check(email: str) -> Result:
10
+ if not shutil.which("curl"):
11
+ return Result.error("curl is not installed, install it to use Quora validation")
12
+
13
+ cookie_path = f"quora_cookie_{os.getpid()}.txt"
14
+ base_url = "https://www.quora.com/"
15
+ gql_url = "https://www.quora.com/graphql/gql_para_POST"
16
+
17
+ headers = {
18
+ 'host': 'www.quora.com',
19
+ 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
20
+ 'sec-ch-ua-mobile': '?1',
21
+ 'sec-ch-ua-platform': '"Android"',
22
+ 'upgrade-insecure-requests': '1',
23
+ 'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36',
24
+ 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
25
+ 'referer': 'https://www.google.com/',
26
+ 'accept-language': 'en-US,en;q=0.9',
27
+ }
28
+
29
+ async def run_curl(url, current_headers, post_data=None, url_params=None):
30
+ cmd = ["curl", "-s", "-k", "-L", "--http2", "--max-time",
31
+ "5", "-c", cookie_path, "-b", cookie_path]
32
+ for k, v in current_headers.items():
33
+ cmd.extend(["-H", f"{k}: {v}"])
34
+ if url_params:
35
+ import urllib.parse
36
+ url += "?" + urllib.parse.urlencode(url_params)
37
+ if post_data:
38
+ cmd.extend(["-X", "POST", "--data-raw", json.dumps(post_data)])
39
+ cmd.append(url)
40
+
41
+ process = await asyncio.create_subprocess_exec(
42
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
43
+ )
44
+ try:
45
+ stdout, _ = await asyncio.wait_for(process.communicate(), timeout=5)
46
+ return stdout.decode('utf-8', errors='ignore')
47
+ except asyncio.TimeoutError:
48
+ try:
49
+ process.kill()
50
+ except Exception:
51
+ pass
52
+ return ""
53
+
54
+ try:
55
+ html = await run_curl(base_url, headers)
56
+ if not html:
57
+ if os.path.exists(cookie_path):
58
+ os.remove(cookie_path)
59
+ return Result.error("Connection timed out")
60
+
61
+ formkey_match = re.search(r'\"formkey\":\s*\"([a-f0-9]{32})\"', html)
62
+ if not formkey_match:
63
+ if os.path.exists(cookie_path):
64
+ os.remove(cookie_path)
65
+ return Result.error("Quora blocked the request (Bot detection/403)")
66
+
67
+ formkey = formkey_match.group(1)
68
+
69
+ gql_headers = headers.copy()
70
+ gql_headers.update({
71
+ 'content-type': 'application/json',
72
+ 'quora-formkey': formkey,
73
+ 'quora-canary-revision': 'false',
74
+ 'origin': 'https://www.quora.com',
75
+ 'referer': 'https://www.quora.com/',
76
+ 'priority': 'u=1, i'
77
+ })
78
+
79
+ payload = {
80
+ "queryName": "SignupEmailForm_validateEmail_Query",
81
+ "variables": {"email": email},
82
+ "extensions": {
83
+ "hash": "1db80096407be846d5581fe1b42b12fd05e0b40a5d3095ed40a0b4bd28f49fe7"
84
+ }
85
+ }
86
+
87
+ response_text = await run_curl(gql_url, gql_headers, post_data=payload, url_params={'q': "SignupEmailForm_validateEmail_Query"})
88
+
89
+ if os.path.exists(cookie_path):
90
+ os.remove(cookie_path)
91
+
92
+ if not response_text.strip():
93
+ return Result.error("Quora timed out or returned empty body")
94
+
95
+ data = json.loads(response_text)
96
+ status = data.get("data", {}).get("validateEmail")
97
+
98
+ if status == "IN_USE":
99
+ return Result.taken()
100
+ elif status == "OK":
101
+ return Result.available()
102
+ else:
103
+ return Result.error(f"Unexpected status: {status}")
104
+
105
+ except Exception as e:
106
+ if os.path.exists(cookie_path):
107
+ os.remove(cookie_path)
108
+ return Result.error(e)
109
+
110
+
111
+ async def validate_quora(email: str) -> Result:
112
+ return await _check(email)
@@ -0,0 +1,2 @@
1
+ # Automatically created by ruff.
2
+ *
@@ -0,0 +1 @@
1
+ Signature: 8a477f597d28d172789f06886806bc55
@@ -1,6 +1,7 @@
1
1
  import httpx
2
2
  from user_scanner.core.result import Result
3
3
 
4
+
4
5
  async def _check(email: str) -> Result:
5
6
  async with httpx.AsyncClient(http2=True) as client:
6
7
  try:
@@ -29,5 +30,6 @@ async def _check(email: str) -> Result:
29
30
  except Exception as e:
30
31
  return Result.error(f"Unexpected exception:{e}")
31
32
 
33
+
32
34
  async def validate_bitbucket(email: str) -> Result:
33
35
  return await _check(email)
@@ -0,0 +1,49 @@
1
+ import httpx
2
+ import re
3
+ from user_scanner.core.result import Result
4
+
5
+
6
+ async def _check(email: str) -> Result:
7
+ headers = {
8
+ 'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
9
+ 'Accept': 'application/json',
10
+ 'Accept-Language': 'en-US,en;q=0.9',
11
+ 'Referer': 'https://www.codecademy.com/register?redirect=%2F',
12
+ 'Content-Type': 'application/json',
13
+ 'Origin': 'https://www.codecademy.com',
14
+ }
15
+
16
+ try:
17
+ async with httpx.AsyncClient(timeout=4.0, follow_redirects=True) as client:
18
+ init_res = await client.get("https://www.codecademy.com/register", headers=headers)
19
+
20
+ csrf_match = re.search(
21
+ r'name="csrf-token" content="([^"]+)"', init_res.text)
22
+ if not csrf_match:
23
+ return Result.error("Could not find CSRF token")
24
+
25
+ headers["X-CSRF-Token"] = csrf_match.group(1)
26
+
27
+ payload = {"user": {"email": email}}
28
+
29
+ response = await client.post(
30
+ 'https://www.codecademy.com/register/validate',
31
+ headers=headers,
32
+ json=payload
33
+ )
34
+
35
+ if response.status_code == 400 and 'has already been taken' in response.text:
36
+ return Result.taken()
37
+ elif response.status_code == 200:
38
+ return Result.available()
39
+
40
+ return Result.error(f"Unexpected response: {response.status_code}")
41
+
42
+ except httpx.TimeoutException:
43
+ return Result.error("Connection timed out")
44
+ except Exception as e:
45
+ return Result.error(str(e))
46
+
47
+
48
+ async def validate_codecademy(email: str) -> Result:
49
+ return await _check(email)
@@ -0,0 +1,54 @@
1
+ import httpx
2
+ import re
3
+ from user_scanner.core.result import Result
4
+
5
+
6
+ async def _check(email: str) -> Result:
7
+ headers = {
8
+ 'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
9
+ 'Accept': '*/*',
10
+ 'Accept-Language': 'en-US,en;q=0.9',
11
+ 'Referer': 'https://codepen.io/accounts/signup/user/free',
12
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
13
+ 'X-Requested-With': 'XMLHttpRequest',
14
+ 'Origin': 'https://codepen.io',
15
+ }
16
+
17
+ try:
18
+ async with httpx.AsyncClient(timeout=10.0, follow_redirects=True) as client:
19
+ init_res = await client.get("https://codepen.io/accounts/signup/user/free", headers=headers)
20
+
21
+ csrf_match = re.search(
22
+ r'name="csrf-token" content="([^"]+)"', init_res.text)
23
+ if not csrf_match:
24
+ return Result.error("Could not find CSRF token")
25
+
26
+ headers["X-CSRF-Token"] = csrf_match.group(1)
27
+
28
+ payload = {
29
+ 'attribute': 'email',
30
+ 'value': email,
31
+ 'context': 'user'
32
+ }
33
+
34
+ response = await client.post(
35
+ 'https://codepen.io/accounts/duplicate_check',
36
+ headers=headers,
37
+ data=payload
38
+ )
39
+
40
+ if "That Email is already taken." in response.text:
41
+ return Result.taken()
42
+ elif response.status_code == 200:
43
+ return Result.available()
44
+
45
+ return Result.error(f"Unexpected response: {response.status_code}")
46
+
47
+ except httpx.TimeoutException:
48
+ return Result.error("Connection timed out")
49
+ except Exception as e:
50
+ return Result.error(str(e))
51
+
52
+
53
+ async def validate_codepen(email: str) -> Result:
54
+ return await _check(email)
@@ -0,0 +1,49 @@
1
+ import httpx
2
+ from user_scanner.core.result import Result
3
+
4
+
5
+ async def _check(email: str) -> Result:
6
+ headers = {
7
+ 'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
8
+ 'Accept': 'application/json, text/javascript, */*; q=0.01',
9
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
10
+ 'X-Requested-With': 'XMLHttpRequest',
11
+ 'Origin': 'https://devrant.com',
12
+ 'Referer': 'https://devrant.com/feed/top/month?login=1',
13
+ }
14
+
15
+ payload = {
16
+ 'app': '3',
17
+ 'type': '1',
18
+ 'email': email,
19
+ 'username': '',
20
+ 'password': '',
21
+ 'guid': '',
22
+ 'plat': '3',
23
+ 'sid': '',
24
+ 'seid': ''
25
+ }
26
+
27
+ try:
28
+ async with httpx.AsyncClient(timeout=10.0) as client:
29
+ response = await client.post('https://devrant.com/api/users', headers=headers, data=payload)
30
+
31
+ if response.status_code != 200:
32
+ return Result.error(f"Unexpected status code: {response.status_code}")
33
+
34
+ data = response.json()
35
+ error_msg = data.get('error', '')
36
+
37
+ if error_msg == 'The email specified is already registered to an account.':
38
+ return Result.taken()
39
+
40
+ return Result.available()
41
+
42
+ except httpx.TimeoutException:
43
+ return Result.error("Connection timed out")
44
+ except Exception as e:
45
+ return Result.error(str(e))
46
+
47
+
48
+ async def validate_devrant(email: str) -> Result:
49
+ return await _check(email)
@@ -2,6 +2,7 @@ import httpx
2
2
  import re
3
3
  from user_scanner.core.result import Result
4
4
 
5
+
5
6
  async def _check(email: str) -> Result:
6
7
  async with httpx.AsyncClient(http2=True, follow_redirects=True) as client:
7
8
  try:
@@ -68,5 +69,6 @@ async def _check(email: str) -> Result:
68
69
  except Exception as e:
69
70
  return Result.error(f"unexpected exception: {e}")
70
71
 
72
+
71
73
  async def validate_github(email: str) -> Result:
72
74
  return await _check(email)
@@ -0,0 +1,52 @@
1
+ import httpx
2
+ from user_scanner.core.result import Result
3
+
4
+
5
+ async def _check(email: str) -> Result:
6
+ url = f"https://public-api.wordpress.com/rest/v1.1/users/{email}/auth-options"
7
+
8
+ params = {
9
+ 'http_envelope': "1"
10
+ }
11
+
12
+ headers = {
13
+ 'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
14
+ 'Accept': "application/json",
15
+ 'sec-ch-ua-platform': '"Linux"',
16
+ 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
17
+ 'sec-ch-ua-mobile': "?0",
18
+ 'sec-fetch-site': "same-origin",
19
+ 'sec-fetch-mode': "cors",
20
+ 'sec-fetch-dest': "empty",
21
+ 'referer': "https://public-api.wordpress.com/wp-admin/rest-proxy/?v=2.0",
22
+ 'accept-language': "en-US,en;q=0.9",
23
+ }
24
+
25
+ try:
26
+ async with httpx.AsyncClient(timeout=5.0) as client:
27
+ response = await client.get(url, params=params, headers=headers)
28
+
29
+ if response.status_code != 200:
30
+ return Result.error(f"WordPress API returned status {response.status_code}")
31
+
32
+ data = response.json()
33
+
34
+ inner_code = data.get("code")
35
+ body = data.get("body", {})
36
+
37
+ if inner_code == 200:
38
+ return Result.taken()
39
+ elif inner_code == 404 and body.get("error") == "unknown_user":
40
+ return Result.available()
41
+ else:
42
+ error_msg = body.get("message", "Unknown API response")
43
+ return Result.error(f"WordPress Error: {error_msg}")
44
+
45
+ except httpx.TimeoutException:
46
+ return Result.error("Connection timed out")
47
+ except Exception as e:
48
+ return Result.error(str(e))
49
+
50
+
51
+ async def validate_wordpress(email: str) -> Result:
52
+ return await _check(email)
@@ -0,0 +1,2 @@
1
+ # Automatically created by ruff.
2
+ *
@@ -0,0 +1 @@
1
+ Signature: 8a477f597d28d172789f06886806bc55
@@ -0,0 +1,60 @@
1
+ import httpx
2
+ from user_scanner.core.result import Result
3
+
4
+ async def _check(email: str) -> Result:
5
+ url = "https://api.render.com/graphql"
6
+
7
+ payload = {
8
+ "operationName": "signUp",
9
+ "variables": {
10
+ "signup": {
11
+ "email": email,
12
+ "githubId": "",
13
+ "name": "",
14
+ "githubToken": "",
15
+ "googleId": "",
16
+ "gitlabId": "",
17
+ "bitbucketId": "",
18
+ "inviteCode": "",
19
+ "password": "StandardPassword123!",
20
+ "newsletterOptIn": False,
21
+ "next": ""
22
+ }
23
+ },
24
+ "query": "mutation signUp($signup: SignupInput!) {\n signUp(signup: $signup) {\n idToken\n __typename\n }\n}\n"
25
+ }
26
+
27
+ headers = {
28
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
29
+ "Content-Type": "application/json",
30
+ "origin": "https://dashboard.render.com",
31
+ "referer": "https://dashboard.render.com/register",
32
+ "accept-language": "en-US,en;q=0.9"
33
+ }
34
+
35
+ async with httpx.AsyncClient(http2=True, timeout=4.0) as client:
36
+ try:
37
+ response = await client.post(url, json=payload, headers=headers)
38
+
39
+ if response.status_code == 429:
40
+ return Result.error("Rate limited, use '-d' flag to avoid bot detection")
41
+
42
+ data = response.json()
43
+ errors = data.get("errors", [])
44
+
45
+ if errors:
46
+ msg = errors[0].get("message", "")
47
+ if '"email":"exists"' in msg:
48
+ return Result.taken()
49
+ elif '"hcaptcha_token":"invalid"' in msg:
50
+ return Result.available()
51
+ else:
52
+ return Result.error(f"Render Error: {msg}")
53
+
54
+ return Result.error("Unexpected error, report it via GitHub issues")
55
+
56
+ except Exception as e:
57
+ return Result.error(e)
58
+
59
+ async def validate_render(email: str) -> Result:
60
+ return await _check(email)
@@ -0,0 +1,2 @@
1
+ # Automatically created by ruff.
2
+ *
@@ -0,0 +1 @@
1
+ Signature: 8a477f597d28d172789f06886806bc55