hh-applicant-tool 1.4.7__py3-none-any.whl → 1.4.12__py3-none-any.whl

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 (46) hide show
  1. hh_applicant_tool/__main__.py +1 -1
  2. hh_applicant_tool/ai/openai.py +2 -2
  3. hh_applicant_tool/api/__init__.py +4 -2
  4. hh_applicant_tool/api/client.py +23 -12
  5. hh_applicant_tool/{constants.py → api/client_keys.py} +3 -3
  6. hh_applicant_tool/{datatypes.py → api/datatypes.py} +2 -0
  7. hh_applicant_tool/api/errors.py +8 -2
  8. hh_applicant_tool/{utils → api}/user_agent.py +1 -1
  9. hh_applicant_tool/main.py +12 -13
  10. hh_applicant_tool/operations/apply_similar.py +125 -47
  11. hh_applicant_tool/operations/authorize.py +82 -25
  12. hh_applicant_tool/operations/call_api.py +3 -3
  13. hh_applicant_tool/operations/{check_negotiations.py → clear_negotiations.py} +40 -25
  14. hh_applicant_tool/operations/list_resumes.py +5 -7
  15. hh_applicant_tool/operations/query.py +3 -1
  16. hh_applicant_tool/operations/reply_employers.py +80 -40
  17. hh_applicant_tool/operations/settings.py +2 -2
  18. hh_applicant_tool/operations/update_resumes.py +5 -4
  19. hh_applicant_tool/operations/whoami.py +1 -1
  20. hh_applicant_tool/storage/__init__.py +5 -1
  21. hh_applicant_tool/storage/facade.py +2 -2
  22. hh_applicant_tool/storage/models/base.py +4 -4
  23. hh_applicant_tool/storage/models/contacts.py +28 -0
  24. hh_applicant_tool/storage/queries/schema.sql +22 -9
  25. hh_applicant_tool/storage/repositories/base.py +69 -15
  26. hh_applicant_tool/storage/repositories/contacts.py +5 -10
  27. hh_applicant_tool/storage/repositories/employers.py +1 -0
  28. hh_applicant_tool/storage/repositories/errors.py +19 -0
  29. hh_applicant_tool/storage/repositories/negotiations.py +1 -0
  30. hh_applicant_tool/storage/repositories/resumes.py +2 -7
  31. hh_applicant_tool/storage/repositories/settings.py +1 -0
  32. hh_applicant_tool/storage/repositories/vacancies.py +1 -0
  33. hh_applicant_tool/storage/utils.py +6 -15
  34. hh_applicant_tool/utils/__init__.py +3 -3
  35. hh_applicant_tool/utils/config.py +1 -1
  36. hh_applicant_tool/utils/log.py +4 -1
  37. hh_applicant_tool/utils/mixins.py +20 -19
  38. hh_applicant_tool/utils/terminal.py +13 -0
  39. {hh_applicant_tool-1.4.7.dist-info → hh_applicant_tool-1.4.12.dist-info}/METADATA +197 -140
  40. hh_applicant_tool-1.4.12.dist-info/RECORD +68 -0
  41. hh_applicant_tool/storage/models/contact.py +0 -16
  42. hh_applicant_tool-1.4.7.dist-info/RECORD +0 -67
  43. /hh_applicant_tool/utils/{dateutil.py → date.py} +0 -0
  44. /hh_applicant_tool/utils/{jsonutil.py → json.py} +0 -0
  45. {hh_applicant_tool-1.4.7.dist-info → hh_applicant_tool-1.4.12.dist-info}/WHEEL +0 -0
  46. {hh_applicant_tool-1.4.7.dist-info → hh_applicant_tool-1.4.12.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hh-applicant-tool
3
- Version: 1.4.7
3
+ Version: 1.4.12
4
4
  Summary: HH-Applicant-Tool: An automation utility for HeadHunter (hh.ru) designed to streamline the job search process by auto-applying to relevant vacancies and periodically refreshing resumes to stay at the top of recruiter searches.
5
5
  Author: Senior YAML Developer
6
6
  Author-email: yamldeveloper@proton.me
@@ -11,7 +11,9 @@ Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Programming Language :: Python :: 3.14
14
+ Provides-Extra: pillow
14
15
  Provides-Extra: playwright
16
+ Requires-Dist: pillow (>=12.1.0,<13.0.0) ; extra == "pillow"
15
17
  Requires-Dist: playwright (>=1.57.0,<2.0.0) ; extra == "playwright"
16
18
  Requires-Dist: prettytable (>=3.6.0,<4.0.0)
17
19
  Requires-Dist: requests[socks] (>=2.32.3,<3.0.0)
@@ -21,6 +23,8 @@ Description-Content-Type: text/markdown
21
23
 
22
24
  ## HH Applicant Tool
23
25
 
26
+ > Ищу почасовую или проектную [@feedback_s3rgeym_bot](https://t.me/feedback_s3rgeym_bot) (Python, Vue.js, Devops)
27
+
24
28
  ![Publish to PyPI](https://github.com/s3rgeym/hh-applicant-tool/actions/workflows/publish.yml/badge.svg)
25
29
  [![PyPi Version](https://img.shields.io/pypi/v/hh-applicant-tool)]()
26
30
  [![Python Versions](https://img.shields.io/pypi/pyversions/hh-applicant-tool.svg)]()
@@ -34,9 +38,11 @@ Description-Content-Type: text/markdown
34
38
 
35
39
  ### ✨ Ключевые преимущества
36
40
 
37
- - 💸 **Бесплатно.** В то время как сервисы в интернете или Telegram с аналогичным функционалом просят за свои услуги от 5.000 до 12.000 рублей в месяц.
41
+ - 💸 **Полностью бесплатно.** В то время как сервисы в интернете или Telegram с аналогичным функционалом просят за свои услуги от 5.000 до 12.000 рублей в месяц.
42
+
43
+ - 🔒 **Безопасность личных данных.** Ваши email, телефон, пароль и другие личные данные никуда не передаются в отличие от сторонних сервисов. В этом можно убедиться, изучив [открытый исходный код](https://github.com/s3rgeym/hh-applicant-tool/tree/main/src/hh_applicant_tool). Владельцы сторонних сервисов никогда вам не покажут исходники. Они знают о вас все и эти данные спокойно продадут каким-нибудь жуликам, либо те утекут в результате взлома.
38
44
 
39
- - 🔒 **Безопасность личных данных.** Ваши email, телефон, пароль и другие личные данные никуда не передаются в отличие от сторонних сервисов. В этом можно убедиться, изучив [открытый исходный код](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool). Владельцы сторонних сервисов никогда вам не покажут исходники. Они знают о вас все и эти данные спокойно продадут каким-нибудь жуликам, либо те утекут в результате взлома.
45
+ - 💾 **Сохранение контактов и прочей информации.** Контакты работодалей и информация о них и их вакансиях сохраняется в базе данных, что позволяет производить быстрый поиск нужной информации в отличии от сайта.
40
46
 
41
47
  - 🛡️ **Гарантия от блокировок.** Утилита выполняет запросы с вашего устройства, имитируя обычного пользователя. Сервисы рассылают запросы для сотен аккаунтов с одного сервера, что повышает вероятность блокировки вашего аккаунта до 100%.
42
48
 
@@ -46,7 +52,7 @@ Description-Content-Type: text/markdown
46
52
 
47
53
  - 🖥️ **Полноценный CLI и работа на серверах.** Утилита имеет чистый консольный интерфейс. Несмотря на то, что для обхода защиты при авторизации используется браузер, он работает по умолчанию в фоновом (headless) режиме. Для `hh-applicant-tool` не нужна видеокарта или графическая оболочка (X-сервер), что позволяет авторизоваться даже с сервера или из докер-контейнера.
48
54
 
49
- - 🚀 **Скриптинг.** Вы можете использовать утилиту из Python-скриптов!!! Благодаря этому вы можете ее интегрировать, например, в своего Telegram-бота.
55
+ - 🚀 **Скриптинг.** Вы можете использовать утилиту из своих Python-скриптов.
50
56
 
51
57
  - 🤖 **Борьба с ATS и HR.** Компании уже массово внедрили ATS-системы с нейронными сетями, которые отклоняют ваш отклик в течение 30 секунд. Отказ может прийти из-за отсутствия одного ключевого слова в резюме, это уже не говоря о давно существующих фильтрах по полу, возрасту и даже региону происхождения (безопасники в банках отказывают даже русским, рожденным в Дагестане). Это обесценивает ваши усилия на написание сопроводительных писем и чтение бесконечных портянок бреда, сгенерированных нейронками по запросу каких-то дур. Если тупые кобылы решили себя не утруждать чтением резюме (они сейчас и сами перестали писать), то и вам незачем читать их высеры. Утилита избавляет вас от этой рутины, превращающей поиск работы в полноценную работу. Сейчас доля отказов составляет 98-99%, включая "молчунов", и единственный способ увеличить шансы просто попасть на собеседование — это автоматическая рассылка откликов на все подходящие вакансии.
52
58
 
@@ -56,20 +62,25 @@ Description-Content-Type: text/markdown
56
62
  - [✨ Ключевые преимущества](#-ключевые-преимущества)
57
63
  - [Содержание](#содержание)
58
64
  - [Описание](#описание)
59
- - [Внимание!!!](#внимание)
60
65
  - [Предыстория](#предыстория)
61
66
  - [Установка](#установка)
62
- - [Установка утилиты](#установка-утилиты)
63
- - [Установка зависимостей](#установка-зависимостей)
64
- - [Авторизация](#авторизация)
65
- - [Конфигурация](#конфигурация)
67
+ - [Через Docker](#через-docker)
68
+ - [Обычная установка](#обычная-установка)
69
+ - [Установка самой утилиты](#установка-самой-утилиты)
70
+ - [Установка дополнительных зависимостей](#установка-дополнительных-зависимостей)
71
+ - [Об авторизации](#об-авторизации)
66
72
  - [Описание команд](#описание-команд)
67
- - [Формат текста сообщений](#формат-текста-сообщений)
68
73
  - [Использование AI](#использование-ai)
69
74
  - [OpenAI/ChatGPT](#openaichatgpt)
75
+ - [Шаблоны сообщений](#шаблоны-сообщений)
76
+ - [Данные приложения](#данные-приложения)
77
+ - [Конфигурационный файл](#конфигурационный-файл)
78
+ - [Логи](#логи)
79
+ - [База данных](#база-данных)
70
80
  - [Использование в скриптах](#использование-в-скриптах)
71
81
  - [Дополнительные настройки](#дополнительные-настройки)
72
- - [Лицензия / License](#лицензия--license)
82
+ - [TODO](#todo)
83
+ - [Лицензионное соглашение (Limited Non-Commercial License)](#лицензионное-соглашение-limited-non-commercial-license)
73
84
 
74
85
  ---
75
86
 
@@ -95,14 +106,6 @@ asdf/pyenv/conda и что-то еще. В школотронской Manjaro и
95
106
 
96
107
  > Утилита автоматически подхватывает прокси из переменных окружения типа http_proxy или HTTPS_PROXY
97
108
 
98
- Данные об откликах, вакансиях и работодателях хранятся локально в БД. Для ее просмотра советую использовать **DB Browser**:
99
-
100
- <img width="1306" height="1000" alt="image" src="https://github.com/user-attachments/assets/67742b8d-a16c-4304-bd79-7ac99d53ed38" />
101
-
102
- ### Внимание!!!
103
-
104
- Если для Вас проблема установить данную утилиту, лень разбираться с ее настройкой, то Вы можете установить мое приложение под **Android** [HH Resume Automate](https://github.com/s3rgeym/hh-resume-automate/). Оно обладает минимальным функционалом: обновление резюме (одного) и рассылка откликов (чистить их и т. п. нельзя).
105
-
106
109
  ### Предыстория
107
110
 
108
111
  Долгое время я делал массовые заявки с помощью консоли браузера:
@@ -115,7 +118,73 @@ $$('[data-qa="vacancy-serp__vacancy_response"]').forEach((el) => el.click());
115
118
 
116
119
  ### Установка
117
120
 
118
- #### Установка утилиты
121
+ #### Через Docker
122
+
123
+ Это самый простой способ для тех, кому лень разбираться с работой утилиты.
124
+
125
+ Для начала нужно установить `docker` и `docker-compose`:
126
+
127
+ ```sh
128
+ sudo apt install docker.io docker-compose-v2
129
+ ```
130
+
131
+ Выкачиваем репозиторий:
132
+
133
+ ```sh
134
+ git clone https://github.com/s3rgeym/hh-applicant-tool
135
+ ```
136
+
137
+ Переходим в каталог с `docker-compose.yml`:
138
+
139
+ ```sh
140
+ cd hh-applicant-tool/docker
141
+ ```
142
+
143
+ Теперь авторизуйтесь:
144
+
145
+ ```sh
146
+ docker-compose run --rm -it -e TERM=$TERM hh-applicant-tool \
147
+ hh-applicant-tool -vv -c /app/config auth -k
148
+ ```
149
+
150
+ Пример вывода:
151
+
152
+ ```
153
+ WARN[0000] No services to build
154
+ WARN[0000] No services to build
155
+ Container docker-tool-run-dfbc9f44c6a9 Creating
156
+ Container docker-tool-run-dfbc9f44c6a9 Created
157
+ 👤 Введите email или телефон: your-mail@gmail.com
158
+ 📨 Код был отправлен. Проверьте почту или SMS.
159
+ 📩 Введите полученный код: 1234
160
+ 🔓 Авторизация прошла успешно!
161
+ ```
162
+
163
+
164
+ Капча отобразится только в терминале с поддержкой протокола **kitty**, например, в **Konsole**.
165
+
166
+ В случае успешной авторизации можно запускать рассылку откликов по крону:
167
+
168
+ ```sh
169
+ docker-compose up -d
170
+ ```
171
+
172
+ Что будет делать?
173
+
174
+ - Рассылать отклики со всех опубликованных резюме.
175
+ - Поднимать резюме.
176
+
177
+ Информацию об ошибках можно посмотреть в файле `config/log.txt`, а контакты работодателей посмотреть в `config/data` с помощью `sqlite3`.
178
+
179
+ Для остановки выполните:
180
+
181
+ ```sh
182
+ docker-compose down
183
+ ```
184
+
185
+ #### Обычная установка
186
+
187
+ ##### Установка самой утилиты
119
188
 
120
189
  Универсальный с использованием pipx (требует пакета `python-pipx` в Arch):
121
190
 
@@ -192,7 +261,7 @@ pip install 'hh-applicant-tool[playwright]'
192
261
  - В случае неудачи вернитесь к первому шагу.
193
262
  - Для последующих запусков сначала активируйте виртуальное окружение.
194
263
 
195
- #### Установка зависимостей
264
+ ##### Установка дополнительных зависимостей
196
265
 
197
266
  После вышеописанного нужно установить зависимости в виде Chromium и других средств отладки:
198
267
 
@@ -202,7 +271,7 @@ $ hh-applicant-tool install
202
271
 
203
272
  Этот шаг необязателен. Все это нужно только для авторизации.
204
273
 
205
- ### Авторизация
274
+ ### Об авторизации
206
275
 
207
276
  Прямая авторизация:
208
277
 
@@ -232,18 +301,21 @@ $ hh-applicant-tool authorize '<ваш телефон или email>'
232
301
  🔓 Авторизация прошла успешно!
233
302
  ```
234
303
 
235
- - Если вы ввели телефон, то код придет через SMS
236
- - Если был введен Email, то проверьте почту
237
-
238
304
  Если же при вводе правильных данных возникает ошибка авторизации, то, скорее всего, требуется ввод капчи.
239
305
 
240
- Для ввода данных вручную:
306
+ Капчу можно ввести через терминал, если тот поддерживает kitty protocol (например, Kitty, Konsole, Ghostty и др):
241
307
 
242
308
  ```sh
243
- hh-applicant-tool authorize --manual
309
+ hh-applicant-tool authorize --use-kitty
244
310
  ```
245
311
 
246
- > Этот флаг не будет работать на сервере, так как требует наличия графического окружения
312
+ <img width="843" height="602" alt="Untitled" src="https://github.com/user-attachments/assets/8f5dec0c-c3d4-4c5c-bd8b-3aeffa623d87" />
313
+
314
+ Ручная авторизация с запуском встроенного браузера:
315
+
316
+ ```sh
317
+ hh-applicant-tool authorize --manual
318
+ ```
247
319
 
248
320
  Проверка авторизации:
249
321
 
@@ -262,48 +334,6 @@ $ hh-applicant-tool refresh-token
262
334
 
263
335
  Помните, что у `refresh_token` тоже есть время жизни, поэтому может потребоваться полная авторизация.
264
336
 
265
- ### Конфигурация
266
-
267
- Конфигурации хранятся по следующим путям:
268
-
269
- | OS | Путь |
270
- | ----------- | -------------------------------------------------------- |
271
- | **Windows** | `C:\Users\%username%\AppData\Roaming\hh-applicant-tool\` |
272
- | **macOS** | `~/Library/Application Support/hh-applicant-tool/` |
273
- | **Linux** | `~/.config/hh-applicant-tool/` |
274
-
275
- Главный конфиг называется `config.json`. Он содержит токены. Полный путь до конфигурационного файла можно вывести с помощью команды:
276
-
277
- ```bash
278
- hh-applicant-tool config -p
279
- ```
280
-
281
- Через конфиг можно задать дополнительные настройки:
282
-
283
- | Имя атрибута | Описание |
284
- | --------------- | ------------------------------------------------------------------------------------------ |
285
- | `proxy_url` | Прокси, используемый для всех запросов, например, `socks5h://127.0.0.1:9050` |
286
- | `reply_message` | Сообщение для ответа работодателю при отклике на вакансии, см. формат сообщений |
287
- | `user_agent` | Кастомный юзерагент, передаваемый при каждом запросе. По умолчанию используется от Android |
288
- | `client_id` | Идентификатор клиента, используемый для авторизации. По умолчанию используется от Android |
289
- | `client_secret` | Секретный ключ клиента, используемый для авторизации. По умолчанию используется от Android |
290
-
291
- В `log.txt` всегда можно посмотреть подробную информацию об ошибках. В целях безопасности токены, идентефикаторы резюме и тп затираются.
292
-
293
- Данные о работодателях и их вакансиях хранятся в файле `data`. Это обычная база `sqlite3`, вы ее можете просматривать через `DB Browser` и т. п.
294
-
295
- Что хранится в базе:
296
-
297
- * все просмотренные вакансии;
298
- * профили работодателей;
299
- * контакты работодателей;
300
- * данные об откликах;
301
- * иные данные, важные для работы.
302
-
303
- Если вы залогинитесь под другим аккаунтом, то данные не исчезнут.
304
-
305
- При использовании профиля, отличного от дефолтного, данные хранятся в подкаталоге.
306
-
307
337
  ### Описание команд
308
338
 
309
339
  Примеры команд:
@@ -356,7 +386,7 @@ $ hh-applicant-tool config -s proxy_url socks5h://localhost:1080
356
386
  $ hh-applicant-tool config -u proxy_url
357
387
 
358
388
  # Утилита все данные об откликах хранит в SQLite
359
- $ hh-applicant-tool query 'select count(*) from employer_contacts;'
389
+ $ hh-applicant-tool query 'select count(*) from vacancy_contacts;'
360
390
  +----------+
361
391
  | count(*) |
362
392
  +----------+
@@ -364,38 +394,14 @@ $ hh-applicant-tool query 'select count(*) from employer_contacts;'
364
394
  +----------+
365
395
 
366
396
  # Экспорт контактов в csv
367
- $ hh-applicant-tool query 'select * from employer_contacts' --csv -o
397
+ $ hh-applicant-tool query 'select * from vacancy_contacts' --csv -o
368
398
  contacts.csv
369
399
 
370
400
  # Выполнение запросов в интерактивном режиме
371
401
  $ hh-applicant-tool query
372
402
 
373
- # Вывести приглашения с удаленкой и зарплатой от 200.000 рублей
374
- $ hh-applicant-tool query <<<"SELECT
375
- v.alternate_url,
376
- v.name AS vacancy_name,
377
- v.salary_from,
378
- v.salary_to,
379
- e.name AS employer_name,
380
- e.site_url,
381
- ec.name,
382
- ec.email,
383
- ec.phone_numbers
384
- FROM vacancies v
385
- JOIN negotiations n ON v.id = n.vacancy_id
386
- JOIN employers e ON n.employer_id = e.id
387
- LEFT JOIN employer_contacts ec ON e.id = ec.employer_id
388
- WHERE v.salary_from >= 200000
389
- AND v.currency = 'RUR'
390
- AND v.remote = 1
391
- AND n.state IN ('invitation', 'interview', 'hired')
392
- ORDER BY v.salary_from DESC, v.salary_to DESC;"
393
-
394
- # Перед выполнением запросов к базе желательно синхронизировать отклики
395
- $ hh-applicant-tool sync-negotiations
396
-
397
403
  # Чистим отказы
398
- $ hh-applicant-tool sync --clean
404
+ $ hh-applicant-tool clear-negotiations
399
405
 
400
406
  # При обновлении может сломаться схема БД, для ее починки нужно выполнить
401
407
  # поочерёдно все миграции, добавленные после выхода последней версии
@@ -435,9 +441,9 @@ $ hh-applicant-tool settings auth.username 'user@example.com'
435
441
  | **whoami**, **id** | Выводит информацию об авторизованном пользователе |
436
442
  | **list-resumes**, **list**, **ls** | Список резюме |
437
443
  | **update-resumes**, **update** | Обновить все резюме. Аналогично нажатию кнопки «Обновить дату». |
438
- | **apply-similar** | Откликнуться на все подходящие вакансии. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со ссылками, иначе рискуете попасть в теневой бан. |
444
+ | **apply-similar** | Откликнуться на все подходящие вакансии СО ВСЕХ РЕЗЮМЕ. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со ссылками, иначе рискуете попасть в теневой бан. |
439
445
  | **reply-employers**, **reply** | Ответить во все чаты с работодателями, где нет ответа либо не прочитали ваш предыдущий ответ |
440
- | **check-negotiations** | Синхронизация откликов с возможностью их отмены |
446
+ | **clear-negotiations** | Отмена откликов |
441
447
  | **call-api**, **api** | Вызов произвольного метода API с выводом результата. |
442
448
  | **refresh-token**, **refresh** | Обновляет access_token. |
443
449
  | **config** | Показывает содержимое конфига. С флагом -e открывает его для редактирования. |
@@ -447,9 +453,9 @@ $ hh-applicant-tool settings auth.username 'user@example.com'
447
453
  | **check-proxy** | Проверяет используемые прокси |
448
454
  | **migrate** | Починить базу |
449
455
  | **query** | Выполнение SQL-запросов к базе. Схема БД находится в файле [schema.sql](./hh_hh_applicant_tool/storage/queries/schema.sql). Если скормить ее [DeepSeek](https://chat.deepseek.com), то он поможет написать любой запрос. |
450
- | **log** | Просмотр файла-лога. С флагом -f будет следить за изменениями. |
456
+ | **log** | Просмотр файла-лога. С флагом -f будет следить за изменениями. В логах частично скрыты идентефикаторы в целях безопасности. |
451
457
 
452
- Утилита использует систему плагинов. Все они лежат в [operations](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool/operations). Модули, расположенные там, автоматически добавляются как доступные команды. За основу для своего плагина можно взять [whoami.py](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool/operations/whoami.py).
458
+ Утилита использует систему плагинов. Все они лежат в [operations](https://github.com/s3rgeym/hh-applicant-tool/tree/main/src/hh_applicant_tool/operations). Модули, расположенные там, автоматически добавляются как доступные команды. За основу для своего плагина можно взять [whoami.py](https://github.com/s3rgeym/hh-applicant-tool/tree/main/src/hh_applicant_tool/operations/whoami.py).
453
459
 
454
460
  Для тестирования запросов к API используйте команду `call-api` совместно с `jq` для обработки JSON.
455
461
 
@@ -465,7 +471,7 @@ https://hh.ru/employer/4679771
465
471
  Синтаксис `call-api` немного похож на `httpie` или `curlie`:
466
472
 
467
473
  ```sh
468
- $ hh-applicant-tool call-api -m {GET|POST|PUT|DELETE} /path/to/endpoint key1=value1 ... keyN=valueN
474
+ $ hh-applicant-tool call-api [-m {GET|POST|PUT|DELETE}] <endpoint> [<key=value> ...]
469
475
  ```
470
476
 
471
477
  Если используется метод `GET` или `DELETE` (или ничего не указано), то параметры будут переданы как query string. Во всех остальных случаях парметры передаются как `application/x-www-form-urlencoded` в теле запроса.
@@ -490,9 +496,40 @@ npx @redocly/cli preview -d docs/hhapi
490
496
 
491
497
  По сути, никакие дополнительные команды, кроме имеющихся, не нужны. Вы можете сделать что угодно с помощью `call-api`, но если хочется чего-то особенного, можно добавить свои команды.
492
498
 
493
- ### Формат текста сообщений
499
+ ### Использование AI
500
+
501
+ Для генерации опроводительных писем при откликах и ответа в чаты работодателей (`reply-employers`) можно использовать OpenAI (ChatGPT).
502
+
503
+ Пример рассылки откликов с генерированным письмом:
504
+
505
+ ```sh
506
+ hh-applicant-tool apply-similar -f --ai
507
+ ```
494
508
 
495
- Команда `apply-similar` поддерживает специальный формат сообщений.
509
+ Генерацию сопроводительных писем в откликах я считаю лишним, так как их никто не читает. Экономнее воспользоваться шаблонами сообщений.
510
+
511
+ #### OpenAI/ChatGPT
512
+
513
+ Отредактируйте конфиг:
514
+
515
+ ```sh
516
+ hh-applicant-tool config -e
517
+ ```
518
+
519
+ Добавьте в него эти строки:
520
+
521
+ ```json
522
+ {
523
+ "openai": {
524
+ "token": "ВАШ_API_КЛЮЧ_OPENAI",
525
+ "model": "ВАША_МОДЕЛЬ",
526
+ }
527
+ }
528
+ ```
529
+
530
+ ### Шаблоны сообщений
531
+
532
+ Команды `apply-similar` и `reply-employers` поддерживают специальный формат сообщений.
496
533
 
497
534
  Так же в сообщении можно использовать плейсхолдеры:
498
535
 
@@ -502,6 +539,7 @@ npx @redocly/cli preview -d docs/hhapi
502
539
  - **`%(last_name)s`**: Фамилия пользователя.
503
540
  - **`%(email)s`**: Email пользователя.
504
541
  - **`%(phone)s`**: Телефон пользователя.
542
+ - **`%(resume_title)s`**: Название резюме.
505
543
 
506
544
  Эти плейсхолдеры могут быть использованы в сообщениях для отклика на вакансии, чтобы динамически подставлять соответствующие данные в текст сообщения. Например:
507
545
 
@@ -521,34 +559,53 @@ npx @redocly/cli preview -d docs/hhapi
521
559
  Привет, как ты?
522
560
  ```
523
561
 
524
- ### Использование AI
562
+ ### Данные приложения
525
563
 
526
- Для генерации опроводительных писем при откликах и ответа в чаты работодателей (`reply-employers`) можно использовать OpenAI (ChatGPT).
564
+ Данные приложения хранятся по следующим путям:
527
565
 
528
- Пример рассылки откликов с генерированным письмом:
566
+ | OS | Путь |
567
+ | ----------- | -------------------------------------------------------- |
568
+ | **Windows** | `C:\Users\%username%\AppData\Roaming\hh-applicant-tool\` |
569
+ | **macOS** | `~/Library/Application Support/hh-applicant-tool/` |
570
+ | **Linux** | `~/.config/hh-applicant-tool/` |
529
571
 
530
- ```sh
531
- hh-applicant-tool apply-similar -f --ai
572
+ #### Конфигурационный файл
573
+
574
+ Главный конфиг называется `config.json`. Он содержит токены. Полный путь до конфигурационного файла можно вывести с помощью команды:
575
+
576
+ ```bash
577
+ hh-applicant-tool config -p
532
578
  ```
533
579
 
534
- #### OpenAI/ChatGPT
580
+ Через конфиг можно задать дополнительные настройки:
535
581
 
536
- Отредактируйте конфиг:
582
+ | Имя атрибута | Описание |
583
+ | --------------- | ------------------------------------------------------------------------------------------ |
584
+ | `proxy_url` | Прокси, используемый для всех запросов, например, `socks5h://127.0.0.1:9050` |
585
+ | `reply_message` | Сообщение для ответа работодателю при отклике на вакансии, см. формат сообщений |
586
+ | `user_agent` | Кастомный юзерагент, передаваемый при каждом запросе. По умолчанию используется от Android |
587
+ | `client_id` | Идентификатор клиента, используемый для авторизации. По умолчанию используется от Android |
588
+ | `client_secret` | Секретный ключ клиента, используемый для авторизации. По умолчанию используется от Android |
537
589
 
538
- ```sh
539
- hh-applicant-tool config -e
540
- ```
590
+ Если вы залогинитесь под другим аккаунтом, то данные не исчезнут.
541
591
 
542
- Добавьте в него эти строки:
592
+ При использовании профиля, отличного от дефолтного, данные хранятся в подкаталоге.
543
593
 
544
- ```json
545
- {
546
- "openai": {
547
- "token": "ВАШ_API_КЛЮЧ_OPENAI",
548
- "model": "ВАША_МОДЕЛЬ",
549
- }
550
- }
551
- ```
594
+ #### Логи
595
+
596
+ В `log.txt` всегда можно посмотреть подробную информацию об ошибках. В целях безопасности токены, идентефикаторы резюме и тп затираются.
597
+
598
+ #### База данных
599
+
600
+ Данные о работодателях и их вакансиях хранятся в файле `data`. Это обычная база `sqlite3`, вы ее можете просматривать через `DB Browser` и т. п.
601
+
602
+ Что хранится в базе:
603
+
604
+ * все просмотренные вакансии;
605
+ * профили работодателей;
606
+ * контакты работодателей;
607
+ * данные об откликах;
608
+ * иные данные, важные для работы.
552
609
 
553
610
  ### Использование в скриптах
554
611
 
@@ -599,30 +656,30 @@ $ hh-applicant-tool settings disable_version_check true
599
656
  ```sh
600
657
  $ hh-applicant-tool settings send_error_reports false
601
658
  ```
602
- </details>
603
659
 
604
- ### Лицензия / License
660
+ ### TODO
605
661
 
606
- **© 2023-2026 Sergey M. Все права защищены.**
662
+ - Выкинуть ненужный функционал. Например, хранить отзывы нет смысла, так как они нигде не используются
607
663
 
608
- Данное программное обеспечение предоставляется на условиях **ограниченной некоммерческой лицензии**.
609
664
 
610
- - Разрешенное использование
611
- * Разрешается бесплатное использование, копирование и модификация кода исключительно в **личных**, **образовательных** и **ознакомительных** целях.
612
- * Разрешено использование в свободном некоммерческом ПО с открытым исходным кодом СТРОГО С УКАЗАНИЕМ ССЫЛОК НА ДАННЫЙ РЕПОЗИТОРИЙ И АВТОРА.
665
+ ### Лицензионное соглашение (Limited Non-Commercial License)
613
666
 
614
- - Ограничения в использовании
615
- Категорически запрещается использование данного кода (а также его частей или производных) в любых коммерческих целях без предварительного псогласия автора. Это включает, но не ограничивается:
616
- * Интеграцию кода в платные сервисы, приложения или веб-сайты.
617
- * Использование кода для оказания платных услуг (SaaS, консалтинг, техподдержка).
618
- * Перепродажу или сублицензирование кода.
667
+ Данное программное обеспечение распространяется на условиях **ограниченной некоммерческой лицензии**.
619
668
 
620
- - Отказ от ответственности
621
- Программа предоставляется на условиях «как есть» (AS IS). Автор не несет ответственности за любые прямые или косвенные убытки, возникшие в результате использования данного ПО.
669
+ - **Разрешённое использование**
670
+ * **Личное использование и изучение:** Разрешается копирование и модификация кода исключительно для личного ознакомления, обучения и отладки **без права публикации или распространения изменений**.
671
+ * **Интеграция в программное обеспечение:** Разрешается включение данного кода в состав сторонних бесплатных некоммерческих продуктов **только при полном сохранении исходного кода в неизменном виде**.
672
+ * **Атрибуция:** Любое распространение, демонстрация или использование кода (в том числе в составе других продуктов) допускается **только при обязательном указании автора и ссылки на оригинальный репозиторий**.
622
673
 
623
- ---
674
+ - **Ограничения на использование**
675
+ **Строго запрещается** использование данного кода в любых коммерческих целях без предварительного письменного согласия автора, включая, но не ограничиваясь:
676
+ * Интеграцией в платные сервисы, приложения, веб-сайты либо использованием в рамках оказания платных услуг.
677
+ * Публикацией, распространением или передачей третьим лицам **модифицированных (изменённых) версий** кода.
678
+ * Перепродажей, сублицензированием либо использованием кода в интересах коммерческих организаций.
624
679
 
625
- **Copyright (c) 2023-2026 Sergey M. All rights reserved.**
680
+ - **Отказ от ответственности**
681
+ Программное обеспечение предоставляется по принципу «как есть» (**AS IS**). Автор не несёт ответственности за любые прямые или косвенные убытки, включая, но не ограничиваясь, блокировкой аккаунтов, потерей данных или иными негативными последствиями, возникшими в результате использования данного программного обеспечения.
626
682
 
627
- This software is provided for **FREE PERSONAL USE ONLY**. Any commercial use, including integration into paid services or commercial consulting, is **STRICTLY PROHIBITED**.
683
+
684
+ **© 2023-2026 Sergey M. Все права защищены.**
628
685
 
@@ -0,0 +1,68 @@
1
+ hh_applicant_tool/__init__.py,sha256=ic_GIg9QtlrtgbXEDdhFg3J52VJRRu_OoEsFoRmZ_wk,34
2
+ hh_applicant_tool/__main__.py,sha256=iPpiz09xKqtAjrhONS99OYp6R2dQ6Anbhw1qPIN8ELo,80
3
+ hh_applicant_tool/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ hh_applicant_tool/ai/base.py,sha256=wrccJEO5FNfW6LQTj-pLZAu0VCcs8QXdzf74erBuTew,35
5
+ hh_applicant_tool/ai/openai.py,sha256=m6iRZ3Q-FhzJRttWoriwisq6Pl5o72QLws2JbGCuutw,1657
6
+ hh_applicant_tool/api/__init__.py,sha256=HJtIt4Mp4poqRdHwxsLF0DzD_pC6z1Kk25GfKm6rfOo,152
7
+ hh_applicant_tool/api/client.py,sha256=BzSpTZyzroxiRTTCMlnV2ED4hsRcq9C8epoY0w7hL48,9765
8
+ hh_applicant_tool/api/client_keys.py,sha256=LsMdYNaGNMUV9kvUBqGBd-oMwuUyyLkObOU_wfEnNMQ,491
9
+ hh_applicant_tool/api/datatypes.py,sha256=m5oorneUkc-B1031mGU8cWRDC2X-IaszLiZwHahr_rc,6093
10
+ hh_applicant_tool/api/errors.py,sha256=I-b_MriyjlGMnAvCRNu0pbPxpuWRUwCf5bqWfq7kwAE,3500
11
+ hh_applicant_tool/api/user_agent.py,sha256=ZbbaGcLSrMyP7ATtHPCxIrTFSR4MAjpvDfqZR9YtcVE,504
12
+ hh_applicant_tool/main.py,sha256=POyWgXPqbIsvhtuwzBFxbxP2BCvaGiy-4aYqeX70i8E,9801
13
+ hh_applicant_tool/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ hh_applicant_tool/operations/apply_similar.py,sha256=CF6TBM_O5qv0MT75kMLHJ_jkvTU5elHTGjP2LDJywSo,22933
15
+ hh_applicant_tool/operations/authorize.py,sha256=vdVFT81DbeTUBEhj1ScdolAFuPE9pSjhn7fAgRwh2Xs,12703
16
+ hh_applicant_tool/operations/call_api.py,sha256=J15RLJIIYmoaHL8icNKVvSlDuqovjXOujFaZXTc7CMY,1489
17
+ hh_applicant_tool/operations/check_proxy.py,sha256=HUbDN_CacFEQLGq8B2SBZ_F7-appdMeIrblFrxvt5MI,777
18
+ hh_applicant_tool/operations/clear_negotiations.py,sha256=NBiMmRQ56t-YxeM1Hd1ED-d2Zsv5PCAocE7pCmgVuUY,4246
19
+ hh_applicant_tool/operations/config.py,sha256=eNQik_sBobrNMBB3tZ2tuCveCqH-XCub26WInd6GYT0,4725
20
+ hh_applicant_tool/operations/install.py,sha256=e626LnUB5OVsZ1M6cMXfW94hSlN9BDwPfKYcXMtPEgc,794
21
+ hh_applicant_tool/operations/list_resumes.py,sha256=Xf_Hf1B6cu8OGbGUZcI-hUT7QQXHJtRuA3KSMMcpRNk,1227
22
+ hh_applicant_tool/operations/log.py,sha256=VwnKYDYOOMJKZPGe3X2auo89rAIdbR_7KzXzbt4ve7Y,2542
23
+ hh_applicant_tool/operations/migrate_db.py,sha256=CMWpkhnvJvyGb4QSrtfxrWfEehmHyZ_flevMMgobkfI,2073
24
+ hh_applicant_tool/operations/query.py,sha256=noINFgTBHpcTq9Gu5xPIvtSI-y57HX9py-oAcULQ3aE,3705
25
+ hh_applicant_tool/operations/refresh_token.py,sha256=K-L8GMC9azu3tngdVsb8zub9SmzKpuCjbCYAwNgp6Uo,640
26
+ hh_applicant_tool/operations/reply_employers.py,sha256=zOzJr0Jlu4JM36u-xTadvKvldbTFpsLrTlRWJUzo64g,13481
27
+ hh_applicant_tool/operations/settings.py,sha256=_dZ-EOypRf8gLQx8PGH_LvFned5UVA5bn3s1gKcYcvI,2918
28
+ hh_applicant_tool/operations/uninstall.py,sha256=IfFTCzvMT1FfoVj-yvIXwa-UaxV5ai8mmRs9hVDiWa4,626
29
+ hh_applicant_tool/operations/update_resumes.py,sha256=_YgQvfEapwsqHIXeo6X_Z4WYr1O17mhr5_jCd5h_0co,1253
30
+ hh_applicant_tool/operations/whoami.py,sha256=hHhBscBRh2MIFrhmhDwB4BI1jAoA0DRr8nSlqcG9a7s,1690
31
+ hh_applicant_tool/storage/__init__.py,sha256=lj5dMbmk5y3j050VYNp_No9cPVAEr_J3T6MXGC9y__Y,168
32
+ hh_applicant_tool/storage/facade.py,sha256=CnAKKp7wJOHqORPBUEzK-26A6xl3U_bOfgceYeFJ4B0,907
33
+ hh_applicant_tool/storage/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ hh_applicant_tool/storage/models/base.py,sha256=cBbsQKFt4S_-TDk3xGUofUQHOU72KimFmqbr_ytHH70,5495
35
+ hh_applicant_tool/storage/models/contacts.py,sha256=OrP5czEbGB4reBbH7PaW3oguGMaA1UiXWJt5rlg34nk,1155
36
+ hh_applicant_tool/storage/models/employer.py,sha256=QH9F-SIUWweeHZzWoptgIdlFQy4wxqakLmpVs7Fg9nI,344
37
+ hh_applicant_tool/storage/models/negotiation.py,sha256=HSSXD2YMvaVkNqHBLmFxVcpbpOpQzaCPraL-7j7m7Fk,454
38
+ hh_applicant_tool/storage/models/resume.py,sha256=R3FcVhlUvG-5K23OvLtOWbf0zGQLx7Nods25L6xq-1c,548
39
+ hh_applicant_tool/storage/models/setting.py,sha256=DIRvW1IX-1E3Af-JJY8RZwxn-E39OSHHwNDk-N4Yh-4,123
40
+ hh_applicant_tool/storage/models/vacancy.py,sha256=97OkoCh6kvjRuQoKYRGAHJE9L1ncELL427L-TXcnqbA,1097
41
+ hh_applicant_tool/storage/queries/migrations/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ hh_applicant_tool/storage/queries/schema.sql,sha256=s0DwiTdr2FxMvfke7FkBAuSIECwbTMvbjfwQLClrfEU,4265
43
+ hh_applicant_tool/storage/repositories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
+ hh_applicant_tool/storage/repositories/base.py,sha256=DMcxh5K7OvKLHi2PkyfLe1Cz4Hfd4gzrUCsOqdduh18,7176
45
+ hh_applicant_tool/storage/repositories/contacts.py,sha256=zUbGdgc-oD6nDDk0KfJnNVSZSlJU7iWGA0JOyxAcH5U,343
46
+ hh_applicant_tool/storage/repositories/employers.py,sha256=dscO_W2__zjIQmmyr9Sf00e1XqyYJtzyQDrLwmIyXwo,337
47
+ hh_applicant_tool/storage/repositories/errors.py,sha256=tAm5p8l1JsWCTfUSdrSdtt-fw_TWiThYyPm2wfjTIrA,394
48
+ hh_applicant_tool/storage/repositories/negotiations.py,sha256=jGw8k3FAZqAq9ltvUDJ2vwPY7lbR9fK7yPaKe9RAhCI,290
49
+ hh_applicant_tool/storage/repositories/resumes.py,sha256=-k9F_sPvkSSR75vGudhhKdQcgP_TYLra-xi3YiUZY_k,202
50
+ hh_applicant_tool/storage/repositories/settings.py,sha256=puidy8aDfp0zWINbF-vzxUIYfHtSczqEc3flSXFPYqE,835
51
+ hh_applicant_tool/storage/repositories/vacancies.py,sha256=EIWrxykKDJu3ueOKn-MTZfNtVO83-PeQSPvJkX2s5N4,209
52
+ hh_applicant_tool/storage/utils.py,sha256=KDVnb6Osx0HCh3EzzoEXPiK_KKysAR6F7ek9sBsQN7Y,1220
53
+ hh_applicant_tool/utils/__init__.py,sha256=-GZwAZSYGLO5D8Gzmdqlo1CrBjCx6l-lfTAs44olNdU,757
54
+ hh_applicant_tool/utils/attrdict.py,sha256=wlbow24rovk9kZ0lc0xA4ULlgZ-UWj4GUAmZhAbW9Wg,155
55
+ hh_applicant_tool/utils/binpack.py,sha256=qW55IPleip_wi1GyNBhPwCYP3GGQzi8BASGKD3sOIw8,4658
56
+ hh_applicant_tool/utils/config.py,sha256=4npQLjhi5d89gEebYjoFq16jTO8-Q4RMMwvVgRnWmXU,1588
57
+ hh_applicant_tool/utils/date.py,sha256=foPghTLlgThL-oiMu_LedaG8KS5IMfjGo1wsrAanhPM,456
58
+ hh_applicant_tool/utils/json.py,sha256=uW5Ajdv_IYCfVRHJiUVjQnb5nI7XRMva-s3QcVWruvY,1701
59
+ hh_applicant_tool/utils/jsonc.py,sha256=WATp8MeKglEI6MRdXWBmqvW3q8IRNpt7UPjAKIf5VBs,4072
60
+ hh_applicant_tool/utils/log.py,sha256=EbAvCnKMDQTWIPnYyIVY9T3KOkR3ljA9I5yk1yRmAFE,4094
61
+ hh_applicant_tool/utils/misc.py,sha256=BW0oUEozsMS8WBBIH6y-lUC_MBkuwhO2zbL0nM_Fi50,238
62
+ hh_applicant_tool/utils/mixins.py,sha256=p3I9VOCcfRwjH2hcELP8irCb1-_GVx8L2LvCqaqOW54,7408
63
+ hh_applicant_tool/utils/string.py,sha256=dQn1uhwYXesjRmqkDn5HAHOdeaGF2v1HXpT1Quff6Eg,618
64
+ hh_applicant_tool/utils/terminal.py,sha256=rCzAZj6Q0LYTCj1et16BfifvK8OMTsORoMP2vxG-JCk,1164
65
+ hh_applicant_tool-1.4.12.dist-info/METADATA,sha256=9rGEB-9QDSfac8SL0k5qTD51tZ4sYx6qauMLaIpRWEs,46122
66
+ hh_applicant_tool-1.4.12.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
67
+ hh_applicant_tool-1.4.12.dist-info/entry_points.txt,sha256=Vb7M2YaYLMtKYJZh8chIrXZApMzSRFT1-rQw-U9r10g,65
68
+ hh_applicant_tool-1.4.12.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- from .base import BaseModel, mapped
2
-
3
-
4
- # Из вакансии извлекается
5
- class EmployerContactModel(BaseModel):
6
- id: int
7
- employer_id: int = mapped(path="employer.id")
8
- email: str = mapped(path="contacts.email")
9
- name: str = mapped(path="contacts.name", default=None)
10
- phone_numbers: str = mapped(
11
- path="contacts.phones",
12
- transform=lambda phones: ", ".join(
13
- p["formatted"] for p in phones if p.get("number")
14
- ),
15
- default=None,
16
- )