4 import java.io.UnsupportedEncodingException;
\r
5 import java.net.URLDecoder;
\r
6 import java.util.ArrayList;
\r
7 import java.util.Calendar;
\r
8 import java.util.Date;
\r
9 import java.util.GregorianCalendar;
\r
10 import java.util.HashMap;
\r
11 import java.util.regex.Matcher;
\r
12 import java.util.regex.Pattern;
\r
15 public class PlugIn_CSPSkyperfectTV2012 extends TVProgramUtils implements TVProgram,Cloneable {
\r
17 public PlugIn_CSPSkyperfectTV2012 clone() {
\r
18 return (PlugIn_CSPSkyperfectTV2012) super.clone();
\r
21 private static final String thisEncoding = "UTF-8";
\r
24 /*******************************************************************************
\r
26 ******************************************************************************/
\r
29 public String getTVProgramId() { return "スカパー!"; }
\r
32 public ProgType getType() { return ProgType.PROG; }
\r
34 public ProgSubtype getSubtype() { return ProgSubtype.CS; }
\r
38 public boolean isAreaSelectSupported() { return false; }
\r
40 /*******************************************************************************
\r
42 ******************************************************************************/
\r
45 public int getTimeBarStart() {return 5;}
\r
47 private int getDogDays() { return ((getExpandTo8())?(8):(7)); }
\r
50 /*******************************************************************************
\r
52 ******************************************************************************/
\r
54 private static final String XTYPE_BASIC = "e2";
\r
55 private static final String XTYPE_PREMIUM = "HD";
\r
57 private static final String CHNM_PREFIX_BS = "BS";
\r
58 private static final String CHNM_PREFIX_CS = "CS";
\r
59 private static final String CHNM_PREFIX_PR = "Ch.";
\r
61 private static final String CHID_PREFIX_BS = "BS";
\r
62 private static final String CHID_PREFIX_CS = "CS";
\r
63 private static final String CHID_PREFIX_PR = "HD";
\r
65 private final String MSGID = "["+getTVProgramId()+"] ";
\r
66 private final String ERRID = "[ERROR]"+MSGID;
\r
67 private final String DBGID = "[DEBUG]"+MSGID;
\r
70 /*******************************************************************************
\r
72 ******************************************************************************/
\r
74 protected ArrayList<ProgList> newplist;
\r
76 private HashMap<String,String> nf = null;
\r
77 private HashMap<String,String> gf = null;
\r
81 private static final HashMap<String,ProgGenre> genremap = new HashMap<String, TVProgram.ProgGenre>() {
\r
83 private static final long serialVersionUID = 1L;
\r
86 put("アニメ/特撮",ProgGenre.ANIME);
\r
87 put("こども向け/教育",ProgGenre.ANIME);
\r
89 put("映画",ProgGenre.MOVIE);
\r
90 put("洋画",ProgGenre.MOVIE);
\r
91 put("邦画",ProgGenre.MOVIE);
\r
93 put("ドラマ/演劇",ProgGenre.DORAMA);
\r
94 put("ドラマ",ProgGenre.DORAMA);
\r
96 put("劇場/公演",ProgGenre.THEATER);
\r
98 put("ドキュメンタリー/教養",ProgGenre.DOCUMENTARY);
\r
100 put("音楽",ProgGenre.MUSIC);
\r
102 put("バラエティー",ProgGenre.VARIETYSHOW);
\r
103 put("バラエティ",ProgGenre.VARIETYSHOW);
\r
105 put("スポーツ",ProgGenre.SPORTS);
\r
107 put("ニュース/報道",ProgGenre.NEWS);
\r
109 put("アダルト",ProgGenre.NOGENRE);
\r
115 public void loadProgram(String areaCode, boolean force) {
\r
116 // 新しい入れ物(トップ)を用意する
\r
117 newplist = new ArrayList<ProgList>();
\r
119 nf = new HashMap<String, String>();
\r
120 gf = new HashMap<String, String>();
\r
122 // 最終日の24時以降の情報は、+1したとこから取得する
\r
123 int counterMax = getSortedCRlist().size() * (getDogDays()+1);
\r
125 for ( Center c : getSortedCRlist() ) {
\r
126 if (getDebug()) System.err.println(DBGID+"load program: "+c.getCenter());
\r
127 _loadProgram(c, force, counter, counterMax);
\r
128 counter += getDogDays()+1;
\r
131 // 古いデータから補完できないかな?
\r
132 CompensatesPrograms(newplist);
\r
136 for ( String f : nf.keySet() ) {
\r
137 System.err.println(String.format("【デバッグ情報】未定義のフラグです: [%s]",f));
\r
139 for ( String g : gf.keySet() ) {
\r
140 System.err.println(String.format("【デバッグ情報】未定義のジャンルです: [%s]",g));
\r
145 pcenter = newplist;
\r
155 protected void _loadProgram(Center cr, boolean force, int counter, int counterMax) {
\r
161 ProgList pl = new ProgList();
\r
162 pl.Center = cr.getCenter();
\r
163 pl.CenterId = cr.getLink();
\r
167 if ( cr.getCenterOrig().startsWith(CHNM_PREFIX_BS) ) {
\r
170 else if ( cr.getCenterOrig().startsWith(CHNM_PREFIX_CS) ) {
\r
173 if ( onid != -1 ) {
\r
174 Matcher ma = Pattern.compile("(\\d+)").matcher(cr.getCenterOrig());
\r
176 ContentIdDIMORA.decodeChId(String.format("%04X%04X%04X", onid,0,Integer.valueOf(ma.group(1))));
\r
177 pl.ChId = ContentIdDIMORA.getContentId(0,"");
\r
181 pl.Area = cr.getAreaCode();
\r
182 pl.BgColor = cr.getBgColor();
\r
190 for ( int dtidx=0; dtidx<pl.pdate.size(); dtidx++ ) {
\r
192 GregorianCalendar cal = CommonUtils.getCalendar(pl.pdate.get(dtidx).Date);
\r
194 boolean isNextpageExist = true;
\r
195 for ( int pgidx=1; isNextpageExist; pgidx++ ) {
\r
197 final String progCacheFile =
\r
198 pgidx == 1 ? String.format("%s%sSKP2012_%s_%d.txt", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH)) :
\r
199 String.format("%s%sSKP2012_%s_%d_%d.txt", getProgDir(), File.separator, pl.CenterId, cal.get(Calendar.DAY_OF_MONTH),pgidx);
\r
201 File f = new File(progCacheFile);
\r
202 if (force == true ||
\r
203 (f.exists() == true && isCacheOld(progCacheFile) == true) ||
\r
204 (f.exists() == false && isCacheOld(null) == true)) {
\r
206 String xtype = (pl.CenterId.startsWith(CHID_PREFIX_BS) || pl.CenterId.startsWith(CHID_PREFIX_CS)) ? XTYPE_BASIC : XTYPE_PREMIUM;
\r
207 String chid = xtype != XTYPE_PREMIUM ? pl.CenterId : pl.CenterId.replaceFirst("^"+CHID_PREFIX_PR, "");
\r
208 String dt = CommonUtils.getDateYMD(cal);
\r
209 String url = "http://bangumi.skyperfectv.co.jp/"+xtype+"/channel:"+chid+"/date:"+dt.substring(2)+"/";
\r
211 url += "?p="+pgidx;
\r
214 if ( pl.ChId.length() == 0 ) {
\r
215 url = "http://bangumi.skyperfectv.co.jp/api/version:3/search/date:"+dt.substring(2)+"/channel:"+pl.CenterId+"/?api_key=336eec3423";
\r
218 url = "http://www.skyperfectv.co.jp/xml/"+dt+"_"+pl.ChId.substring(2)+".xml";
\r
221 webToFile(url, progCacheFile, thisEncoding);
\r
223 printProgress("(オンライン)を取得しました", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), url);
\r
225 else if (CommonUtils.isFileAvailable(f,10)) {
\r
226 printProgress("(キャッシュ)を取得しました", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), progCacheFile);
\r
229 printProgress("(キャッシュ)がみつかりません", counter+dtidx, pgidx, counterMax, pl.Center, cal.get(Calendar.DAY_OF_MONTH), progCacheFile);
\r
233 String response = CommonUtils.read4file(progCacheFile, true);
\r
234 if ( response == null || ! response.matches("^.*<a href=\"\\?p=\\d+[^>]+?>次.*$") ) {
\r
235 isNextpageExist = false;
\r
240 getPrograms(pl, dtidx, response);
\r
242 if ( pl.ChId.length() == 0 ) {
\r
243 getPrograms(pl, i, response);
\r
246 getPrograms_basic(pl, i, response);
\r
250 catch ( Exception e ) {
\r
251 e.printStackTrace();
\r
257 refreshList(pl.pdate);
\r
259 catch (Exception e) {
\r
261 System.out.println("Exception: _loadProgram()");
\r
265 private void printProgress(String msg, int count, int pgidx, int countMax, String center, int date, String uri) {
\r
266 reportProgress(String.format("%s %s: (%d/%d) page=%d %s[%d日] %s", getTVProgramId(), msg, count, countMax, pgidx, center, date, uri));
\r
269 private void getDate(ProgList pl) {
\r
271 GregorianCalendar c = new GregorianCalendar();
\r
272 c.setTime(new Date());
\r
273 if ( CommonUtils.isLateNight(c) ) {
\r
275 c.add(Calendar.DATE, -1);
\r
277 // 最終日の24時以降の情報は、+1したとこから取得する
\r
278 for ( int i=0; i<getDogDays()+1; i++ ) {
\r
279 ProgDateList cl = new ProgDateList();
\r
280 cl.Date = CommonUtils.getDate(c);
\r
283 c.add(Calendar.DATE,1);
\r
288 private void refreshList(ArrayList<ProgDateList> pcenter) {
\r
290 for ( int i=0; i<pcenter.size(); i++ ) {
\r
291 ProgDateList pl = pcenter.get(i);
\r
292 GregorianCalendar ca = CommonUtils.getCalendar(pl.Date);
\r
293 for ( int j=pl.pdetail.size()-1,k=0; j>=0; j--,k++ ) {
\r
294 ProgDetailList pdl = pl.pdetail.get(j);
\r
295 GregorianCalendar cz = (GregorianCalendar) ca.clone();
\r
297 if ( CommonUtils.isLateNight(pdl.start.substring(0,2)) ) {
\r
299 ca.add(Calendar.DATE, 1);
\r
300 cz = (GregorianCalendar) ca.clone();
\r
302 else if ( pdl.start.compareTo(pdl.end) > 0 ) {
\r
304 cz.add(Calendar.DATE, 1);
\r
308 if ( pdl.start.compareTo(pdl.end) > 0 ) {
\r
310 ca.add(Calendar.DATE, -1);
\r
313 pdl.accurateDate = CommonUtils.getDate(ca);
\r
314 pdl.startDateTime = CommonUtils.getDate(ca,false)+" "+pdl.start;
\r
315 pdl.endDateTime = CommonUtils.getDate(cz,false)+" "+pdl.end;
\r
320 ProgDateList all = new ProgDateList();
\r
321 all.pdetail = new ArrayList<ProgDetailList>();
\r
322 for ( ProgDateList pcl : pcenter ) {
\r
323 for ( ProgDetailList pdl : pcl.pdetail ) {
\r
324 if ( all.row == 0 ) {
\r
325 String prevend = CommonUtils.getDateTime(CommonUtils.getCalendar(pcenter.get(0).Date+" 05:00"));
\r
326 if ( prevend.compareTo(pdl.startDateTime) < 0 ) {
\r
328 addEnmptyInfo(all, prevend, pdl.startDateTime);
\r
332 ProgDetailList prevpdl = all.pdetail.get(all.pdetail.size()-1);
\r
333 if ( prevpdl.startDateTime.equals(pdl.startDateTime) ) {
\r
337 else if ( prevpdl.endDateTime.compareTo(pdl.startDateTime) < 0 ) {
\r
339 addEnmptyInfo(all, prevpdl.endDateTime, pdl.startDateTime);
\r
342 all.pdetail.add(pdl);
\r
343 all.row += pdl.length;
\r
346 pcl.pdetail = new ArrayList<ProgDetailList>();
\r
351 for ( ProgDetailList pdl : all.pdetail ) {
\r
353 for ( ProgDateList pcl : pcenter ) {
\r
354 GregorianCalendar cz = CommonUtils.getCalendar(pcl.Date+" 05:00");
\r
355 String da = CommonUtils.getDateTime(cz);
\r
356 cz.add(Calendar.DATE, 1);
\r
357 String dz = CommonUtils.getDateTime(cz);
\r
358 if ( CommonUtils.isOverlap(pdl.startDateTime, pdl.endDateTime, da, dz, true) ) {
\r
359 if ( cnt++ == 0 ) {
\r
360 pcl.pdetail.add(pdl);
\r
363 pcl.pdetail.add(pdl.clone());
\r
369 // 24時以降の情報は日付+1したとこから取得しているので、最終日の次のリストは削除
\r
370 pcenter.remove(pcenter.size()-1);
\r
373 for ( ProgDateList pcl : pcenter ) {
\r
375 for ( ProgDetailList pdl : pcl.pdetail ) {
\r
376 String da = (pcl.row == 0) ? pcl.Date+" 05:00" : pdl.startDateTime;
\r
377 pdl.length = (int)(CommonUtils.getCompareDateTime(pdl.endDateTime, da)/60000L);
\r
378 pcl.row += pdl.length;
\r
380 // おしりがとどかない場合(デメリット:これをやると、サイト側のエラーで欠けてるのか、そもそも休止なのかの区別がつかなくなる)
\r
381 if ( pcl.row < 24*60 ) {
\r
382 GregorianCalendar ca = CommonUtils.getCalendar(pcl.Date+" 05:00");
\r
383 GregorianCalendar cz = (GregorianCalendar) ca.clone();
\r
384 ca.add(Calendar.MINUTE, pcl.row);
\r
385 cz.add(Calendar.MINUTE, 24*60);
\r
386 addEnmptyInfo(pcl, CommonUtils.getDateTime(ca), CommonUtils.getDateTime(cz));
\r
392 private void getPrograms(ProgList pl, int dtidx, String response) {
\r
394 ProgDateList pcl = pl.pdate.get(dtidx);
\r
396 String[][] keys = {
\r
397 { "class", "pg-title" },
\r
398 { "class", "start-time" },
\r
399 { "class", "end-time" },
\r
400 { "class", "pg-genre" },
\r
401 { "class", "pg-explanation" },
\r
402 { "id", "actor-name" },
\r
405 Matcher ma = Pattern.compile("<tbody\\s+id=\"event-\\d+\"[^>]*?>(.+?)</tbody>",Pattern.DOTALL).matcher(response);
\r
406 for ( int cnt = 0; ma.find(); cnt++ ) {
\r
407 ProgDetailList pdl = new ProgDetailList();
\r
408 String subtitle = "";
\r
409 String person = "";
\r
411 for ( String[] k : keys ) {
\r
412 Matcher mb = Pattern.compile("<span\\s+"+k[0]+"=\""+k[1]+"\"[^>]*?>\\s*(.+?)\\s*</span>",Pattern.DOTALL).matcher(ma.group(1));
\r
413 while ( mb.find() ) {
\r
414 if ( mb.group(1) == null ) {
\r
418 if ( k[1].equals("pg-title") ) {
\r
419 pdl.title = CommonUtils.unEscape(mb.group(1)).trim();
\r
421 else if ( k[1].equals("start-time") ) {
\r
422 pdl.start = mb.group(1);
\r
424 else if ( k[1].equals("end-time") ) {
\r
425 pdl.end = mb.group(1);
\r
427 GregorianCalendar c = CommonUtils.getCalendar(pcl.Date);
\r
429 if ( cnt == 0 && pdl.start.compareTo(pdl.end) > 0 ) {
\r
430 c.add(Calendar.DATE, -1);
\r
432 pdl.accurateDate = CommonUtils.getDate(c);
\r
433 pdl.startDateTime = CommonUtils.getDate(c,false)+" "+pdl.start;
\r
435 if ( pdl.start.compareTo(pdl.end) > 0 ) {
\r
436 c.add(Calendar.DATE, 1);
\r
438 pdl.endDateTime = CommonUtils.getDate(c,false)+" "+pdl.end;
\r
440 pdl.length = CommonUtils.getRecMinVal(pdl.start, pdl.end);
\r
442 else if ( k[1].equals("pg-genre") ) {
\r
443 Matcher mc = Pattern.compile("/large_genre:(.+?)/medium_genre:(.+?)/",Pattern.DOTALL).matcher(mb.group(1));
\r
446 String grstr = URLDecoder.decode(mc.group(1),"utf8").replaceAll("/", "/");
\r
447 ProgGenre gr = ProgGenre.get(grstr);
\r
448 if ( gr == null ) {
\r
449 gr = genremap.get(grstr);
\r
452 gr = ProgGenre.NOGENRE;
\r
453 gf.put(grstr,null);
\r
456 if ( pdl.genre == null || (pdl.genre == ProgGenre.NOGENRE && gr != ProgGenre.NOGENRE) ) {
\r
460 String sgstr = URLDecoder.decode(mc.group(2),"utf8").replaceAll("ィー", "ィ");
\r
461 ProgSubgenre sg = ProgSubgenre.get(gr, sgstr);
\r
462 if ( sg == null ) {
\r
464 ArrayList<ProgSubgenre> vals = ProgSubgenre.values(gr);
\r
465 sg = vals.get(vals.size()-1);
\r
468 } catch (UnsupportedEncodingException e) {
\r
469 e.printStackTrace();
\r
470 pdl.genre = ProgGenre.NOGENRE;
\r
471 pdl.subgenre = ProgSubgenre.NOGENRE_ETC;
\r
475 pdl.genre = ProgGenre.NOGENRE;
\r
476 pdl.subgenre = ProgSubgenre.NOGENRE_ETC;
\r
479 else if ( k[1].equals("pg-explanation") ) {
\r
480 pdl.detail += CommonUtils.decBr(CommonUtils.unEscape(mb.group(1))).trim()+"\n";
\r
482 else if ( k[1].equals("actor-name") ) {
\r
483 person += "、"+CommonUtils.unEscape(mb.group(1)).trim();
\r
489 if ( person.length() > 0 ) {
\r
490 person = person.substring(1);
\r
495 ((subtitle.length()>0)?(subtitle+DETAIL_SEP):(""))
\r
497 +((person.length()>0)?(DETAIL_SEP+person):(""));
\r
498 pdl.detail = pdl.detail.replaceFirst("[\r\n]+$", "");
\r
500 Matcher mb = Pattern.compile("<img\\s+src=\"/i/icon_(.+?)\\.gif",Pattern.DOTALL).matcher(ma.group(1));
\r
501 while ( mb.find() ) {
\r
502 if ( mb.group(1).equals("5.1") ) {
\r
503 pdl.addOption(ProgOption.SURROUND);
\r
505 else if ( mb.group(1).equals("jimaku") ) {
\r
506 pdl.addOption(ProgOption.SUBTITLE);
\r
508 else if ( mb.group(1).equals("2kakoku") ) {
\r
509 pdl.addOption(ProgOption.BILINGUAL);
\r
511 else if ( mb.group(1).equals("fukikae") ) {
\r
512 pdl.addOption(ProgOption.STANDIN);
\r
514 else if ( mb.group(1).equals("tajuu") ) {
\r
515 pdl.addOption(ProgOption.MULTIVOICE);
\r
517 else if ( mb.group(1).equals("r15") || mb.group(1).equals("r18") || mb.group(1).equals("adult") ) {
\r
518 pdl.addOption(ProgOption.RATING);
\r
520 else if ( mb.group(1).equals("ppv") ) {
\r
521 pdl.addOption(ProgOption.PV);
\r
523 else if ( mb.group(1).equals("nama") ) {
\r
524 pdl.addOption(ProgOption.LIVE);
\r
527 nf.put(mb.group(1), null);
\r
531 // タイトルから各種フラグを分離する
\r
532 doSplitFlags(pdl, nf);
\r
534 // サブタイトル分離(ポインタを活用してメモリを節約する)
\r
535 doSplitSubtitle(pdl);
\r
538 if ( ContentIdDIMORA.isValid(pl.ChId) ) {
\r
539 pdl.progid = pl.ChId;
\r
543 pdl.extension = false;
\r
544 pdl.nosyobo = false;
\r
546 pcl.pdetail.add(pdl);
\r
548 if (getDebug()) System.err.println(DBGID+"program: "+pdl.startDateTime+" - "+pdl.endDateTime+" "+pdl.length+"m "+pdl.noscrumble+" "+pdl.title);
\r
554 * こちらは番組IDがとれる代わりに出演者情報がとれなくなるので保留とする
\r
556 private void getPrograms_basic(ProgList pl, int dtidx, String response) {
\r
558 Matcher ma = Pattern.compile("<SIInformation(.+?)</SIInformation>",Pattern.DOTALL).matcher(response);
\r
559 while ( ma.find() ) {
\r
560 Matcher mb = Pattern.compile("eventId=\"(.+?)\".+?broadCastStartDate=\"(\\d{8})(\\d{4})",Pattern.DOTALL).matcher(ma.group(1));
\r
565 mb = Pattern.compile("<(.+?)>(.+?)</\\1>",Pattern.DOTALL).matcher(ma.group(1));
\r
566 while ( mb.find() ) {
\r
567 if ( mb.group(1).equals("ChannelName") ) {
\r
570 else if ( mb.group(1).equals("Title") ) {
\r
573 else if ( mb.group(1).equals("Synopsis") ) {
\r
576 else if ( mb.group(1).equals("Genres") ) {
\r
577 Matcher mc = Pattern.compile("<Genre majorGenreId=\".+?\" minorGenreId=\".+?\"",Pattern.DOTALL).matcher(mb.group(2));
\r
578 while ( mc.find() ) {
\r
589 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
590 * ★★★★★ 放送地域を取得する(TVAreaから降格)-ここから ★★★★★
\r
591 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
599 public String getDefaultArea() {return "全国";}
\r
600 private String getDefaultCode() {return "SKP2012";}
\r
603 public void loadAreaCode() {
\r
604 aclist = new ArrayList<AreaCode>();
\r
605 AreaCode ac = new AreaCode();
\r
606 ac.setArea(getDefaultArea());
\r
607 ac.setCode(getDefaultCode());
\r
608 ac.setSelected(true);
\r
612 public void saveAreaCode() {}
\r
615 public String getArea(String code) { return(getDefaultArea()); }
\r
617 public String getCode(String area) { return(getDefaultCode()); }
\r
619 public String setSelectedAreaByName(String area) { return(getDefaultCode()); }
\r
621 public String getSelectedArea() { return(getDefaultArea()); }
\r
623 public String getSelectedCode() { return(getDefaultCode()); }
\r
626 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
627 * ★★★★★ 放送地域を取得する(TVAreaから降格)-ここまで ★★★★★
\r
628 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
634 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
635 * ★★★★★ 放送局を選択する(TVCenterから降格)-ここから ★★★★★
\r
636 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
643 // 設定ファイルがなければWebから取得
\r
645 public void loadCenter(String code, boolean force) {
\r
647 if ( code == null ) {
\r
648 System.out.println(ERRID+"地域コードがnullです.");
\r
652 String centerListFile = getCenterListFile(getTVProgramId(), code);
\r
655 File f = new File(centerListFile);
\r
659 File f = new File(centerListFile);
\r
660 if (f.exists() == true) {
\r
661 @SuppressWarnings("unchecked")
\r
662 ArrayList<Center> tmp = (ArrayList<Center>)CommonUtils.readXML(centerListFile);
\r
663 if ( tmp != null ) {
\r
670 {CHNM_PREFIX_BS, CHID_PREFIX_BS},
\r
671 {CHNM_PREFIX_CS, CHID_PREFIX_CS},
\r
672 {CHNM_PREFIX_PR, CHID_PREFIX_PR},
\r
676 for ( Center cr : crlist ) {
\r
677 for ( String[] a : prs ) {
\r
678 if ( cr.getCenterOrig().startsWith(a[0]) ) {
\r
679 if ( ! cr.getLink().startsWith(a[1]) ) {
\r
680 Matcher ma = Pattern.compile("^.*?(\\d+)",Pattern.DOTALL).matcher(cr.getCenterOrig());
\r
682 String chid = a[1]+ma.group(1);
\r
683 System.err.println(DBGID+"converted: "+cr.getCenterOrig()+", "+cr.getLink()+" -> "+chid);
\r
693 System.out.println("放送局リストを読み込みました: "+centerListFile);
\r
697 System.out.println("放送局リストの読み込みに失敗しました: "+centerListFile);
\r
702 ArrayList<Center> newcrlist = new ArrayList<Center>();
\r
704 for ( String xtype : new String[] { XTYPE_BASIC,XTYPE_PREMIUM } ) {
\r
705 ArrayList<Center> crl = getCenters(xtype,code);
\r
706 if ( crl != null ) {
\r
707 reportProgress("放送局情報を取得しました: ("+xtype+") "+crl.size()+"ch");
\r
710 for ( Center cr : crl ) {
\r
715 if ( newcrlist.size() == 0 ) {
\r
716 System.err.println(ERRID+"放送局情報の取得結果が0件だったため情報を更新しません");
\r
720 crlist = newcrlist;
\r
721 attachChFilters(); // 放送局名にフィルタをかける
\r
725 private ArrayList<Center> getCenters(String xtype, String areacode) {
\r
727 ArrayList<Center> crl = new ArrayList<Center>();
\r
729 String url = String.format("http://bangumi.skyperfectv.co.jp/index/channel/%s/",xtype);
\r
730 if (getDebug()) System.err.println(DBGID+"get page: "+url);
\r
731 String response = webToBuffer(url,thisEncoding,true);
\r
732 if ( response == null ) {
\r
733 reportProgress("放送局情報の取得に失敗しました: "+xtype);
\r
737 Matcher ma = Pattern.compile("<td class=\"channel-icon\">\\s*<a href=\".*?/channel:(.+?)/\".*?>\\s*<img src=\".*?\" alt=\"(.+?)\"",Pattern.DOTALL).matcher(response);
\r
738 while ( ma.find() ) {
\r
739 String chid = (xtype.equals(XTYPE_PREMIUM) ? CHID_PREFIX_PR : "") + ma.group(1);
\r
740 String chnm = CommonUtils.toHANALNUM(CommonUtils.unEscape(ma.group(2))).replaceFirst("[ \\t]+▲$", "");
\r
743 if ( xtype.equals(XTYPE_PREMIUM) && ! chnm.startsWith(CHNM_PREFIX_PR) ) {
\r
744 chnm = CHNM_PREFIX_PR+chnm;
\r
747 Center cr = new Center();
\r
748 cr.setAreaCode(areacode);
\r
750 cr.setEnabled(true);
\r
751 cr.setCenterOrig(chnm);
\r
755 for ( Center ct : crl ) {
\r
756 if ( ct.getCenterOrig().compareTo(cr.getCenterOrig()) > 0 ) {
\r
763 if (getDebug()) System.err.println(DBGID+"center: "+cr.getCenterOrig()+", "+cr.getLink());
\r
770 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
771 * ★★★★★ 放送局を選択する(TVCenterから降格)-ここまで ★★★★★
\r
772 * ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r