1 package org.crazybob.rss; 2 3 import java.util.*; 4 import java.io.*; 5 6 import org.jdom.input.*; 7 8 import org.crazybob.util.NestedException; 9 import org.crazybob.util.EmailUtils; 10 11 15 public class FetchRss { 16 17 FetchRss(String [] args) throws Exception { 18 File lock = new File("fetchrss.lock"); 19 if (!lock.createNewFile()) { 20 System.err.println("Another instance is already running."); 21 System.exit(1); 22 } 23 lock.deleteOnExit(); 24 Map oldChannels = readOldChannels(); 25 pollFeeds(args, oldChannels); 26 writeOldChannels(oldChannels); 27 } 28 29 private void emailDifferences(Channel old, Channel current) 30 throws IOException { 31 Set oldSet = (old == null) ? Collections.EMPTY_SET : 32 new HashSet(old.getItems()); 33 for (Iterator iterator = current.getItems().iterator(); 34 iterator.hasNext();) { 35 Item item = (Item) iterator.next(); 36 if (!oldSet.contains(item)) 37 emailItem(item, EmailUtils.formatFriendlyFrom(current.getTitle())); 38 } 39 } 40 41 private void emailItem(Item item, String channelTitle) throws IOException { 42 Mailer mailer = new Mailer(getProperty("smtp.server")); 43 mailer.send( 44 getProperty("to.address"), 45 getProperty("from.address"), 46 channelTitle + " <" + getProperty("from.address") + ">", 47 item.getTitle(), 48 "<p><a HREF=\"" + item.getLink() + "\">" + 49 item.getLink() + "</a></p><p>" + 50 item.getDescription() + "</p>" 51 ); 52 } 53 54 public void pollFeeds(String [] feeds, Map oldChannels) throws IOException, 55 ClassNotFoundException { 56 boolean blogRollerFlag = false; 57 58 for (int i = 0; i < feeds.length; i++) { 59 blogRollerFlag = (feeds[i].substring(0, 3).equalsIgnoreCase("BR:")) ? true : false; 61 try { 62 String link = feeds[i]; 63 Channel old = (Channel) oldChannels.get(link); 64 UrlLoader.Response response = 65 new UrlLoader().load((blogRollerFlag == false) ? link : link.substring(3), 66 (old == null) ? null : old.getLastModified()); 67 if (response == null) 68 continue; 69 Channel current = new Parser().parse( 70 new SAXBuilder().build(new 71 StringReader(response.getBody()))); 72 73 current.setLastModified(response.getLastModified()); 74 emailDifferences(old, current); 75 oldChannels.put(link, current); 76 77 if (blogRollerFlag) { 78 String [] blogLinks = new String [current.getItems().size()]; 79 int counter = 0; 80 for (Iterator it = current.getItems().iterator(); it.hasNext(); counter++) { 81 Item item = (Item) it.next(); 82 blogLinks[counter] = item.getDescription(); 83 } 84 pollFeeds(blogLinks, oldChannels); 86 } 87 88 } catch (Exception  89 e) { 90 System.err.println("ERROR. URL: " + feeds[i]); 91 e.printStackTrace(); 92 } 93 } 94 } 95 96 private Map readOldChannels() throws IOException, ClassNotFoundException { 97 File channelsFile = getHistoryFile(); 98 99 Map oldChannels = null; 100 if (channelsFile.exists()) { 101 ObjectInputStream oIn = new ObjectInputStream( 102 new FileInputStream(channelsFile) 103 ); 104 oldChannels = (Map) oIn.readObject(); 105 oIn.close(); 106 } 107 if (oldChannels == null) 108 oldChannels = new HashMap(); 109 return oldChannels; 110 } 111 112 private void writeOldChannels(Map oldChannels) throws IOException { 113 File channelsFile = getHistoryFile(); 114 115 ObjectOutputStream oOut = new ObjectOutputStream( 116 new FileOutputStream(channelsFile) 117 ); 118 oOut.writeObject(oldChannels); 119 oOut.flush(); 120 oOut.close(); 121 } 122 123 private File getHistoryFile() { 124 return new File(getProperty("history.file")); 125 } 126 127 private static final Properties properties = new Properties(); 128 129 static { 130 try { 131 properties.load(new FileInputStream("./fetchrss.properties")); 132 } catch (Exception e) { 133 throw NestedException.wrap(e); 134 } 135 } 136 137 static String getProperty(String key) { 138 return properties.getProperty(key); 139 } 140 141 public static void main(String [] args) throws Exception { 142 FetchRss fetchRss = new FetchRss(args); 143 } 144 } 145
| Popular Tags
|