yasint 0.3.0__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.
@@ -0,0 +1,56 @@
1
+ # Changelog
2
+
3
+ ## 0.3.0
4
+
5
+ - Fetch profile pictures safely and consistently
6
+ - Better cookie handling
7
+ - Add PyPI build metadata
8
+ - Rename project
9
+ - Update README
10
+ - Sunset pictures/
11
+
12
+ ## 0.2.1
13
+
14
+ - High-level tests
15
+ - Fix Unicode issue in file put()
16
+ - Make relevant cookie loading status explicit with colourised output.
17
+ - Update README
18
+ - Update .gitignore
19
+
20
+ ## 0.2.0
21
+
22
+ - Implement a case system utilizing timestamps for reports
23
+ - Fix stale `run.py` wrapper to delegate to the package CLI entrypoint.
24
+ - Make zero-lead results explicit in console, TXT, and CSV reports
25
+ - Save auxiliary TXT and CSV evidence reports inside each session folder
26
+ - Show the full per-session reports path in output
27
+ - Fix HTML metadata handling per encodings.
28
+ - Implement test-driven CI/CD.
29
+
30
+ ## 0.1.0
31
+
32
+ - Fix Cookie handling
33
+ - Turn into a pip-installable package.
34
+
35
+ ## 0.0.8
36
+
37
+ - Add per-input UTC-timestamped response sessions
38
+ - Save all attempted HTTP responses to session folders
39
+ - Embed response headers in saved HTML output where possible
40
+ - Save non-HTML responses as raw header-plus-body files
41
+ - Track progress by attempted URL hits per session
42
+
43
+ ## 0.0.4
44
+
45
+ - Fixes to asyncio usage for Python 3.14 (Python 3.8 or higher), while maintaining backwards compatibility.
46
+ - Fix relative import in `__main__.py`
47
+ - Add URLs and request-method information to the final summary
48
+ - Add missing requirements to `requirements.txt`
49
+ - Fix flimsy packaging entrypoint
50
+ - Misc: Create changelog
51
+ - Misc: Update User-Agent
52
+ - Bump version
53
+
54
+ ## 0.0.3
55
+
56
+ - ...
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Soxoj
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,12 @@
1
+ include CHANGELOG.md
2
+ include MANIFEST.in
3
+ include NOTICE
4
+ include PUBLISHING.md
5
+ include README.md
6
+ include requirements.txt
7
+ include requirements-dev.txt
8
+ include run.py
9
+ recursive-include LICENCES *.txt
10
+ recursive-include tests *.py
11
+ global-exclude __pycache__
12
+ global-exclude *.py[cod]
yasint-0.3.0/NOTICE ADDED
@@ -0,0 +1,5 @@
1
+ This project is derived in part from YaSeeker.
2
+ Portions copyright (c) 2021 Soxoj.
3
+ Those portions were originally licensed under the MIT License.
4
+ The MIT License text is reproduced below / in LICENCES/MIT-Soxoj.txt.
5
+
yasint-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: yasint
3
+ Version: 0.3.0
4
+ Summary: Yandex profile OSINT tool
5
+ Home-page: https://github.com/TAbdiukov/YaSINT
6
+ Author: Tim Abdiukov
7
+ Project-URL: Source, https://github.com/TAbdiukov/YaSINT
8
+ Project-URL: Issues, https://github.com/TAbdiukov/YaSINT/issues
9
+ Project-URL: Changelog, https://github.com/TAbdiukov/YaSINT/blob/main/CHANGELOG.md
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Information Technology
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Security
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: NOTICE
26
+ License-File: LICENCES/MIT-Soxoj.txt
27
+ Requires-Dist: socid-extractor>=0.0.8
28
+ Requires-Dist: aiohttp>=3.8.0
29
+ Requires-Dist: requests>=2.0.0
30
+ Requires-Dist: charset-normalizer>=2.0.0
31
+ Requires-Dist: termcolor
32
+ Requires-Dist: colorama
33
+ Requires-Dist: tqdm
34
+ Requires-Dist: aiohttp-socks>=0.11.0
35
+ Dynamic: author
36
+ Dynamic: classifier
37
+ Dynamic: description
38
+ Dynamic: description-content-type
39
+ Dynamic: home-page
40
+ Dynamic: license-file
41
+ Dynamic: project-url
42
+ Dynamic: requires-dist
43
+ Dynamic: requires-python
44
+ Dynamic: summary
45
+
46
+ # YaSINT
47
+
48
+ [![GitHub](https://img.shields.io/badge/GitHub-TAbdiukov/YaSINT-black?logo=github)](https://github.com/TAbdiukov/YaSINT)
49
+ [![PyPI Version](https://img.shields.io/pypi/v/YaSINT.svg)](https://pypi.org/project/YaSINT)
50
+ ![License](https://img.shields.io/github/license/TAbdiukov/YaSINT)
51
+
52
+ [![buymeacoffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/tabdiukov)
53
+
54
+ YaSINT is a command line OSINT ttolkit for looking up public Yandex account information by username, email address, or Yandex public ID.
55
+
56
+ It is a greatly updated package based on the original YaSeeker project. YaSINT is now intended to be installed as a Python package and run with a command, although it can still be run directly from a source checkout.
57
+
58
+ ## Artifacts
59
+
60
+ Depending on what public Yandex pages and APIs return, YaSINT may find:
61
+
62
+ * full name;
63
+ * profile photo or other possible avatar URLs;
64
+ * gender;
65
+ * Yandex UID;
66
+ * Yandex public ID;
67
+ * linked social accounts;
68
+ * public activity information;
69
+ * account flags, such as verified, banned, deleted, restricted, or business status.
70
+
71
+ Some services return useful information only when valid Yandex cookies are
72
+ provided. See [Cookies](#cookies).
73
+
74
+ ## Installation
75
+
76
+ Python 3.8 or newer is required.
77
+
78
+ Install from PyPI:
79
+
80
+ ```bash
81
+ python -m pip install yasint
82
+ ```
83
+
84
+ If you already downloaded the source code, install it from the project directory:
85
+
86
+ ```bash
87
+ python -m pip install .
88
+ ```
89
+
90
+ After installation, the `yasint` command should be available:
91
+
92
+ ```bash
93
+ yasint --version
94
+ ```
95
+
96
+ If you do not want to install the package, you can run it from the source
97
+ directory instead:
98
+
99
+ ```bash
100
+ python -m pip install -r requirements.txt
101
+ python -m yasint login
102
+ ```
103
+
104
+ ## Usage
105
+
106
+ Give YaSINT one or more targets:
107
+
108
+ ```bash
109
+ yasint TARGET
110
+ ```
111
+
112
+ Examples:
113
+
114
+ ```bash
115
+ yasint login
116
+ yasint login@yandex.ru
117
+ yasint c48fhxw0qppa50289r5c9ku4k4
118
+ ```
119
+
120
+ The tool recognises the target type automatically. Email addresses
121
+ are supported. A 26-character value is treated as a Yandex public ID.
122
+
123
+ For many targets, put one target per line in a text file:
124
+
125
+ ```bash
126
+ yasint --target-list targets.txt
127
+ ```
128
+
129
+ ## Results
130
+
131
+ For every target, YaSINT creates a per-session folder under `reports/`.
132
+ The folder name contains a UTC timestamp and the target value.
133
+
134
+ ```text
135
+ reports/20260101T120000Z_login/
136
+ ```
137
+
138
+ The session folder keeps the evidence collected during the run, including saved
139
+ responses where possible and auxiliary TXT/CSV reports. The console output gives
140
+ you the human-readable summary.
141
+
142
+ You can also write your own report files:
143
+
144
+ ```bash
145
+ yasint login -oT report.txt -oC report.csv
146
+ ```
147
+
148
+ A `No leads found` result means the checked sources did not return useful
149
+ profile data for that target. It does not prove that the account does not exist.
150
+
151
+ ## Cookies
152
+
153
+ Some Yandex services require cookies before they return useful API responses.
154
+ YaSINT can read browser cookies exported in Netscape `cookies.txt` format.
155
+
156
+ 1. Log in to Yandex in your browser.
157
+ 2. Export your Yandex cookies as `cookies.txt` ([Chrome](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc), [Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookies-txt/)).
158
+ 3. Put `cookies.txt` in the directory where you run YaSINT.
159
+ 4. Run YaSINT normally.
160
+
161
+ You can also pass a custom cookie file path:
162
+
163
+ ```bash
164
+ yasint login --cookie-jar-file /path/to/cookies.txt
165
+ ```
166
+
167
+ When cookies are loaded, YaSINT prints whether any of them match the
168
+ Yandex domains queried by the tool.
169
+
170
+ ## SOWEL classification
171
+
172
+ This tool uses the following OSINT techniques:
173
+
174
+ * [SOTL-1.4. Analyze Internal Identifiers](https://sowel.soxoj.com/internal-identifiers)
175
+ * [SOTL-2.2. Search For Accounts On Other Platforms](https://sowel.soxoj.com/other-platform-accounts)
176
+ * [SOTL-6.1. Check Logins Reuse To Find Another Account](https://sowel.soxoj.com/logins-reuse)
177
+ * [SOTL-6.2. Check Nicknames Reuse To Find Another Account](https://sowel.soxoj.com/nicknames-reuse)
yasint-0.3.0/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # YaSINT
2
+
3
+ [![GitHub](https://img.shields.io/badge/GitHub-TAbdiukov/YaSINT-black?logo=github)](https://github.com/TAbdiukov/YaSINT)
4
+ [![PyPI Version](https://img.shields.io/pypi/v/YaSINT.svg)](https://pypi.org/project/YaSINT)
5
+ ![License](https://img.shields.io/github/license/TAbdiukov/YaSINT)
6
+
7
+ [![buymeacoffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/tabdiukov)
8
+
9
+ YaSINT is a command line OSINT ttolkit for looking up public Yandex account information by username, email address, or Yandex public ID.
10
+
11
+ It is a greatly updated package based on the original YaSeeker project. YaSINT is now intended to be installed as a Python package and run with a command, although it can still be run directly from a source checkout.
12
+
13
+ ## Artifacts
14
+
15
+ Depending on what public Yandex pages and APIs return, YaSINT may find:
16
+
17
+ * full name;
18
+ * profile photo or other possible avatar URLs;
19
+ * gender;
20
+ * Yandex UID;
21
+ * Yandex public ID;
22
+ * linked social accounts;
23
+ * public activity information;
24
+ * account flags, such as verified, banned, deleted, restricted, or business status.
25
+
26
+ Some services return useful information only when valid Yandex cookies are
27
+ provided. See [Cookies](#cookies).
28
+
29
+ ## Installation
30
+
31
+ Python 3.8 or newer is required.
32
+
33
+ Install from PyPI:
34
+
35
+ ```bash
36
+ python -m pip install yasint
37
+ ```
38
+
39
+ If you already downloaded the source code, install it from the project directory:
40
+
41
+ ```bash
42
+ python -m pip install .
43
+ ```
44
+
45
+ After installation, the `yasint` command should be available:
46
+
47
+ ```bash
48
+ yasint --version
49
+ ```
50
+
51
+ If you do not want to install the package, you can run it from the source
52
+ directory instead:
53
+
54
+ ```bash
55
+ python -m pip install -r requirements.txt
56
+ python -m yasint login
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ Give YaSINT one or more targets:
62
+
63
+ ```bash
64
+ yasint TARGET
65
+ ```
66
+
67
+ Examples:
68
+
69
+ ```bash
70
+ yasint login
71
+ yasint login@yandex.ru
72
+ yasint c48fhxw0qppa50289r5c9ku4k4
73
+ ```
74
+
75
+ The tool recognises the target type automatically. Email addresses
76
+ are supported. A 26-character value is treated as a Yandex public ID.
77
+
78
+ For many targets, put one target per line in a text file:
79
+
80
+ ```bash
81
+ yasint --target-list targets.txt
82
+ ```
83
+
84
+ ## Results
85
+
86
+ For every target, YaSINT creates a per-session folder under `reports/`.
87
+ The folder name contains a UTC timestamp and the target value.
88
+
89
+ ```text
90
+ reports/20260101T120000Z_login/
91
+ ```
92
+
93
+ The session folder keeps the evidence collected during the run, including saved
94
+ responses where possible and auxiliary TXT/CSV reports. The console output gives
95
+ you the human-readable summary.
96
+
97
+ You can also write your own report files:
98
+
99
+ ```bash
100
+ yasint login -oT report.txt -oC report.csv
101
+ ```
102
+
103
+ A `No leads found` result means the checked sources did not return useful
104
+ profile data for that target. It does not prove that the account does not exist.
105
+
106
+ ## Cookies
107
+
108
+ Some Yandex services require cookies before they return useful API responses.
109
+ YaSINT can read browser cookies exported in Netscape `cookies.txt` format.
110
+
111
+ 1. Log in to Yandex in your browser.
112
+ 2. Export your Yandex cookies as `cookies.txt` ([Chrome](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc), [Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookies-txt/)).
113
+ 3. Put `cookies.txt` in the directory where you run YaSINT.
114
+ 4. Run YaSINT normally.
115
+
116
+ You can also pass a custom cookie file path:
117
+
118
+ ```bash
119
+ yasint login --cookie-jar-file /path/to/cookies.txt
120
+ ```
121
+
122
+ When cookies are loaded, YaSINT prints whether any of them match the
123
+ Yandex domains queried by the tool.
124
+
125
+ ## SOWEL classification
126
+
127
+ This tool uses the following OSINT techniques:
128
+
129
+ * [SOTL-1.4. Analyze Internal Identifiers](https://sowel.soxoj.com/internal-identifiers)
130
+ * [SOTL-2.2. Search For Accounts On Other Platforms](https://sowel.soxoj.com/other-platform-accounts)
131
+ * [SOTL-6.1. Check Logins Reuse To Find Another Account](https://sowel.soxoj.com/logins-reuse)
132
+ * [SOTL-6.2. Check Nicknames Reuse To Find Another Account](https://sowel.soxoj.com/nicknames-reuse)
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,9 @@
1
+ -r requirements.txt
2
+
3
+ black
4
+ build
5
+ coverage
6
+ flake8
7
+ mypy
8
+ pytest
9
+ twine
@@ -0,0 +1,8 @@
1
+ socid-extractor>=0.0.8
2
+ aiohttp>=3.8.0
3
+ requests>=2.0.0
4
+ charset-normalizer>=2.0.0
5
+ termcolor
6
+ colorama
7
+ tqdm
8
+ aiohttp-socks>=0.11.0
yasint-0.3.0/run.py ADDED
@@ -0,0 +1,5 @@
1
+ #! /usr/bin/env python3
2
+ from yasint.cli import run
3
+
4
+ if __name__ == "__main__":
5
+ run()
yasint-0.3.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
yasint-0.3.0/setup.py ADDED
@@ -0,0 +1,49 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ exec(open('yasint/_version.py', encoding='utf-8').read())
4
+
5
+ with open('requirements.txt', encoding='utf-8') as rf:
6
+ requires = [
7
+ line.strip()
8
+ for line in rf
9
+ if line.strip() and not line.lstrip().startswith('#')
10
+ ]
11
+
12
+ with open('README.md', encoding='utf-8') as fh:
13
+ long_description = fh.read()
14
+
15
+ setup(
16
+ name="yasint",
17
+ version=__version__,
18
+ description="Yandex profile OSINT tool",
19
+ long_description=long_description,
20
+ long_description_content_type="text/markdown",
21
+ url="https://github.com/TAbdiukov/YaSINT",
22
+ author="Tim Abdiukov",
23
+ entry_points={'console_scripts': ['yasint = yasint.cli:run']},
24
+ packages=find_packages(),
25
+ include_package_data=True,
26
+ install_requires=requires,
27
+ python_requires=">=3.8",
28
+ license_files=["NOTICE", "LICENCES/MIT-Soxoj.txt"],
29
+ project_urls={
30
+ "Source": "https://github.com/TAbdiukov/YaSINT",
31
+ "Issues": "https://github.com/TAbdiukov/YaSINT/issues",
32
+ "Changelog": "https://github.com/TAbdiukov/YaSINT/blob/main/CHANGELOG.md",
33
+ },
34
+ classifiers=[
35
+ "Environment :: Console",
36
+ 'Intended Audience :: Information Technology',
37
+ "Operating System :: OS Independent",
38
+ "Programming Language :: Python :: 3",
39
+ "Programming Language :: Python :: 3 :: Only",
40
+ "Programming Language :: Python :: 3.8",
41
+ "Programming Language :: Python :: 3.9",
42
+ "Programming Language :: Python :: 3.10",
43
+ "Programming Language :: Python :: 3.11",
44
+ "Programming Language :: Python :: 3.12",
45
+ "Programming Language :: Python :: 3.13",
46
+ "Programming Language :: Python :: 3.14",
47
+ "Topic :: Security",
48
+ ],
49
+ )
@@ -0,0 +1,195 @@
1
+ import csv
2
+ import io
3
+ import sys
4
+
5
+ import pytest
6
+
7
+ import yasint.cli as cli
8
+
9
+
10
+ PUBLIC_ID = 'c48fhxw0qppa50289r5c9ku4k4'
11
+
12
+
13
+ def _no_lead_results(input_data):
14
+ return [
15
+ cli.OutputDataList(
16
+ item,
17
+ [cli.OutputData(item.value, {'platform': 'Music'}, None)],
18
+ session_dir='',
19
+ )
20
+ for item in input_data
21
+ ]
22
+
23
+
24
+ def _lead_results(input_data, session_dir=''):
25
+ return [
26
+ cli.OutputDataList(
27
+ item,
28
+ [cli.OutputData(item.value, {'platform': 'Music', 'username': item.value}, None)],
29
+ session_dir=session_dir,
30
+ )
31
+ for item in input_data
32
+ ]
33
+
34
+
35
+ class FakeProcessor:
36
+ instances = []
37
+ result_builder = _no_lead_results
38
+
39
+ def __init__(self, *args, **kwargs):
40
+ self.args = args
41
+ self.kwargs = kwargs
42
+ self.input_data = None
43
+ self.closed = False
44
+ type(self).instances.append(self)
45
+
46
+ async def process(self, input_data):
47
+ self.input_data = input_data
48
+ return type(self).result_builder(input_data)
49
+
50
+ async def close(self):
51
+ self.closed = True
52
+
53
+
54
+ @pytest.fixture()
55
+ def fake_processor(monkeypatch):
56
+ FakeProcessor.instances = []
57
+ FakeProcessor.result_builder = _no_lead_results
58
+ monkeypatch.setattr(cli, 'Processor', FakeProcessor)
59
+ return FakeProcessor
60
+
61
+
62
+ def test_run_exits_without_targets(monkeypatch, capsys, fake_processor):
63
+ monkeypatch.setattr(sys, 'argv', ['yasint'])
64
+
65
+ with pytest.raises(SystemExit) as exc_info:
66
+ cli.run()
67
+
68
+ assert exc_info.value.code == 1
69
+ assert fake_processor.instances == []
70
+ assert 'There are no targets to check!' in capsys.readouterr().out
71
+
72
+
73
+ def test_run_processes_positional_targets_and_closes_processor(monkeypatch, capsys, fake_processor):
74
+ monkeypatch.setattr(
75
+ sys,
76
+ 'argv',
77
+ [
78
+ 'yasint',
79
+ '--no-progressbar',
80
+ '--no-color',
81
+ '--proxy',
82
+ 'socks5://127.0.0.1:1080',
83
+ '--cookie-jar-file',
84
+ 'cookies.txt',
85
+ 'login',
86
+ PUBLIC_ID,
87
+ ],
88
+ )
89
+
90
+ cli.run()
91
+
92
+ assert len(fake_processor.instances) == 1
93
+ processor = fake_processor.instances[0]
94
+ assert processor.kwargs == {
95
+ 'no_progressbar': True,
96
+ 'no_color': True,
97
+ 'proxy': 'socks5://127.0.0.1:1080',
98
+ 'cookie_file': 'cookies.txt',
99
+ }
100
+ assert [(i.value, i.identifier_type) for i in processor.input_data] == [
101
+ ('login', 'username'),
102
+ (PUBLIC_ID, 'yandex_public_id'),
103
+ ]
104
+ assert processor.closed is True
105
+
106
+ out = capsys.readouterr().out
107
+ assert 'Target: login (username)' in out
108
+ assert f'Target: {PUBLIC_ID} (yandex_public_id)' in out
109
+ assert out.count('Leads found: 0') == 2
110
+ assert 'Total leads found: 0' in out
111
+
112
+
113
+ def test_run_reads_targets_from_stdin(monkeypatch, fake_processor):
114
+ monkeypatch.setattr(sys, 'argv', ['yasint', '--targets-from-stdin', '--silent', '--no-progressbar'])
115
+ monkeypatch.setattr(sys, 'stdin', io.StringIO('alpha\nbeta@yandex.ru\n'))
116
+
117
+ cli.run()
118
+
119
+ processor = fake_processor.instances[0]
120
+ assert [(i.value, i.identifier_type) for i in processor.input_data] == [
121
+ ('alpha', 'username'),
122
+ ('beta', 'username'),
123
+ ]
124
+ assert processor.closed is True
125
+
126
+
127
+ def test_run_reads_target_list_and_writes_requested_reports(monkeypatch, capsys, tmp_path, fake_processor):
128
+ target_file = tmp_path / 'targets.txt'
129
+ txt_file = tmp_path / 'report.txt'
130
+ csv_file = tmp_path / 'report.csv'
131
+ target_file.write_text('login\nperson@yandex.ru\n', encoding='utf-8')
132
+ fake_processor.result_builder = _lead_results
133
+ monkeypatch.setattr(
134
+ sys,
135
+ 'argv',
136
+ [
137
+ 'yasint',
138
+ '--target-list',
139
+ str(target_file),
140
+ '--silent',
141
+ '--no-progressbar',
142
+ '-oT',
143
+ str(txt_file),
144
+ '-oC',
145
+ str(csv_file),
146
+ ],
147
+ )
148
+
149
+ cli.run()
150
+
151
+ processor = fake_processor.instances[0]
152
+ assert [i.value for i in processor.input_data] == ['login', 'person']
153
+
154
+ out = capsys.readouterr().out
155
+ assert 'Target:' not in out
156
+ assert f'Results were saved to file {csv_file}' in out
157
+ assert f'Results were saved to file {txt_file}' in out
158
+
159
+ text = txt_file.read_text()
160
+ assert 'Target: login (username)' in text
161
+ assert 'Target: person (username)' in text
162
+ assert 'Leads found: 1' in text
163
+ assert 'Requests:' in text
164
+ assert 'Music: GET https://music.yandex.ru/handlers/library.jsx?owner=login' in text
165
+
166
+ with csv_file.open(newline='') as f:
167
+ rows = list(csv.DictReader(f))
168
+
169
+ assert [row['Target'] for row in rows] == ['login (username)', 'person (username)']
170
+ assert [row['Leads Found'] for row in rows] == ['Yes', 'Yes']
171
+ assert [row['Username'] for row in rows] == ['login', 'person']
172
+
173
+
174
+ def test_run_writes_auxiliary_reports_for_session_outputs(monkeypatch, capsys, tmp_path, fake_processor):
175
+ session_dir = tmp_path / 'reports' / 'session'
176
+ session_dir.mkdir(parents=True)
177
+
178
+ def session_results(input_data):
179
+ return _lead_results(input_data, session_dir=str(session_dir))
180
+
181
+ fake_processor.result_builder = session_results
182
+ monkeypatch.setattr(sys, 'argv', ['yasint', '--no-progressbar', '--no-color', 'login'])
183
+
184
+ cli.run()
185
+
186
+ aux_txt = session_dir / 'auxiliary_report.txt'
187
+ aux_csv = session_dir / 'auxiliary_report.csv'
188
+ assert aux_txt.exists()
189
+ assert aux_csv.exists()
190
+ assert f'Reports session: {session_dir}' in aux_txt.read_text()
191
+
192
+ out = capsys.readouterr().out
193
+ assert f'Reports session: {session_dir}' in out
194
+ assert f'Results were saved to file {aux_txt}' in out
195
+ assert f'Results were saved to file {aux_csv}' in out