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.
Files changed (76) hide show
  1. hh_applicant_tool/__init__.py +1 -0
  2. hh_applicant_tool/__main__.py +1 -1
  3. hh_applicant_tool/ai/base.py +2 -0
  4. hh_applicant_tool/ai/openai.py +25 -35
  5. hh_applicant_tool/api/__init__.py +4 -2
  6. hh_applicant_tool/api/client.py +65 -68
  7. hh_applicant_tool/{constants.py → api/client_keys.py} +3 -6
  8. hh_applicant_tool/api/datatypes.py +293 -0
  9. hh_applicant_tool/api/errors.py +57 -7
  10. hh_applicant_tool/api/user_agent.py +17 -0
  11. hh_applicant_tool/main.py +234 -113
  12. hh_applicant_tool/operations/apply_similar.py +353 -371
  13. hh_applicant_tool/operations/authorize.py +313 -120
  14. hh_applicant_tool/operations/call_api.py +18 -8
  15. hh_applicant_tool/operations/check_proxy.py +30 -0
  16. hh_applicant_tool/operations/clear_negotiations.py +90 -82
  17. hh_applicant_tool/operations/config.py +119 -16
  18. hh_applicant_tool/operations/install.py +34 -0
  19. hh_applicant_tool/operations/list_resumes.py +23 -11
  20. hh_applicant_tool/operations/log.py +77 -0
  21. hh_applicant_tool/operations/migrate_db.py +65 -0
  22. hh_applicant_tool/operations/query.py +122 -0
  23. hh_applicant_tool/operations/refresh_token.py +14 -13
  24. hh_applicant_tool/operations/reply_employers.py +201 -180
  25. hh_applicant_tool/operations/settings.py +95 -0
  26. hh_applicant_tool/operations/uninstall.py +26 -0
  27. hh_applicant_tool/operations/update_resumes.py +23 -11
  28. hh_applicant_tool/operations/whoami.py +40 -7
  29. hh_applicant_tool/storage/__init__.py +8 -0
  30. hh_applicant_tool/storage/facade.py +24 -0
  31. hh_applicant_tool/storage/models/__init__.py +0 -0
  32. hh_applicant_tool/storage/models/base.py +169 -0
  33. hh_applicant_tool/storage/models/contacts.py +28 -0
  34. hh_applicant_tool/storage/models/employer.py +12 -0
  35. hh_applicant_tool/storage/models/negotiation.py +16 -0
  36. hh_applicant_tool/storage/models/resume.py +19 -0
  37. hh_applicant_tool/storage/models/setting.py +6 -0
  38. hh_applicant_tool/storage/models/vacancy.py +36 -0
  39. hh_applicant_tool/storage/queries/migrations/.gitkeep +0 -0
  40. hh_applicant_tool/storage/queries/schema.sql +132 -0
  41. hh_applicant_tool/storage/repositories/__init__.py +0 -0
  42. hh_applicant_tool/storage/repositories/base.py +230 -0
  43. hh_applicant_tool/storage/repositories/contacts.py +14 -0
  44. hh_applicant_tool/storage/repositories/employers.py +14 -0
  45. hh_applicant_tool/storage/repositories/errors.py +19 -0
  46. hh_applicant_tool/storage/repositories/negotiations.py +13 -0
  47. hh_applicant_tool/storage/repositories/resumes.py +9 -0
  48. hh_applicant_tool/storage/repositories/settings.py +35 -0
  49. hh_applicant_tool/storage/repositories/vacancies.py +9 -0
  50. hh_applicant_tool/storage/utils.py +40 -0
  51. hh_applicant_tool/utils/__init__.py +31 -0
  52. hh_applicant_tool/utils/attrdict.py +6 -0
  53. hh_applicant_tool/utils/binpack.py +167 -0
  54. hh_applicant_tool/utils/config.py +55 -0
  55. hh_applicant_tool/utils/date.py +19 -0
  56. hh_applicant_tool/utils/json.py +61 -0
  57. hh_applicant_tool/{jsonc.py → utils/jsonc.py} +12 -6
  58. hh_applicant_tool/utils/log.py +147 -0
  59. hh_applicant_tool/utils/misc.py +12 -0
  60. hh_applicant_tool/utils/mixins.py +221 -0
  61. hh_applicant_tool/utils/string.py +27 -0
  62. hh_applicant_tool/utils/terminal.py +32 -0
  63. hh_applicant_tool-1.4.12.dist-info/METADATA +685 -0
  64. hh_applicant_tool-1.4.12.dist-info/RECORD +68 -0
  65. hh_applicant_tool/ai/blackbox.py +0 -55
  66. hh_applicant_tool/color_log.py +0 -47
  67. hh_applicant_tool/mixins.py +0 -13
  68. hh_applicant_tool/operations/delete_telemetry.py +0 -30
  69. hh_applicant_tool/operations/get_employer_contacts.py +0 -348
  70. hh_applicant_tool/telemetry_client.py +0 -106
  71. hh_applicant_tool/types.py +0 -45
  72. hh_applicant_tool/utils.py +0 -119
  73. hh_applicant_tool-0.7.10.dist-info/METADATA +0 -452
  74. hh_applicant_tool-0.7.10.dist-info/RECORD +0 -33
  75. {hh_applicant_tool-0.7.10.dist-info → hh_applicant_tool-1.4.12.dist-info}/WHEEL +0 -0
  76. {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 Any
5
- from ..api import ApiError, ApiClient
6
- from ..main import BaseOperation
7
- from ..main import Namespace as BaseNamespace
8
- from ..utils import print_err
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, _, api_client: ApiClient, *args: Any) -> None:
24
- try:
25
- api_client.refresh_access_token()
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("✅ Токен обновлен!")