Skip to content

Commit

Permalink
Merge pull request #346 from wdpypere/more_cleanup
Browse files Browse the repository at this point in the history
cleanup more code
  • Loading branch information
stdweird authored Nov 16, 2023
2 parents 4253437 + c561f93 commit baf1113
Show file tree
Hide file tree
Showing 30 changed files with 278 additions and 298 deletions.
28 changes: 15 additions & 13 deletions bin/logdaemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,18 @@
@author: Jens Timmerman (Ghent University)
"""
from optparse import OptionParser
from vsc.utils import fancylogger
from vsc.utils.daemon import Daemon

import logging
import os
import pickle
import socket
import sys
import traceback

from optparse import OptionParser
from vsc.utils import fancylogger
from vsc.utils.daemon import Daemon

class LogDaemon(Daemon):
"""
This is the logging daemon, it get a logger and can log to a local file.
Expand Down Expand Up @@ -78,21 +80,21 @@ def start(self):
"""
# Check for a pidfile to see if the daemon already runs
try:
with open(self.pidfile, 'r') as pidf:
with open(self.pidfile, encoding='utf8') as pidf:
pid = int(pidf.read().strip())
except IOError:
except OSError:
pid = None

if pid:
message = "pidfile %s already exist. Daemon already running?\n"
sys.stderr.write(message % self.pidfile)
message = f"pidfile {self.pidfile} already exist. Daemon already running?\n"
sys.stderr.write(message)
sys.exit(1)

# get socket
self.socket_.bind((self.hostname, self.port))
print("FANCYLOG_SERVER_PID=%s" % self.pidfile)
print("FANCYLOG_SERVER=%s:%d" % (socket.gethostname(), self.socket_.getsockname()[-1]))
print("FANCYLOG_SERVER_LOGFILE=%s" % self.logfile)
print(f"FANCYLOG_SERVER_PID={self.pidfile}")
print(f"FANCYLOG_SERVER={socket.gethostname()}:{int(self.socket_.getsockname()[-1])}")
print(f"FANCYLOG_SERVER_LOGFILE={self.logfile}")
sys.stdout.flush()

# Start the daemon
Expand Down Expand Up @@ -122,7 +124,7 @@ def main(args):
Initiate the daemon
"""
# parse options
parser = OptionParser(usage="usage: %s start|stop|restart [options]" % args[0])
parser = OptionParser(usage=f"usage: {args[0]} start|stop|restart [options]")
# general options
parser.add_option("-i", "--ip", dest="host", help="Ip to bind to [default: %default (all)]",
default="", type="string")
Expand Down Expand Up @@ -153,15 +155,15 @@ def main(args):
if len(args) == 2:
if 'stop' == args[1]:
# save state before stopping?
sys.stderr.write("stopping daemon with pidfile: %s\n" % pidfile)
sys.stderr.write(f"stopping daemon with pidfile: {pidfile}\n")
daemon.stop()
elif 'restart' == args[1]:
daemon.restart()
elif 'start' == args[1]:
daemon.start()
else:
sys.stderr.write("Unknown command\n")
sys.stderr.write("usage: %s start|stop|restart [options]\n" % args[0])
sys.stderr.write(f"usage: {args[0]} start|stop|restart [options]\n")
sys.exit(2)
sys.exit(0)
else:
Expand Down
16 changes: 8 additions & 8 deletions lib/vsc/utils/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def daemonize(self):
# exit first parent
sys.exit(0)
except OSError as err:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (err.errno, err.strerror))
sys.stderr.write(f"fork #1 failed: {int(err.errno)} ({err.strerror})\n")
sys.exit(1)

# decouple from parent environment
Expand All @@ -57,13 +57,13 @@ def daemonize(self):
# exit from second parent
sys.exit(0)
except OSError as err:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (err.errno, err.strerror))
sys.stderr.write(f"fork #2 failed: {int(err.errno)} ({err.strerror})\n")
sys.exit(1)

# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
with open(self.stdin, 'r') as sti:
with open(self.stdin) as sti:
os.dup2(sti.fileno(), sys.stdin.fileno())
with open(self.stdout, 'a+') as sto:
os.dup2(sto.fileno(), sys.stdout.fileno())
Expand All @@ -74,7 +74,7 @@ def daemonize(self):
atexit.register(self.delpid)
pid = str(os.getpid())
with open(self.pidfile, 'w+') as pidf:
pidf.write("%s\n" % pid)
pidf.write(f"{pid}\n")

def delpid(self):
os.remove(self.pidfile)
Expand All @@ -85,9 +85,9 @@ def start(self):
"""
# Check for a pidfile to see if the daemon already runs
try:
with open(self.pidfile, 'r') as pidf:
with open(self.pidfile) as pidf:
pid = int(pidf.read().strip())
except IOError:
except OSError:
pid = None

if pid:
Expand All @@ -105,9 +105,9 @@ def stop(self):
"""
# Get the pid from the pidfile
try:
with open(self.pidfile, 'r') as pidf:
with open(self.pidfile) as pidf:
pid = int(pidf.read().strip())
except IOError:
except OSError:
pid = None

if not pid:
Expand Down
31 changes: 16 additions & 15 deletions lib/vsc/utils/dateandtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def __init__(self, tmpdate=None, year=None, month=None, day=None):

def set_details(self):
"""Get first/last day of the month of date"""
class MyCalendar(object):
class MyCalendar:
"""Backport minimal calendar.Calendar code from 2.7 to support itermonthdays in 2.4"""
def __init__(self, firstweekday=0):
self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday
Expand Down Expand Up @@ -132,7 +132,7 @@ def number(self, otherdate):
"""
if self.include is False:
msg = "number: include=False not implemented"
raise(Exception(msg))
raise NotImplementedError(msg)
else:
startdate, enddate = self.get_start_end(otherdate)

Expand All @@ -152,7 +152,7 @@ def interval(self, otherdate):
"""Return time ordered list of months between date and otherdate"""
if self.include is False:
msg = "interval: include=False not implemented"
raise(Exception(msg))
raise NotImplementedError(msg)
else:
nr = self.number(otherdate)
startdate, _ = self.get_start_end(otherdate)
Expand All @@ -166,13 +166,13 @@ def parser(self, txt):
"""Based on strings, return date: eg BEGINTHIS returns first day of the current month"""
supportedtime = (BEGIN, END,)
supportedshift = ['THIS', 'LAST', 'NEXT']
regtxt = r"^(%s)(%s)?" % ('|'.join(supportedtime), '|'.join(supportedshift))
regtxt = rf"^({'|'.join(supportedtime)})({'|'.join(supportedshift)})?"

reseervedregexp = re.compile(regtxt)
reg = reseervedregexp.search(txt)
if not reg:
msg = "parse: no match for regexp %s for txt %s" % (regtxt, txt)
raise(Exception(msg))
msg = f"parse: no match for regexp {regtxt} for txt {txt}"
raise ValueError(msg)

shifttxt = reg.group(2)
if shifttxt is None or shifttxt == 'THIS':
Expand All @@ -182,8 +182,8 @@ def parser(self, txt):
elif shifttxt == 'NEXT':
shift = 1
else:
msg = "parse: unknown shift %s (supported: %s)" % (shifttxt, supportedshift)
raise(Exception(msg))
msg = f"parse: unknown shift {shifttxt} (supported: {supportedshift})"
raise ValueError(msg)

nm = self.get_other(shift)

Expand All @@ -193,8 +193,8 @@ def parser(self, txt):
elif timetxt == END:
res = nm.last
else:
msg = "parse: unknown time %s (supported: %s)" % (timetxt, supportedtime)
raise(Exception(msg))
msg = f"parse: unknown time {timetxt} (supported: {supportedtime})"
raise ValueError(msg)

return res

Expand Down Expand Up @@ -235,16 +235,17 @@ def date_parser(txt):
thisday -= oneday
res = thisday.date()
else:
msg = 'dateparser: unimplemented reservedword %s' % txt
raise(Exception(msg))
msg = f'dateparser: unimplemented reservedword {txt}'
raise NotImplementedError(msg)
else:
try:
datetuple = [int(x) for x in txt.split("-")]
res = date(*datetuple)
except:
msg = ("dateparser: failed on '%s' date txt expects a YYYY-MM-DD format or "
"reserved words %s") % (txt, ','.join(reserveddate))
raise(Exception(msg))
msg = (
f"dateparser: failed on '{txt}' date txt expects a YYYY-MM-DD format or "
f"reserved words {','.join(reserveddate)}")
raise ValueError(msg)

return res

Expand Down
40 changes: 23 additions & 17 deletions lib/vsc/utils/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
@author: Caroline De Brouwer (Ghent University)
"""

INDENT_4SPACES = ' ' * 4


class LengthNotEqualException(ValueError):
pass

Expand All @@ -46,30 +43,39 @@ def mk_rst_table(titles, columns):

title_cnt, col_cnt = len(titles), len(columns)
if title_cnt != col_cnt:
msg = "Number of titles/columns should be equal, found %d titles and %d columns" % (title_cnt, col_cnt)
msg = f"Number of titles/columns should be equal, found {int(title_cnt)} titles and {int(col_cnt)} columns"
raise LengthNotEqualException(msg)

table = []
tmpl = []
line = []
separator_blocks = []
title_items = []
column_widths = []

# figure out column widths
for i, title in enumerate(titles):
# figure out column widths
width = max(map(len, columns[i] + [title]))

# make line template
tmpl.append('{%s:{c}<%s}' % (i, width))
column_widths.append(width)
separator_blocks.append(f"{'='*width}")
title_items.append(f'{title}'.ljust(width))

line = [''] * col_cnt
line_tmpl = INDENT_4SPACES.join(tmpl)
table_line = line_tmpl.format(*line, c='=')
separator_line = " ".join(separator_blocks)

table.append(table_line)
table.append(line_tmpl.format(*titles, c=' '))
table.append(table_line)
# header
table.extend([
separator_line,
" ".join(title_items),
separator_line
])

# rows
for row in map(list, zip(*columns)):
table.append(line_tmpl.format(*row, c=' '))
row_items = []
for i, item in enumerate(row):
row_items.append((item.ljust(column_widths[i])))
table.append(" ".join(row_items))

table.extend([table_line, ''])
# footer
table.extend([separator_line, ''])

return table
4 changes: 2 additions & 2 deletions lib/vsc/utils/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def __init__(self, msg, *args, **kwargs):

# include location info at the end of the message
# for example: "Nope, giving up (at easybuild/tools/somemodule.py:123 in some_function)"
msg = "%s (at %s:%s in %s)" % (msg, relpath, frameinfo[2], frameinfo[3])
msg = f"{msg} (at {relpath}:{frameinfo[2]} in {frameinfo[3]})"

logger = kwargs.get('logger', None)
# try to use logger defined in caller's environment
Expand All @@ -123,4 +123,4 @@ def __init__(self, msg, *args, **kwargs):

getattr(logger, self.LOGGING_METHOD_NAME)(msg)

super(LoggedException, self).__init__(msg)
super().__init__(msg)
2 changes: 1 addition & 1 deletion lib/vsc/utils/frozendict.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __len__(self):
return len(self.__dict)

def __repr__(self):
return '<FrozenDict %s>' % repr(self.__dict)
return f'<FrozenDict {repr(self.__dict)}>'

def __hash__(self):
if self.__hash is None:
Expand Down
14 changes: 7 additions & 7 deletions lib/vsc/utils/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ def getgrouplist(user, groupnames=True):
"""
libc = cdll.LoadLibrary(find_library('libc'))

getgrouplist = libc.getgrouplist
ngetgrouplist = libc.getgrouplist
# max of 50 groups should be enough as first try
ngroups = 50
getgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint * ngroups), POINTER(c_int32)]
getgrouplist.restype = c_int32
ngetgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint * ngroups), POINTER(c_int32)]
ngetgrouplist.restype = c_int32

grouplist = (c_uint * ngroups)()
ngrouplist = c_int32(ngroups)
Expand All @@ -59,15 +59,15 @@ def getgrouplist(user, groupnames=True):
# .encode() is required in Python 3, since we need to pass a bytestring to getgrouplist
user_name, user_gid = user.pw_name.encode(), user.pw_gid

ct = getgrouplist(user_name, user_gid, byref(grouplist), byref(ngrouplist))
ct = ngetgrouplist(user_name, user_gid, byref(grouplist), byref(ngrouplist))
# if a max of 50 groups was not enough, try again with exact given nr
if ct < 0:
getgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint * int(ngrouplist.value)), POINTER(c_int32)]
ngetgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint * int(ngrouplist.value)), POINTER(c_int32)]
grouplist = (c_uint * int(ngrouplist.value))()
ct = getgrouplist(user_name, user_gid, byref(grouplist), byref(ngrouplist))
ct = ngetgrouplist(user_name, user_gid, byref(grouplist), byref(ngrouplist))

if ct < 0:
raise Exception("Could not find groups for %s: getgrouplist returned %s" % (user, ct))
raise ValueError(f"Could not find groups for {user}: getgrouplist returned {ct}")

grouplist = [grouplist[i] for i in range(ct)]
if groupnames:
Expand Down
12 changes: 6 additions & 6 deletions lib/vsc/utils/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(self, mail_host=None, mail_to=None, mail_from=None, mail_subject=No
self.err = err


class VscMail(object):
class VscMail:
"""Class providing functionality to send out mail."""

def __init__(
Expand All @@ -84,7 +84,7 @@ def __init__(
mail_options = ConfigParser()
if mail_config:
logging.info("Reading config file: %s", mail_config)
with open(mail_config, "r") as mc:
with open(mail_config) as mc:
mail_options.read_file(mc)

# we can have cases where the host part is actually host:port
Expand Down Expand Up @@ -238,8 +238,8 @@ def _replace_images_cid(self, html, images):
"""

for im in images:
re_src = re.compile("src=\"%s\"" % im)
(html, count) = re_src.subn("src=\"cid:%s\"" % im, html)
re_src = re.compile(f"src=\"{im}\"")
(html, count) = re_src.subn(f"src=\"cid:{im}\"", html)
if count == 0:
logging.error("Could not find image %s in provided HTML.", im)
raise VscMailError("Could not find image")
Expand Down Expand Up @@ -337,9 +337,9 @@ def sendHTMLMail(

if images is not None:
for im in images:
with open(im, 'r') as image_fp:
with open(im) as image_fp:
msg_image = MIMEImage(image_fp.read(), 'jpeg') # FIXME: for now, we assume jpegs
msg_image.add_header('Content-ID', "<%s>" % im)
msg_image.add_header('Content-ID', f"<{im}>")
msg_alt.attach(msg_image)

msg_root.attach(msg_alt)
Expand Down
Loading

0 comments on commit baf1113

Please sign in to comment.