Created
March 22, 2013 19:55
-
-
Save LyndonArmitage/5224257 to your computer and use it in GitHub Desktop.
Speak the top news from reddit.
Runs in an infinite loop.
Quite messy code, makes use of 3 different libraries.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.lyndonarmitage.reddit; | |
import com.omrlnr.jreddit.submissions.Submission; | |
import com.omrlnr.jreddit.submissions.Submissions; | |
import com.omrlnr.jreddit.user.User; | |
import com.sun.speech.freetts.VoiceManager; | |
import org.joda.time.DateTime; | |
import org.joda.time.LocalDateTime; | |
import org.joda.time.LocalTime; | |
import org.joda.time.Period; | |
import java.util.ArrayList; | |
import java.util.LinkedList; | |
/** | |
* Created with IntelliJ IDEA. | |
* Created By: Lyndon Armitage | |
* Date: 04/03/13 | |
*/ | |
public class Main { | |
private static final String USERNAME = "username"; | |
private static final String PASSWORD = "password"; | |
private static final int AMOUNT = 10; // amount of news stories to get | |
// subreddit to get news stories from | |
private static final String NEWS_SUBREDDIT = "worldnews"; | |
// user object | |
private User user; | |
private boolean runMe = true; | |
// http://moderntone.blogspot.co.uk/2013/02/freetts-tutorial.html | |
private static final String VOICE_NAME = "kevin16"; | |
private VoiceManager voiceManager = VoiceManager.getInstance(); | |
private com.sun.speech.freetts.Voice voice; | |
private static final int NEWS_CHECK_INTERVAL = 10; // in minutes | |
private LocalDateTime lastCheckedNews; | |
private static final int NEWS_SPEAK_INTERVAL = 1; // in hours | |
private LocalDateTime lastSpokenNews; | |
public static void main(String[] args) { | |
Main m = new Main(); | |
m.begin(); | |
} | |
public Main() { | |
Runtime.getRuntime().addShutdownHook(new ShutdownHook(this)); | |
//System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory"); | |
user = new User(USERNAME, PASSWORD); | |
voice = voiceManager.getVoice(VOICE_NAME); | |
voice.allocate(); | |
// voice.setRate(100); | |
System.out.println("Lyndon's News Bot started\n---"); | |
voice.startBatch(); | |
voice.speak("Freetts initialised"); | |
voice.speak("The current date is: "); | |
speakDate(); | |
voice.endBatch(); | |
} | |
public void speakDate() { | |
DateTime dateTime = new DateTime(); | |
String month = dateTime.monthOfYear().getAsText(); | |
String day = dateTime.dayOfMonth().getAsText(); | |
String year = dateTime.year().getAsText(); | |
String output = month + ", " + day + ", " + year; | |
//System.out.println(output); | |
voice.speak(output); | |
} | |
public void speakTime() { | |
speakTime(false); | |
} | |
public void speakTime(boolean includeSecs) { | |
LocalTime time = new LocalTime(); | |
String hour = time.hourOfDay().getAsText(); | |
String min = time.minuteOfHour().getAsText(); | |
String secs = time.secondOfMinute().getAsText(); | |
String output = hour + ":" + min; | |
if(includeSecs) { | |
output += ":" + secs; | |
} | |
//System.out.println(output); | |
voice.speak(output); | |
} | |
public void begin() { | |
ArrayList<String> news = getNews(); | |
if(news == null) { | |
System.out.println("Could not connect to Reddit. Exiting program."); | |
voice.speak("Could not connect to Reddit. Exiting program."); | |
runMe = false; | |
} | |
lastCheckedNews = new LocalDateTime(); | |
boolean lastFailed = false; | |
while(runMe) { | |
if(hasElapsedMinutes(lastCheckedNews, NEWS_CHECK_INTERVAL)) { | |
ArrayList<String> temp = getNews(); | |
if(temp == null) { | |
System.out.println("Failed to connect to Reddit, using previous news for now."); | |
lastFailed = true; | |
} | |
else { | |
news = temp; | |
lastFailed = false; | |
} | |
lastCheckedNews = new LocalDateTime(); | |
} | |
if(lastSpokenNews == null || hasElapsedHours(lastSpokenNews, NEWS_SPEAK_INTERVAL)) { | |
voice.startBatch(); | |
voice.speak("The current time is: "); | |
speakTime(); | |
voice.endBatch(); | |
speakNews(news, lastFailed); | |
lastSpokenNews = new LocalDateTime(); | |
} | |
try { | |
Thread.sleep(10000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
private boolean hasElapsedMinutes(LocalDateTime previous, int minuteInterval) { | |
LocalDateTime now = new LocalDateTime(); | |
Period period = new Period(previous, now); | |
if(period.getMinutes() >= minuteInterval) { | |
return true; | |
} | |
return false; | |
} | |
private boolean hasElapsedHours(LocalDateTime previous, int hourInterval) { | |
LocalDateTime now = new LocalDateTime(); | |
Period period = new Period(previous, now); | |
if(period.getHours() >= hourInterval) { | |
return true; | |
} | |
return false; | |
} | |
public void speakNews(ArrayList<String> news, boolean failedToLoadLatest) { | |
LocalDateTime start = new LocalDateTime(); | |
if(!failedToLoadLatest) { | |
System.out.println("Current trending news stories on reddit.com/r/" + NEWS_SUBREDDIT + " are: "); | |
voice.speak("Current trending news stories on reddit dot com/r/" + NEWS_SUBREDDIT + " are: "); | |
} | |
else { | |
System.out.println("Last updated news stories on reddit.com/r/" + NEWS_SUBREDDIT + " are: "); | |
voice.speak("Last updated news stories on reddit dot com/r/" + NEWS_SUBREDDIT + " are: "); | |
} | |
for(int i = 1; i <= news.size(); i ++) { | |
String s = news.get(i-1); | |
System.out.println("Item " + i + ": " + s); | |
voice.startBatch(); | |
voice.speak("Item " + i); | |
voice.speak(s); | |
voice.endBatch(); | |
} | |
System.out.println("Next update will be in: " + NEWS_SPEAK_INTERVAL + "hour" + (NEWS_SPEAK_INTERVAL > 1 ? "s" : "")); | |
voice.speak("Next update will be in: " + NEWS_SPEAK_INTERVAL + "hour" + (NEWS_SPEAK_INTERVAL > 1 ? "s" : "")); | |
LocalDateTime end = new LocalDateTime(); | |
Period duration = new Period(start, end); | |
System.out.println("[" + end.getHourOfDay() + ":" + end.getMinuteOfHour() + ":" + end.getSecondOfMinute() + "] Took " + duration.getMinutes() + " minutes and " + duration.getSeconds() + " seconds"); | |
System.out.println(); // new space in output | |
} | |
private ArrayList<String> getNews() { | |
LocalDateTime start = new LocalDateTime(); | |
System.out.println("[" + start.getHourOfDay() + ":" + start.getMinuteOfHour() + ":" + start.getSecondOfMinute() + "] Loading News this can take some time..."); | |
LinkedList<Submission> subs = null; | |
ArrayList<String> titles = null; | |
String failed = null; | |
try { | |
subs = Submissions.getSubmissions(NEWS_SUBREDDIT, Submissions.Popularity.HOT, Submissions.Page.FRONTPAGE, user); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
failed = "Could not get list of submissions."; | |
} | |
if(failed == null) { | |
titles = new ArrayList<String>(Math.min(subs.size(), AMOUNT)); | |
for(int i = 0; i < Math.min(subs.size(), AMOUNT); i ++) { | |
try { | |
titles.add(subs.get(i).getTitle()); | |
} catch (Exception e) { | |
failed = "Could not get submission title: " + i; | |
e.printStackTrace(); | |
titles = null; | |
break; | |
} | |
} | |
} | |
LocalDateTime end = new LocalDateTime(); | |
Period duration = new Period(start, end); | |
System.out.println("[" + end.getHourOfDay() + ":" + end.getMinuteOfHour() + ":" + end.getSecondOfMinute() + "] Took " + duration.getMinutes() + " minutes and " + duration.getSeconds() + " seconds"); | |
if(failed != null) { | |
System.out.println("Failed to get news: " + failed); | |
} | |
return titles; | |
} | |
private class ShutdownHook extends Thread { | |
private Main owner; | |
private ShutdownHook(Main controller) { | |
owner = controller; | |
} | |
@Override | |
public void run() { | |
if(owner != null && owner.voice != null) { | |
System.out.println("Deallocating voice."); | |
owner.voice.deallocate(); | |
owner = null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment