package tainavi.plugintv;\r
\r
import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
import java.io.UnsupportedEncodingException;\r
import java.net.URLDecoder;\r
import java.util.ArrayList;\r
import java.util.regex.Matcher;\r
import java.util.regex.Pattern;\r
\r
-import tainavi.AreaCode;\r
-import tainavi.Center;\r
-import tainavi.CommonUtils;\r
-import tainavi.ContentIdDIMORA;\r
-import tainavi.ProgDateList;\r
-import tainavi.ProgDetailList;\r
-import tainavi.ProgList;\r
-import tainavi.TVProgram;\r
-import tainavi.TVProgramUtils;\r
-import tainavi.TVProgram.ProgGenre;\r
-import tainavi.TVProgram.ProgOption;\r
-import tainavi.TVProgram.ProgSubgenre;\r
-import tainavi.TVProgram.ProgSubtype;\r
-import tainavi.TVProgram.ProgType;\r
+import tainavi.*;\r
\r
+import javax.xml.parsers.DocumentBuilder;\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.NamedNodeMap;\r
+import org.w3c.dom.Node;\r
+import org.w3c.dom.NodeList;\r
+import org.xml.sax.SAXException;\r
\r
public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProgram,Cloneable {\r
\r
getDate(pl);\r
\r
//\r
+ String xtype = (pl.CenterId.startsWith(CHID_PREFIX_BS) || pl.CenterId.startsWith(CHID_PREFIX_CS)) ? XTYPE_BASIC : XTYPE_PREMIUM;\r
+ String chid = xtype == XTYPE_BASIC ? pl.CenterId : pl.CenterId.replaceFirst("^"+CHID_PREFIX_PR, "");\r
+ //String cacheFileExt = xtype == XTYPE_BASIC ? "xml" : "txt";\r
+ String cacheFileExt = "txt";\r
+\r
for ( int dtidx=0; dtidx<pl.pdate.size(); dtidx++ ) {\r
//\r
GregorianCalendar cal = CommonUtils.getCalendar(pl.pdate.get(dtidx).Date);\r
- \r
+ String dt = CommonUtils.getDateYMD(cal);\r
+\r
boolean isNextpageExist = true;\r
for ( int pgidx=1; isNextpageExist; pgidx++ ) {\r
\r
final String progCacheFile = \r
- pgidx == 1 ? String.format("%s%sSKP2012_%s_%d.txt", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH)) :\r
- String.format("%s%sSKP2012_%s_%d_%d.txt", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH),pgidx);\r
+ pgidx == 1 ? String.format("%s%sSKP2012_%s_%d.%s", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH), cacheFileExt) :\r
+ String.format("%s%sSKP2012_%s_%d_%d.%s", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH),pgidx, cacheFileExt);\r
//\r
File f = new File(progCacheFile);\r
if (force == true ||\r
(f.exists() == true && isCacheOld(progCacheFile) == true) ||\r
(f.exists() == false && isCacheOld(null) == true)) {\r
//\r
- String xtype = (pl.CenterId.startsWith(CHID_PREFIX_BS) || pl.CenterId.startsWith(CHID_PREFIX_CS)) ? XTYPE_BASIC : XTYPE_PREMIUM;\r
- String chid = xtype != XTYPE_PREMIUM ? pl.CenterId : pl.CenterId.replaceFirst("^"+CHID_PREFIX_PR, "");\r
- String dt = CommonUtils.getDateYMD(cal);\r
String url = "http://bangumi.skyperfectv.co.jp/"+xtype+"/channel:"+chid+"/date:"+dt.substring(2)+"/";\r
if ( pgidx > 1 ) {\r
url += "?p="+pgidx;\r
}\r
+\r
/*\r
- if ( pl.ChId.length() == 0 ) {\r
- url = "http://bangumi.skyperfectv.co.jp/api/version:3/search/date:"+dt.substring(2)+"/channel:"+pl.CenterId+"/?api_key=336eec3423";\r
+ if ( xtype == XTYPE_BASIC ) {\r
+ url = "http://www.skyperfectv.co.jp/xml/"+dt+"_"+chid.replaceFirst("^[^0-9]+","")+".xml?_="+System.currentTimeMillis();\r
}\r
else {\r
- url = "http://www.skyperfectv.co.jp/xml/"+dt+"_"+pl.ChId.substring(2)+".xml";\r
+ url = "http://bangumi.skyperfectv.co.jp/"+xtype+"/channel:"+chid+"/date:"+dt.substring(2)+"/";\r
+ if ( pgidx > 1 ) {\r
+ url += "?p="+pgidx;\r
+ }\r
}\r
*/\r
+\r
webToFile(url, progCacheFile, thisEncoding);\r
\r
printProgress("(オンライン)を取得しました", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), url);\r
printProgress("(キャッシュ)がみつかりません", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), progCacheFile);\r
break;\r
}\r
- \r
+\r
String response = CommonUtils.read4file(progCacheFile, true);\r
if ( response == null || ! response.matches("^.*<a href=\"\\?p=\\d+[^>]+?>次.*$") ) {\r
isNextpageExist = false;\r
}\r
- \r
+\r
// 番組リストの追加\r
try {\r
getPrograms(pl, dtidx, response);\r
/*\r
- if ( pl.ChId.length() == 0 ) {\r
- getPrograms(pl, i, response);\r
+ if ( xtype == XTYPE_BASIC ) {\r
+ getPrograms_basic(pl, dtidx, progCacheFile);\r
+ isNextpageExist = false;\r
}\r
else {\r
- getPrograms_basic(pl, i, response);\r
+ String response = CommonUtils.read4file(progCacheFile, true);\r
+\r
+ if ( xtype != XTYPE_BASIC ) {\r
+ if ( response == null || ! response.matches("^.*<a href=\"\\?p=\\d+[^>]+?>次.*$") ) {\r
+ isNextpageExist = false;\r
+ }\r
+ }\r
+\r
+ getPrograms(pl, dtidx, response);\r
}\r
*/\r
}\r
private void printProgress(String msg, int count, int pgidx, int countMax, String center, int date, String uri) {\r
reportProgress(String.format("%s %s: (%d/%d) page=%d %s[%d日] %s", getTVProgramId(), msg, count, countMax, pgidx, center, date, uri));\r
}\r
+\r
//\r
private void getDate(ProgList pl) {\r
// 日付の処理\r
// 隙間を埋めつつ一個にまとめる\r
ProgDateList all = new ProgDateList();\r
all.pdetail = new ArrayList<ProgDetailList>();\r
+ String prevStart = null;\r
+ String prevEnd = null;\r
for ( ProgDateList pcl : pcenter ) {\r
for ( ProgDetailList pdl : pcl.pdetail ) {\r
- if ( all.row == 0 ) {\r
- String prevend = CommonUtils.getDateTime(CommonUtils.getCalendar(pcenter.get(0).Date+" 05:00"));\r
- if ( prevend.compareTo(pdl.startDateTime) < 0 ) {\r
+ if ( prevEnd == null ) {\r
+ prevEnd = CommonUtils.getDateTime(CommonUtils.getCalendar(pcenter.get(0).Date+" 05:00"));\r
+ if ( prevEnd.compareTo(pdl.startDateTime) < 0 ) {\r
// 最前列の情報がとれなかった\r
- addEnmptyInfo(all, prevend, pdl.startDateTime);\r
+ addEmptyInfo(all, prevEnd, pdl.startDateTime);\r
}\r
}\r
else {\r
- ProgDetailList prevpdl = all.pdetail.get(all.pdetail.size()-1);\r
- if ( prevpdl.startDateTime.equals(pdl.startDateTime) ) {\r
+ if ( prevStart.equals(pdl.startDateTime) ) {\r
// 重複は破棄\r
continue;\r
}\r
- else if ( prevpdl.endDateTime.compareTo(pdl.startDateTime) < 0 ) {\r
+ else if ( prevEnd.compareTo(pdl.startDateTime) < 0 ) {\r
// 隙間を埋める\r
- addEnmptyInfo(all, prevpdl.endDateTime, pdl.startDateTime);\r
+ addEmptyInfo(all, prevEnd, pdl.startDateTime);\r
}\r
}\r
+\r
+ prevStart = pdl.startDateTime;\r
+ prevEnd = pdl.endDateTime;\r
+\r
all.pdetail.add(pdl);\r
all.row += pdl.length;\r
}\r
String da = CommonUtils.getDateTime(cz);\r
cz.add(Calendar.DATE, 1);\r
String dz = CommonUtils.getDateTime(cz);\r
- if ( CommonUtils.isOverlap(pdl.startDateTime, pdl.endDateTime, da, dz, true) ) {\r
+ String endDateTime = pdl.endDateTime.length() > 0 ? pdl.endDateTime : CommonUtils.getDateTime(CommonUtils.getCalendar(pdl.startDateTime, pdl.length * 60));\r
+ if ( CommonUtils.isOverlap(pdl.startDateTime, endDateTime, da, dz, true) ) {\r
if ( cnt++ == 0 ) {\r
pcl.pdetail.add(pdl);\r
}\r
// 1日の合計分数を足し合わせる\r
for ( ProgDetailList pdl : pcl.pdetail ) {\r
String da = (pcl.row == 0) ? pcl.Date+" 05:00" : pdl.startDateTime;\r
- pdl.length = (int)(CommonUtils.getCompareDateTime(pdl.endDateTime, da)/60000L);\r
+ if ( pdl.endDateTime.length() > 0 ) {\r
+ pdl.length = (int)(CommonUtils.getCompareDateTime(pdl.endDateTime, da)/60000L);\r
+ }\r
pcl.row += pdl.length;\r
}\r
// おしりがとどかない場合(デメリット:これをやると、サイト側のエラーで欠けてるのか、そもそも休止なのかの区別がつかなくなる)\r
GregorianCalendar cz = (GregorianCalendar) ca.clone();\r
ca.add(Calendar.MINUTE, pcl.row);\r
cz.add(Calendar.MINUTE, 24*60);\r
- addEnmptyInfo(pcl, CommonUtils.getDateTime(ca), CommonUtils.getDateTime(cz));\r
+ addEmptyInfo(pcl, CommonUtils.getDateTime(ca), CommonUtils.getDateTime(cz));\r
}\r
}\r
}\r
\r
\r
/**\r
- * こちらは番組IDがとれる代わりに出演者情報がとれなくなるので保留とする\r
+ * こちらは50番組/日までしかとれないため、保留\r
*/\r
- private void getPrograms_basic(ProgList pl, int dtidx, String response) {\r
- \r
- Matcher ma = Pattern.compile("<SIInformation(.+?)</SIInformation>",Pattern.DOTALL).matcher(response);\r
- while ( ma.find() ) {\r
- Matcher mb = Pattern.compile("eventId=\"(.+?)\".+?broadCastStartDate=\"(\\d{8})(\\d{4})",Pattern.DOTALL).matcher(ma.group(1));\r
- if ( mb.find() ) {\r
- \r
- }\r
- /*\r
- mb = Pattern.compile("<(.+?)>(.+?)</\\1>",Pattern.DOTALL).matcher(ma.group(1));\r
- while ( mb.find() ) {\r
- if ( mb.group(1).equals("ChannelName") ) {\r
- \r
+ private void getPrograms_basic(ProgList pl, int dtidx, String filename) throws ParserConfigurationException, IOException, SAXException {\r
+\r
+ ProgDateList pcl = pl.pdate.get(dtidx);\r
+\r
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
+ DocumentBuilder db = dbf.newDocumentBuilder();\r
+\r
+ Document parseDoc = db.parse(new FileInputStream(filename));\r
+\r
+ NodeList list = parseDoc.getElementsByTagName("SIInformation");\r
+ for ( int i=0; i < list.getLength(); i++ ) {\r
+ ProgDetailList pdl = new ProgDetailList();\r
+ Node node = list.item(i);\r
+ try {\r
+ NamedNodeMap attributes = node.getAttributes();\r
+ String startValue = attributes.getNamedItem("broadCastStartDate").getNodeValue().substring(8,12);\r
+ pdl.start = startValue.substring(0,2) + ":" + startValue.substring(2);\r
+ String endValue = attributes.getNamedItem("broadCastEndDate").getNodeValue().substring(8,12);\r
+ pdl.end = endValue.substring(0,2) + ":" + endValue.substring(2);\r
+ pdl.length = CommonUtils.getRecMinVal(pdl.start, pdl.end);\r
+\r
+ int onid = Integer.decode(attributes.getNamedItem("networkId").getNodeValue());\r
+ //Node tsid = attributes.getNamedItem("").getNodeValue();\r
+ int sid = Integer.decode(attributes.getNamedItem("serviceId").getNodeValue());\r
+ Node evidNode = attributes.getNamedItem("eventId");\r
+ if ( evidNode != null ) {\r
+ int evid = Integer.decode(evidNode.getNodeValue());\r
+ pdl.progid = ContentIdEDCB.getContentId(onid, 0, sid, evid);\r
}\r
- else if ( mb.group(1).equals("Title") ) {\r
- \r
+\r
+ pdl.title = queryNode(node, "Title").getTextContent();\r
+\r
+ Node detailNode = queryNode(node, "Synopsis");\r
+ if ( detailNode != null ) {\r
+ pdl.detail = detailNode.getTextContent();\r
}\r
- else if ( mb.group(1).equals("Synopsis") ) {\r
- \r
+\r
+ Node genreNode = queryNode(node, "Genres");\r
+ if ( genreNode != null ) {\r
+ NamedNodeMap genreAttributes = queryNode(genreNode, "Genre").getAttributes();\r
+ String majorGenreId = genreAttributes.getNamedItem("majorGenreId").getNodeValue();\r
+ String minorGenreId = genreAttributes.getNamedItem("minorGenreId").getNodeValue();\r
+ pdl.genre = ProgGenre.getByIEPG(majorGenreId.substring(majorGenreId.length()-1));\r
+ pdl.subgenre = ProgSubgenre.getByIEPG(pdl.genre, minorGenreId.substring(minorGenreId.length() - 1));\r
}\r
- else if ( mb.group(1).equals("Genres") ) {\r
- Matcher mc = Pattern.compile("<Genre majorGenreId=\".+?\" minorGenreId=\".+?\"",Pattern.DOTALL).matcher(mb.group(2));\r
- while ( mc.find() ) {\r
- \r
+ if ( pdl.genre == null || pdl.subgenre == null ) {\r
+ pdl.genre = ProgGenre.NOGENRE;\r
+ pdl.subgenre = ProgSubgenre.NOGENRE_ETC;\r
+ }\r
+\r
+ Node actorNode = queryNode(node, "ActorInformation");\r
+ if ( actorNode != null ) {\r
+ if ( pdl.detail == null ) {\r
+ pdl.detail = "";\r
+ }\r
+ else if ( pdl.detail.length() > 0 ) {\r
+ pdl.detail += "\n";\r
+ }\r
+\r
+ String prePostValue = "";\r
+ ArrayList<Node> nodes = queryNodes(queryNode(actorNode, "Actors"), "Actor");\r
+ for ( Node actor : nodes ) {\r
+ Node post = queryNode(actor, "Post");\r
+ Node name = queryNode(actor, "Name");\r
+ if ( post != null && name != null ) {\r
+ String postValue = post.getTextContent();\r
+ if ( ! postValue.equals(prePostValue) ) {\r
+ pdl.detail += "\n" + postValue + ":";\r
+ prePostValue = postValue;\r
+ }\r
+ pdl.detail += name.getTextContent() + "、";\r
+ }\r
}\r
+\r
+ pdl.detail = pdl.detail.replaceFirst("、$","");\r
}\r
+\r
+ Node copyRights = queryNode(node, "CopyRights");\r
+ if ( copyRights != null ) {\r
+ pdl.detail += "\n\n"+copyRights.getTextContent();\r
+ }\r
+\r
+ // タイトルから各種フラグを分離する\r
+ doSplitFlags(pdl, nf);\r
+\r
+ // サブタイトル分離(ポインタを活用してメモリを節約する)\r
+ doSplitSubtitle(pdl);\r
+\r
+ // その他フラグ\r
+ pdl.extension = false;\r
+ pdl.nosyobo = false;\r
+\r
+ pcl.pdetail.add(pdl);\r
+ }\r
+ catch ( Exception e ) {\r
+ e.printStackTrace();\r
}\r
- */\r
}\r
}\r
\r
- \r
+ private Node queryNode(Node root, String query) {\r
+ if ( root.getNodeType() != Node.ELEMENT_NODE ) {\r
+ return null;\r
+ }\r
+ if ( root.getNodeName().equals(query) ) {\r
+ return root;\r
+ }\r
+ NodeList list = root.getChildNodes();\r
+ for ( int i=0; i < list.getLength(); i++ ) {\r
+ Node n = queryNode(list.item(i), query);\r
+ if ( n != null ) {\r
+ return n;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ private ArrayList<Node> queryNodes(Node root, String query) {\r
+ ArrayList<Node> nodes = new ArrayList<Node>();\r
+ if ( root.getNodeType() != Node.ELEMENT_NODE ) {\r
+ return null;\r
+ }\r
+ NodeList list = root.getChildNodes();\r
+ for ( int i=0; i < list.getLength(); i++ ) {\r
+ Node n = queryNode(list.item(i), query);\r
+ if ( n != null ) {\r
+ nodes.add(n);\r
+ }\r
+ }\r
+ return nodes;\r
+ }\r
/*\r
* ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★\r
* ★★★★★ 放送地域を取得する(TVAreaから降格)-ここから ★★★★★\r