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