-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
218 lines (167 loc) · 5.74 KB
/
utils.py
File metadata and controls
218 lines (167 loc) · 5.74 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def is_numeric(string: str) -> bool:
""" Also accepts '.' in the string. Function 'isnumeric()' doesn't """
try:
float(string)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(string)
return True
except (TypeError, ValueError):
pass
return False
def format(value,
decimals=None,
force_length=False,
template=None,
on_zero=0,
on_none=None,
symbol=None):
""" Format a crypto coin value so that it isn't unnecessarily long """
fiat = False
if symbol and isinstance(symbol, str):
pass
if value is None:
return on_none
try:
if isinstance(value, str):
value = value.replace(",", "")
v = float(value)
except:
return str(value)
try:
if isinstance(template, str):
template = template.replace(",", "")
t = float(template)
except:
t = v
try:
decimals = int(decimals)
except:
decimals = None
try:
if float(value) == 0:
return on_zero
except:
return str(value)
if t < 1:
if decimals:
v = "{1:.{0}f}".format(decimals, v)
else:
v = "{0:.8f}".format(v)
elif t < 100:
if decimals:
v = "{1:.{0}f}".format(decimals, v)
else:
v = "{0:.4f}".format(v)
elif t < 10000:
if decimals:
v = "{1:,.{0}f}".format(decimals, v)
else:
v = "{0:,.2f}".format(v)
else:
v = "{0:,.0f}".format(v)
if not force_length:
cut_zeros = False
if t >= 1:
cut_zeros = True
else:
if fiat:
cut_zeros = True
if cut_zeros:
while "." in v and v.endswith(("0", ".")):
v = v[:-1]
return v
def format_float(value):
# Check if the number has no decimal part
if value == int(value):
return str(int(value))
# Convert to string and split into integer and decimal parts
str_value = str(value)
parts = str_value.split('.')
# If there's somehow no decimal part after splitting
if len(parts) == 1:
return parts[0]
integer_part, decimal_part = parts
# Find the position of the first non-zero digit
first_non_zero_pos = 0
while first_non_zero_pos < len(decimal_part) and decimal_part[first_non_zero_pos] == '0':
first_non_zero_pos += 1
# If all decimal digits are zeros or we reached the end
if first_non_zero_pos >= len(decimal_part):
return integer_part
# Find the position of the second non-zero digit
second_non_zero_pos = first_non_zero_pos + 1
while second_non_zero_pos < len(decimal_part) and decimal_part[second_non_zero_pos] == '0':
second_non_zero_pos += 1
# Determine how many decimal places to keep
if second_non_zero_pos >= len(decimal_part):
# If there's only one non-zero digit, keep up to that position
decimal_places_to_keep = first_non_zero_pos + 1
else:
# Otherwise keep up to the second non-zero digit
decimal_places_to_keep = second_non_zero_pos + 1
# Format the number with the required decimal places
formatted_decimal = decimal_part[:decimal_places_to_keep]
# Remove trailing zeros
trimmed_decimal = formatted_decimal.rstrip('0')
# If all decimal digits were trimmed, return just the integer part
if trimmed_decimal == '':
return integer_part
return f"{integer_part}.{trimmed_decimal}"
def build_menu(buttons, n_cols: int = 1, header_buttons=None, footer_buttons=None):
""" Build button-menu for Telegram """
menu = [buttons[i:i + n_cols] for i in range(0, len(buttons), n_cols)]
if header_buttons:
menu.insert(0, header_buttons)
if footer_buttons:
menu.append(footer_buttons)
return menu
def str2bool(value: str):
return value.lower() in ("yes", "true", "t", "1")
def split_msg(msg: str, max_len: int = None, split_char: str = "\n", only_one: bool = False):
""" Restrict message length to max characters as defined by Telegram """
if not max_len:
import constants as con
max_len = con.MAX_TG_MSG_LEN
if only_one:
return [msg[:max_len][:msg[:max_len].rfind(split_char)]]
remaining = msg
messages = list()
while len(remaining) > max_len:
split_at = remaining[:max_len].rfind(split_char)
message = remaining[:max_len][:split_at]
messages.append(message)
remaining = remaining[len(message):]
else:
messages.append(remaining)
return messages
def encode_url(url: str):
import urllib.parse as ul
return ul.quote_plus(url)
def id():
import time
return int(time.time() * 1000)
def random_id(length: int = 8):
import string, random
alphabet = string.ascii_uppercase + string.digits
return ''.join(random.choices(alphabet, k=length))
def md5(input_str: str, to_int: bool = False):
import hashlib
md5_hash = hashlib.md5(input_str.encode("utf-8")).hexdigest()
return int(md5_hash, 16) if to_int else md5_hash
def to_unix_time(date_time, millis: bool = False):
from datetime import datetime
seconds = (date_time - datetime(1970, 1, 1)).total_seconds()
return int(seconds * 1000 if millis else seconds)
def from_unix_time(seconds, millis: bool = False):
from datetime import datetime
return datetime.utcfromtimestamp(seconds / 1000 if millis else seconds)
def get_ip():
import socket
return socket.gethostbyname(socket.gethostname())
def get_external_ip(website: str = 'https://api.ipify.org/'):
import urllib.request
return urllib.request.urlopen(website).read().decode("utf-8")