• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

タイニー番組ナビゲータ本体


コミットメタ情報

リビジョン764eaf9b8993a6064ea1c72e90e806171c7d140e (tree)
日時2014-02-22 16:36:33
作者peeweedee <peeweedee@user...>
コミッターpeeweedee

ログメッセージ

・オンラインバージョンアップの参照先の調整
・Web番組表対応の微修正

変更サマリ

差分

--- a/TinyBannavi/05_history.txt
+++ b/TinyBannavi/05_history.txt
@@ -10,12 +10,23 @@
1010 2chの番ナビスレ:http://toro.2ch.net/test/read.cgi/av/1352223253/
1111 ★☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆★
1212
13+3.22.15β+1.5.12(2014-02-22)
14+■変更点
15+ ・(その他) sfのサイト構成変更にオンラインバージョンアップのコードを対応
16+■バグ修正
17+ ・(Web番組表対応[Dimora]) 複数地域を同時選択している場合に過去ログデータにゴミデータが残ってしまう問題を修正
18+ ・(Web番組表対応[スカパー]) 番組情報がない枠が、「番組情報がありません」というタイトルの番組として解析してしまう問題を修正
19+ ・(新聞形式&Web番組表対応) サブタイトル分離をONにしていると番組情報がない枠に「番組情報がありません」が表示されない場合がある問題を修正
20+
1321 3.22.14β+1.5.12(2014-02-21)
1422 ■変更点
1523  ・(録画結果一覧) 検索キーワード「@d(rop)」でエラー行のみ絞り込み表示
1624  ・(新聞形式) 不評なデバッグメッセージの一つを抑制
1725 ■バグ修正
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
1930
2031 3.22.13β+1.5.12(2014-02-01)
2132 ■変更点
--- a/TinyBannavi/src/tainavi/CommonUtils.java
+++ b/TinyBannavi/src/tainavi/CommonUtils.java
@@ -482,13 +482,21 @@ public class CommonUtils {
482482 return c;
483483 }
484484 /**
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+ /**
485493 * 日付時刻文字列をCalendarに変換
486494 * @param date YYYY/MM/DD[(.)][ hh:mm[:ss]] or YYYY-MM-DD[Thh:mm[:ss]] or YYYYMMDD[hhmm[ss]]
487495 */
488496 public static GregorianCalendar getCalendar(String date) {
489497 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);
490498 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);
492500 if ( ! ma.find()) {
493501 return null;
494502 }
--- a/TinyBannavi/src/tainavi/ProgDetailList.java
+++ b/TinyBannavi/src/tainavi/ProgDetailList.java
@@ -109,10 +109,12 @@ public class ProgDetailList implements Cloneable {
109109 /*******************************************************************************
110110 * NGワード処理
111111 ******************************************************************************/
112-
112+
113+ private static final String NO_PROG_TITLE = "番組情報がありません";
114+
113115 public void abon() {
114116 start = "";
115- title = "番組情報がありません";
117+ title = splitted_title = NO_PROG_TITLE;
116118 detail = "";
117119 addedDetail = "";
118120
--- a/TinyBannavi/src/tainavi/TVProgramUtils.java
+++ b/TinyBannavi/src/tainavi/TVProgramUtils.java
@@ -935,15 +935,12 @@ public class TVProgramUtils implements Cloneable {
935935 }
936936 }
937937
938- protected void addEnmptyInfo(ProgDateList pcl, String sdat, String edat) {
938+ protected void addEmptyInfo(ProgDateList pcl, String sdat, String edat) {
939939 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();
945941 pdl.startDateTime = sdat;
946- pdl.endDateTime = edat;
942+ //pdl.endDateTime = edat;
943+ pdl.length = (int)(CommonUtils.getDiffDateTime(sdat, edat)/60000L);
947944 pcl.pdetail.add(pdl);
948945 pcl.row += pdl.length;
949946 }
--- a/TinyBannavi/src/tainavi/VWUpdate.java
+++ b/TinyBannavi/src/tainavi/VWUpdate.java
@@ -323,7 +323,7 @@ public class VWUpdate {
323323
324324 // リリースファイルのURLを取得する
325325 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);
327327 if ( ! ma.find()) {
328328 String msg = "リリースファイルの情報が取得できませんでした。プロジェクトサイト(http://sourceforge.jp/projects/tainavi/)を確認してください。";
329329 StWinAppendError(msg);
--- a/TinyBannavi/src/tainavi/VersionInfo.java
+++ b/TinyBannavi/src/tainavi/VersionInfo.java
@@ -5,7 +5,7 @@ import java.util.regex.Pattern;
55
66
77 public class VersionInfo {
8- private static final String Version = "タイニー番組ナビゲータ 3.22.14β";
8+ private static final String Version = "タイニー番組ナビゲータ 3.22.15β";
99
1010 private static final String OSname = System.getProperty("os.name");
1111 private static final String OSvers = System.getProperty("os.version");
--- a/TinyBannavi/src/tainavi/plugintv/PlugIn_CSPSkyperfectTV2012.java
+++ b/TinyBannavi/src/tainavi/plugintv/PlugIn_CSPSkyperfectTV2012.java
@@ -1,6 +1,8 @@
11 package tainavi.plugintv;
22
33 import java.io.File;
4+import java.io.FileInputStream;
5+import java.io.IOException;
46 import java.io.UnsupportedEncodingException;
57 import java.net.URLDecoder;
68 import java.util.ArrayList;
@@ -11,21 +13,16 @@ import java.util.HashMap;
1113 import java.util.regex.Matcher;
1214 import java.util.regex.Pattern;
1315
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.*;
2817
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;
2926
3027 public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProgram,Cloneable {
3128
@@ -202,37 +199,45 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg
202199 getDate(pl);
203200
204201 //
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+
205207 for ( int dtidx=0; dtidx<pl.pdate.size(); dtidx++ ) {
206208 //
207209 GregorianCalendar cal = CommonUtils.getCalendar(pl.pdate.get(dtidx).Date);
208-
210+ String dt = CommonUtils.getDateYMD(cal);
211+
209212 boolean isNextpageExist = true;
210213 for ( int pgidx=1; isNextpageExist; pgidx++ ) {
211214
212215 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);
215218 //
216219 File f = new File(progCacheFile);
217220 if (force == true ||
218221 (f.exists() == true && isCacheOld(progCacheFile) == true) ||
219222 (f.exists() == false && isCacheOld(null) == true)) {
220223 //
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);
224224 String url = "http://bangumi.skyperfectv.co.jp/"+xtype+"/channel:"+chid+"/date:"+dt.substring(2)+"/";
225225 if ( pgidx > 1 ) {
226226 url += "?p="+pgidx;
227227 }
228+
228229 /*
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();
231232 }
232233 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+ }
234238 }
235239 */
240+
236241 webToFile(url, progCacheFile, thisEncoding);
237242
238243 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
244249 printProgress("(キャッシュ)がみつかりません", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), progCacheFile);
245250 break;
246251 }
247-
252+
248253 String response = CommonUtils.read4file(progCacheFile, true);
249254 if ( response == null || ! response.matches("^.*<a href=\"\\?p=\\d+[^>]+?>次.*$") ) {
250255 isNextpageExist = false;
251256 }
252-
257+
253258 // 番組リストの追加
254259 try {
255260 getPrograms(pl, dtidx, response);
256261 /*
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;
259265 }
260266 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);
262276 }
263277 */
264278 }
@@ -280,6 +294,7 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg
280294 private void printProgress(String msg, int count, int pgidx, int countMax, String center, int date, String uri) {
281295 reportProgress(String.format("%s %s: (%d/%d) page=%d %s[%d日] %s", getTVProgramId(), msg, count, countMax, pgidx, center, date, uri));
282296 }
297+
283298 //
284299 private void getDate(ProgList pl) {
285300 // 日付の処理
@@ -334,26 +349,31 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg
334349 // 隙間を埋めつつ一個にまとめる
335350 ProgDateList all = new ProgDateList();
336351 all.pdetail = new ArrayList<ProgDetailList>();
352+ String prevStart = null;
353+ String prevEnd = null;
337354 for ( ProgDateList pcl : pcenter ) {
338355 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 ) {
342359 // 最前列の情報がとれなかった
343- addEnmptyInfo(all, prevend, pdl.startDateTime);
360+ addEmptyInfo(all, prevEnd, pdl.startDateTime);
344361 }
345362 }
346363 else {
347- ProgDetailList prevpdl = all.pdetail.get(all.pdetail.size()-1);
348- if ( prevpdl.startDateTime.equals(pdl.startDateTime) ) {
364+ if ( prevStart.equals(pdl.startDateTime) ) {
349365 // 重複は破棄
350366 continue;
351367 }
352- else if ( prevpdl.endDateTime.compareTo(pdl.startDateTime) < 0 ) {
368+ else if ( prevEnd.compareTo(pdl.startDateTime) < 0 ) {
353369 // 隙間を埋める
354- addEnmptyInfo(all, prevpdl.endDateTime, pdl.startDateTime);
370+ addEmptyInfo(all, prevEnd, pdl.startDateTime);
355371 }
356372 }
373+
374+ prevStart = pdl.startDateTime;
375+ prevEnd = pdl.endDateTime;
376+
357377 all.pdetail.add(pdl);
358378 all.row += pdl.length;
359379 }
@@ -370,7 +390,8 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg
370390 String da = CommonUtils.getDateTime(cz);
371391 cz.add(Calendar.DATE, 1);
372392 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) ) {
374395 if ( cnt++ == 0 ) {
375396 pcl.pdetail.add(pdl);
376397 }
@@ -389,7 +410,9 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg
389410 // 1日の合計分数を足し合わせる
390411 for ( ProgDetailList pdl : pcl.pdetail ) {
391412 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+ }
393416 pcl.row += pdl.length;
394417 }
395418 // おしりがとどかない場合(デメリット:これをやると、サイト側のエラーで欠けてるのか、そもそも休止なのかの区別がつかなくなる)
@@ -398,7 +421,7 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg
398421 GregorianCalendar cz = (GregorianCalendar) ca.clone();
399422 ca.add(Calendar.MINUTE, pcl.row);
400423 cz.add(Calendar.MINUTE, 24*60);
401- addEnmptyInfo(pcl, CommonUtils.getDateTime(ca), CommonUtils.getDateTime(cz));
424+ addEmptyInfo(pcl, CommonUtils.getDateTime(ca), CommonUtils.getDateTime(cz));
402425 }
403426 }
404427 }
@@ -566,40 +589,139 @@ public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProg
566589
567590
568591 /**
569- * こちらは番組IDがとれる代わりに出演者情報がとれなくなるので保留とする
592+ * こちらは50番組/日までしかとれないため、保留
570593 */
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);
584622 }
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();
587629 }
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));
590638 }
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+ }
595666 }
667+
668+ pdl.detail = pdl.detail.replaceFirst("、$","");
596669 }
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();
597690 }
598- */
599691 }
600692 }
601693
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+ }
603725 /*
604726 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
605727 * ★★★★★ 放送地域を取得する(TVAreaから降格)-ここから ★★★★★
--- a/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPDimora.java
+++ b/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPDimora.java
@@ -19,8 +19,6 @@ import tainavi.ProgDetailList;
1919 import tainavi.ProgList;
2020 import tainavi.TVProgram;
2121 import tainavi.TVProgramUtils;
22-import tainavi.TVProgram.ProgSubtype;
23-import tainavi.TVProgram.ProgType;
2422
2523
2624 public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Cloneable {
@@ -308,7 +306,8 @@ public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Clonea
308306 break;
309307 }
310308 }
311- if ( pcl == null ) {
309+ if ( pcl == null || pcl.row > 0 ) {
310+ // 複数地域を同時に選択していると、BSの番組情報が重複して取得されるので、既得(pcl.row>0)ならスキップ
312311 continue;
313312 }
314313
@@ -355,13 +354,13 @@ public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Clonea
355354 }
356355 else if ( cx.compareTo(ca) < 0 ) {
357356 // 開始時刻が05:00よりあと
358- addEnmptyInfo(pcl, sdat, dat[1]);
357+ addEmptyInfo(pcl, sdat, dat[1]);
359358 }
360359 }
361360 else {
362361 if ( pcz.compareTo(ca) < 0 ) {
363362 // 前の番組との間が空いている
364- addEnmptyInfo(pcl, CommonUtils.getDateTime(pcz), dat[1]);
363+ addEmptyInfo(pcl, CommonUtils.getDateTime(pcz), dat[1]);
365364 }
366365 }
367366
@@ -418,11 +417,11 @@ public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Clonea
418417 }
419418 if ( pcz == null ) {
420419 // 番組情報がないよ
421- addEnmptyInfo(pcl, CommonUtils.getDateTime(cx), CommonUtils.getDateTime(cy));
420+ addEmptyInfo(pcl, CommonUtils.getDateTime(cx), CommonUtils.getDateTime(cy));
422421 }
423422 else if ( pcz.compareTo(cy) < 0 ) {
424423 // 終了時刻が29:00より前
425- addEnmptyInfo(pcl, CommonUtils.getDateTime(pcz), CommonUtils.getDateTime(cy));
424+ addEmptyInfo(pcl, CommonUtils.getDateTime(pcz), CommonUtils.getDateTime(cy));
426425 }
427426 }
428427 }