hh-applicant-tool 0.6.8__py3-none-any.whl → 0.6.10__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.
Potentially problematic release.
This version of hh-applicant-tool might be problematic. Click here for more details.
- hh_applicant_tool/operations/apply_similar.py +86 -39
- {hh_applicant_tool-0.6.8.dist-info → hh_applicant_tool-0.6.10.dist-info}/METADATA +1 -1
- {hh_applicant_tool-0.6.8.dist-info → hh_applicant_tool-0.6.10.dist-info}/RECORD +5 -5
- {hh_applicant_tool-0.6.8.dist-info → hh_applicant_tool-0.6.10.dist-info}/WHEEL +0 -0
- {hh_applicant_tool-0.6.8.dist-info → hh_applicant_tool-0.6.10.dist-info}/entry_points.txt +0 -0
|
@@ -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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
parser.add_argument(
|
|
177
|
-
|
|
178
|
-
|
|
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[
|
|
502
|
+
params["schedule"] = self.schedule
|
|
459
503
|
if self.experience:
|
|
460
|
-
params[
|
|
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]:
|
|
@@ -11,7 +11,7 @@ hh_applicant_tool/jsonc.py,sha256=QNS4gRHfi7SAeOFnffAIuhH7auC4Y4HAkmH12eX5PkI,40
|
|
|
11
11
|
hh_applicant_tool/main.py,sha256=A4YPkNXAdZY0GoGm0iigiQtzXTrpR3SaIGo54q9-Dd0,5652
|
|
12
12
|
hh_applicant_tool/mixins.py,sha256=8VoyrNgdlljy6pLTSFGJOYd9kagWT3yFOZYIGR6MEbI,425
|
|
13
13
|
hh_applicant_tool/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
hh_applicant_tool/operations/apply_similar.py,sha256=
|
|
14
|
+
hh_applicant_tool/operations/apply_similar.py,sha256=iVnmYgYC2MjzTHc-zzJpyLklNy9SyNQ29ySMJ97XrO0,24414
|
|
15
15
|
hh_applicant_tool/operations/authorize.py,sha256=NYrxe6oemUBcDHioT1t1lJmi9l45V4ZXzQPD_-nf6hk,3328
|
|
16
16
|
hh_applicant_tool/operations/call_api.py,sha256=o3GZgtqk6w4zpCm-JTHVjFrKVOwW-vsu1HdRi-hqAjo,1423
|
|
17
17
|
hh_applicant_tool/operations/clear_negotiations.py,sha256=FG_43P5GWmfKUggkKZqDznQ2_iBJ3zrZtv8yEI2XOXQ,4527
|
|
@@ -26,7 +26,7 @@ hh_applicant_tool/operations/whoami.py,sha256=pNWJMmEQLBk3U6eiGz4CHcX7eXzDXcfezF
|
|
|
26
26
|
hh_applicant_tool/telemetry_client.py,sha256=1EKZWc5kMx2yERW9SrR9vaf-OB6M_KKcMXeicH5YyY0,3834
|
|
27
27
|
hh_applicant_tool/types.py,sha256=sQbt_vGXtWPRJ3UzcUkE87BTHOaGTsFxqdZa_qFghZE,864
|
|
28
28
|
hh_applicant_tool/utils.py,sha256=3T4A2AykGqTwtGAttmYplIjHwFl3pNAcbWIVuA-OheQ,3080
|
|
29
|
-
hh_applicant_tool-0.6.
|
|
30
|
-
hh_applicant_tool-0.6.
|
|
31
|
-
hh_applicant_tool-0.6.
|
|
32
|
-
hh_applicant_tool-0.6.
|
|
29
|
+
hh_applicant_tool-0.6.10.dist-info/METADATA,sha256=Vmcl9F_QP4ZrT31Xe6m-dMP_cvZQj5_KN_me_u3M5wE,21402
|
|
30
|
+
hh_applicant_tool-0.6.10.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
31
|
+
hh_applicant_tool-0.6.10.dist-info/entry_points.txt,sha256=Vb7M2YaYLMtKYJZh8chIrXZApMzSRFT1-rQw-U9r10g,65
|
|
32
|
+
hh_applicant_tool-0.6.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|