hh-applicant-tool 0.6.8__tar.gz → 0.6.10__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.

Potentially problematic release.


This version of hh-applicant-tool might be problematic. Click here for more details.

Files changed (31) hide show
  1. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/PKG-INFO +1 -1
  2. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/apply_similar.py +86 -39
  3. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/pyproject.toml +1 -1
  4. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/README.md +0 -0
  5. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/__init__.py +0 -0
  6. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/__main__.py +0 -0
  7. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/ai/__init__.py +0 -0
  8. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/ai/blackbox.py +0 -0
  9. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/api/__init__.py +0 -0
  10. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/api/client.py +0 -0
  11. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/api/errors.py +0 -0
  12. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/color_log.py +0 -0
  13. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/constants.py +0 -0
  14. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/jsonc.py +0 -0
  15. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/main.py +0 -0
  16. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/mixins.py +0 -0
  17. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/__init__.py +0 -0
  18. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/authorize.py +0 -0
  19. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/call_api.py +0 -0
  20. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/clear_negotiations.py +0 -0
  21. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/config.py +0 -0
  22. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/delete_telemetry.py +0 -0
  23. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/get_employer_contacts.py +0 -0
  24. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/list_resumes.py +0 -0
  25. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/refresh_token.py +0 -0
  26. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/reply_employers.py +0 -0
  27. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/update_resumes.py +0 -0
  28. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/operations/whoami.py +0 -0
  29. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/telemetry_client.py +0 -0
  30. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/types.py +0 -0
  31. {hh_applicant_tool-0.6.8 → hh_applicant_tool-0.6.10}/hh_applicant_tool/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hh-applicant-tool
3
- Version: 0.6.8
3
+ Version: 0.6.10
4
4
  Summary:
5
5
  Author: Senior YAML Developer
6
6
  Author-email: yamldeveloper@proton.me
@@ -4,11 +4,11 @@ import random
4
4
  import time
5
5
  from collections import defaultdict
6
6
  from datetime import datetime, timedelta, timezone
7
- from typing import TextIO
7
+ from typing import Any, TextIO
8
8
 
9
- from ..api.errors import LimitExceeded
10
9
  from ..ai.blackbox import BlackboxChat, BlackboxError
11
- from ..api import ApiError, ApiClient
10
+ from ..api import ApiClient, ApiError
11
+ from ..api.errors import LimitExceeded
12
12
  from ..main import BaseOperation
13
13
  from ..main import Namespace as BaseNamespace
14
14
  from ..mixins import GetResumeIdMixin
@@ -63,9 +63,15 @@ class Namespace(BaseNamespace):
63
63
  premium: bool
64
64
  responses_count_enabled: bool
65
65
 
66
+
66
67
  def _bool(v: bool) -> str:
67
68
  return str(v).lower()
68
69
 
70
+
71
+ def _join_list(items: list[Any] | None) -> str:
72
+ return ",".join(f"{v}" for v in items) if items else ""
73
+
74
+
69
75
  class Operation(BaseOperation, GetResumeIdMixin):
70
76
  """Откликнуться на все подходящие вакансии.
71
77
 
@@ -150,16 +156,22 @@ class Operation(BaseOperation, GetResumeIdMixin):
150
156
  type=str,
151
157
  default=None,
152
158
  )
153
- parser.add_argument("--employment", nargs="+", help="Тип занятости (employment)")
159
+ parser.add_argument(
160
+ "--employment", nargs="+", help="Тип занятости (employment)"
161
+ )
154
162
  parser.add_argument("--area", nargs="+", help="Регион (area id)")
155
163
  parser.add_argument("--metro", nargs="+", help="Станции метро (metro id)")
156
164
  parser.add_argument("--professional-role", nargs="+", help="Проф. роль (id)")
157
165
  parser.add_argument("--industry", nargs="+", help="Индустрия (industry id)")
158
166
  parser.add_argument("--employer-id", nargs="+", help="ID работодателей")
159
- parser.add_argument("--excluded-employer-id", nargs="+", help="Исключить работодателей")
167
+ parser.add_argument(
168
+ "--excluded-employer-id", nargs="+", help="Исключить работодателей"
169
+ )
160
170
  parser.add_argument("--currency", help="Код валюты (RUR, USD, EUR)")
161
171
  parser.add_argument("--salary", type=int, help="Минимальная зарплата")
162
- parser.add_argument("--only-with-salary", default=False, action=argparse.BooleanOptionalAction)
172
+ parser.add_argument(
173
+ "--only-with-salary", default=False, action=argparse.BooleanOptionalAction
174
+ )
163
175
  parser.add_argument("--label", nargs="+", help="Метки вакансий (label)")
164
176
  parser.add_argument("--period", type=int, help="Искать вакансии за N дней")
165
177
  parser.add_argument("--date-from", help="Дата публикации с (YYYY-MM-DD)")
@@ -168,14 +180,43 @@ class Operation(BaseOperation, GetResumeIdMixin):
168
180
  parser.add_argument("--bottom-lat", type=float, help="Гео: нижняя широта")
169
181
  parser.add_argument("--left-lng", type=float, help="Гео: левая долгота")
170
182
  parser.add_argument("--right-lng", type=float, help="Гео: правая долгота")
171
- parser.add_argument("--sort-point-lat", type=float, help="Координата lat для сортировки по расстоянию")
172
- parser.add_argument("--sort-point-lng", type=float, help="Координата lng для сортировки по расстоянию")
173
- parser.add_argument("--no-magic", default=False, action=argparse.BooleanOptionalAction, help="Отключить авторазбор текста запроса")
174
- parser.add_argument("--premium", default=False, action=argparse.BooleanOptionalAction, help="Только премиум вакансии")
175
- parser.add_argument("--responses-count-enabled", default=False, action=argparse.BooleanOptionalAction, help="Включить счётчик откликов")
176
- parser.add_argument("--search-field", nargs="+", help="Поля поиска (name, company_name и т.п.)")
177
- parser.add_argument("--clusters", action=argparse.BooleanOptionalAction, help="Включить кластеры (по умолчанию None)")
178
- #parser.add_argument("--describe-arguments", action=argparse.BooleanOptionalAction, help="Вернуть описание параметров запроса")
183
+ parser.add_argument(
184
+ "--sort-point-lat",
185
+ type=float,
186
+ help="Координата lat для сортировки по расстоянию",
187
+ )
188
+ parser.add_argument(
189
+ "--sort-point-lng",
190
+ type=float,
191
+ help="Координата lng для сортировки по расстоянию",
192
+ )
193
+ parser.add_argument(
194
+ "--no-magic",
195
+ default=False,
196
+ action=argparse.BooleanOptionalAction,
197
+ help="Отключить авторазбор текста запроса",
198
+ )
199
+ parser.add_argument(
200
+ "--premium",
201
+ default=False,
202
+ action=argparse.BooleanOptionalAction,
203
+ help="Только премиум вакансии",
204
+ )
205
+ parser.add_argument(
206
+ "--responses-count-enabled",
207
+ default=False,
208
+ action=argparse.BooleanOptionalAction,
209
+ help="Включить счётчик откликов",
210
+ )
211
+ parser.add_argument(
212
+ "--search-field", nargs="+", help="Поля поиска (name, company_name и т.п.)"
213
+ )
214
+ parser.add_argument(
215
+ "--clusters",
216
+ action=argparse.BooleanOptionalAction,
217
+ help="Включить кластеры (по умолчанию None)",
218
+ )
219
+ # parser.add_argument("--describe-arguments", action=argparse.BooleanOptionalAction, help="Вернуть описание параметров запроса")
179
220
 
180
221
  def run(
181
222
  self, args: Namespace, api_client: ApiClient, telemetry_client: TelemetryClient
@@ -242,7 +283,7 @@ class Operation(BaseOperation, GetResumeIdMixin):
242
283
  self.sort_point_lat = args.sort_point_lat
243
284
  self.sort_point_lng = args.sort_point_lng
244
285
  self.clusters = args.clusters
245
- #self.describe_arguments = args.describe_arguments
286
+ # self.describe_arguments = args.describe_arguments
246
287
  self.no_magic = args.no_magic
247
288
  self.premium = args.premium
248
289
  self._apply_similar()
@@ -363,7 +404,9 @@ class Operation(BaseOperation, GetResumeIdMixin):
363
404
  telemetry_data["employers"][employer_id] = employer_data
364
405
 
365
406
  if not do_apply:
366
- logger.debug("Останавливаем рассылку откликов, так как достигли лимита, попробуйте через сутки.")
407
+ logger.debug(
408
+ "Останавливаем рассылку откликов, так как достигли лимита, попробуйте через сутки."
409
+ )
367
410
  break
368
411
 
369
412
  if relations:
@@ -452,36 +495,17 @@ class Operation(BaseOperation, GetResumeIdMixin):
452
495
  "per_page": per_page,
453
496
  "order_by": self.order_by,
454
497
  }
498
+
455
499
  if self.search:
456
500
  params["text"] = self.search
457
501
  if self.schedule:
458
- params['schedule'] = self.schedule
502
+ params["schedule"] = self.schedule
459
503
  if self.experience:
460
- params['experience'] = self.experience
461
- if self.search_field:
462
- params["search_field"] = self.search_field
463
- if self.employment:
464
- params["employment"] = self.employment
465
- if self.area:
466
- params["area"] = self.area
467
- if self.metro:
468
- params["metro"] = self.metro
469
- if self.professional_role:
470
- params["professional_role"] = self.professional_role
471
- if self.industry:
472
- params["industry"] = self.industry
473
- if self.employer_id:
474
- params["employer_id"] = self.employer_id
475
- if self.excluded_employer_id:
476
- params["excluded_employer_id"] = self.excluded_employer_id
504
+ params["experience"] = self.experience
477
505
  if self.currency:
478
506
  params["currency"] = self.currency
479
507
  if self.salary:
480
508
  params["salary"] = self.salary
481
- if self.only_with_salary is not None:
482
- params["only_with_salary"] = _bool(self.only_with_salary)
483
- if self.label:
484
- params["label"] = self.label
485
509
  if self.period:
486
510
  params["period"] = self.period
487
511
  if self.date_from:
@@ -500,12 +524,35 @@ class Operation(BaseOperation, GetResumeIdMixin):
500
524
  params["sort_point_lat"] = self.sort_point_lat
501
525
  if self.sort_point_lng:
502
526
  params["sort_point_lng"] = self.sort_point_lng
527
+ if self.search_field:
528
+ params["search_field"] = _join_list(self.search_field)
529
+ if self.employment:
530
+ params["employment"] = _join_list(self.employment)
531
+ if self.area:
532
+ params["area"] = _join_list(self.area)
533
+ if self.metro:
534
+ params["metro"] = _join_list(self.metro)
535
+ if self.professional_role:
536
+ params["professional_role"] = _join_list(self.professional_role)
537
+ if self.industry:
538
+ params["industry"] = _join_list(self.industry)
539
+ if self.employer_id:
540
+ params["employer_id"] = _join_list(self.employer_id)
541
+ if self.excluded_employer_id:
542
+ params["excluded_employer_id"] = _join_list(self.excluded_employer_id)
543
+ if self.label:
544
+ params["label"] = _join_list(self.label)
545
+ if self.only_with_salary is not None:
546
+ params["only_with_salary"] = _bool(self.only_with_salary)
503
547
  if self.clusters is not None:
504
- params["clusters"] = self.clusters
548
+ params["clusters"] = _bool(self.clusters)
505
549
  if self.no_magic is not None:
506
550
  params["no_magic"] = _bool(self.no_magic)
507
551
  if self.premium is not None:
508
552
  params["premium"] = _bool(self.premium)
553
+ if self.responses_count_enabled is not None:
554
+ params["responses_count_enabled"] = _bool(self.responses_count_enabled)
555
+
509
556
  return params
510
557
 
511
558
  def _get_vacancies(self, per_page: int = 100) -> list[VacancyItem]:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "hh-applicant-tool"
3
- version = "0.6.8"
3
+ version = "0.6.10"
4
4
  description = ""
5
5
  authors = ["Senior YAML Developer <yamldeveloper@proton.me>"]
6
6
  readme = "README.md"