Author: ssmiweve Date: 2008-09-26 22:52:08 +0200 (Fri, 26 Sep 2008) New Revision: 6849
Added: trunk/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/YoutubeCommandConfig.java trunk/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/YoutubeSearchCommand.java Log: http://sesat.no/scarab/issues/id/SKER4753 Added: trunk/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/YoutubeCommandConfig.java =================================================================== --- trunk/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/YoutubeCommandConfig.java (rev 0) +++ trunk/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/YoutubeCommandConfig.java 2008-09-26 20:52:08 UTC (rev 6849) @@ -0,0 +1,68 @@ +/* Copyright (2008) Schibsted Søk AS + * This file is part of SESAT. + * + * SESAT is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SESAT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with SESAT. If not, see <http://www.gnu.org/licenses/>. + */ +package no.sesat.search.mode.config; + +import no.sesat.search.mode.SearchModeFactory.Context; +import no.sesat.search.mode.config.CommandConfig.Controller; +import no.sesat.search.site.config.AbstractDocumentFactory; +import no.sesat.search.site.config.AbstractDocumentFactory.ParseType; +import org.w3c.dom.Element; + +/** + * Search against googles youtube API + * http://code.google.com/apis/youtube/developers_guide_protocol.html#Searching_for_Videos + */ [EMAIL PROTECTED]("YoutubeSearchCommand") +public class YoutubeCommandConfig extends AbstractXmlSearchConfiguration { + + private String format; + private String racy; + private String sortBy; + + public void setFormat(String format) { + this.format = format; + } + public String getFormat() { + return format; + } + + public void setRacy(String racy) { + this.racy = racy; + } + public String getRacy() { + return racy; + } + + public void setSortBy(String sortBy) { + this.sortBy = sortBy; + } + public String getSortBy() { + return sortBy; + } + + @Override + public YoutubeCommandConfig readSearchConfiguration( + final Element element, + final SearchConfiguration inherit, + final Context context) { + super.readSearchConfiguration(element, inherit, context); + AbstractDocumentFactory.fillBeanProperty(this, inherit, "format", ParseType.String, element, "5"); + AbstractDocumentFactory.fillBeanProperty(this, inherit, "racy", ParseType.String, element, "exclude"); + AbstractDocumentFactory.fillBeanProperty(this, inherit, "sortBy", ParseType.String, element, "relevance"); + return this; + } +} Property changes on: trunk/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/YoutubeCommandConfig.java ___________________________________________________________________ Name: svn:keywords + Id Added: trunk/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/YoutubeSearchCommand.java =================================================================== --- trunk/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/YoutubeSearchCommand.java (rev 0) +++ trunk/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/YoutubeSearchCommand.java 2008-09-26 20:52:08 UTC (rev 6849) @@ -0,0 +1,197 @@ +/* + * Copyright (2008) Schibsted Søk AS + * This file is part of SESAT. + * + * SESAT is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SESAT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with SESAT. If not, see <http://www.gnu.org/licenses/>. + + */ +package no.sesat.search.mode.command; +import java.io.IOException; +import java.io.Serializable; +import java.net.SocketTimeoutException; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; +import no.sesat.search.mode.config.YoutubeCommandConfig; +import no.sesat.search.result.BasicResultItem; +import no.sesat.search.result.BasicResultList; +import no.sesat.search.result.ResultItem; +import no.sesat.search.result.ResultList; +import java.util.ArrayList; +import java.util.List; +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * @see YoutubeCommandConfig + */ +public class YoutubeSearchCommand extends AbstractXmlSearchCommand { + + private static final Logger LOG = Logger.getLogger(YoutubeSearchCommand.class); + + private static final String COMMAND_URL_PATTERN = + "/feeds/api/videos?vq={0}&orderby={1}&start-index={2}&max-results={3}" + +"&format={4}&racy={5}"; + + private Context cxt; + private YoutubeCommandConfig conf; + + + public YoutubeSearchCommand(final Context cxt) { + super(cxt); + this.cxt = cxt; + conf = (YoutubeCommandConfig) cxt.getSearchConfiguration(); + } + + @Override + @SuppressWarnings("static-access") + public ResultList<? extends ResultItem> execute() { + + ResultList<ResultItem> result = new BasicResultList<ResultItem>(); + Document doc; + try { + doc = getXmlResult(); + } catch (SocketTimeoutException ste) { + LOG.error(getSearchConfiguration().getName() + " --> " + ste.getMessage()); + return new BasicResultList<ResultItem>(); + } catch (IOException ex) { + throw new SearchCommandException(ex); + } catch (SAXException ex) { + throw new SearchCommandException(ex); + } + + if(null != doc) { + final Element rootEl = doc.getDocumentElement(); + final Element totalResultsEl = (Element) rootEl.getElementsByTagName("openSearch:totalResults").item(0); + final String totalResults = totalResultsEl.getFirstChild().getNodeValue(); + result.setHitCount(Integer.parseInt(totalResults)); + + final NodeList entryList = rootEl.getElementsByTagName("entry"); + + for(int i = 0; i < entryList.getLength(); i++) { + ResultItem resItem = new BasicResultItem(); + final Element entryEl = (Element) entryList.item(i); + final Element publishedEl = (Element) entryEl.getElementsByTagName("published").item(0); + final String published = publishedEl.getFirstChild().getNodeValue(); + + final NodeList categoryList = entryEl.getElementsByTagName("category"); + List<String> tags = new ArrayList<String>(); + List<String> categories = new ArrayList<String>(); + for(int j = 0; j < categoryList.getLength(); j++) { + final Element categoryEl = (Element) categoryList.item(j); + final String term = categoryEl.getAttribute("term"); + final String label = categoryEl.getAttribute("label"); + if(null != label && label.length() > 0) { + categories.add(term); + } else if(!term.startsWith("http")) { // Filter out junk + tags.add(term); + } + } + + final Element titleEl = (Element) entryEl.getElementsByTagName("title").item(0); + final String title = titleEl.getFirstChild().getNodeValue(); + + final Element contentEl = (Element) entryEl.getElementsByTagName("content").item(0); + final String content = contentEl.getFirstChild().getNodeValue(); + + final Element authorEl = (Element) entryEl.getElementsByTagName("author").item(0); + final Element authorNameEl = (Element) authorEl.getElementsByTagName("name").item(0); + final Element authorUrlEl = (Element) authorEl.getElementsByTagName("uri").item(0); + final String author = authorNameEl.getFirstChild().getNodeValue(); + final String authorUrl = authorUrlEl.getFirstChild().getNodeValue(); + + final Element mediaGroupEl = (Element) entryEl.getElementsByTagName("media:group").item(0); + final Element durationEl = (Element) mediaGroupEl.getElementsByTagName("yt:duration").item(0); + final String duration = durationEl.getAttribute("seconds"); + final String durationMin = String.valueOf(Integer.parseInt(duration) / 60); + final String durationSec = String.valueOf(Integer.parseInt(duration) % 60); + + final NodeList mediaContentList = mediaGroupEl.getElementsByTagName("media:content"); + for(int j = 0; j < mediaContentList.getLength(); j++) { + final Element mediaContentEl = (Element) mediaContentList.item(j); + final String url = mediaContentEl.getAttribute("url"); + final String format = mediaContentEl.getAttribute("yt:format"); + final String type = mediaContentEl.getAttribute("type"); + if(format.equals(conf.getFormat())) { + resItem.addField("videoUrl", url); + resItem.addField("videoType", type); + } + } + + final Element mediaPlayerEl = (Element) mediaGroupEl.getElementsByTagName("media:player").item(0); + final String playerUrl = mediaPlayerEl.getAttribute("url"); + + final List<Map<String,String>> thumbnails = new ArrayList<Map<String,String>>(); + final NodeList mediaThumbnailList = mediaGroupEl.getElementsByTagName("media:thumbnail"); + for(int j = 0; j < mediaThumbnailList.getLength(); j++) { + final Element mediaThumbnailEl = (Element) mediaThumbnailList.item(j); + final String url = mediaThumbnailEl.getAttribute("url"); + final String height = mediaThumbnailEl.getAttribute("height"); + final String width = mediaThumbnailEl.getAttribute("width"); + final String time = mediaThumbnailEl.getAttribute("time"); + final Map<String,String> thumbnail = new HashMap<String,String>(); + thumbnail.put("url", url); + thumbnail.put("height", height); + thumbnail.put("width", width); + thumbnail.put("time", time); + int lastDot = url.lastIndexOf("."); + thumbnail.put("id", url.substring(lastDot-1, lastDot)); + thumbnails.add(thumbnail); + } + + final Element gdRating = (Element)entryEl.getElementsByTagName("gd:rating").item(0); + String ratingNum = null; + String rating = null; + if(null != gdRating) { + ratingNum = gdRating.getAttribute("numRaters"); + rating = gdRating.getAttribute("average"); + } + + resItem.addField("title", title); + resItem.addField("content", content); + resItem.addField("published", published); + resItem.addField("author", author); + resItem.addField("authorUrl", authorUrl); + resItem.addField("duration", duration); + resItem.addField("durationMin", durationMin); + resItem.addField("durationSec", durationSec); + resItem.addObjectField("thumbnails",(Serializable) thumbnails); + resItem.addObjectField("categories",(Serializable) categories); + resItem.addObjectField("tags",(Serializable) tags); + resItem.addField("ratingNum", ratingNum); + resItem.addField("rating", rating); + resItem.addField("youtubeUrl", playerUrl); + + result.addResult(resItem); + } + + } + return result; + } + + protected String createRequestURL() { + + return MessageFormat.format(COMMAND_URL_PATTERN, + datamodel.getQuery().getUtf8UrlEncoded(), + (null != getParameter("userSortBy") ? getParameter("userSortBy") : conf.getSortBy()), + // first result is 1, not 0 + (null != getParameter("offset") ? Integer.parseInt(getParameter("offset"))+1 : "1"), + conf.getResultsToReturn(), + conf.getFormat(), + conf.getRacy()); + } +} \ No newline at end of file Property changes on: trunk/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/YoutubeSearchCommand.java ___________________________________________________________________ Name: svn:keywords + Id _______________________________________________ Kernel-commits mailing list [email protected] http://sesat.no/mailman/listinfo/kernel-commits
