Much better filename creation for the tmp file
[rss2maildir.git] / rss2maildir.py
1 #!/usr/bin/python
2
3 import mailbox
4 import sys
5 import os
6 import stat
7 import urllib
8
9 import feedparser
10
11 import email
12
13 import datetime
14 import random
15 import string
16
17 from optparse import OptionParser
18 from ConfigParser import SafeConfigParser
19
20
21 def parse_and_deliver(maildir, url, statedir):
22     md = mailbox.Maildir(maildir)
23     fp = feedparser.parse(url)
24     for item in fp["items"]:
25         # things that we need in the message
26         msg = email.message_from_string("")
27         msg.add_header("Subject", item["title"])
28         msg.set_unixfrom("Brett Parker <iDunno@sommitrealweird.co.uk>")
29         msg.add_header("Date", datetime.datetime(*item["created_parsed"][0:6]).strftime("%a, %e %b %Y %T -0000"))
30         msg.add_header("To", url)
31         msg.set_payload(item["content"][0]["value"])
32         msg.set_charset("utf8")
33         msg.set_default_type("text/plain")
34
35         # start by working out the filename we should be writting to, we do
36         # this following the normal maildir style rules
37         fname = str(os.getpid()) + "".join([random.choice(string.ascii_letters + string.digits) for a in range(0,10)]) + datetime.datetime.now().strftime('%s')
38         fn = os.path.join(maildir, "tmp", fname)
39         fh = open(fn, "w")
40         fh.write(msg.as_string())
41         fh.close()
42         # now move it in to the new directory
43         newfn = os.path.join(maildir, "new", fname)
44         os.link(fn, newfn)
45         os.unlink(fn)
46
47 # first off, parse the command line arguments
48
49 oparser = OptionParser()
50 oparser.add_option(
51     "-c", "--conf", dest="conf",
52     help="location of config file"
53     )
54 oparser.add_option(
55     "-s", "--statedir", dest="statedir",
56     help="location of directory to store state in"
57     )
58
59 (options, args) = oparser.parse_args()
60
61 # check for the configfile
62
63 configfile = None
64
65 if options.conf != None:
66     # does the file exist?
67     try:
68         os.stat(options.conf)
69         configfile = options.conf
70     except:
71         # should exit here as the specified file doesn't exist
72         sys.stderr.write("Config file %s does not exist. Exiting.\n" %(options.conf,))
73         sys.exit(2)
74 else:
75     # check through the default locations
76     try:
77         os.stat("%s/.rss2maildir.conf" %(os.environ["HOME"],))
78         configfile = "%s/.rss2maildir.conf" %(os.environ["HOME"],)
79     except:
80         try:
81             os.stat("/etc/rss2maildir.conf")
82             configfile = "/etc/rss2maildir.conf"
83         except:
84             sys.stderr.write("No config file found. Exiting.\n")
85             sys.exit(2)
86
87 # Right - if we've got this far, we've got a config file, now for the hard
88 # bits...
89
90 scp = SafeConfigParser()
91 scp.read(configfile)
92
93 maildir_root = "RSSMaildir"
94 state_dir = "state"
95
96 if options.statedir != None:
97     state_dir = options.statedir
98     try:
99         mode = os.stat(state_dir)[stat.ST_MODE]
100         if not stat.S_ISDIR(mode):
101             sys.stderr.write("State directory (%s) is not a directory\n" %(state_dir))
102             sys.exit(1)
103     except:
104         # try to make the directory
105         try:
106             os.mkdir(state_dir)
107         except:
108             sys.stderr.write("Couldn't create statedir %s" %(state_dir))
109             sys.exit(1)
110 elif scp.has_option("general", "state_dir"):
111     new_state_dir = scp.get("general", "state_dir")
112     try:
113         mode = os.stat(state_dir)[stat.ST_MODE]
114         if not stat.S_ISDIR(mode):
115             sys.stderr.write("State directory (%s) is not a directory\n" %(state_dir))
116             sys.exit(1)
117     except:
118         # try to create it
119         try:
120             os.mkdir(new_state_dir)
121             state_dir = new_state_dir
122         except:
123             sys.stderr.write("Couldn't create state directory %s\n" %(new_state_dir))
124             sys.exit(1)
125
126 if scp.has_option("general", "maildir_root"):
127     maildir_root = scp.get("general", "maildir_root")
128
129 try:
130     mode = os.stat(maildir_root)[stat.ST_MODE]
131     if not stat.S_ISDIR(mode):
132         sys.stderr.write("Maildir Root %s is not a directory\n" %(maildir_root))
133         sys.exit(1)
134 except:
135     try:
136         os.mkdir(maildir_root)
137     except:
138         sys.stderr.write("Couldn't create Maildir Root %s\n" %(maildir_root))
139         sys.exit(1)
140
141 feeds = scp.sections()
142 try:
143     feeds.remove("general")
144 except:
145     pass
146
147 for section in feeds:
148     # check if the directory exists
149     maildir = None
150     try:
151         maildir = scp.get(section, "maildir")
152     except:
153         maildir = section
154
155     maildir = urllib.urlencode(((section, maildir),)).split("=")[1]
156     maildir = os.path.join(maildir_root, maildir)
157
158     try:
159         exists = os.stat(maildir)
160         if stat.S_ISDIR(exists[stat.ST_MODE]):
161             # check if there's a new, cur and tmp directory
162             try:
163                 mode = os.stat(os.path.join(maildir, "cur"))[stat.ST_MODE]
164             except:
165                 os.mkdir(os.path.join(maildir, "cur"))
166                 if not stat.S_ISDIR(mode):
167                     sys.stderr.write("Broken maildir: %s\n" %(maildir))
168             try:
169                 mode = os.stat(os.path.join(maildir, "tmp"))[stat.ST_MODE]
170             except:
171                 os.mkdir(os.path.join(maildir, "tmp"))
172                 if not stat.S_ISDIR(mode):
173                     sys.stderr.write("Broken maildir: %s\n" %(maildir))
174             try:
175                 mode = os.stat(os.path.join(maildir, "new"))[stat.ST_MODE]
176                 if not stat.S_ISDIR(mode):
177                     sys.stderr.write("Broken maildir: %s\n" %(maildir))
178             except:
179                 os.mkdir(os.path.join(maildir, "new"))
180         else:
181             sys.stderr.write("Broken maildir: %s\n" %(maildir))
182     except:
183         try:
184             os.mkdir(maildir)
185         except:
186             sys.stderr.write("Couldn't create root maildir %s\n" %(maildir))
187             sys.exit(1)
188         try:
189             os.mkdir(os.path.join(maildir, "new"))
190             os.mkdir(os.path.join(maildir, "cur"))
191             os.mkdir(os.path.join(maildir, "tmp"))
192         except:
193             sys.stderr.write("Couldn't create required maildir directories for %s\n" %(section,))
194             sys.exit(1)
195
196     # right - we've got the directories, we've got the section, we know the
197     # url... lets play!
198
199     parse_and_deliver(maildir, section, state_dir)