-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
132 lines (115 loc) · 3.79 KB
/
utils.py
File metadata and controls
132 lines (115 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import csv
import re
import zipfile
import locale
from typing import List, Optional, Any, Tuple
from pathlib import Path
from zoneinfo import ZoneInfo
from datetime import (
date,
timedelta,
datetime,
timezone)
from dataclasses import dataclass
from decimal import Decimal
BULLET = "\U0001F518"
NOBR = "\U000000A0"
BOX = "\U0001F4E6"
TODAY = date.today()
KYIV_ZONE = ZoneInfo("Europe/Kyiv")
YESTERDAY = TODAY - timedelta(days=1)
START_DATE = YESTERDAY.isoformat()
DUCKDB_NAME = "procurements2.db"
LIMIT = 6
@dataclass
class Tender:
entity_id: Optional[str] = None
entity_name: Optional[str] = None
proc_type: Optional[str] = None
status: Optional[str] = None
clarif_until: Optional[str] = None
title: Optional[str] = None
uaid: Optional[str] = None
id: Optional[str] = None
price: Optional[float] = None
price_uah: Optional[float] = None
currency: Optional[str] = None
vat: Optional[bool] = None
date: Optional[datetime] = None
procedure_name: Optional[str] = None
status_name: Optional[str] = None
@classmethod
def from_tuple(cls, row: Tuple[Any, ...]) -> "Tender":
fields = list(cls.__dataclass_fields__.keys())
data = {k: v for k, v in zip(fields, row)}
return cls(**data)
def mk_offset_param(date_: date) -> str:
"""
Makes an offset parameter for the API
"""
date_obj = datetime.combine(date_, datetime.min.time(), tzinfo=timezone.utc)
kyiv_zone = ZoneInfo("Europe/Kyiv")
date_obj_offset = date_obj.astimezone(kyiv_zone)
iso_string = date_obj_offset.isoformat()
return iso_string
def beautify_number(n, suffix='грн.'):
divider = Decimal(1000.0)
if not n or n is None:
return ""
for unit in ('', 'тис.', 'млн', 'млрд', 'трлн'):
if abs(n) < divider:
n = locale.format_string("%3.1f", n)
return f"{n} {unit} {suffix}"
n /= divider
n = locale.format_string("%.1f", n)
return f"{n} квдрлн {suffix}"
def make_csv_datafile(data: List, filedate: str):
backup_dir = Path.cwd().joinpath('archive')
Path(backup_dir).mkdir(parents=True, exist_ok=True)
if not data:
return 1
header = ['entity_id', 'entity_name', 'proc_type', 'status',
'clarif_until', 'title', 'uaid', 'id', 'price',
'price_uah', 'currency', 'vat', 'date', 'procedure_name',
'status_name']
csv_file_name = f"{filedate.replace('-', '')}_data.csv"
zip_file_name = Path.cwd().joinpath('archive', f"{csv_file_name}.zip")
with open(csv_file_name, "w") as f:
writer = csv.writer(f, delimiter='\t', quoting=2)
writer.writerow(header)
writer.writerows(data)
try:
with zipfile.ZipFile(
zip_file_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
zip_file.write(csv_file_name)
except Exception as e:
pass
else:
Path(csv_file_name).unlink()
return 0
def seconds_to_hms(seconds):
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
remaining_seconds = int(seconds % 60)
return hours, minutes, remaining_seconds
def text_clean(string: str, typostrofe=False, translit=False,
uk2en=False) -> Optional[str]:
en_letters = "aeiopcxBKMHTyAEIOPCX"
uk_letters = "аеіорсхВКМНТуАЕІОРСХ"
if not uk2en:
order = en_letters, uk_letters
else:
order = uk_letters, en_letters
transpose = str.maketrans(*order)
k = string.replace('\xa0', ' ') \
.replace('"', '”') \
.replace('`', "'")
if typostrofe:
k = k.replace("'", '’')
k = re.sub(" ?", "", k)
k = re.sub(r"\s+", " ", k)
if translit:
k = k.translate(transpose)
return k.strip()