hh-applicant-tool 0.7.10__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.
- hh_applicant_tool/__init__.py +1 -0
- hh_applicant_tool/__main__.py +1 -1
- hh_applicant_tool/ai/base.py +2 -0
- hh_applicant_tool/ai/openai.py +25 -35
- hh_applicant_tool/api/__init__.py +4 -2
- hh_applicant_tool/api/client.py +65 -68
- hh_applicant_tool/{constants.py → api/client_keys.py} +3 -6
- hh_applicant_tool/api/datatypes.py +293 -0
- hh_applicant_tool/api/errors.py +57 -7
- hh_applicant_tool/api/user_agent.py +17 -0
- hh_applicant_tool/main.py +234 -113
- hh_applicant_tool/operations/apply_similar.py +353 -371
- hh_applicant_tool/operations/authorize.py +313 -120
- hh_applicant_tool/operations/call_api.py +18 -8
- hh_applicant_tool/operations/check_proxy.py +30 -0
- hh_applicant_tool/operations/clear_negotiations.py +90 -82
- hh_applicant_tool/operations/config.py +119 -16
- hh_applicant_tool/operations/install.py +34 -0
- hh_applicant_tool/operations/list_resumes.py +23 -11
- hh_applicant_tool/operations/log.py +77 -0
- hh_applicant_tool/operations/migrate_db.py +65 -0
- hh_applicant_tool/operations/query.py +122 -0
- hh_applicant_tool/operations/refresh_token.py +14 -13
- hh_applicant_tool/operations/reply_employers.py +201 -180
- hh_applicant_tool/operations/settings.py +95 -0
- hh_applicant_tool/operations/uninstall.py +26 -0
- hh_applicant_tool/operations/update_resumes.py +23 -11
- hh_applicant_tool/operations/whoami.py +40 -7
- hh_applicant_tool/storage/__init__.py +8 -0
- hh_applicant_tool/storage/facade.py +24 -0
- hh_applicant_tool/storage/models/__init__.py +0 -0
- hh_applicant_tool/storage/models/base.py +169 -0
- hh_applicant_tool/storage/models/contacts.py +28 -0
- hh_applicant_tool/storage/models/employer.py +12 -0
- hh_applicant_tool/storage/models/negotiation.py +16 -0
- hh_applicant_tool/storage/models/resume.py +19 -0
- hh_applicant_tool/storage/models/setting.py +6 -0
- hh_applicant_tool/storage/models/vacancy.py +36 -0
- hh_applicant_tool/storage/queries/migrations/.gitkeep +0 -0
- hh_applicant_tool/storage/queries/schema.sql +132 -0
- hh_applicant_tool/storage/repositories/__init__.py +0 -0
- hh_applicant_tool/storage/repositories/base.py +230 -0
- hh_applicant_tool/storage/repositories/contacts.py +14 -0
- hh_applicant_tool/storage/repositories/employers.py +14 -0
- hh_applicant_tool/storage/repositories/errors.py +19 -0
- hh_applicant_tool/storage/repositories/negotiations.py +13 -0
- hh_applicant_tool/storage/repositories/resumes.py +9 -0
- hh_applicant_tool/storage/repositories/settings.py +35 -0
- hh_applicant_tool/storage/repositories/vacancies.py +9 -0
- hh_applicant_tool/storage/utils.py +40 -0
- hh_applicant_tool/utils/__init__.py +31 -0
- hh_applicant_tool/utils/attrdict.py +6 -0
- hh_applicant_tool/utils/binpack.py +167 -0
- hh_applicant_tool/utils/config.py +55 -0
- hh_applicant_tool/utils/date.py +19 -0
- hh_applicant_tool/utils/json.py +61 -0
- hh_applicant_tool/{jsonc.py → utils/jsonc.py} +12 -6
- hh_applicant_tool/utils/log.py +147 -0
- hh_applicant_tool/utils/misc.py +12 -0
- hh_applicant_tool/utils/mixins.py +221 -0
- hh_applicant_tool/utils/string.py +27 -0
- hh_applicant_tool/utils/terminal.py +32 -0
- hh_applicant_tool-1.4.12.dist-info/METADATA +685 -0
- hh_applicant_tool-1.4.12.dist-info/RECORD +68 -0
- hh_applicant_tool/ai/blackbox.py +0 -55
- hh_applicant_tool/color_log.py +0 -47
- hh_applicant_tool/mixins.py +0 -13
- hh_applicant_tool/operations/delete_telemetry.py +0 -30
- hh_applicant_tool/operations/get_employer_contacts.py +0 -348
- hh_applicant_tool/telemetry_client.py +0 -106
- hh_applicant_tool/types.py +0 -45
- hh_applicant_tool/utils.py +0 -119
- hh_applicant_tool-0.7.10.dist-info/METADATA +0 -452
- hh_applicant_tool-0.7.10.dist-info/RECORD +0 -33
- {hh_applicant_tool-0.7.10.dist-info → hh_applicant_tool-1.4.12.dist-info}/WHEEL +0 -0
- {hh_applicant_tool-0.7.10.dist-info → hh_applicant_tool-1.4.12.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import csv
|
|
5
|
+
import logging
|
|
6
|
+
import sqlite3
|
|
7
|
+
import sys
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from prettytable import PrettyTable
|
|
11
|
+
|
|
12
|
+
from ..main import BaseNamespace, BaseOperation
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from ..main import HHApplicantTool
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
import readline
|
|
19
|
+
|
|
20
|
+
readline.parse_and_bind("tab: complete")
|
|
21
|
+
except ImportError:
|
|
22
|
+
readline = None
|
|
23
|
+
|
|
24
|
+
MAX_RESULTS = 10
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__package__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Namespace(BaseNamespace):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Operation(BaseOperation):
|
|
35
|
+
"""Выполняет SQL-запрос. Поддерживает вывод в консоль или CSV файл."""
|
|
36
|
+
|
|
37
|
+
__aliases__: list[str] = ["sql"]
|
|
38
|
+
|
|
39
|
+
def setup_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
40
|
+
parser.add_argument("sql", nargs="?", help="SQL запрос")
|
|
41
|
+
parser.add_argument(
|
|
42
|
+
"--csv", action="store_true", help="Вывести результат в формате CSV"
|
|
43
|
+
)
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"-o",
|
|
46
|
+
"--output",
|
|
47
|
+
type=argparse.FileType("w", encoding="utf-8"),
|
|
48
|
+
help="Файл для сохранения",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def run(self, tool: HHApplicantTool) -> None:
|
|
52
|
+
def execute(sql_query: str) -> None:
|
|
53
|
+
sql_query = sql_query.strip()
|
|
54
|
+
if not sql_query:
|
|
55
|
+
return
|
|
56
|
+
try:
|
|
57
|
+
cursor = tool.db.cursor()
|
|
58
|
+
cursor.execute(sql_query)
|
|
59
|
+
|
|
60
|
+
if cursor.description:
|
|
61
|
+
columns = [d[0] for d in cursor.description]
|
|
62
|
+
|
|
63
|
+
if tool.args.csv or tool.args.output:
|
|
64
|
+
# Если -o не задан, используем sys.stdout
|
|
65
|
+
output = tool.args.output or sys.stdout
|
|
66
|
+
writer = csv.writer(output)
|
|
67
|
+
writer.writerow(columns)
|
|
68
|
+
writer.writerows(cursor.fetchall())
|
|
69
|
+
|
|
70
|
+
if tool.args.output:
|
|
71
|
+
print(f"✅ Exported to {tool.args.output.name}")
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
rows = cursor.fetchmany(MAX_RESULTS + 1)
|
|
75
|
+
if not rows:
|
|
76
|
+
print("No results found.")
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
table = PrettyTable()
|
|
80
|
+
table.field_names = columns
|
|
81
|
+
for row in rows[:MAX_RESULTS]:
|
|
82
|
+
table.add_row(row)
|
|
83
|
+
|
|
84
|
+
print(table)
|
|
85
|
+
if len(rows) > MAX_RESULTS:
|
|
86
|
+
print(
|
|
87
|
+
f"⚠️ Warning: Showing only first {MAX_RESULTS} results."
|
|
88
|
+
)
|
|
89
|
+
else:
|
|
90
|
+
tool.db.commit()
|
|
91
|
+
|
|
92
|
+
if cursor.rowcount > 0:
|
|
93
|
+
print(f"Rows affected: {cursor.rowcount}")
|
|
94
|
+
|
|
95
|
+
except sqlite3.Error as ex:
|
|
96
|
+
print(f"❌ SQL Error: {ex}")
|
|
97
|
+
return 1
|
|
98
|
+
|
|
99
|
+
if initial_sql := tool.args.sql:
|
|
100
|
+
return execute(initial_sql)
|
|
101
|
+
|
|
102
|
+
if not sys.stdin.isatty():
|
|
103
|
+
return execute(sys.stdin.read())
|
|
104
|
+
|
|
105
|
+
print("SQL Console (q or ^D to exit)")
|
|
106
|
+
try:
|
|
107
|
+
while True:
|
|
108
|
+
try:
|
|
109
|
+
user_input = input("query> ").strip()
|
|
110
|
+
if user_input.lower() in (
|
|
111
|
+
"exit",
|
|
112
|
+
"quit",
|
|
113
|
+
"q",
|
|
114
|
+
):
|
|
115
|
+
break
|
|
116
|
+
execute(user_input)
|
|
117
|
+
print()
|
|
118
|
+
except KeyboardInterrupt:
|
|
119
|
+
print("^C")
|
|
120
|
+
continue
|
|
121
|
+
except EOFError:
|
|
122
|
+
print()
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
import argparse
|
|
3
4
|
import logging
|
|
4
|
-
from typing import
|
|
5
|
-
|
|
6
|
-
from ..main import BaseOperation
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from ..main import BaseNamespace, BaseOperation
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ..main import HHApplicantTool
|
|
11
|
+
|
|
9
12
|
|
|
10
13
|
logger = logging.getLogger(__package__)
|
|
11
14
|
|
|
@@ -17,13 +20,11 @@ class Namespace(BaseNamespace):
|
|
|
17
20
|
class Operation(BaseOperation):
|
|
18
21
|
"""Получает новый access_token."""
|
|
19
22
|
|
|
23
|
+
__aliases__ = ["refresh"]
|
|
24
|
+
|
|
20
25
|
def setup_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
21
26
|
pass
|
|
22
27
|
|
|
23
|
-
def run(self,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
print("✅ Токен обновлен!")
|
|
27
|
-
except ApiError as ex:
|
|
28
|
-
print_err("❗ Ошибка:", ex)
|
|
29
|
-
return 1
|
|
28
|
+
def run(self, tool: HHApplicantTool) -> None:
|
|
29
|
+
tool.api_client.refresh_access_token()
|
|
30
|
+
print("✅ Токен обновлен!")
|