// Google news parser v2
// Searches Google news XML feeds for terms in the file "search.txt"
//
// Gian Pablo Villamil
// October 8, 2006
// constants
int MAX_TERMS = 20;
int MAX_ITEMS = 20;
String proxyURL = "http://itp.nyu.edu/icm/proxy/proxy.php?url=";
String googleNewsPrefix = "http://news.google.com/news?q=\"";
String googleNewsSuffix = "\"&output=rss";
String searchSource = "http://itp.nyu.edu/~gpv206/icm/week5/google_scope/search.txt";
// String searchSource = "search.txt";
String itemBegin = "- ";
String itemEnd = "
";
String titleBegin = "
";
String titleEnd = "";
PFont newsFont;
int newsFontHeight = 24;
PFont searchFont;
int searchFontHeight = 36;
// variables
int currentItem = 0;
int currentTerm = 0;
String[] searchTerms = new String[MAX_TERMS];
String[] newsItems = new String[MAX_ITEMS];
int numItems ;
String currentTermText;
boolean doneWithNews = true ;
int searchPos = 0;
void setup() {
size(640,480);
smooth();
background(0,0,0);
colorMode(HSB, 100);
newsFont = loadFont("ArialNarrow-Bold-24.vlw");
searchFont = loadFont("ArialNarrow-Bold-36.vlw");
searchTerms = GetSearchTerms(searchSource);
}
void draw() {
// fade the previous iteration by drawing a transparent black rectangle
fill(0,25);
rectMode(CORNER);
rect(0,0,width,height);
// if there are no news items left, then get items for the next search term
if (doneWithNews) {
currentTermText = searchTerms[currentTerm];
GetNews(currentTermText);
currentTerm = (currentTerm + 1) % searchTerms.length;
currentItem = 0;
doneWithNews = false;
// update the position at which to draw the search string
// this is ugly - should be encapsulated within the draw search term function somehow
searchPos = searchPos + searchFontHeight;
if (searchPos > height) {
searchPos = searchFontHeight;
};
delay(400);
}
// draw the current news item, and increment the counter
DrawNewsItem(newsItems[currentItem]);
currentItem++;
DrawSearchTerm(currentTermText, 10, searchPos);
// if we have printed all the news items, then we are done with news for
// that search term, and should move on to the next
if (currentItem >= numItems) {
currentItem = 0;
doneWithNews = true;
}
delay(200);
}
// get the search terms
String[] GetSearchTerms(String Source) {
String searchTerms[] = loadStrings(Source);
return searchTerms;
}
// this is where all the heavy lifting is done
// call Google News RSS feed
// parse it for news items
// and put them in an array of strings
void GetNews(String searchTerm) {
// initialization
numItems = 0;
int currentItem = 0;
int currentPos = 0;
String URLSearchTerm;
// build the URL
URLSearchTerm = URLEncoder.encode(searchTerm); // encode the search term nicely
String queryURL = proxyURL + googleNewsPrefix + URLSearchTerm + googleNewsSuffix ;
String[] lines = loadStrings(queryURL);
String xml = join(lines, " "); // Get rid of the array and make it one very long String
// start the main loop
boolean done = false;
while (!done){
currentPos = xml.indexOf(itemBegin, currentPos); // look for an item begin token
if (currentPos == -1) {
done = true ; // if we didn't find it, then we're done
}
else {
currentPos = currentPos + itemBegin.length(); // skip past the token
currentPos = xml.indexOf(titleBegin, currentPos); // and look for the title
if (currentPos == -1) {
done = true; // and if we don't find that, then we're done
}
else {
currentPos = currentPos + titleBegin.length(); // skip past the title
int endPos = xml.indexOf(titleEnd, currentPos); // and find the end of it
if (endPos == -1) { // if we don't find the end
endPos = xml.length(); // then return until the end of the string
done = true; // and we're done
}
newsItems[currentItem] = xml.substring(currentPos, endPos); // put the substring into newsitems
currentItem++; // and on to the next
}
}
}
numItems = currentItem;
}
// draw the current search term in white, on the side
void DrawSearchTerm(String item, int Xpos, int Ypos) {
textFont(searchFont, searchFontHeight);
textMode(SCREEN);
colorMode(RGB);
fill(255,255,255);
text(item,Xpos,Ypos);
}
// draw a news item at a random position and color on the screen
void DrawNewsItem(String item) {
// clean up the incoming string
// I'll put some code in here to get rid of the & nonsense
item = unescapeHTML(item, 0); // unescape does not recurse properly, hence is
item = unescapeHTML(item, 0); // repeated twice to clean up correctly
// set up font stuff
textFont(newsFont, newsFontHeight);
textMode(SCREEN);
colorMode(HSB);
fill(RandomColor());
int textXpos = int(random(width - 300));
int textYpos = int(random(height - 2*newsFontHeight))+2*newsFontHeight;
text(item, textXpos, textYpos, 300, 300);
}
// returns a random color
color RandomColor() {
return color(random(100), 100,100); // random is not really random
}