Dirk Mueller ea3b07568c Fix E203
This fixes incorrect whitespacing inside dictionaries.
2019-12-10 08:54:32 +01:00

148 lines
4.6 KiB
Python
Executable File

#!/usr/bin/python3
import http.client
import re
from urllib.parse import urlparse, urljoin
import smtplib
from email.mime.text import MIMEText
import os
import sys
import email.utils
import argparse
import logging
import yaml
from xdg.BaseDirectory import save_data_path
from collections import namedtuple
logger = logging.getLogger()
# map of default config entries
config_defaults = {
'sender': 'noreply@opensuse.org',
'to': 'opensuse-factory@opensuse.org',
'relay': 'relay.suse.de',
'changesfile': "Changes.{version}.txt",
}
def _load_config(handle = None):
d = config_defaults
y = yaml.safe_load(handle) if handle is not None else {}
keys = set(d.keys()) | set(y.keys())
for key in keys:
y[key] = y.get(key, d.get(key, None))
return y
parser = argparse.ArgumentParser(description="Announce new snapshots")
parser.add_argument("--dry", action="store_true", help="dry run")
parser.add_argument("--debug", action="store_true", help="debug output")
parser.add_argument("--verbose", action="store_true", help="verbose")
parser.add_argument("--from", dest='sender', metavar="EMAIL", help="sender email address")
parser.add_argument("--to", metavar="EMAIL", help="recepient email address")
parser.add_argument("--relay", metavar="RELAY", help="SMTP relay server address")
parser.add_argument("--version", metavar="VERSION", help="announce specific version")
parser.add_argument("--config", metavar="FILE", type=argparse.FileType(), help="YAML config file to override defaults")
parser.add_argument("--dump-config", action="store_true", help="dump built in YAML config")
parser.add_argument("--state-file", metavar="STATE_FILE", help="Yaml config of previously announced", required=True)
options = parser.parse_args()
# Set logging configuration
logging.basicConfig(level=logging.DEBUG if options.debug
else logging.INFO,
format='%(asctime)s - %(module)s:%(lineno)d - %(levelname)s - %(message)s')
state = {}
try:
with open(options.state_file, 'r') as file:
state = yaml.safe_load(file)
if state is None:
state = {}
except IOError:
pass
config = _load_config(options.config)
if options.sender:
config['sender'] = options.sender
if options.to:
config['to'] = options.to
if options.relay:
config['relay'] = options.relay
if options.dump_config:
print(yaml.dump(config, default_flow_style=False))
sys.exit(0)
if not config['sender'] or not config['to'] or not config['relay']:
logger.error("need to specify --from and --to and --relay")
sys.exit(1)
if not options.version:
u = urlparse(urljoin(config['url'], config['iso']))
conn = http.client.HTTPConnection(u.hostname, 80)
conn.request('HEAD', u.path)
res = conn.getresponse()
if res.status != 302:
raise Exception("http fail: %s %s" % (res.status, res.reason))
loc = res.getheader('location')
if loc is None:
raise Exception("empty location!")
m = re.search(r'(?:Snapshot|Build)([\d.]+)-Media', loc)
if m is None:
raise Exception("failed to parse %s" % loc)
version = m.group(1)
logger.debug("found version %s", version)
else:
version = options.version
if state.get(config['name'], None) == version:
logger.info("version unchanged, exit")
sys.exit(0)
url = urljoin(config['url'], config['changesfile'].format(version=version))
# take the safer route
url = url.replace('download.opensuse.org', 'downloadcontent.opensuse.org')
u = urlparse(url)
conn = http.client.HTTPConnection(u.hostname, 80)
conn.request('HEAD', u.path)
res = conn.getresponse()
if res.status == 302:
loc = res.getheader('location')
if loc is None:
raise Exception("empty location!")
u = urlparse(loc)
conn = http.client.HTTPConnection(u.hostname, 80)
conn.request('GET', u.path)
res = conn.getresponse()
if res.status != 200:
raise Exception("http %s fail: %s %s" % (u, res.status, res.reason))
txt = res.read().decode('latin1')
if '====' not in txt:
logger.error("no changes or file corrupt? not sending anything")
sys.exit(1)
msg = MIMEText(config['bodytemplate'].format(version=version, text=txt))
msg['Subject'] = config['subject'].format(version=version)
msg['From'] = config['sender']
msg['To'] = config['to']
msg['Mail-Followup-To'] = config['to']
msg['Date'] = email.utils.formatdate(localtime=1)
msg['Message-ID'] = email.utils.make_msgid()
if options.dry:
print("sending ...")
print(msg.as_string())
else:
logger.info("announcing version {}".format(version))
s = smtplib.SMTP(config['relay'])
s.send_message(msg)
s.quit()
state[config['name']] = version
with open(options.state_file, 'w') as file:
yaml.dump(state, file)