hh-applicant-tool 0.6.7__py3-none-any.whl → 0.6.8__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 +146 -13
- hh_applicant_tool/operations/reply_employers.py +1 -1
- {hh_applicant_tool-0.6.7.dist-info → hh_applicant_tool-0.6.8.dist-info}/METADATA +1 -1
- {hh_applicant_tool-0.6.7.dist-info → hh_applicant_tool-0.6.8.dist-info}/RECORD +6 -6
- {hh_applicant_tool-0.6.7.dist-info → hh_applicant_tool-0.6.8.dist-info}/WHEEL +0 -0
- {hh_applicant_tool-0.6.7.dist-info → hh_applicant_tool-0.6.8.dist-info}/entry_points.txt +0 -0
|
@@ -37,11 +37,40 @@ class Namespace(BaseNamespace):
|
|
|
37
37
|
search: str
|
|
38
38
|
schedule: str
|
|
39
39
|
dry_run: bool
|
|
40
|
+
# Пошли доп фильтры, которых не было
|
|
40
41
|
experience: str
|
|
41
|
-
|
|
42
|
+
employment: list[str] | None
|
|
43
|
+
area: list[str] | None
|
|
44
|
+
metro: list[str] | None
|
|
45
|
+
professional_role: list[str] | None
|
|
46
|
+
industry: list[str] | None
|
|
47
|
+
employer_id: list[str] | None
|
|
48
|
+
excluded_employer_id: list[str] | None
|
|
49
|
+
currency: str | None
|
|
50
|
+
salary: int | None
|
|
51
|
+
only_with_salary: bool
|
|
52
|
+
label: list[str] | None
|
|
53
|
+
period: int | None
|
|
54
|
+
date_from: str | None
|
|
55
|
+
date_to: str | None
|
|
56
|
+
top_lat: float | None
|
|
57
|
+
bottom_lat: float | None
|
|
58
|
+
left_lng: float | None
|
|
59
|
+
right_lng: float | None
|
|
60
|
+
sort_point_lat: float | None
|
|
61
|
+
sort_point_lng: float | None
|
|
62
|
+
no_magic: bool
|
|
63
|
+
premium: bool
|
|
64
|
+
responses_count_enabled: bool
|
|
65
|
+
|
|
66
|
+
def _bool(v: bool) -> str:
|
|
67
|
+
return str(v).lower()
|
|
42
68
|
|
|
43
69
|
class Operation(BaseOperation, GetResumeIdMixin):
|
|
44
|
-
"""Откликнуться на все подходящие вакансии.
|
|
70
|
+
"""Откликнуться на все подходящие вакансии.
|
|
71
|
+
|
|
72
|
+
Описание фильтров для поиска вакансий: <https://api.hh.ru/openapi/redoc#tag/Poisk-vakansij-dlya-soiskatelya/operation/get-vacancies-similar-to-resume>
|
|
73
|
+
"""
|
|
45
74
|
|
|
46
75
|
def setup_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
47
76
|
parser.add_argument("--resume-id", help="Идентефикатор резюме")
|
|
@@ -121,6 +150,32 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
121
150
|
type=str,
|
|
122
151
|
default=None,
|
|
123
152
|
)
|
|
153
|
+
parser.add_argument("--employment", nargs="+", help="Тип занятости (employment)")
|
|
154
|
+
parser.add_argument("--area", nargs="+", help="Регион (area id)")
|
|
155
|
+
parser.add_argument("--metro", nargs="+", help="Станции метро (metro id)")
|
|
156
|
+
parser.add_argument("--professional-role", nargs="+", help="Проф. роль (id)")
|
|
157
|
+
parser.add_argument("--industry", nargs="+", help="Индустрия (industry id)")
|
|
158
|
+
parser.add_argument("--employer-id", nargs="+", help="ID работодателей")
|
|
159
|
+
parser.add_argument("--excluded-employer-id", nargs="+", help="Исключить работодателей")
|
|
160
|
+
parser.add_argument("--currency", help="Код валюты (RUR, USD, EUR)")
|
|
161
|
+
parser.add_argument("--salary", type=int, help="Минимальная зарплата")
|
|
162
|
+
parser.add_argument("--only-with-salary", default=False, action=argparse.BooleanOptionalAction)
|
|
163
|
+
parser.add_argument("--label", nargs="+", help="Метки вакансий (label)")
|
|
164
|
+
parser.add_argument("--period", type=int, help="Искать вакансии за N дней")
|
|
165
|
+
parser.add_argument("--date-from", help="Дата публикации с (YYYY-MM-DD)")
|
|
166
|
+
parser.add_argument("--date-to", help="Дата публикации по (YYYY-MM-DD)")
|
|
167
|
+
parser.add_argument("--top-lat", type=float, help="Гео: верхняя широта")
|
|
168
|
+
parser.add_argument("--bottom-lat", type=float, help="Гео: нижняя широта")
|
|
169
|
+
parser.add_argument("--left-lng", type=float, help="Гео: левая долгота")
|
|
170
|
+
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="Вернуть описание параметров запроса")
|
|
124
179
|
|
|
125
180
|
def run(
|
|
126
181
|
self, args: Namespace, api_client: ApiClient, telemetry_client: TelemetryClient
|
|
@@ -165,6 +220,31 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
165
220
|
self.schedule = args.schedule
|
|
166
221
|
self.dry_run = args.dry_run
|
|
167
222
|
self.experience = args.experience
|
|
223
|
+
self.search_field = args.search_field
|
|
224
|
+
self.employment = args.employment
|
|
225
|
+
self.area = args.area
|
|
226
|
+
self.metro = args.metro
|
|
227
|
+
self.professional_role = args.professional_role
|
|
228
|
+
self.industry = args.industry
|
|
229
|
+
self.employer_id = args.employer_id
|
|
230
|
+
self.excluded_employer_id = args.excluded_employer_id
|
|
231
|
+
self.currency = args.currency
|
|
232
|
+
self.salary = args.salary
|
|
233
|
+
self.only_with_salary = args.only_with_salary
|
|
234
|
+
self.label = args.label
|
|
235
|
+
self.period = args.period
|
|
236
|
+
self.date_from = args.date_from
|
|
237
|
+
self.date_to = args.date_to
|
|
238
|
+
self.top_lat = args.top_lat
|
|
239
|
+
self.bottom_lat = args.bottom_lat
|
|
240
|
+
self.left_lng = args.left_lng
|
|
241
|
+
self.right_lng = args.right_lng
|
|
242
|
+
self.sort_point_lat = args.sort_point_lat
|
|
243
|
+
self.sort_point_lng = args.sort_point_lng
|
|
244
|
+
self.clusters = args.clusters
|
|
245
|
+
#self.describe_arguments = args.describe_arguments
|
|
246
|
+
self.no_magic = args.no_magic
|
|
247
|
+
self.premium = args.premium
|
|
168
248
|
self._apply_similar()
|
|
169
249
|
|
|
170
250
|
def _get_application_messages(self, message_list: TextIO | None) -> list[str]:
|
|
@@ -366,20 +446,73 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
366
446
|
except TelemetryError as ex:
|
|
367
447
|
logger.error(ex)
|
|
368
448
|
|
|
449
|
+
def _get_search_params(self, page: int, per_page: int) -> dict:
|
|
450
|
+
params = {
|
|
451
|
+
"page": page,
|
|
452
|
+
"per_page": per_page,
|
|
453
|
+
"order_by": self.order_by,
|
|
454
|
+
}
|
|
455
|
+
if self.search:
|
|
456
|
+
params["text"] = self.search
|
|
457
|
+
if self.schedule:
|
|
458
|
+
params['schedule'] = self.schedule
|
|
459
|
+
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
|
|
477
|
+
if self.currency:
|
|
478
|
+
params["currency"] = self.currency
|
|
479
|
+
if self.salary:
|
|
480
|
+
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
|
+
if self.period:
|
|
486
|
+
params["period"] = self.period
|
|
487
|
+
if self.date_from:
|
|
488
|
+
params["date_from"] = self.date_from
|
|
489
|
+
if self.date_to:
|
|
490
|
+
params["date_to"] = self.date_to
|
|
491
|
+
if self.top_lat:
|
|
492
|
+
params["top_lat"] = self.top_lat
|
|
493
|
+
if self.bottom_lat:
|
|
494
|
+
params["bottom_lat"] = self.bottom_lat
|
|
495
|
+
if self.left_lng:
|
|
496
|
+
params["left_lng"] = self.left_lng
|
|
497
|
+
if self.right_lng:
|
|
498
|
+
params["right_lng"] = self.right_lng
|
|
499
|
+
if self.sort_point_lat:
|
|
500
|
+
params["sort_point_lat"] = self.sort_point_lat
|
|
501
|
+
if self.sort_point_lng:
|
|
502
|
+
params["sort_point_lng"] = self.sort_point_lng
|
|
503
|
+
if self.clusters is not None:
|
|
504
|
+
params["clusters"] = self.clusters
|
|
505
|
+
if self.no_magic is not None:
|
|
506
|
+
params["no_magic"] = _bool(self.no_magic)
|
|
507
|
+
if self.premium is not None:
|
|
508
|
+
params["premium"] = _bool(self.premium)
|
|
509
|
+
return params
|
|
510
|
+
|
|
369
511
|
def _get_vacancies(self, per_page: int = 100) -> list[VacancyItem]:
|
|
370
512
|
rv = []
|
|
513
|
+
# API отдает только 2000 результатов
|
|
371
514
|
for page in range(20):
|
|
372
|
-
params =
|
|
373
|
-
"page": page,
|
|
374
|
-
"per_page": per_page,
|
|
375
|
-
"order_by": self.order_by,
|
|
376
|
-
}
|
|
377
|
-
if self.search:
|
|
378
|
-
params["text"] = self.search
|
|
379
|
-
if self.schedule:
|
|
380
|
-
params['schedule'] = self.schedule
|
|
381
|
-
if self.experience:
|
|
382
|
-
params['experience'] = self.experience
|
|
515
|
+
params = self._get_search_params(page, per_page)
|
|
383
516
|
res: ApiListResponse = self.api_client.get(
|
|
384
517
|
f"/resumes/{self.resume_id}/similar_vacancies", params
|
|
385
518
|
)
|
|
@@ -61,7 +61,7 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
61
61
|
"-m",
|
|
62
62
|
"--reply-message",
|
|
63
63
|
"--reply",
|
|
64
|
-
help="Отправить сообщение во все чаты, где ожидают ответа либо не прочитали ответ.
|
|
64
|
+
help="Отправить сообщение во все чаты, где ожидают ответа либо не прочитали ответ. Если не передать сообщение, то нужно будет вводить его в интерактивном режиме.",
|
|
65
65
|
)
|
|
66
66
|
parser.add_argument(
|
|
67
67
|
"-p",
|
|
@@ -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=o7co4d3zc9sDCXAOjqs3dQe8_OoXU5M9PaiUtvfLxak,23590
|
|
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
|
|
@@ -20,13 +20,13 @@ hh_applicant_tool/operations/delete_telemetry.py,sha256=JHdh_l7IJL_qy5AIIy8FQpUu
|
|
|
20
20
|
hh_applicant_tool/operations/get_employer_contacts.py,sha256=Sd-x3O08bmKm1OGVLtJ6rcPZ_j1jwjlqKV4z1n_G-38,9918
|
|
21
21
|
hh_applicant_tool/operations/list_resumes.py,sha256=dILHyBCSEVqdNAvD8SML5f2Lau1R2AzTaKE9B4FG8Wg,1109
|
|
22
22
|
hh_applicant_tool/operations/refresh_token.py,sha256=v_Fcw9mCfOdE6MLTCQjZQudhJPX0fup3k0BaIM394Qw,834
|
|
23
|
-
hh_applicant_tool/operations/reply_employers.py,sha256=
|
|
23
|
+
hh_applicant_tool/operations/reply_employers.py,sha256=40rsTgpoEUaRQUq5ZQYgojKb42smYRkbDDD2S_7Vwtg,13512
|
|
24
24
|
hh_applicant_tool/operations/update_resumes.py,sha256=_r7HA_vpYMs5DFY-mVP1ZRG9bggsv7ebKYrwteBmJ30,1053
|
|
25
25
|
hh_applicant_tool/operations/whoami.py,sha256=pNWJMmEQLBk3U6eiGz4CHcX7eXzDXcfezFjX7zLjqyA,711
|
|
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.8.dist-info/METADATA,sha256=CTMbI2mzDnQZRxZ71qnP1yM-XZblyQmiQnZ49fypvtg,21401
|
|
30
|
+
hh_applicant_tool-0.6.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
31
|
+
hh_applicant_tool-0.6.8.dist-info/entry_points.txt,sha256=Vb7M2YaYLMtKYJZh8chIrXZApMzSRFT1-rQw-U9r10g,65
|
|
32
|
+
hh_applicant_tool-0.6.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|