| 1 |
jeroen |
1154 |
# -*- coding: utf8 -*-
|
| 2 |
hertzog |
344 |
# vim: expandtab
|
| 3 |
|
|
|
| 4 |
jeroen |
1154 |
# Copyright 2002 Raphaël Hertzog
|
| 5 |
hertzog |
352 |
# This file is distributed under the terms of the General Public License
|
| 6 |
|
|
# version 2 or (at your option) any later version.
|
| 7 |
|
|
|
| 8 |
jeroen |
1155 |
import os, os.path, re, rfc822
|
| 9 |
|
|
from email import Utils, Header
|
| 10 |
hertzog |
344 |
|
| 11 |
jeroen |
923 |
from config import root
|
| 12 |
|
|
|
| 13 |
hertzog |
344 |
def save_msg_in_dir(msg, dir, nb=20):
|
| 14 |
|
|
"""Add the message in the directory.
|
| 15 |
|
|
Keep only the nb last messages."""
|
| 16 |
|
|
if not os.path.isdir(dir):
|
| 17 |
|
|
os.makedirs(dir)
|
| 18 |
|
|
if os.path.isfile("%s/%d.txt" % (dir, nb)):
|
| 19 |
|
|
os.unlink("%s/%d.txt" % (dir, nb))
|
| 20 |
|
|
for i in range(nb - 1, 0, -1):
|
| 21 |
|
|
if os.path.isfile("%s/%d.txt" % (dir, i)):
|
| 22 |
|
|
os.rename("%s/%d.txt" % (dir, i), "%s/%d.txt" % (dir, i+1))
|
| 23 |
|
|
f = open("%s/1.txt" % dir, "w")
|
| 24 |
|
|
f.write(msg.as_string())
|
| 25 |
|
|
f.close()
|
| 26 |
hertzog |
416 |
os.chmod("%s/1.txt" % dir, 0664)
|
| 27 |
hertzog |
344 |
|
| 28 |
|
|
def generate_html_msg(src, dst, nb=20):
|
| 29 |
|
|
"""Convert all message in src directory
|
| 30 |
|
|
in HTML messages in dst directory"""
|
| 31 |
|
|
# Clean old attachments first
|
| 32 |
|
|
os.system("find %s -maxdepth 1 -type f -not -name '*.html' | xargs -r rm -f" % dst)
|
| 33 |
|
|
# Regenerate HTML messages
|
| 34 |
|
|
for i in range(nb):
|
| 35 |
|
|
if os.path.isfile("%s/%d.txt" % (src, i + 1)):
|
| 36 |
hertzog |
579 |
os.system("cd %s; /usr/bin/mhonarc -rcfile ../../../../etc/mhonarc.rc -single %s/%d.txt > %d.html 2>/dev/null; chmod 0664 %d.html" % (dst, src, i+1, i+1, i+1))
|
| 37 |
hertzog |
344 |
|
| 38 |
jeroen |
933 |
re_katie_install = re.compile(r"^\S+ \S+ (\S+)")
|
| 39 |
|
|
re_distribution = re.compile(r"^Distribution:\s*(\S+)", re.M)
|
| 40 |
|
|
re_urgency = re.compile(r"^Urgency:\s*(\S+)", re.M)
|
| 41 |
|
|
|
| 42 |
hertzog |
344 |
def extract_info(msg):
|
| 43 |
|
|
"""Extract pseudo-header informations in a dictionnary"""
|
| 44 |
|
|
info = {}
|
| 45 |
|
|
if msg.is_multipart():
|
| 46 |
|
|
for part in msg.walk():
|
| 47 |
|
|
if part.get_type("text/plain") == "text/plain":
|
| 48 |
|
|
body = part.get_payload(None, 1)
|
| 49 |
|
|
break
|
| 50 |
|
|
else:
|
| 51 |
|
|
body = msg.get_payload(None, 1)
|
| 52 |
|
|
lines = body.split("\n", 3)
|
| 53 |
|
|
for i in range(3):
|
| 54 |
|
|
res = re.match(r"^(\w+): (\S+)(.*)", lines[i])
|
| 55 |
|
|
if res:
|
| 56 |
|
|
field = res.group(1).lower()
|
| 57 |
|
|
info[field] = res.group(2)
|
| 58 |
|
|
if field == "subject":
|
| 59 |
|
|
info[field] = info[field] + res.group(3)
|
| 60 |
|
|
else:
|
| 61 |
|
|
break
|
| 62 |
jeroen |
933 |
|
| 63 |
hertzog |
344 |
if not info.has_key("subject"):
|
| 64 |
jeroen |
1155 |
subject = unicode(Header.make_header(Header.decode_header(msg.get("subject"))))
|
| 65 |
jeroen |
933 |
if subject.split()[0] in ['Accepted', 'Installed']:
|
| 66 |
|
|
# katie install mail
|
| 67 |
|
|
version = re_katie_install.search(subject).group(1)
|
| 68 |
jeroen |
937 |
distribution = re_distribution.search(body)
|
| 69 |
|
|
if distribution:
|
| 70 |
|
|
distribution = " in %s" % distribution.group(1)
|
| 71 |
|
|
else:
|
| 72 |
|
|
distribution = ""
|
| 73 |
|
|
urgency = re_urgency.search(body)
|
| 74 |
|
|
if urgency:
|
| 75 |
|
|
urgency = " (%s)" % urgency.group(1)
|
| 76 |
|
|
else:
|
| 77 |
|
|
urgency = ""
|
| 78 |
|
|
subject = "Accepted %s%s%s" % (version, distribution, urgency)
|
| 79 |
jeroen |
933 |
info["subject"] = subject
|
| 80 |
|
|
if msg.has_key("X-PTS-Subject"):
|
| 81 |
|
|
info["subject"] = msg.get("X-PTS-Subject")
|
| 82 |
hertzog |
344 |
if msg.has_key("X-PTS-Url"):
|
| 83 |
|
|
info["url"] = msg.get("X-PTS-Url")
|
| 84 |
|
|
if msg.has_key("X-PTS-Package"):
|
| 85 |
|
|
info["package"] = msg.get("X-PTS-Package")
|
| 86 |
|
|
if msg.has_key("date"):
|
| 87 |
|
|
t = rfc822.parsedate(msg["date"])
|
| 88 |
|
|
if t:
|
| 89 |
|
|
info["date"] = "%04d-%02d-%02d" % (t[0:3])
|
| 90 |
jeroen |
928 |
if msg.has_key("From"):
|
| 91 |
jeroen |
933 |
frm = msg.get("From")
|
| 92 |
|
|
if msg.has_key("X-PTS-From"): frm = msg.get("X-PTS-From")
|
| 93 |
|
|
(realname, address) = rfc822.parseaddr(frm)
|
| 94 |
|
|
if realname:
|
| 95 |
|
|
frm = realname
|
| 96 |
|
|
else:
|
| 97 |
|
|
frm = address
|
| 98 |
jeroen |
934 |
frm = ensure_utf8(frm)
|
| 99 |
|
|
try:
|
| 100 |
jeroen |
1155 |
frm = unicode(Header.make_header(Header.decode_header(frm)))
|
| 101 |
jeroen |
934 |
except UnicodeError:
|
| 102 |
|
|
pass
|
| 103 |
|
|
info["from_name"] = frm
|
| 104 |
hertzog |
344 |
return info
|
| 105 |
|
|
|
| 106 |
jeroen |
923 |
def store_news(pkg, msg):
|
| 107 |
|
|
hash = pkg[0]
|
| 108 |
|
|
if pkg[:3] == "lib":
|
| 109 |
|
|
hash = pkg[:4]
|
| 110 |
|
|
basedir = "%s/base/%s/%s" % (root, hash, pkg)
|
| 111 |
|
|
htmldir = "%s/web/%s/%s" % (root, hash, pkg)
|
| 112 |
|
|
save_msg_in_dir(msg, basedir+"/news", 30)
|
| 113 |
|
|
generate_html_msg(basedir+"/news", htmldir+"/news", 30)
|
| 114 |
|
|
# Synchronize the XML document
|
| 115 |
|
|
f = os.popen("%s/bin/update_news.py" % root, "w")
|
| 116 |
|
|
f.write(pkg+"\n")
|
| 117 |
|
|
f.close()
|
| 118 |
|
|
# Regenerate the HTML page
|
| 119 |
|
|
f = os.popen("%s/bin/generate_html.sh" % root, "w")
|
| 120 |
|
|
f.write(pkg+"\n")
|
| 121 |
|
|
f.close()
|
| 122 |
|
|
|
| 123 |
jeroen |
931 |
|
| 124 |
|
|
def ensure_utf8(str):
|
| 125 |
|
|
try:
|
| 126 |
|
|
str.decode("utf8")
|
| 127 |
|
|
except UnicodeError:
|
| 128 |
|
|
str = str.decode("latin1")
|
| 129 |
|
|
return str
|
| 130 |
|
|
|