タイニー番組ナビゲータ本体
リビジョン | 764eaf9b8993a6064ea1c72e90e806171c7d140e (tree) |
---|---|
日時 | 2014-02-22 16:36:33 |
作者 | peeweedee <peeweedee@user...> |
コミッター | peeweedee |
・オンラインバージョンアップの参照先の調整
・Web番組表対応の微修正
@@ -10,12 +10,23 @@ | ||
10 | 10 | 2chの番ナビスレ:http://toro.2ch.net/test/read.cgi/av/1352223253/ |
11 | 11 | ★☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆★ |
12 | 12 | |
13 | +3.22.15β+1.5.12(2014-02-22) | |
14 | +■変更点 | |
15 | + ・(その他) sfのサイト構成変更にオンラインバージョンアップのコードを対応 | |
16 | +■バグ修正 | |
17 | + ・(Web番組表対応[Dimora]) 複数地域を同時選択している場合に過去ログデータにゴミデータが残ってしまう問題を修正 | |
18 | + ・(Web番組表対応[スカパー]) 番組情報がない枠が、「番組情報がありません」というタイトルの番組として解析してしまう問題を修正 | |
19 | + ・(新聞形式&Web番組表対応) サブタイトル分離をONにしていると番組情報がない枠に「番組情報がありません」が表示されない場合がある問題を修正 | |
20 | + | |
13 | 21 | 3.22.14β+1.5.12(2014-02-21) |
14 | 22 | ■変更点 |
15 | 23 | ・(録画結果一覧) 検索キーワード「@d(rop)」でエラー行のみ絞り込み表示 |
16 | 24 | ・(新聞形式) 不評なデバッグメッセージの一つを抑制 |
17 | 25 | ■バグ修正 |
18 | - ・(Web番組表対応[Dimora]) 02/23のBSアニマックスの情報が正しくひょい表示されない問題を修正 | |
26 | + ・(Web番組表対応[Dimora]) 02/23のBSアニマックスの情報が正しく表示されない問題を修正 | |
27 | + | |
28 | +★対応チケット | |
29 | +http://sourceforge.jp/ticket/browse.php?group_id=4315&tid=33239 | |
19 | 30 | |
20 | 31 | 3.22.13β+1.5.12(2014-02-01) |
21 | 32 | ■変更点 |
@@ -482,13 +482,21 @@ public class CommonUtils { | ||
482 | 482 | return c; |
483 | 483 | } |
484 | 484 | /** |
485 | + * 指定日時+min分のCalendarを返す | |
486 | + */ | |
487 | + public static GregorianCalendar getCalendar(String date, int sec) { | |
488 | + GregorianCalendar c = getCalendar(date); | |
489 | + c.add(Calendar.SECOND, sec); | |
490 | + return c; | |
491 | + } | |
492 | + /** | |
485 | 493 | * 日付時刻文字列をCalendarに変換 |
486 | 494 | * @param date YYYY/MM/DD[(.)][ hh:mm[:ss]] or YYYY-MM-DD[Thh:mm[:ss]] or YYYYMMDD[hhmm[ss]] |
487 | 495 | */ |
488 | 496 | public static GregorianCalendar getCalendar(String date) { |
489 | 497 | Matcher ma = Pattern.compile("^(\\d\\d\\d\\d)[/-](\\d{1,2})[/-](\\d{1,2})(\\(.\\))?([ T](\\d{1,2}):(\\d{1,2})(:\\d{1,2})?)?$").matcher(date); |
490 | 498 | if ( ! ma.find()) { |
491 | - ma = Pattern.compile("^(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)()?((\\d\\d)(\\d\\d)(\\d\\d)?)?$").matcher(date); | |
499 | + ma = Pattern.compile("^(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)(\\s)?((\\d\\d)(\\d\\d)(\\d\\d)?)?$").matcher(date); | |
492 | 500 | if ( ! ma.find()) { |
493 | 501 | return null; |
494 | 502 | } |
@@ -109,10 +109,12 @@ public class ProgDetailList implements Cloneable { | ||
109 | 109 | /******************************************************************************* |
110 | 110 | * NGワード処理 |
111 | 111 | ******************************************************************************/ |
112 | - | |
112 | + | |
113 | + private static final String NO_PROG_TITLE = "番組情報がありません"; | |
114 | + | |
113 | 115 | public void abon() { |
114 | 116 | start = ""; |
115 | - title = "番組情報がありません"; | |
117 | + title = splitted_title = NO_PROG_TITLE; | |
116 | 118 | detail = ""; |
117 | 119 | addedDetail = ""; |
118 | 120 |
@@ -935,15 +935,12 @@ public class TVProgramUtils implements Cloneable { | ||
935 | 935 | } |
936 | 936 | } |
937 | 937 | |
938 | - protected void addEnmptyInfo(ProgDateList pcl, String sdat, String edat) { | |
938 | + protected void addEmptyInfo(ProgDateList pcl, String sdat, String edat) { | |
939 | 939 | ProgDetailList pdl = new ProgDetailList(); |
940 | - pdl.title = pdl.splitted_title = "番組情報がありません"; | |
941 | - pdl.detail = ""; | |
942 | - pdl.length = (int)(CommonUtils.getDiffDateTime(sdat, edat)/60000L); | |
943 | - pdl.genre = ProgGenre.NOGENRE; | |
944 | - pdl.start = ""; | |
940 | + pdl.abon(); | |
945 | 941 | pdl.startDateTime = sdat; |
946 | - pdl.endDateTime = edat; | |
942 | + //pdl.endDateTime = edat; | |
943 | + pdl.length = (int)(CommonUtils.getDiffDateTime(sdat, edat)/60000L); | |
947 | 944 | pcl.pdetail.add(pdl); |
948 | 945 | pcl.row += pdl.length; |
949 | 946 | } |
@@ -323,7 +323,7 @@ public class VWUpdate { | ||
323 | 323 | |
324 | 324 | // リリースファイルのURLを取得する |
325 | 325 | String flink = ""; |
326 | - Matcher ma = Pattern.compile("<meta http-equiv=\"refresh\" content=\"1; url=(.+?)\">").matcher(response); | |
326 | + Matcher ma = Pattern.compile("<meta http-equiv=\"refresh\" content=\"\\d+; url=(.+?\\.zip)\">").matcher(response); | |
327 | 327 | if ( ! ma.find()) { |
328 | 328 | String msg = "リリースファイルの情報が取得できませんでした。プロジェクトサイト(http://sourceforge.jp/projects/tainavi/)を確認してください。"; |
329 | 329 | StWinAppendError(msg); |
@@ -5,7 +5,7 @@ import java.util.regex.Pattern; | ||
5 | 5 | |
6 | 6 | |
7 | 7 | public class VersionInfo { |
8 | - private static final String Version = "タイニー番組ナビゲータ 3.22.14β"; | |
8 | + private static final String Version = "タイニー番組ナビゲータ 3.22.15β"; | |
9 | 9 | |
10 | 10 | private static final String OSname = System.getProperty("os.name"); |
11 | 11 | private static final String OSvers = System.getProperty("os.version"); |
@@ -1,6 +1,8 @@ | ||
1 | 1 | package tainavi.plugintv; |
2 | 2 | |
3 | 3 | import java.io.File; |
4 | +import java.io.FileInputStream; | |
5 | +import java.io.IOException; | |
4 | 6 | import java.io.UnsupportedEncodingException; |
5 | 7 | import java.net.URLDecoder; |
6 | 8 | import java.util.ArrayList; |
@@ -11,21 +13,16 @@ import java.util.HashMap; | ||
11 | 13 | import java.util.regex.Matcher; |
12 | 14 | import java.util.regex.Pattern; |
13 | 15 | |
14 | -import tainavi.AreaCode; | |
15 | -import tainavi.Center; | |
16 | -import tainavi.CommonUtils; | |
17 | -import tainavi.ContentIdDIMORA; | |
18 | -import tainavi.ProgDateList; | |
19 | -import tainavi.ProgDetailList; | |
20 | -import tainavi.ProgList; | |
21 | -import tainavi.TVProgram; | |
22 | -import tainavi.TVProgramUtils; | |
23 | -import tainavi.TVProgram.ProgGenre; | |
24 | -import tainavi.TVProgram.ProgOption; | |
25 | -import tainavi.TVProgram.ProgSubgenre; | |
26 | -import tainavi.TVProgram.ProgSubtype; | |
27 | -import tainavi.TVProgram.ProgType; | |
16 | +import tainavi.*; | |
28 | 17 | |
18 | +import javax.xml.parsers.DocumentBuilder; | |
19 | +import javax.xml.parsers.DocumentBuilderFactory; | |
20 | +import javax.xml.parsers.ParserConfigurationException; | |
21 | +import org.w3c.dom.Document; | |
22 | +import org.w3c.dom.NamedNodeMap; | |
23 | +import org.w3c.dom.Node; | |
24 | +import org.w3c.dom.NodeList; | |
25 | +import org.xml.sax.SAXException; | |
29 | 26 | |
30 | 27 | public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProgram,Cloneable { |
31 | 28 |
@@ -202,37 +199,45 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
202 | 199 | getDate(pl); |
203 | 200 | |
204 | 201 | // |
202 | + String xtype = (pl.CenterId.startsWith(CHID_PREFIX_BS) || pl.CenterId.startsWith(CHID_PREFIX_CS)) ? XTYPE_BASIC : XTYPE_PREMIUM; | |
203 | + String chid = xtype == XTYPE_BASIC ? pl.CenterId : pl.CenterId.replaceFirst("^"+CHID_PREFIX_PR, ""); | |
204 | + //String cacheFileExt = xtype == XTYPE_BASIC ? "xml" : "txt"; | |
205 | + String cacheFileExt = "txt"; | |
206 | + | |
205 | 207 | for ( int dtidx=0; dtidx<pl.pdate.size(); dtidx++ ) { |
206 | 208 | // |
207 | 209 | GregorianCalendar cal = CommonUtils.getCalendar(pl.pdate.get(dtidx).Date); |
208 | - | |
210 | + String dt = CommonUtils.getDateYMD(cal); | |
211 | + | |
209 | 212 | boolean isNextpageExist = true; |
210 | 213 | for ( int pgidx=1; isNextpageExist; pgidx++ ) { |
211 | 214 | |
212 | 215 | final String progCacheFile = |
213 | - pgidx == 1 ? String.format("%s%sSKP2012_%s_%d.txt", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH)) : | |
214 | - String.format("%s%sSKP2012_%s_%d_%d.txt", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH),pgidx); | |
216 | + pgidx == 1 ? String.format("%s%sSKP2012_%s_%d.%s", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH), cacheFileExt) : | |
217 | + String.format("%s%sSKP2012_%s_%d_%d.%s", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH),pgidx, cacheFileExt); | |
215 | 218 | // |
216 | 219 | File f = new File(progCacheFile); |
217 | 220 | if (force == true || |
218 | 221 | (f.exists() == true && isCacheOld(progCacheFile) == true) || |
219 | 222 | (f.exists() == false && isCacheOld(null) == true)) { |
220 | 223 | // |
221 | - String xtype = (pl.CenterId.startsWith(CHID_PREFIX_BS) || pl.CenterId.startsWith(CHID_PREFIX_CS)) ? XTYPE_BASIC : XTYPE_PREMIUM; | |
222 | - String chid = xtype != XTYPE_PREMIUM ? pl.CenterId : pl.CenterId.replaceFirst("^"+CHID_PREFIX_PR, ""); | |
223 | - String dt = CommonUtils.getDateYMD(cal); | |
224 | 224 | String url = "http://bangumi.skyperfectv.co.jp/"+xtype+"/channel:"+chid+"/date:"+dt.substring(2)+"/"; |
225 | 225 | if ( pgidx > 1 ) { |
226 | 226 | url += "?p="+pgidx; |
227 | 227 | } |
228 | + | |
228 | 229 | /* |
229 | - if ( pl.ChId.length() == 0 ) { | |
230 | - url = "http://bangumi.skyperfectv.co.jp/api/version:3/search/date:"+dt.substring(2)+"/channel:"+pl.CenterId+"/?api_key=336eec3423"; | |
230 | + if ( xtype == XTYPE_BASIC ) { | |
231 | + url = "http://www.skyperfectv.co.jp/xml/"+dt+"_"+chid.replaceFirst("^[^0-9]+","")+".xml?_="+System.currentTimeMillis(); | |
231 | 232 | } |
232 | 233 | else { |
233 | - url = "http://www.skyperfectv.co.jp/xml/"+dt+"_"+pl.ChId.substring(2)+".xml"; | |
234 | + url = "http://bangumi.skyperfectv.co.jp/"+xtype+"/channel:"+chid+"/date:"+dt.substring(2)+"/"; | |
235 | + if ( pgidx > 1 ) { | |
236 | + url += "?p="+pgidx; | |
237 | + } | |
234 | 238 | } |
235 | 239 | */ |
240 | + | |
236 | 241 | webToFile(url, progCacheFile, thisEncoding); |
237 | 242 | |
238 | 243 | printProgress("(オンライン)を取得しました", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), url); |
@@ -244,21 +249,30 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
244 | 249 | printProgress("(キャッシュ)がみつかりません", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), progCacheFile); |
245 | 250 | break; |
246 | 251 | } |
247 | - | |
252 | + | |
248 | 253 | String response = CommonUtils.read4file(progCacheFile, true); |
249 | 254 | if ( response == null || ! response.matches("^.*<a href=\"\\?p=\\d+[^>]+?>次.*$") ) { |
250 | 255 | isNextpageExist = false; |
251 | 256 | } |
252 | - | |
257 | + | |
253 | 258 | // 番組リストの追加 |
254 | 259 | try { |
255 | 260 | getPrograms(pl, dtidx, response); |
256 | 261 | /* |
257 | - if ( pl.ChId.length() == 0 ) { | |
258 | - getPrograms(pl, i, response); | |
262 | + if ( xtype == XTYPE_BASIC ) { | |
263 | + getPrograms_basic(pl, dtidx, progCacheFile); | |
264 | + isNextpageExist = false; | |
259 | 265 | } |
260 | 266 | else { |
261 | - getPrograms_basic(pl, i, response); | |
267 | + String response = CommonUtils.read4file(progCacheFile, true); | |
268 | + | |
269 | + if ( xtype != XTYPE_BASIC ) { | |
270 | + if ( response == null || ! response.matches("^.*<a href=\"\\?p=\\d+[^>]+?>次.*$") ) { | |
271 | + isNextpageExist = false; | |
272 | + } | |
273 | + } | |
274 | + | |
275 | + getPrograms(pl, dtidx, response); | |
262 | 276 | } |
263 | 277 | */ |
264 | 278 | } |
@@ -280,6 +294,7 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
280 | 294 | private void printProgress(String msg, int count, int pgidx, int countMax, String center, int date, String uri) { |
281 | 295 | reportProgress(String.format("%s %s: (%d/%d) page=%d %s[%d日] %s", getTVProgramId(), msg, count, countMax, pgidx, center, date, uri)); |
282 | 296 | } |
297 | + | |
283 | 298 | // |
284 | 299 | private void getDate(ProgList pl) { |
285 | 300 | // 日付の処理 |
@@ -334,26 +349,31 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
334 | 349 | // 隙間を埋めつつ一個にまとめる |
335 | 350 | ProgDateList all = new ProgDateList(); |
336 | 351 | all.pdetail = new ArrayList<ProgDetailList>(); |
352 | + String prevStart = null; | |
353 | + String prevEnd = null; | |
337 | 354 | for ( ProgDateList pcl : pcenter ) { |
338 | 355 | for ( ProgDetailList pdl : pcl.pdetail ) { |
339 | - if ( all.row == 0 ) { | |
340 | - String prevend = CommonUtils.getDateTime(CommonUtils.getCalendar(pcenter.get(0).Date+" 05:00")); | |
341 | - if ( prevend.compareTo(pdl.startDateTime) < 0 ) { | |
356 | + if ( prevEnd == null ) { | |
357 | + prevEnd = CommonUtils.getDateTime(CommonUtils.getCalendar(pcenter.get(0).Date+" 05:00")); | |
358 | + if ( prevEnd.compareTo(pdl.startDateTime) < 0 ) { | |
342 | 359 | // 最前列の情報がとれなかった |
343 | - addEnmptyInfo(all, prevend, pdl.startDateTime); | |
360 | + addEmptyInfo(all, prevEnd, pdl.startDateTime); | |
344 | 361 | } |
345 | 362 | } |
346 | 363 | else { |
347 | - ProgDetailList prevpdl = all.pdetail.get(all.pdetail.size()-1); | |
348 | - if ( prevpdl.startDateTime.equals(pdl.startDateTime) ) { | |
364 | + if ( prevStart.equals(pdl.startDateTime) ) { | |
349 | 365 | // 重複は破棄 |
350 | 366 | continue; |
351 | 367 | } |
352 | - else if ( prevpdl.endDateTime.compareTo(pdl.startDateTime) < 0 ) { | |
368 | + else if ( prevEnd.compareTo(pdl.startDateTime) < 0 ) { | |
353 | 369 | // 隙間を埋める |
354 | - addEnmptyInfo(all, prevpdl.endDateTime, pdl.startDateTime); | |
370 | + addEmptyInfo(all, prevEnd, pdl.startDateTime); | |
355 | 371 | } |
356 | 372 | } |
373 | + | |
374 | + prevStart = pdl.startDateTime; | |
375 | + prevEnd = pdl.endDateTime; | |
376 | + | |
357 | 377 | all.pdetail.add(pdl); |
358 | 378 | all.row += pdl.length; |
359 | 379 | } |
@@ -370,7 +390,8 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
370 | 390 | String da = CommonUtils.getDateTime(cz); |
371 | 391 | cz.add(Calendar.DATE, 1); |
372 | 392 | String dz = CommonUtils.getDateTime(cz); |
373 | - if ( CommonUtils.isOverlap(pdl.startDateTime, pdl.endDateTime, da, dz, true) ) { | |
393 | + String endDateTime = pdl.endDateTime.length() > 0 ? pdl.endDateTime : CommonUtils.getDateTime(CommonUtils.getCalendar(pdl.startDateTime, pdl.length * 60)); | |
394 | + if ( CommonUtils.isOverlap(pdl.startDateTime, endDateTime, da, dz, true) ) { | |
374 | 395 | if ( cnt++ == 0 ) { |
375 | 396 | pcl.pdetail.add(pdl); |
376 | 397 | } |
@@ -389,7 +410,9 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
389 | 410 | // 1日の合計分数を足し合わせる |
390 | 411 | for ( ProgDetailList pdl : pcl.pdetail ) { |
391 | 412 | String da = (pcl.row == 0) ? pcl.Date+" 05:00" : pdl.startDateTime; |
392 | - pdl.length = (int)(CommonUtils.getCompareDateTime(pdl.endDateTime, da)/60000L); | |
413 | + if ( pdl.endDateTime.length() > 0 ) { | |
414 | + pdl.length = (int)(CommonUtils.getCompareDateTime(pdl.endDateTime, da)/60000L); | |
415 | + } | |
393 | 416 | pcl.row += pdl.length; |
394 | 417 | } |
395 | 418 | // おしりがとどかない場合(デメリット:これをやると、サイト側のエラーで欠けてるのか、そもそも休止なのかの区別がつかなくなる) |
@@ -398,7 +421,7 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
398 | 421 | GregorianCalendar cz = (GregorianCalendar) ca.clone(); |
399 | 422 | ca.add(Calendar.MINUTE, pcl.row); |
400 | 423 | cz.add(Calendar.MINUTE, 24*60); |
401 | - addEnmptyInfo(pcl, CommonUtils.getDateTime(ca), CommonUtils.getDateTime(cz)); | |
424 | + addEmptyInfo(pcl, CommonUtils.getDateTime(ca), CommonUtils.getDateTime(cz)); | |
402 | 425 | } |
403 | 426 | } |
404 | 427 | } |
@@ -566,40 +589,139 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg | ||
566 | 589 | |
567 | 590 | |
568 | 591 | /** |
569 | - * こちらは番組IDがとれる代わりに出演者情報がとれなくなるので保留とする | |
592 | + * こちらは50番組/日までしかとれないため、保留 | |
570 | 593 | */ |
571 | - private void getPrograms_basic(ProgList pl, int dtidx, String response) { | |
572 | - | |
573 | - Matcher ma = Pattern.compile("<SIInformation(.+?)</SIInformation>",Pattern.DOTALL).matcher(response); | |
574 | - while ( ma.find() ) { | |
575 | - Matcher mb = Pattern.compile("eventId=\"(.+?)\".+?broadCastStartDate=\"(\\d{8})(\\d{4})",Pattern.DOTALL).matcher(ma.group(1)); | |
576 | - if ( mb.find() ) { | |
577 | - | |
578 | - } | |
579 | - /* | |
580 | - mb = Pattern.compile("<(.+?)>(.+?)</\\1>",Pattern.DOTALL).matcher(ma.group(1)); | |
581 | - while ( mb.find() ) { | |
582 | - if ( mb.group(1).equals("ChannelName") ) { | |
583 | - | |
594 | + private void getPrograms_basic(ProgList pl, int dtidx, String filename) throws ParserConfigurationException, IOException, SAXException { | |
595 | + | |
596 | + ProgDateList pcl = pl.pdate.get(dtidx); | |
597 | + | |
598 | + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
599 | + DocumentBuilder db = dbf.newDocumentBuilder(); | |
600 | + | |
601 | + Document parseDoc = db.parse(new FileInputStream(filename)); | |
602 | + | |
603 | + NodeList list = parseDoc.getElementsByTagName("SIInformation"); | |
604 | + for ( int i=0; i < list.getLength(); i++ ) { | |
605 | + ProgDetailList pdl = new ProgDetailList(); | |
606 | + Node node = list.item(i); | |
607 | + try { | |
608 | + NamedNodeMap attributes = node.getAttributes(); | |
609 | + String startValue = attributes.getNamedItem("broadCastStartDate").getNodeValue().substring(8,12); | |
610 | + pdl.start = startValue.substring(0,2) + ":" + startValue.substring(2); | |
611 | + String endValue = attributes.getNamedItem("broadCastEndDate").getNodeValue().substring(8,12); | |
612 | + pdl.end = endValue.substring(0,2) + ":" + endValue.substring(2); | |
613 | + pdl.length = CommonUtils.getRecMinVal(pdl.start, pdl.end); | |
614 | + | |
615 | + int onid = Integer.decode(attributes.getNamedItem("networkId").getNodeValue()); | |
616 | + //Node tsid = attributes.getNamedItem("").getNodeValue(); | |
617 | + int sid = Integer.decode(attributes.getNamedItem("serviceId").getNodeValue()); | |
618 | + Node evidNode = attributes.getNamedItem("eventId"); | |
619 | + if ( evidNode != null ) { | |
620 | + int evid = Integer.decode(evidNode.getNodeValue()); | |
621 | + pdl.progid = ContentIdEDCB.getContentId(onid, 0, sid, evid); | |
584 | 622 | } |
585 | - else if ( mb.group(1).equals("Title") ) { | |
586 | - | |
623 | + | |
624 | + pdl.title = queryNode(node, "Title").getTextContent(); | |
625 | + | |
626 | + Node detailNode = queryNode(node, "Synopsis"); | |
627 | + if ( detailNode != null ) { | |
628 | + pdl.detail = detailNode.getTextContent(); | |
587 | 629 | } |
588 | - else if ( mb.group(1).equals("Synopsis") ) { | |
589 | - | |
630 | + | |
631 | + Node genreNode = queryNode(node, "Genres"); | |
632 | + if ( genreNode != null ) { | |
633 | + NamedNodeMap genreAttributes = queryNode(genreNode, "Genre").getAttributes(); | |
634 | + String majorGenreId = genreAttributes.getNamedItem("majorGenreId").getNodeValue(); | |
635 | + String minorGenreId = genreAttributes.getNamedItem("minorGenreId").getNodeValue(); | |
636 | + pdl.genre = ProgGenre.getByIEPG(majorGenreId.substring(majorGenreId.length()-1)); | |
637 | + pdl.subgenre = ProgSubgenre.getByIEPG(pdl.genre, minorGenreId.substring(minorGenreId.length() - 1)); | |
590 | 638 | } |
591 | - else if ( mb.group(1).equals("Genres") ) { | |
592 | - Matcher mc = Pattern.compile("<Genre majorGenreId=\".+?\" minorGenreId=\".+?\"",Pattern.DOTALL).matcher(mb.group(2)); | |
593 | - while ( mc.find() ) { | |
594 | - | |
639 | + if ( pdl.genre == null || pdl.subgenre == null ) { | |
640 | + pdl.genre = ProgGenre.NOGENRE; | |
641 | + pdl.subgenre = ProgSubgenre.NOGENRE_ETC; | |
642 | + } | |
643 | + | |
644 | + Node actorNode = queryNode(node, "ActorInformation"); | |
645 | + if ( actorNode != null ) { | |
646 | + if ( pdl.detail == null ) { | |
647 | + pdl.detail = ""; | |
648 | + } | |
649 | + else if ( pdl.detail.length() > 0 ) { | |
650 | + pdl.detail += "\n"; | |
651 | + } | |
652 | + | |
653 | + String prePostValue = ""; | |
654 | + ArrayList<Node> nodes = queryNodes(queryNode(actorNode, "Actors"), "Actor"); | |
655 | + for ( Node actor : nodes ) { | |
656 | + Node post = queryNode(actor, "Post"); | |
657 | + Node name = queryNode(actor, "Name"); | |
658 | + if ( post != null && name != null ) { | |
659 | + String postValue = post.getTextContent(); | |
660 | + if ( ! postValue.equals(prePostValue) ) { | |
661 | + pdl.detail += "\n" + postValue + ":"; | |
662 | + prePostValue = postValue; | |
663 | + } | |
664 | + pdl.detail += name.getTextContent() + "、"; | |
665 | + } | |
595 | 666 | } |
667 | + | |
668 | + pdl.detail = pdl.detail.replaceFirst("、$",""); | |
596 | 669 | } |
670 | + | |
671 | + Node copyRights = queryNode(node, "CopyRights"); | |
672 | + if ( copyRights != null ) { | |
673 | + pdl.detail += "\n\n"+copyRights.getTextContent(); | |
674 | + } | |
675 | + | |
676 | + // タイトルから各種フラグを分離する | |
677 | + doSplitFlags(pdl, nf); | |
678 | + | |
679 | + // サブタイトル分離(ポインタを活用してメモリを節約する) | |
680 | + doSplitSubtitle(pdl); | |
681 | + | |
682 | + // その他フラグ | |
683 | + pdl.extension = false; | |
684 | + pdl.nosyobo = false; | |
685 | + | |
686 | + pcl.pdetail.add(pdl); | |
687 | + } | |
688 | + catch ( Exception e ) { | |
689 | + e.printStackTrace(); | |
597 | 690 | } |
598 | - */ | |
599 | 691 | } |
600 | 692 | } |
601 | 693 | |
602 | - | |
694 | + private Node queryNode(Node root, String query) { | |
695 | + if ( root.getNodeType() != Node.ELEMENT_NODE ) { | |
696 | + return null; | |
697 | + } | |
698 | + if ( root.getNodeName().equals(query) ) { | |
699 | + return root; | |
700 | + } | |
701 | + NodeList list = root.getChildNodes(); | |
702 | + for ( int i=0; i < list.getLength(); i++ ) { | |
703 | + Node n = queryNode(list.item(i), query); | |
704 | + if ( n != null ) { | |
705 | + return n; | |
706 | + } | |
707 | + } | |
708 | + return null; | |
709 | + } | |
710 | + | |
711 | + private ArrayList<Node> queryNodes(Node root, String query) { | |
712 | + ArrayList<Node> nodes = new ArrayList<Node>(); | |
713 | + if ( root.getNodeType() != Node.ELEMENT_NODE ) { | |
714 | + return null; | |
715 | + } | |
716 | + NodeList list = root.getChildNodes(); | |
717 | + for ( int i=0; i < list.getLength(); i++ ) { | |
718 | + Node n = queryNode(list.item(i), query); | |
719 | + if ( n != null ) { | |
720 | + nodes.add(n); | |
721 | + } | |
722 | + } | |
723 | + return nodes; | |
724 | + } | |
603 | 725 | /* |
604 | 726 | * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ |
605 | 727 | * ★★★★★ 放送地域を取得する(TVAreaから降格)-ここから ★★★★★ |
@@ -19,8 +19,6 @@ import tainavi.ProgDetailList; | ||
19 | 19 | import tainavi.ProgList; |
20 | 20 | import tainavi.TVProgram; |
21 | 21 | import tainavi.TVProgramUtils; |
22 | -import tainavi.TVProgram.ProgSubtype; | |
23 | -import tainavi.TVProgram.ProgType; | |
24 | 22 | |
25 | 23 | |
26 | 24 | public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Cloneable { |
@@ -308,7 +306,8 @@ public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Clonea | ||
308 | 306 | break; |
309 | 307 | } |
310 | 308 | } |
311 | - if ( pcl == null ) { | |
309 | + if ( pcl == null || pcl.row > 0 ) { | |
310 | + // 複数地域を同時に選択していると、BSの番組情報が重複して取得されるので、既得(pcl.row>0)ならスキップ | |
312 | 311 | continue; |
313 | 312 | } |
314 | 313 |
@@ -355,13 +354,13 @@ public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Clonea | ||
355 | 354 | } |
356 | 355 | else if ( cx.compareTo(ca) < 0 ) { |
357 | 356 | // 開始時刻が05:00よりあと |
358 | - addEnmptyInfo(pcl, sdat, dat[1]); | |
357 | + addEmptyInfo(pcl, sdat, dat[1]); | |
359 | 358 | } |
360 | 359 | } |
361 | 360 | else { |
362 | 361 | if ( pcz.compareTo(ca) < 0 ) { |
363 | 362 | // 前の番組との間が空いている |
364 | - addEnmptyInfo(pcl, CommonUtils.getDateTime(pcz), dat[1]); | |
363 | + addEmptyInfo(pcl, CommonUtils.getDateTime(pcz), dat[1]); | |
365 | 364 | } |
366 | 365 | } |
367 | 366 |
@@ -418,11 +417,11 @@ public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Clonea | ||
418 | 417 | } |
419 | 418 | if ( pcz == null ) { |
420 | 419 | // 番組情報がないよ |
421 | - addEnmptyInfo(pcl, CommonUtils.getDateTime(cx), CommonUtils.getDateTime(cy)); | |
420 | + addEmptyInfo(pcl, CommonUtils.getDateTime(cx), CommonUtils.getDateTime(cy)); | |
422 | 421 | } |
423 | 422 | else if ( pcz.compareTo(cy) < 0 ) { |
424 | 423 | // 終了時刻が29:00より前 |
425 | - addEnmptyInfo(pcl, CommonUtils.getDateTime(pcz), CommonUtils.getDateTime(cy)); | |
424 | + addEmptyInfo(pcl, CommonUtils.getDateTime(pcz), CommonUtils.getDateTime(cy)); | |
426 | 425 | } |
427 | 426 | } |
428 | 427 | } |