package com.tubeonfire.service;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import com.google.gdata.client.youtube.YouTubeQuery;
import com.google.gdata.client.youtube.YouTubeService;
import com.google.gdata.data.youtube.UserProfileEntry;
import com.google.gdata.data.youtube.VideoEntry;
import com.google.gdata.data.youtube.VideoFeed;
import com.google.gdata.util.ServiceException;
import com.google.gdata.util.ServiceForbiddenException;
import com.tubeonfire.entity.Author;
import com.tubeonfire.entity.Tube;
import com.tubeonfire.util.StringHelper;
public class YoutubeService {
private int limit = 12;
private static YouTubeService service = new YouTubeService(
"tubeilike",
"AI39si4hdZVHF2A5UZmnr1yRZ3mWhwQ9lIqfBggC66zeM3qdfUB1DYAdckeqd6IB24-1WGeCZRKh5KruMxYF9cmcBdq9ymU6IQ");
private int page = 1;
private int totalResult = 0;
private int totalPage = 0;
private boolean isCache = false;
private List<Tube> listResult = new ArrayList<Tube>();
private Tube currentTube = new Tube();
public static Cache cache = null;
private static String cachePrefix = "YoutubeService_";
public static boolean startedCache = false;
private static final Logger log = Logger.getLogger(YoutubeService.class
.getName());
private static boolean tooManyRecentCallError = false;
public static Cache getCache() {
return cache;
}
public static boolean isStartedCache() {
return startedCache;
}
public boolean isCache() {
return isCache;
}
public void setCache(boolean isCache) {
this.isCache = isCache;
}
public Tube getCurrentTube() {
return currentTube;
}
public void setCurrentTube(Tube currentTube) {
this.currentTube = currentTube;
}
public static void setTooManyRecentCallError(boolean tooManyRecentCallError) {
YoutubeService.tooManyRecentCallError = tooManyRecentCallError;
}
public boolean isTooManyRecentCallError() {
return tooManyRecentCallError;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getTotalPage() {
totalPage = totalResult / limit;
if ((totalResult % limit) > 0) {
totalPage += 1;
}
return totalPage;
}
public int getLimit() {
return limit;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getTotalResult() {
return totalResult;
}
public void setTotalResult(int totalResult) {
this.totalResult = totalResult;
}
public List<Tube> getListResult() {
return listResult;
}
public void setListResult(List<Tube> listResult) {
this.listResult = listResult;
}
public static void initCache() {
if (cache == null || !startedCache) {
try {
cache = CacheManager.getInstance().getCacheFactory()
.createCache(Collections.emptyMap());
startedCache = true;
} catch (CacheException e) {
log.warning(e.toString());
e.printStackTrace();
}
}
}
@SuppressWarnings("unchecked")
public void searchByChannel(String channel, boolean all) {
try {
System.out.println("Searching videos from Youtube Channel...");
String prefix = cachePrefix + "channel_" + channel + page;
int start = (page - 1);
if (start < 0) {
start = 0;
}
if (cache != null && cache.containsKey(prefix) && !all) {
listResult = (List<Tube>) cache.get(prefix);
page = (Integer) cache.get(prefix + "page");
totalPage = (Integer) cache.get(prefix + "totalPage");
totalResult = (Integer) cache.get(prefix + "totalResult");
System.out.println("Getting video from cache...");
} else {
if (start < 0) {
start = 0;
}
listResult = new ArrayList<Tube>();
String feedUrl = "http://gdata.youtube.com/feeds/api/videos?max-results="
+ limit
+ "&start-index="
+ ((start * limit) + 1)
+ "&orderby=published" + "&author=" + channel;
VideoFeed videoFeed = service.getFeed(new URL(feedUrl),
VideoFeed.class);
totalResult = videoFeed.getTotalResults();
System.out.println("Found : " + totalResult);
initCache();
for (VideoEntry videoEntry : videoFeed.getEntries()) {
Tube tube = new Tube();
tube = videoEntryToTube(videoEntry);
if (tube != null) {
listResult.add(tube);
}
}
System.out.println("Return : " + listResult.size());
if (!all) {
cache.put(prefix, listResult);
cache.put(prefix + "page", page);
cache.put(prefix + "totalPage", totalPage);
cache.put(prefix + "totalResult", totalResult);
System.out.println("Putting to cache success !");
}
tooManyRecentCallError = false;
}
} catch (MalformedURLException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (IOException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (ServiceForbiddenException e) {
log.warning(e.toString());
e.printStackTrace();
tooManyRecentCallError = true;
} catch (ServiceException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public void searchByKey(String key, boolean hd) {
try {
System.out.println("Searching videos from Youtube...");
String prefix = cachePrefix + "key_" + key + page + hd;
System.out.println("search..." + prefix);
int start = (page - 1);
if (start < 0) {
start = 0;
}
if (cache != null && cache.containsKey(prefix)) {
listResult = (List<Tube>) cache.get(prefix);
page = (Integer) cache.get(prefix + "page");
totalPage = (Integer) cache.get(prefix + "totalPage");
totalResult = (Integer) cache.get(prefix + "totalResult");
isCache = true;
System.out.println("Getting video from cache...");
} else {
listResult = new ArrayList<Tube>();
YouTubeQuery query = new YouTubeQuery(new URL(
"https://gdata.youtube.com/feeds/api/videos"));
query.setFullTextQuery(key);
query.setMaxResults(limit);
query.setStartIndex(limit * start + 1);
query.setSafeSearch(YouTubeQuery.SafeSearch.NONE);
if (hd) {
query.setStringCustomParameter("hd", "true");
}
VideoFeed videoFeed = service.query(query, VideoFeed.class);
totalResult = videoFeed.getTotalResults();
System.out.println("Found : " + totalResult);
initCache();
for (VideoEntry videoEntry : videoFeed.getEntries()) {
Tube tube = videoEntryToTube(videoEntry);
if (tube != null) {
listResult.add(tube);
}
}
System.out.println("Return : " + listResult.size());
cache.put(prefix, listResult);
cache.put(prefix + "page", page);
cache.put(prefix + "totalPage", totalPage);
cache.put(prefix + "totalResult", totalResult);
System.out.println("Putting to cache success !");
tooManyRecentCallError = false;
isCache = false;
}
} catch (MalformedURLException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (IOException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (ServiceForbiddenException e) {
log.warning(e.toString());
e.printStackTrace();
tooManyRecentCallError = true;
} catch (ServiceException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
}
}
public void searchById(String id) {
Tube tub = new Tube();
try {
String prefix = "tubeModel_" + "id_" + id;
listResult = new ArrayList<Tube>();
if (cache != null && cache.containsKey(prefix)) {
tub = (Tube) cache.get(prefix);
currentTube = tub;
listResult.add(tub);
page = 1;
totalPage = 1;
totalResult = 1;
} else {
System.out.println("Searching video from Youtube...");
String videoEntryUrl = "http://gdata.youtube.com/feeds/api/videos/"
+ id;
VideoEntry videoEntry = service.getEntry(
new URL(videoEntryUrl), VideoEntry.class);
tub = videoEntryToTube(videoEntry);
initCache();
currentTube = tub;
listResult.add(tub);
page = 1;
totalPage = 1;
totalResult = 1;
tooManyRecentCallError = false;
}
} catch (MalformedURLException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (IOException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (ServiceForbiddenException e) {
log.warning(e.toString());
e.printStackTrace();
tooManyRecentCallError = true;
} catch (ServiceException e) {
log.warning(e.toString());
e.printStackTrace();
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
}
}
public static Tube searchStaticById(String id) {
Tube tub = new Tube();
try {
String prefix = "";
prefix = cachePrefix + "id_" + id;
if (cache != null && cache.containsKey(prefix)) {
tub = (Tube) cache.get(prefix);
System.out.println("Getting video from cache...");
} else {
System.out.println("Searching video from Youtube...");
String videoEntryUrl = "http://gdata.youtube.com/feeds/api/videos/"
+ id;
VideoEntry videoEntry = service.getEntry(
new URL(videoEntryUrl), VideoEntry.class);
tub = videoEntryToTube(videoEntry);
System.out.println("Putting to cache success !");
tooManyRecentCallError = false;
}
} catch (MalformedURLException e) {
log.warning(e.toString());
e.printStackTrace();
tub = null;
} catch (IOException e) {
log.warning(e.toString());
e.printStackTrace();
tub = null;
} catch (ServiceForbiddenException e) {
log.warning(e.toString());
e.printStackTrace();
tooManyRecentCallError = true;
tub = null;
} catch (ServiceException e) {
log.warning(e.toString());
e.printStackTrace();
tub = null;
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
tub = null;
}
return tub;
}
public static boolean checkChannel(String channel) {
boolean result = false;
try {
System.out.println("Checking channel...");
String feedUrl = "http://gdata.youtube.com/feeds/api/videos?author="
+ channel;
VideoFeed feed = service.getFeed(new URL(feedUrl), VideoFeed.class);
if (feed.getEntries().size() > 0) {
result = true;
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
result = false;
}
return result;
}
public static Author getUserProfile(Author author) {
String profileUrl = author.getUri();
UserProfileEntry profileEntry;
try {
profileEntry = service.getEntry(new URL(profileUrl),
UserProfileEntry.class);
author.setThumbnail(profileEntry.getThumbnail().getUrl());
author.setUserId(profileEntry.getId());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
return author;
}
@SuppressWarnings("unchecked")
public static Tube videoEntryToTube(VideoEntry entry) {
Tube tube = new Tube();
try {
tube.setId(entry.getMediaGroup().getVideoId());
if (entry.getMediaGroup().getThumbnails() != null
&& entry.getMediaGroup().getThumbnails().size() > 1) {
tube.setImageUrl(entry.getMediaGroup().getThumbnails().get(1)
.getUrl());
}
tube.setTitle(entry.getMediaGroup().getTitle()
.getPlainTextContent());
if (entry.getMediaGroup().getDescription() != null) {
tube.setDescription(entry.getMediaGroup().getDescription()
.getPlainTextContent());
}
tube.setAlias(StringHelper.getAliasByLanguage(tube.getTitle()));
tube.setAuthorUrl(entry.getAuthors().get(0).getUri());
if (entry.getMediaGroup().getDuration() != null) {
long duration = entry.getMediaGroup().getDuration();
int hours = (int) (duration / 3600);
int remainder = (int) (duration - hours * 3600);
int minutes = remainder / 60;
remainder = remainder - minutes * 60;
int second = remainder;
tube.setDuration(duration);
tube.setTotalTime(((hours > 0) ? (hours + ":") : "")
+ String.format("%02d", minutes) + ":"
+ String.format("%02d", second));
}
if (entry.getMediaGroup().getCategories() != null
&& entry.getMediaGroup().getCategories().size() > 0) {
tube.setChannelId(StringHelper.replace(entry.getMediaGroup()
.getCategories().get(0).getLabel()));
tube.setChannelName(entry.getMediaGroup().getCategories()
.get(0).getLabel());
}
tube.setPublished(new Date(entry.getPublished().getValue()));
if (entry.getStatistics() != null) {
tube.setYoutubeView(entry.getStatistics().getViewCount());
}
tube.setStatus(1);
initCache();
cache.put(cachePrefix + "id_" + tube.getId(), tube);
return tube;
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
return null;
}
}
}