Skip to content

Commit 74c0918

Browse files
committed
refactor
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
1 parent 1746264 commit 74c0918

File tree

1 file changed

+75
-141
lines changed

1 file changed

+75
-141
lines changed

tymely/tymely.py

Lines changed: 75 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,21 @@
55
import datetime
66
import os
77
import random
8-
import shutil
9-
import ssl
10-
import subprocess # nosec B404
8+
import subprocess # nosec B404,S404
119
import sys
10+
import shutil
11+
import requests
1212
import certifi
13-
import urllib3
1413
import yaml
1514

16-
__minimal__ = "{'verbose': 0}"
17-
__url__ = "duckduckgo.com"
18-
__version__ = "0.0.1"
19-
20-
ARGS = None
21-
CONF = None
22-
EXCEPTION_STR = "Exception:"
23-
RESPONSE = None
24-
URL = None
25-
USER_AGENT = None
15+
__version__ = "0.1.0"
2616

2717

2818
def arguments():
29-
"""Command line arguments and help information."""
30-
global ARGS
31-
19+
"""
20+
Parse command line arguments using argparse module and return the parsed
21+
arguments.
22+
"""
3223
parser = argparse.ArgumentParser(
3324
description="tymely fetches HTTP-date over HTTPS and sets the system time",
3425
epilog="version: " + __version__,
@@ -43,167 +34,110 @@ def arguments():
4334
action="store_true",
4435
)
4536

46-
ARGS = parser.parse_args()
47-
37+
return parser.parse_args()
4838

49-
def config():
50-
"""Returns CONF with yaml configuration files or default values."""
51-
global CONF
5239

40+
def config(args):
41+
"""
42+
Read and parse the configuration file specified in the command line arguments.
43+
Return the configuration as a dictionary.
44+
"""
5345
try:
54-
if ARGS.config:
55-
if not os.path.isfile(ARGS.config):
56-
print(ARGS.config, "can't be found.")
46+
if args.config:
47+
if not os.path.isfile(args.config):
48+
print(args.config, "can't be found.")
5749
sys.exit(1)
5850
else:
59-
with open(ARGS.config, "r", encoding="utf-8") as args_file:
60-
CONF = yaml.safe_load(args_file)
61-
conf_file = ARGS.config
51+
with open(args.config, "r", encoding="utf-8") as args_file:
52+
conf = yaml.safe_load(args_file)
6253
else:
63-
CONF = yaml.safe_load(__minimal__)
64-
conf_file = "None"
54+
conf = {"verbose": 0}
6555

66-
if CONF.get("verbose", 0):
56+
if conf.get("verbose", 0):
6757
print("Verbose mode enabled", file=sys.stdout)
68-
print("Configuration file:", conf_file, file=sys.stdout)
69-
print(CONF, file=sys.stdout)
70-
71-
except IOError as exception_string:
72-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
73-
sys.exit(1)
74-
58+
print("Configuration file:", args.config, file=sys.stdout)
59+
print(conf, file=sys.stdout)
7560
except KeyError as exception_string:
76-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
61+
print("Exception:", str(exception_string), file=sys.stderr)
7762
sys.exit(1)
78-
7963
except UnboundLocalError as exception_string:
80-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
64+
print("Exception:", str(exception_string), file=sys.stderr)
8165
sys.exit(1)
66+
return conf
8267

83-
return CONF
8468

69+
def get_site_and_agent(conf):
70+
"""
71+
Choose a site and user agent string from the configuration dictionary.
72+
Return the site URL and user agent string.
73+
"""
74+
user_agent = None
8575

86-
def sites():
87-
"""Get site URLs from configuration file or use default."""
88-
global URL
76+
if conf.get("sites"):
77+
url = conf.get("sites", False)
78+
url = random.SystemRandom().choice(url)
79+
else:
80+
url = "duckduckgo.com"
8981

90-
try:
91-
system_random = random.SystemRandom()
92-
URL = CONF.get("sites", False)
93-
if URL:
94-
URL = system_random.choice(CONF["sites"])
95-
else:
96-
URL = __url__
82+
tymely_agent = "tymely/" + __version__
83+
user_agent = conf.get("user_agents", tymely_agent)
84+
if user_agent != tymely_agent:
85+
user_agent = random.SystemRandom().choice(conf["user_agents"])
9786

98-
except UnboundLocalError as exception_string:
99-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
100-
sys.exit(1)
87+
if conf.get("verbose", 0):
88+
print("URL:", url, file=sys.stdout)
89+
print("User agent:", user_agent, file=sys.stdout)
10190

102-
if CONF.get("verbose", 0):
103-
print("URL:", URL, file=sys.stdout)
91+
return url, user_agent
10492

105-
return URL
10693

107-
108-
def user_agents():
109-
"""Get user agents from configuration file or use default."""
110-
global USER_AGENT
94+
def main():
95+
"""
96+
Main function that fetches the current date over HTTPS, sets the system time
97+
if not in test mode, and prints the date if in test mode.
98+
"""
99+
args = arguments()
100+
conf = config(args)
101+
url, user_agent = get_site_and_agent(conf)
111102

112103
try:
113-
system_random = random.SystemRandom()
114-
115-
try:
116-
tymely_version = __version__
117-
tymely_agent = "tymely/" + tymely_version
118-
119-
USER_AGENT = CONF.get("user_agents", tymely_agent)
120-
if USER_AGENT != tymely_agent:
121-
USER_AGENT = system_random.choice(CONF["user_agents"])
122-
123-
except UnboundLocalError as exception_string:
124-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
125-
sys.exit(1)
126-
127-
except UnboundLocalError as exception_string:
128-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
129-
sys.exit(1)
130-
131-
if CONF.get("verbose", 0):
132-
print("User agent:", USER_AGENT, file=sys.stdout)
133-
134-
return USER_AGENT
135-
136-
137-
def connection():
138-
"""Configure TLS and return the response."""
139-
global RESPONSE
140-
141-
tls_cont = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
142-
tls_cont.options |= ssl.OP_NO_SSLv2
143-
tls_cont.options |= ssl.OP_NO_SSLv3
144-
tls_cont.options |= ssl.OP_NO_TLSv1
145-
tls_cont.options |= ssl.OP_NO_TLSv1_1
146-
147-
https = urllib3.PoolManager(
148-
ssl_context=tls_cont,
149-
cert_reqs="CERT_REQUIRED",
150-
ca_certs=certifi.where(),
151-
retries=False,
152-
timeout=1.0,
153-
)
154-
155-
try:
156-
RESPONSE = https.request(
157-
"HEAD",
158-
"https://" + URL,
159-
headers={"User-Agent": USER_AGENT},
104+
response = requests.head(
105+
"https://" + url,
106+
headers={"User-Agent": user_agent},
107+
verify=certifi.where(),
108+
allow_redirects=True,
109+
timeout=1.0,
160110
)
161111

162-
if CONF.get("verbose", 0):
163-
print("Response headers:", RESPONSE.headers, file=sys.stdout)
164-
print("Verify_mode:", tls_cont.verify_mode)
165-
print("TLS context options:", tls_cont.options)
166-
print(tls_cont.get_ciphers())
167-
168-
except urllib3.exceptions.NewConnectionError:
169-
print("Connection failed to", URL, file=sys.stderr)
112+
if conf.get("verbose", 0):
113+
print("Response headers:", response.headers, file=sys.stdout)
114+
print("Verify_mode:", requests.certs.where())
115+
except requests.exceptions.ConnectionError:
116+
print("Connection failed to", url, file=sys.stderr)
170117
sys.exit(1)
171118

172-
except UnboundLocalError as exception_string:
173-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
174-
sys.exit(1)
175-
176-
return RESPONSE
177-
178-
179-
def http_date():
180-
"""Return the http-date from URL using USER_AGENT."""
181119
try:
182-
if RESPONSE.status != 200:
183-
print("Response code", RESPONSE.status, "from", URL, file=sys.stderr)
120+
if response.status_code != 200:
121+
print("Response code", response.status_code, "from", url, file=sys.stderr)
184122
sys.exit(1)
185123

186-
date_str = RESPONSE.headers["Date"]
124+
date_str = response.headers["Date"]
187125

188126
datetime.datetime.strptime(date_str, "%a, %d %b %Y %H:%M:%S GMT").timestamp()
189127

190-
if ARGS.test:
191-
print(date_str + " returned but not set", file=sys.stdout)
128+
if args.test:
129+
print(f"{date_str} from {url} returned but not set", file=sys.stdout)
192130
else:
193131
date_cmd = shutil.which("date")
194132
subprocess.run(
195-
[date_cmd, "-s", date_str], shell=False, check=True # nosec B603
196-
)
197-
133+
[date_cmd, "-s", date_str],
134+
shell=False,
135+
check=True,
136+
) # nosec B603,S603
198137
except UnboundLocalError as exception_string:
199-
print(EXCEPTION_STR, str(exception_string), file=sys.stderr)
138+
print("Exception:", str(exception_string), file=sys.stderr)
200139
sys.exit(1)
201140

202141

203142
if __name__ == "__main__":
204-
arguments()
205-
config()
206-
sites()
207-
user_agents()
208-
connection()
209-
http_date()
143+
main()

0 commit comments

Comments
 (0)