OSDN Git Service

db173a4e8849a7a90a87facca8e4af32e2a8b40f
[tainavi/TinyBannavi.git] / TinyBannavi / src / tainavi / HDDRecorderUtils.java
1 package tainavi;\r
2 \r
3 import java.io.BufferedReader;\r
4 import java.io.File;\r
5 import java.io.IOException;\r
6 import java.io.InputStreamReader;\r
7 import java.io.OutputStreamWriter;\r
8 import java.io.UnsupportedEncodingException;\r
9 import java.net.Authenticator;\r
10 import java.net.DatagramPacket;\r
11 import java.net.DatagramSocket;\r
12 import java.net.HttpURLConnection;\r
13 import java.net.InetSocketAddress;\r
14 import java.net.PasswordAuthentication;\r
15 import java.net.SocketException;\r
16 import java.net.URL;\r
17 import java.util.ArrayList;\r
18 import java.util.Calendar;\r
19 import java.util.Date;\r
20 import java.util.GregorianCalendar;\r
21 import java.util.Hashtable;\r
22 import java.util.List;\r
23 import java.util.Map;\r
24 import java.util.regex.Matcher;\r
25 import java.util.regex.Pattern;\r
26 \r
27 \r
28 /**\r
29  * {@link HDDRecorder}インタフェース をインプルメントしたレコーダプラグインのクラスで利用できる、共有部品の集合です。\r
30  * @version 3.15.4β クラス名を RecorderUtils から HDDRecorderUtils に変更しました。\r
31  */\r
32 public class HDDRecorderUtils implements HDDRecorder,Cloneable {\r
33         \r
34         /*******************************************************************************\r
35          * ディープコピーが意外と大変\r
36          ******************************************************************************/\r
37         \r
38         public HDDRecorderUtils clone() {\r
39                 try {\r
40                         HDDRecorderUtils ru = (HDDRecorderUtils) super.clone();\r
41                         FieldUtils.deepCopy(ru, this); // ディープコピーするよ\r
42                         return ru;\r
43                 } catch (CloneNotSupportedException e) {\r
44                         throw new InternalError(e.toString());\r
45                 }\r
46         }\r
47 \r
48         /*******************************************************************************\r
49          * オプション確認\r
50          ******************************************************************************/\r
51         \r
52         @Override\r
53         public boolean isThereAdditionalDetails() { return false; }\r
54         @Override\r
55         public boolean isEditAutoReserveSupported() { return false; }\r
56         @Override\r
57         public boolean isRepeatReserveSupported() { return true; }\r
58         @Override\r
59         public boolean isPursuesEditable() { return false; }\r
60         @Override\r
61         public boolean isAutocompleteSupported() { return true; }\r
62         @Override\r
63         public boolean isChangeChannelSupported() { return ChangeChannel(null); }\r
64         @Override\r
65         public boolean isBackgroundOnly() { return false; }\r
66         @Override\r
67         public boolean isChValueAvailable() { return false; }\r
68         @Override\r
69         public boolean isChCodeNeeded() { return true; }\r
70         @Override\r
71         public boolean isRecChNameNeeded() { return true; }\r
72         @Override\r
73         public boolean isBroadcastTypeNeeded() { return false; }\r
74         @Override\r
75         public boolean isAutoEncSelectEnabled() { return true; }\r
76         @Override\r
77         public String getChDatHelp() { return ""; }\r
78         \r
79         // フリーテキストによるオプション指定\r
80         @Override\r
81         public boolean setOptString(String s) { return true; }          // ダミー\r
82         @Override\r
83         public String getOptString() { return null; }   // ダミー\r
84         \r
85         \r
86         /*******************************************************************************\r
87          * 定数\r
88          ******************************************************************************/\r
89         \r
90         // メッセージID\r
91         private static final String MSGID = "[レコーダ共通] ";\r
92         private static final String DBGID = "[DEBUG]"+MSGID;\r
93         private static final String ERRID = "[ERROR]"+MSGID;\r
94         \r
95         \r
96         /*******************************************************************************\r
97          * メンバ変数関連\r
98          ******************************************************************************/\r
99         \r
100         // デバッグログを出力するか\r
101         public void setDebug(boolean b) { debug = b; }\r
102         protected boolean getDebug() { return debug; }\r
103         private boolean debug = false;\r
104         \r
105         // 終了時刻と開始時刻が重なる番組を重複扱いするか\r
106         public void setAdjNotRep(boolean b) { adjnotrep = b; }\r
107         private boolean getAdjNotRep() { return adjnotrep; }\r
108         private boolean adjnotrep = false;\r
109 \r
110         // カレンダー連携を行うかどうか\r
111         public void setUseCalendar(boolean b) { usecalendar = b; }\r
112         public boolean getUseCalendar() { return usecalendar; }\r
113         private boolean usecalendar = true;\r
114 \r
115         // チャンネル操作を行うかどうか\r
116         public void setUseChChange(boolean b) { usechchange = b; }\r
117         public boolean getUseChChange() { return usechchange; }\r
118         private boolean usechchange = true;\r
119 \r
120         // 録画完了チェックの範囲\r
121         public void setRecordedCheckScope(int n) { recordedCheckScope = n; }\r
122         protected int getRecordedCheckScope() { return recordedCheckScope; }\r
123         private int recordedCheckScope = 14;\r
124 \r
125         // 録画結果一覧の保存期間\r
126         public void setRecordedSaveScope(int n) { recordedSaveScope = n; }\r
127         protected int getRecordedSaveScope() { return recordedSaveScope; }\r
128         private int recordedSaveScope = 90;\r
129         \r
130         // HTTPアクセス時のUser-Agent\r
131         public void setUserAgent(String s) { userAgent = s; }\r
132         //public String getUserAgent() { return userAgent; }\r
133         private String userAgent = "";\r
134         \r
135         \r
136         /*******************************************************************************\r
137          * レコーダーの固有情報\r
138          ******************************************************************************/\r
139         \r
140         public String Myself() { return(getIPAddr()+":"+getPortNo()+":"+getRecorderId()); }\r
141         public boolean isMyself(String myself) { return Myself().equals(myself); }\r
142         \r
143         protected ArrayList<TextValueSet> vrate = new ArrayList<TextValueSet>();\r
144         protected ArrayList<TextValueSet> arate = new ArrayList<TextValueSet>();\r
145         protected ArrayList<TextValueSet> folder = new ArrayList<TextValueSet>();\r
146         protected ArrayList<TextValueSet> encoder = new ArrayList<TextValueSet>();\r
147         protected ArrayList<TextValueSet> dvdcompat = new ArrayList<TextValueSet>();\r
148         protected ArrayList<TextValueSet> device = new ArrayList<TextValueSet>();\r
149         protected ArrayList<TextValueSet> channel = new ArrayList<TextValueSet>();\r
150         protected ArrayList<TextValueSet> xchapter = new ArrayList<TextValueSet>();\r
151         protected ArrayList<TextValueSet> mschapter = new ArrayList<TextValueSet>();\r
152         protected ArrayList<TextValueSet> mvchapter = new ArrayList<TextValueSet>();\r
153         protected ArrayList<TextValueSet> chvalue = new ArrayList<TextValueSet>();\r
154         protected ArrayList<TextValueSet> chtype = new ArrayList<TextValueSet>();\r
155         protected ArrayList<TextValueSet> genre = new ArrayList<TextValueSet>();\r
156 \r
157         protected ArrayList<TextValueSet> aspect = new ArrayList<TextValueSet>();\r
158         protected ArrayList<TextValueSet> bvperf = new ArrayList<TextValueSet>();\r
159         protected ArrayList<TextValueSet> lvoice = new ArrayList<TextValueSet>();\r
160         protected ArrayList<TextValueSet> autodel = new ArrayList<TextValueSet>();\r
161         \r
162         public ArrayList<TextValueSet> getVideoRateList() { return(vrate); }\r
163         public ArrayList<TextValueSet> getAudioRateList() { return(arate); }\r
164         public ArrayList<TextValueSet> getFolderList() { return(folder); }\r
165         public ArrayList<TextValueSet> getEncoderList() { return(encoder); }\r
166         public ArrayList<TextValueSet> getDVDCompatList() { return(dvdcompat); }\r
167         public ArrayList<TextValueSet> getDeviceList() { return(device); }\r
168         public ArrayList<TextValueSet> getXChapter() { return(xchapter); }\r
169         public ArrayList<TextValueSet> getMsChapter() { return(mschapter); }\r
170         public ArrayList<TextValueSet> getMvChapter() { return(mvchapter); }\r
171         public ArrayList<TextValueSet> getChValue() { return(chvalue); }\r
172         public ArrayList<TextValueSet> getChType() { return(chtype); }\r
173 \r
174         public ArrayList<TextValueSet> getAspect() { return(aspect); }\r
175         public ArrayList<TextValueSet> getBVperf() { return(bvperf); }\r
176         public ArrayList<TextValueSet> getLVoice() { return(lvoice); }\r
177         public ArrayList<TextValueSet> getAutodel() { return(autodel); }\r
178         \r
179         public String getLabel_Videorate() { return null; }\r
180         public String getLabel_Audiorate() { return null; }\r
181         public String getLabel_Folder() { return null; }\r
182         public String getLabel_Device() { return null; }\r
183         public String getLabel_DVDCompat() { return null; }\r
184         public String getLabel_XChapter() { return null; }\r
185         public String getLabel_MsChapter() { return null; }\r
186         public String getLabel_MvChapter() { return null; }\r
187         public String getLabel_Aspect() { return null; }\r
188         public String getLabel_BVperf() { return null; }\r
189         public String getLabel_LVoice() { return null; }\r
190         public String getLabel_Autodel() { return null; }\r
191 \r
192         /*******************************************************************************\r
193          * レコーダー操作のための固有情報\r
194          ******************************************************************************/\r
195         \r
196         public String getRecorderId() { return "THIS IS DUMMY METHOD"; }\r
197         \r
198         private String recorderIPAddr = "";\r
199         private String recorderPortNo = "";\r
200         private String recorderUser = "";\r
201         private String recorderPasswd = "";\r
202         private String recorderMacAddr = "";\r
203         private String recorderBroadcast = "";\r
204         private int recorderTunerNum = 0;\r
205 \r
206         public String getIPAddr() { return recorderIPAddr; }\r
207         public void setIPAddr(String s) { recorderIPAddr = s; }\r
208         public String getPortNo() { return recorderPortNo; }\r
209         public void setPortNo(String s) { recorderPortNo = s; }\r
210         public String getUser() { return recorderUser; }\r
211         public void setUser(String s) { recorderUser = s; }\r
212         public String getPasswd() { return recorderPasswd; }\r
213         public void setPasswd(String s) { recorderPasswd = s; }\r
214         public String getMacAddr() { return recorderMacAddr; }\r
215         public void setMacAddr(String s) { recorderMacAddr = s; }\r
216         public String getBroadcast() { return recorderBroadcast; }\r
217         public void setBroadcast(String s) { recorderBroadcast = s; }\r
218         public int getTunerNum() { return recorderTunerNum; }\r
219         public void setTunerNum(int n) { recorderTunerNum = n; }\r
220 \r
221         // エンコーダ別の配色を取得する\r
222         public String getColor(String tuner) {\r
223                 //\r
224                 if (tuner != null && tuner.length() != 0) {\r
225                         int idx = 0;\r
226                         for (TextValueSet e : getEncoderList()) {\r
227                                 if (tuner.equals(e.getText())) {\r
228                                         if (recorderColorList.size() > idx) {\r
229                                                 return recorderColorList.get(idx);\r
230                                         }\r
231                                         break;\r
232                                 }\r
233                                 idx++;\r
234                         }\r
235                 }\r
236                 // 適当なエンコーダが見つからない場合は既定値\r
237                 return recorderColorList.get(0);\r
238         }\r
239         \r
240         // Envからもらってきたものを分解して保持する\r
241         public void setColor(String s) {\r
242                 //\r
243                 recorderColorList.clear();\r
244                 //\r
245                 Matcher ma = null;\r
246                 ma = Pattern.compile("^#......$").matcher(s);\r
247                 if (ma.find()) {\r
248                         recorderColorList.add(s);\r
249                 }\r
250                 else {\r
251                         ma = Pattern.compile("(#......);").matcher(s);\r
252                         while (ma.find()) {\r
253                                 recorderColorList.add(ma.group(1));\r
254                         }\r
255                 }\r
256                 return;\r
257         }\r
258 \r
259         public ArrayList<String> getColors() { return recorderColorList; }\r
260         \r
261         private ArrayList<String> recorderColorList = new ArrayList<String>();\r
262         \r
263         /**\r
264          * 特定の予約を決め打ちで\r
265          */\r
266         public ReserveList getReserveList(String rsvId) {\r
267                 for ( ReserveList rsv : RESERVES ) {\r
268                         if ( rsv.getId() != null && rsv.getId().equals(rsvId) ) {\r
269                                 return rsv;\r
270                         }\r
271                 }\r
272                 return null;\r
273         }\r
274         \r
275         /**\r
276          * 持っている予約をすべて…吐き出させるっ…!\r
277          */\r
278         public ArrayList<ReserveList> getReserves() { return RESERVES; }\r
279         \r
280         private ArrayList<ReserveList> RESERVES = new ArrayList<ReserveList>();\r
281         \r
282         /**\r
283          * 自動予約一覧\r
284          */\r
285         public AutoReserveInfoList getAutoReserves() { return AUTORESERVES; }\r
286         private AutoReserveInfoList AUTORESERVES = new AutoReserveInfoList(Env.envDir,null,"dummy","0.0.0.0","0");\r
287         \r
288         /**\r
289          * 録画済み一覧\r
290          */\r
291         public ArrayList<RecordedInfo> getRecorded() { return RECORDED; }\r
292         protected void setRecorded(ArrayList<RecordedInfo> r ) { RECORDED = r; }\r
293         \r
294         private ArrayList<RecordedInfo> RECORDED = new ArrayList<RecordedInfo>();\r
295         \r
296         /*******************************************************************************\r
297          * 小物\r
298          ******************************************************************************/\r
299         \r
300         // 素直にHashMapつかっておけばよかった\r
301         public String text2value(ArrayList<TextValueSet> tvs, String text) {\r
302                 for ( TextValueSet t : tvs ) {\r
303                         if (t.getText().equals(text)) {\r
304                                 return(t.getValue());\r
305                         }\r
306                 }\r
307                 return("");\r
308         }\r
309         public String value2text(ArrayList<TextValueSet> tvs, String value) {\r
310                 for ( TextValueSet t : tvs ) {\r
311                         if (t.getValue().equals(value)) {\r
312                                 return(t.getText());\r
313                         }\r
314                 }\r
315                 return("");\r
316         }\r
317         \r
318         protected TextValueSet add2tvs(ArrayList<TextValueSet> tvs, String text, String value) {\r
319                 TextValueSet t = new TextValueSet();\r
320                 t.setText(text);\r
321                 t.setValue(value);\r
322                 tvs.add(t);\r
323                 return t;\r
324         }\r
325         protected TextValueSet add2tvs(int n, ArrayList<TextValueSet> tvs, String text, String value) {\r
326                 TextValueSet t = new TextValueSet();\r
327                 t.setText(text);\r
328                 t.setValue(value);\r
329                 tvs.add(n,t);\r
330                 return t;\r
331         }\r
332         \r
333         // 予約日付をId化する(単日以外)\r
334         protected int getRec_pattern_Id(String s) {\r
335                 int i = 0;\r
336                 for (; i<HDDRecorder.RPTPTN.length;i++) {\r
337                         //System.out.println(s + "->" + HDDRecorder.RPTPTN[i]);\r
338                         if (s.equals(HDDRecorder.RPTPTN[i])) {\r
339                                 return(i);\r
340                         }\r
341                 }\r
342                 return(i);\r
343         }\r
344         \r
345         /* 予約IDが動的に変化するレコーダ向けの処理 */\r
346         private int rsvcnt = 0;\r
347         protected String getUniqId(String rsvId) { return (!rsvId.startsWith("U$"))?(String.format("U$%14s,%05d,%s",CommonUtils.getDateTimeYMD(0),(rsvcnt++)%100000,rsvId)):(rsvId); }\r
348         protected String getRsvId(String uniqId) { return (uniqId.startsWith("U$"))?(uniqId.substring(23)):(uniqId); }\r
349         \r
350 \r
351         // 開始日時・終了日時を算出する\r
352         public void getStartEndDateTime(ReserveList r) {\r
353                 // \r
354                 GregorianCalendar c = CommonUtils.getCalendar(r.getRec_nextdate());\r
355                 if ( c != null ) {\r
356                         // ★★★ MM/DDをYYYY/MM/DDに戻す? ★★★\r
357                         c.set(Calendar.MINUTE, Integer.valueOf(r.getAmm()));\r
358                         c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(r.getAhh()));\r
359                         r.setStartDateTime(CommonUtils.getDateTime(c));\r
360         \r
361                         c.add(Calendar.MINUTE, Integer.valueOf(r.getRec_min()));\r
362                         r.setEndDateTime(CommonUtils.getDateTime(c));\r
363                 }\r
364         }\r
365         \r
366         //\r
367         public String[] _mmdd2yyyymmdd(String mm, String dd)\r
368         {\r
369                 GregorianCalendar c = new GregorianCalendar();\r
370                 c.setTime(new Date());\r
371                 if ( Integer.valueOf(mm) < c.get(Calendar.MONTH)+1 ) {\r
372                         c.add(Calendar.YEAR, 1);\r
373                 }\r
374                 \r
375                 return (new String[] { String.format("%04d",c.get(Calendar.YEAR)), mm, dd });\r
376         }\r
377         \r
378         //\r
379         public String[] _hhmm2hhmm_min(String ahhmm, String zhhmm)\r
380         {\r
381                 String ahh="";\r
382                 String amm="";\r
383                 String zhh="";\r
384                 String zmm="";\r
385                 \r
386                 Matcher ma = Pattern.compile("^(\\d+):(\\d+)").matcher(ahhmm);\r
387                 if (ma.find()) {\r
388                         ahh = String.format("%02d",Integer.valueOf(ma.group(1)));\r
389                         amm = String.format("%02d",Integer.valueOf(ma.group(2)));\r
390                 }\r
391                 \r
392                 ma = Pattern.compile("^(\\d+):(\\d+)").matcher(zhhmm);\r
393                 if (ma.find()) {\r
394                         zhh = String.format("%02d",Integer.valueOf(ma.group(1)));\r
395                         zmm = String.format("%02d",Integer.valueOf(ma.group(2)));\r
396                 }\r
397                 \r
398                 int min = Integer.valueOf(zhh)*60+Integer.valueOf(zmm) - (Integer.valueOf(ahh)*60+Integer.valueOf(amm));\r
399                 if ( min < 0 ) min += 24*60;\r
400                 \r
401                 return (new String[] {ahh, amm, zhh, zmm, Integer.toString(min)});\r
402         }\r
403 \r
404         // レコーダの設定情報をキャッシュする\r
405         public ArrayList<TextValueSet> TVSload(String filename) {\r
406                 File f = new File(filename);\r
407                 if ( ! f.exists() ) {\r
408                 return new ArrayList<TextValueSet>();\r
409                 }\r
410                 \r
411                 @SuppressWarnings("unchecked")\r
412                 ArrayList<TextValueSet> ar = (ArrayList<TextValueSet>) CommonUtils.readXML(filename);\r
413                 if ( ar == null ) {\r
414                 System.err.println("設定ファイルの読み込みに失敗しました: "+filename);\r
415                 return new ArrayList<TextValueSet>();\r
416                 }\r
417                 \r
418                 return ar;\r
419         }\r
420         public void TVSsave(ArrayList<TextValueSet> ar, String filename) {\r
421                 if ( ! CommonUtils.writeXML(filename, ar) ) {\r
422                 System.err.println("設定ファイルの保存に失敗しました: "+filename);\r
423                 }\r
424         }\r
425 \r
426         /**\r
427          * レコーダの予約リストをキャッシュする\r
428          * @param rsvedFile\r
429          * @return nullは返さない!\r
430          * @see #ReservesToFile(ArrayList, String)\r
431          */\r
432         protected ArrayList<ReserveList> ReservesFromFile(String rsvedFile) {\r
433                 File f = new File(rsvedFile);\r
434                 if ( ! f.exists() ) {\r
435                 System.out.println("+予約キャッシュはありません: "+rsvedFile);\r
436                 return new ArrayList<ReserveList>();\r
437                 }\r
438                 \r
439                 @SuppressWarnings("unchecked")\r
440                 ArrayList<ReserveList> tmp = (ArrayList<ReserveList>) CommonUtils.readXML(rsvedFile);\r
441                 if ( tmp == null ) {\r
442                 System.err.println("予約キャッシュの読み込みに失敗しました: "+rsvedFile);\r
443                 return new ArrayList<ReserveList>();\r
444                 }\r
445 \r
446                 /* もういらんやろ\r
447         // 後方互換\r
448         for (ReserveList r : tmp) {\r
449                 if (r.getId() == null && r.getNo() > 0) {\r
450                         r.setId(String.valueOf(r.getNo()));\r
451                 }\r
452         }\r
453         */\r
454                 \r
455         System.out.println("+予約キャッシュを読み込みました("+tmp.size()+"): "+rsvedFile);\r
456         return tmp;\r
457         }\r
458         \r
459         /**\r
460          * @param reserves\r
461          * @param rsvedFile\r
462          * @see #ReservesFromFile(String)\r
463          */\r
464         protected void ReservesToFile(ArrayList<ReserveList> reserves, String rsvedFile) {\r
465                 if ( ! CommonUtils.writeXML(rsvedFile, reserves) ) {\r
466                 System.err.println("予約キャッシュの保存に失敗しました: "+rsvedFile);\r
467                 }\r
468         }\r
469 \r
470         /**\r
471          * レコーダの録画結果リストをキャッシュする<BR>\r
472          * ※キャッシュから取得したものはIDがnullでクリアされる\r
473          * @param recedFile\r
474          * @return nullは返さない!\r
475          * @see #RecordedToFile(ArrayList, String)\r
476          */\r
477         protected ArrayList<RecordedInfo> RecordedFromFile(String recedFile) {\r
478                 \r
479                 File f = new File(recedFile);\r
480                 if ( ! f.exists() ) {\r
481                 System.out.println("+録画結果キャッシュはありません: "+recedFile);\r
482                 return new ArrayList<RecordedInfo>();\r
483                 }\r
484                 \r
485                 @SuppressWarnings("unchecked")\r
486                 ArrayList<RecordedInfo> tmp = (ArrayList<RecordedInfo>) CommonUtils.readXML(recedFile);\r
487                 if ( tmp == null ) {\r
488                 System.err.println("録画結果キャッシュの読み込みに失敗しました: "+recedFile);\r
489                 return new ArrayList<RecordedInfo>();\r
490                 }\r
491                 \r
492                 // 期限切れの情報は捨てる\r
493                 String critDate = CommonUtils.getDate(CommonUtils.getCalendar(-86400*getRecordedSaveScope()));\r
494                 String specialDate = CommonUtils.getDate(CommonUtils.getCalendar("1970/01/01"));\r
495                 for ( int i=tmp.size()-1; i>=0; i-- ) {\r
496                         if ( tmp.get(i).getDate().compareTo(critDate) < 0 && tmp.get(i).getDate().compareTo(specialDate) > 0) {\r
497                                 // 期限切れ\r
498                                 if (debug) System.out.println("録画結果のキャッシュを削除しました: "+tmp.get(i).getDate()+" "+tmp.get(i).getTitle());\r
499                                 tmp.remove(i);\r
500                         }\r
501                         else {\r
502                                 // オワタ\r
503                                 break;\r
504                         }\r
505                 }\r
506                 \r
507                 for ( RecordedInfo ri : tmp ) {\r
508                         // キャッシュから読みだしたものはIDをクリアする\r
509                         ri.setId(null);\r
510                         // 後方互換\r
511                         if ( ri.getCh_orig() == null ) {\r
512                                 ri.setCh_orig(ri.getCh_name());\r
513                         }\r
514                 }\r
515                 \r
516         System.out.println("+録画結果キャッシュを読み込みました("+tmp.size()+"件): "+recedFile);\r
517         return tmp;\r
518         }\r
519         \r
520         /**\r
521          * @param reserves\r
522          * @param recedFile\r
523          * @see #RecordedToFile(ArrayList, String)\r
524          */\r
525         protected void RecordedToFile(ArrayList<RecordedInfo> recorded, String recedFile) {\r
526                 if ( ! CommonUtils.writeXML(recedFile, recorded) ) {\r
527                 System.err.println("録画結果キャッシュの保存に失敗しました: "+recedFile);\r
528                 }\r
529         }\r
530         \r
531         /*\r
532          * \r
533          */\r
534         protected boolean matchReserveV1(ReserveList n, ReserveList o) {\r
535                 return (\r
536                                 n.getTitle().equals(o.getTitle()) &&\r
537                                 n.getChannel().equals(o.getChannel()) &&\r
538                                 n.getRec_pattern().equals(o.getRec_pattern()) &&\r
539                                 n.getAhh().equals(o.getAhh()) && n.getAmm().equals(o.getAmm())\r
540                 );\r
541         }\r
542         public void setReservesV1(ArrayList<ReserveList> r) {\r
543                 // ライン入力のチャンネル名を保持する\r
544                 //System.out.println(RESERVES.size()+","+r.size());\r
545                 for (ReserveList o : RESERVES) {\r
546                         for (ReserveList n : r) {\r
547                                 if (matchReserveV1(n, o)) {\r
548                                         // 外部入力以外は知らん\r
549                                         if (o.getCh_name() != null && n.getCh_name() != null && n.getCh_name().startsWith("外部入力")) {\r
550                                                 System.out.println("外部入力を次の放送局で置き換えます: "+n.getCh_name()+"->"+o.getCh_name());\r
551                                                 n.setCh_name(o.getCh_name());\r
552                                         }\r
553                                         \r
554                                         // 鯛ナビの内部フラグ\r
555                                         n.setAutocomplete(o.getAutocomplete());\r
556                                         // 予約一覧からは取得できない情報\r
557                                         n.setDetail(o.getDetail());\r
558                                         n.setRec_genre(o.getRec_genre());\r
559                                         n.setRec_device(o.getRec_device());\r
560                                         n.setRec_folder(o.getRec_folder());\r
561                                         n.setRec_dvdcompat(o.getRec_dvdcompat());\r
562                                         n.setRec_xchapter(o.getRec_xchapter());\r
563                                         n.setRec_mschapter(o.getRec_mschapter());\r
564                                         n.setRec_mvchapter(o.getRec_mvchapter());\r
565                                         //\r
566                                         n.setRec_aspect(o.getRec_aspect());\r
567                                         n.setRec_bvperf(o.getRec_bvperf());\r
568                                         n.setRec_lvoice(o.getRec_lvoice());\r
569                                         n.setRec_autodel(o.getRec_autodel());\r
570                                 }\r
571                         }\r
572                 }\r
573                 //\r
574                 RESERVES = r;\r
575                 //\r
576                 refreshReserves();\r
577         }\r
578         public void setReserves(ArrayList<ReserveList> r) {\r
579                 // ライン入力のチャンネル名を保持する\r
580                 for (ReserveList o : RESERVES) {\r
581                         for (ReserveList n : r) {\r
582                                 // 外部入力以外は知らん\r
583                                 if (o.getCh_name() != null && n.getCh_name() != null && n.getCh_name().startsWith("外部入力")) {\r
584                                         if (o.getId() == n.getId() && o.getChannel().equals(n.getChannel())) {\r
585                                                 System.out.println("外部入力を次の放送局で置き換えます: "+n.getCh_name()+"->"+o.getCh_name());\r
586                                                 n.setCh_name(o.getCh_name());\r
587                                         }\r
588                                 }\r
589                         }\r
590                 }\r
591                 // 主にDIGA用\r
592                 {\r
593                         if ( getTunerNum() >= 2 ) {\r
594                                 // 2チューナー以上は可変\r
595                                 \r
596                                 // ちょっと時刻順に整理しよう\r
597                                 ArrayList<ReserveList> s = new ArrayList<ReserveList>();\r
598                                 for ( ReserveList o : r ) {\r
599                                         int idx = -1;\r
600                                         for ( int i=0; i<s.size(); i++ ) {\r
601                                                 if ( o.getStartDateTime().compareTo(s.get(i).getStartDateTime()) < 0 ) {\r
602                                                         idx = i;\r
603                                                         break;\r
604                                                 }\r
605                                         }\r
606                                         if ( idx == -1 ) {\r
607                                                 s.add(o);\r
608                                         }\r
609                                         else {\r
610                                                 s.add(idx,o);\r
611                                         }\r
612                                         \r
613                                         o.setTuner("");\r
614                                 }\r
615 \r
616                                 // チューナーを割り振ろう\r
617                                 for ( int x=0; x<s.size(); x++ ) {\r
618                                         // 全チューナーをリストアップする\r
619                                         ArrayList<String> tuns = new ArrayList<String>();\r
620                                         for ( TextValueSet enc : encoder ) {\r
621                                                 tuns.add(enc.getText());\r
622                                         }\r
623                                         // 残っているチューナーをリストアップする\r
624                                         for ( int y=0; y<s.size() && tuns.size()>0; y++ ) {\r
625                                                 if ( x == y || s.get(y).getTuner().equals("") ) {\r
626                                                         // 自分自身と、チューナー番号が振られていない相手はスルー\r
627                                                         continue;\r
628                                                 }\r
629                                                 // 時間が重なっている予約が既に使用しているチューナーは除外する\r
630                                                 ArrayList<String> starts = new ArrayList<String>();\r
631                                                 ArrayList<String> ends = new ArrayList<String>();\r
632                                                 CommonUtils.getStartEndList(starts, ends, s.get(y));\r
633                                                 for ( int z=0; z<starts.size(); z++ ) {\r
634                                                         // 帯予約を正しく処理するために全予約日時をなめるようにする\r
635                                                         if ( CommonUtils.isOverlap(s.get(x).getStartDateTime(), s.get(x).getEndDateTime(), starts.get(z), ends.get(z), getAdjNotRep()) ) {\r
636                                                                 tuns.remove(s.get(y).getTuner());\r
637                                                                 break;\r
638                                                         }\r
639                                                 }\r
640                                         }\r
641                                         // 残っているチューナーを割り振る\r
642                                         if ( tuns.size() == 0 ) {\r
643                                                 // 余ってないなら全部0\r
644                                                 s.get(x).setTuner(encoder.get(0).getText());\r
645                                         }\r
646                                         else {\r
647                                                 // 余っているならそのうちの最初のものを使用\r
648                                                 s.get(x).setTuner(tuns.get(0));\r
649                                         }\r
650                                 }\r
651                         }\r
652                         else if ( getTunerNum() == 1 ) {\r
653                                 // 1チューナーは固定値\r
654                                 for ( int x=0; x<r.size(); x++ ) {\r
655                                         r.get(x).setTuner("■");\r
656                                 }\r
657                         }\r
658                 }\r
659 \r
660                 //\r
661                 RESERVES = r;\r
662                 \r
663                 //\r
664                 refreshReserves();\r
665         }\r
666         public void refreshReserves() {\r
667                 //\r
668                 String curDateTime = CommonUtils.getCritDateTime();\r
669                 //\r
670                 for (int i=RESERVES.size()-1; i>=0; i--) {\r
671                         ReserveList r = RESERVES.get(i);\r
672                         if (r.getRec_pattern_id() == HDDRecorder.RPTPTN_ID_BYDATE) {\r
673                                 // 単日予約\r
674                                 if (r.getEndDateTime().compareTo(curDateTime) < 0) {\r
675                                         // 当日以前のエントリを削除\r
676                                         RESERVES.remove(r);\r
677                                 }\r
678                         }\r
679                         else {\r
680                                 // 繰り返し予約\r
681                                 String nextDate = CommonUtils.getNextDate(r);\r
682                                 r.setRec_nextdate(nextDate);\r
683                         }\r
684                 }\r
685         }\r
686         \r
687         \r
688         \r
689         \r
690         /***\r
691          *  RDデジタル系の予約一覧の解読\r
692          */\r
693         protected ArrayList<ReserveList> decodeReservedList(String response) {\r
694                 \r
695                 ArrayList<ReserveList> newReserveList = new ArrayList<ReserveList>();\r
696                 \r
697                 Matcher ma = Pattern.compile("(c1\\[\\d+?\\]=[\\s\\S]+?\";)\\n").matcher(response);\r
698                 while ( ma.find() ) {\r
699                         // 個々のデータを取り出す\r
700                         ReserveList entry = new ReserveList();\r
701                         \r
702                         Matcher mb = null;\r
703                                 \r
704                         String[] d = new String[17];\r
705                         mb = Pattern.compile("c\\d+?\\[\\d+?\\]=\"(.*?)\";").matcher(ma.group(1));\r
706                         for (int i=0; i<d.length; i++) {\r
707                                 if ( mb.find()) {\r
708                                         d[i] = mb.group(1);\r
709                                 }\r
710                                 //System.out.println(i+") "+d[i]);\r
711                         }\r
712                         \r
713                         // 実行ON/OFF\r
714                         if (d[1].equals("2")) {\r
715                                 entry.setExec(false);\r
716                         }\r
717                         \r
718                         // 番組追跡\r
719                         //if (d[12].equals("0") || d[12].equals("4") || d[12].equals("3")) {\r
720                         if (d[12].equals("4")) {\r
721                                 entry.setPursues(true);\r
722                         }\r
723                         \r
724                         // 記録先デバイス\r
725                         entry.setRec_device(d[8]);\r
726                         \r
727                         // 予約名のエスケープを解除する\r
728                         String title = CommonUtils.unEscape(d[2]).replaceAll("<BR>","");\r
729 \r
730                         //\r
731                         entry.setId(d[0]);\r
732                         \r
733                         //\r
734                         entry.setRec_pattern(d[5]);\r
735                         entry.setRec_pattern_id(getRec_pattern_Id(entry.getRec_pattern()));\r
736                         mb = Pattern.compile("(\\d\\d):(\\d\\d).*?(\\d\\d):(\\d\\d)").matcher(d[6]+"-"+d[7]);\r
737                         if (mb.find()) {\r
738                                 entry.setAhh(mb.group(1));\r
739                                 entry.setAmm(mb.group(2));\r
740                                 entry.setZhh(mb.group(3));\r
741                                 entry.setZmm(mb.group(4));\r
742                         }\r
743                         entry.setRec_nextdate(CommonUtils.getNextDate(entry));\r
744                         //entry.setRec_nextdate(getNextDate(entry.getRec_pattern(), entry.getZhh()+":"+entry.getZmm()));\r
745                         entry.setRec_min(CommonUtils.getRecMin(entry.getAhh(), entry.getAmm(), entry.getZhh(), entry.getZmm()));\r
746                         getStartEndDateTime(entry);\r
747                         \r
748                         //\r
749                         if (d[3].equals("18") || d[3].equals("10")  || d[3].equals("9")) {\r
750                                 entry.setTuner("TS2");\r
751                         }\r
752                         else if (d[3].equals("17") || d[3].equals("12")  || d[3].equals("11")) {\r
753                                 entry.setTuner("TS1");\r
754                         }\r
755                         else if (d[3].equals("16") || d[3].equals("7")) {\r
756                                 entry.setTuner("RE");\r
757                         }\r
758                         else {\r
759                                 entry.setTuner("--");\r
760                         }\r
761                         \r
762                         //\r
763                         if (d[10].equals("  ")) {\r
764                                 if (d[9].equals("A1")) {\r
765                                         d[9] = "[TSE] AT 4.7GB";\r
766                                 }\r
767                                 else if (d[9].equals("A2")) {\r
768                                         d[9] = "[TSE] AT 9.4GB";\r
769                                 }\r
770                                 else if (d[9].equals("DL")) {\r
771                                         d[9] = "[TSE] AT 8.5GB";\r
772                                 }\r
773                                 else {\r
774                                         Matcher mc = Pattern.compile("^MN").matcher(d[9]);\r
775                                         if (mc.find()) {\r
776                                                 d[9] = mc.replaceFirst("[TSE] ");\r
777                                         }\r
778                                 }\r
779                         }\r
780                         else {\r
781                                 if (d[9].equals("A1")) {\r
782                                         d[9] = "[VR] AT 4.7GB";\r
783                                 }\r
784                                 else if (d[9].equals("A2")) {\r
785                                         d[9] = "[VR] AT 9.4GB";\r
786                                 }\r
787                                 else if (d[9].equals("DL")) {\r
788                                         d[9] = "[VR] AT 8.5GB";\r
789                                 }\r
790                                 else {\r
791                                         Matcher mc = Pattern.compile("^MN").matcher(d[9]);\r
792                                         if (mc.find()) {\r
793                                                 d[9] = mc.replaceFirst("[VR] ");\r
794                                         }\r
795                                         else if ( d[9].startsWith("SP") || d[9].startsWith("LP")) {\r
796                                                 d[9] = "[VR] "+d[9];\r
797                                         }\r
798                                 }\r
799                         }\r
800                         \r
801                         if (d[9].equals("TS")) {\r
802                                 entry.setRec_mode("[TS]");\r
803                         }\r
804                         else {\r
805                                 entry.setRec_mode(d[9]);\r
806                         }\r
807                         \r
808                         entry.setTitle(title);\r
809                         entry.setTitlePop(TraceProgram.replacePop(title));\r
810                         //entry.setCh_name(getChCode().getCH_NO2NAME(d[4]));    // 機種固有領域に移動\r
811                         entry.setChannel(d[4]);\r
812 \r
813                         entry.setRec_audio(d[10]);\r
814                         //entry.rec_folder = data.get();        // 予約一覧からはとれない\r
815                         //entry.rec_genre = data.get();         // 予約一覧からはとれない\r
816                         \r
817                         // 予約情報を保存\r
818                         newReserveList.add(entry.clone());\r
819                 }\r
820                 return(newReserveList);\r
821         }\r
822         \r
823         /**\r
824          * レコーダーから取得できない情報は直接コピー(既存のリストから探して)\r
825          */\r
826         protected void copyAttributes(ReserveList to, ArrayList<ReserveList> fromlist) {\r
827                 ReserveList olde = null;\r
828                 for ( ReserveList from : fromlist ) {\r
829                         if ( from.getId() != null && from.getId().equals(to.getId()) ) {\r
830                                 copyAttribute(to, olde = from);\r
831                                 break;\r
832                         }\r
833                 }\r
834                 \r
835                 // DIGAの終了時間"未定"対応だけど、別にDIGAかどうか確認したりはしない。\r
836                 setAttributesDiga(to,olde);\r
837         }\r
838         \r
839         /**\r
840          * レコーダーから取得できない情報は直接コピー(既存エントリから直に)\r
841          */\r
842         protected void copyAttribute(ReserveList to, ReserveList from) {\r
843                 // 鯛ナビの内部フラグ\r
844                 to.setAutocomplete(from.getAutocomplete());\r
845                 // 予約一覧からは取得できない情報\r
846                 to.setDetail(from.getDetail());\r
847                 to.setRec_genre(from.getRec_genre());\r
848                 //n.setRec_device(o.getRec_device());\r
849                 to.setRec_folder(from.getRec_folder());\r
850                 to.setRec_dvdcompat(from.getRec_dvdcompat());\r
851                 to.setRec_xchapter(from.getRec_xchapter());\r
852                 to.setRec_mschapter(from.getRec_mschapter());\r
853                 to.setRec_mvchapter(from.getRec_mvchapter());\r
854                 //\r
855                 to.setRec_aspect(from.getRec_aspect());\r
856                 to.setRec_bvperf(from.getRec_bvperf());\r
857                 to.setRec_lvoice(from.getRec_lvoice());\r
858                 to.setRec_autodel(from.getRec_autodel());\r
859                 // BZ700以降の取得一覧から取得できない画質の対応\r
860                 if (to.getRec_mode().equals("")) {\r
861                         to.setRec_mode(from.getRec_mode());\r
862                 }\r
863         }\r
864         \r
865         protected void setAttributesDiga(ReserveList to, ReserveList from) {\r
866                 if ( to.getZhh() != null && to.getZmm() != null && to.getRec_min() != null ) {\r
867                         // 埋まってる\r
868                         return;\r
869                 }\r
870                 \r
871                 if ( from != null && from.getZhh() != null ) {\r
872                         // 引継ぎもとがあれば引き継ぐ\r
873                         to.setZhh(from.getZhh());\r
874                         to.setZmm(from.getZmm());\r
875                         to.setRec_min(from.getRec_min());\r
876                         to.setRec_nextdate(CommonUtils.getNextDate(to));\r
877                         getStartEndDateTime(to);\r
878                         return;\r
879                 }\r
880                 \r
881                 /*\r
882                 // 現在時刻から30分後か、開始時刻から1時間後の、どちらか短い方に強制設定する\r
883                 String curTM = CommonUtils.getTime(30);\r
884                 String endTM = String.format("%02d:%s", (Integer.valueOf(to.getAhh())+1)%24,to.getAmm());\r
885                 if ( curTM.compareTo(endTM) > 0 ) {\r
886                         endTM = curTM;\r
887                 }\r
888                 to.setZhh(endTM.substring(0,2));\r
889                 to.setZmm(endTM.substring(3,5));\r
890                 to.setRec_min(CommonUtils.getRecMin(to.getAhh()+":"+to.getAmm(), endTM));\r
891                 */\r
892                 \r
893                 // 開始時刻から1時間後に強制設定する\r
894                 to.setZhh(String.format("%02d", (Integer.valueOf(to.getAhh())+1)%24));\r
895                 to.setZmm(to.getAmm());\r
896                 to.setRec_min("60");\r
897                 \r
898                 to.setRec_nextdate(CommonUtils.getNextDate(to));\r
899                 getStartEndDateTime(to);\r
900         }\r
901         \r
902         /**\r
903          * 録画済みフラグを立てる\r
904          */\r
905         protected void setRecordedFlag() {\r
906                 \r
907                 // 過去X日分までチェック(初期値は14日)\r
908                 final String critDateTime = CommonUtils.getDateTimeW(-86400*getRecordedCheckScope());\r
909                 \r
910                 for ( ReserveList reserved : RESERVES ) {\r
911                         reserved.setRecorded(false);\r
912                 }\r
913                 \r
914                 for ( RecordedInfo recorded : RECORDED ) {\r
915                         if ( critDateTime.compareTo(recorded.getDate()+" "+recorded.getAhh()+":"+recorded.getAmm()) > 0 ) {\r
916                                 break;\r
917                         }\r
918                         String chktitle = recorded.getTitle().replaceFirst(TVProgram.titlePrefixRemoveExpr, "");\r
919                         for ( ReserveList reserved : RESERVES ) {\r
920                                 if ( reserved.getRecorded() ) {\r
921                                         // 既にフラグが立ってるものはスルー\r
922                                         continue;\r
923                                 }\r
924                                 if ( reserved.getRec_pattern_id() != HDDRecorder.RPTPTN_ID_BYDATE ) {\r
925                                         // 単日予約のみ\r
926                                         continue;\r
927                                 }\r
928                                 String restitle = reserved.getTitle().replaceFirst(TVProgram.titlePrefixRemoveExpr, "");\r
929                                 boolean chchk = (recorded.getChannel() != null && recorded.getChannel().length() > 0) ?  (recorded.getChannel().equals(reserved.getChannel())) : (true);\r
930                                 if ( recorded.getSucceeded() && recorded.getDrop_mpeg() == 0 && chchk && chktitle.equals(restitle) ) {\r
931                                         // 成功していて、放送局とタイトルが一致\r
932                                         reserved.setRecorded(true);\r
933                                 }\r
934                         }\r
935                 }\r
936         }\r
937         \r
938         /**\r
939          * 録画結果一覧は開始日時降順で保存\r
940          * @param newRecordedList\r
941          * @param entry\r
942          */\r
943         protected RecordedInfo addRecorded(ArrayList<RecordedInfo> newRecordedList, RecordedInfo entry) {\r
944                 \r
945                 String endt = entry.getDate()+entry.getAhh()+entry.getAmm();\r
946                 \r
947                 int n = 0;\r
948                 int dn = -1;\r
949                 for ( ; n<newRecordedList.size(); n++ ) {\r
950                         RecordedInfo ri = newRecordedList.get(n);\r
951                         String ridt = ri.getDate()+ri.getAhh()+ri.getAmm();\r
952                         int result = ridt.compareTo(endt);\r
953                         if ( result == 0 ) {\r
954                                 if ( dn == -1 ) {\r
955                                         // 開始時刻が同じ情報を発見したら、最終的にはそれの前に差し込みたいので、nを保存する\r
956                                         dn = n;\r
957                                 }\r
958                                 \r
959                                 // 開始時刻が一致して\r
960                                 if ( ri.getId() == null ) {\r
961                                         // キャッシュから取得したものだった場合に重複チェックする\r
962                                         if ( ri.getTitle().equals(entry.getTitle()) && ri.getCh_orig().equals(entry.getCh_orig()) && ri.getLength() == entry.getLength()/* && ri.getDrop() == entry.getDrop()*/ ) {\r
963                                                 // 重複しているようなので捨てる\r
964                                                 System.out.println(MSGID+"録画結果はすでにキャッシュ上に存在していたようです: "+endt+" "+entry.getTitle());\r
965                                                 return null;\r
966                                         }\r
967                                         else {\r
968                                                 if (getDebug()) System.out.println(DBGID+"よく似た録画結果です: "+endt+" "+entry.getTitle()+" <-> "+ridt+ri.getTitle());\r
969                                         }\r
970                                 }\r
971                         }\r
972                         else if ( result < 0 ) {\r
973                                 break;\r
974                         }\r
975                 }\r
976                 \r
977                 entry.setDrop_mpeg(entry.getDrop()-entry.getDrop_mpeg());\r
978                 \r
979                 newRecordedList.add((dn!=-1)?(dn):(n),entry);\r
980                 \r
981                 if (getDebug()) System.out.println(DBGID+"録画結果を追加しました: "+endt+" "+entry.getTitle());\r
982                 \r
983                 return entry;\r
984         }\r
985 \r
986         /**\r
987          * <P>自動予約一覧の置き換え\r
988          * <P>chCode→chName変換もこの中でやる\r
989          */\r
990         protected void setAutoReserves(AutoReserveInfoList l) {\r
991                 for ( AutoReserveInfo r : l ) {\r
992                         r.clearChNames();\r
993                         for ( String chCode : r.getChCodes() ) {\r
994                                 String chName = getChCode().getCH_CODE2WEB(chCode);\r
995                                 r.addChName((chName!=null) ? chName : chCode);\r
996                         }\r
997                 }\r
998                 AUTORESERVES = l;\r
999         }\r
1000         \r
1001         /*******************************************************************************\r
1002          * ログと進捗ダイアログ\r
1003          ******************************************************************************/\r
1004         \r
1005         private StatusWindow stw = null;\r
1006         public void setProgressArea(StatusWindow o) { stw = o; }\r
1007         protected void reportProgress(String msg) {\r
1008                 if (stw != null) {\r
1009                         stw.append(msg);\r
1010                 }\r
1011                 System.out.println(msg);\r
1012         }\r
1013         \r
1014         // RD系のNewId取得\r
1015         protected String getNewId(String response) {\r
1016                 Matcher ma = null;\r
1017                 String newid = null;\r
1018                 ma = Pattern.compile("c1\\[\\d+?\\]=\"(\\d+?)\";").matcher(response);\r
1019                 while (ma.find()) {\r
1020 \r
1021                         String idtmp = ma.group(1);\r
1022                         \r
1023                         boolean flag = true;\r
1024                         for (ReserveList rx : getReserves()) {\r
1025                                 if (rx.getId().equals(idtmp)) {\r
1026                                         flag = false;\r
1027                                         break;\r
1028                                 }\r
1029                         }\r
1030                         if (flag == true) {\r
1031                                 newid = idtmp;\r
1032                                 break;\r
1033                         }\r
1034                 }\r
1035                 return(newid);\r
1036         }\r
1037         \r
1038         /*******************************************************************************\r
1039          * ログ系\r
1040          ******************************************************************************/\r
1041         \r
1042         protected void ShowReserves(ArrayList<ReserveList> ress) {\r
1043                 \r
1044                 System.out.println("---Reserved List Start---");\r
1045                 int i=0;\r
1046                 for ( ReserveList e : ress ) {\r
1047                         // 詳細情報の取得\r
1048                         System.out.println(String.format("[%s] %s\t%s\t%s %s:%s-%s:%s\t%sm\t%s\t%s\t%s(%s)\t%s\t%s\t%s",\r
1049                                         ++i, e.getId(), e.getRec_pattern(), e.getRec_nextdate(), e.getAhh(), e.getAmm(), e.getZhh(), e.getZmm(), e.getRec_min(), e.getContentId(), e.getRec_audio(), e.getTitle(), e.getTitlePop(), e.getChannel(), e.getCh_name(), e.getRecorded()));\r
1050                 }\r
1051                 System.out.println("---Reserved List End---");\r
1052                 \r
1053         }\r
1054         \r
1055         protected void ShowRecorded(ArrayList<RecordedInfo> recs) {\r
1056                 \r
1057                 System.out.println("---Recorded List Start---");\r
1058                 int i=0;\r
1059                 for ( RecordedInfo e : recs ) {\r
1060                         // 詳細情報の取得\r
1061                         System.out.println(String.format("[%s] %s %s\t%s:%s-%s:%s\t%s(%s)\t%s",\r
1062                                         ++i, e.getId(), e.getDate(), e.getAhh(), e.getAmm(), e.getZhh(), e.getZmm(), e.getTitle(), e.getCh_name(), e.getResult()));\r
1063                 }\r
1064                 System.out.println("---Recorded List End---");\r
1065                 \r
1066         }\r
1067 \r
1068         /*******************************************************************************\r
1069          * 通信系\r
1070          ******************************************************************************/\r
1071 \r
1072         private final DumpHttp dump = new DumpHttp();\r
1073         \r
1074         //\r
1075         public void wakeup() {\r
1076                 if ( ! getMacAddr().equals("") && ! getBroadcast().equals("")) {\r
1077                         //\r
1078                         byte[] magic = new byte[102];\r
1079                         int i = 0;\r
1080                         for (; i<6; i++) {\r
1081                                 magic[i] = (byte) 0xff;\r
1082                         }\r
1083                         for (int j=0; j<16; j++) {\r
1084                                 for (int k=0; k<6; k++) {\r
1085                                         short sv = Short.decode("0x"+getMacAddr().substring(k*2,k*2+2));\r
1086                                         magic[i++] = (byte)sv;\r
1087                                 }\r
1088                         }\r
1089                         \r
1090                         //\r
1091                         try {\r
1092                                 InetSocketAddress remote = new InetSocketAddress(getBroadcast(), 1234);\r
1093                                 DatagramPacket packet = new DatagramPacket(magic, magic.length, remote);\r
1094                                 new DatagramSocket().send(packet);\r
1095                         } catch (SocketException e) {\r
1096                                 e.printStackTrace();\r
1097                         } catch (IOException e) {\r
1098                                 e.printStackTrace();\r
1099                         }\r
1100                         \r
1101                         //\r
1102                         System.out.println("send magic packet to "+getBroadcast()+","+getMacAddr());\r
1103                 }\r
1104         }\r
1105         \r
1106         //\r
1107         public void shutdown() {\r
1108                 // おまじない\r
1109                 Authenticator.setDefault(new MyAuthenticator(getUser(), getPasswd()));\r
1110                 //\r
1111                 reqGET("http://"+getIPAddr()+":"+getPortNo()+"/remote/remote.htm?key=12", null);\r
1112                 //\r
1113                 System.out.println("send shutdown request to "+getBroadcast()+","+getMacAddr());\r
1114         }\r
1115         \r
1116         // おまじない\r
1117         public class MyAuthenticator extends Authenticator {\r
1118                 private String username;\r
1119                 private String password;\r
1120 \r
1121                 public MyAuthenticator(String username, String password) {\r
1122                         this.username = username;\r
1123                         this.password = password;\r
1124                 }\r
1125                 protected PasswordAuthentication getPasswordAuthentication() {\r
1126                         return new PasswordAuthentication(username, password.toCharArray());\r
1127                 }\r
1128         }\r
1129         \r
1130         // GET\r
1131         public String[] reqGET(String uri, Hashtable<String, String>property) {\r
1132                 return reqGET(uri, property, "MS932");\r
1133         }\r
1134         public String[] reqGET(String uri, Hashtable<String, String>property, String encoding)\r
1135         {\r
1136         //CookieManager manager = new CookieManager();\r
1137         //CookieHandler.setDefault(manager);\r
1138 \r
1139                 String header = "";\r
1140                 String response = "";\r
1141                 boolean getSuccess = false;\r
1142                 \r
1143                 HttpURLConnection conn = null;\r
1144                 BufferedReader reader = null;\r
1145                 InputStreamReader sr = null;\r
1146                 try {\r
1147                         if (debug) {\r
1148                                 System.out.println("# GET: "+uri);\r
1149                                 dump.request("# GET: "+uri);\r
1150                         }\r
1151 \r
1152                         // コネクションの確立\r
1153                         URL url = new URL(uri);\r
1154                         conn = (HttpURLConnection)url.openConnection();\r
1155                         conn.setRequestMethod("GET");\r
1156                         conn.setConnectTimeout(5*1000);\r
1157                         conn.setReadTimeout(15*1000);\r
1158                         conn.addRequestProperty("User-Agent", userAgent);\r
1159                         if (property != null) {\r
1160                                 for (String key : property.keySet()) {\r
1161                                         conn.setRequestProperty(key, property.get(key));\r
1162                                 }\r
1163                         }\r
1164                         \r
1165                         //conn.connect();\r
1166 \r
1167                         Map<String, List<String>> h = conn.getHeaderFields();\r
1168                         for ( String key : h.keySet() ) {\r
1169                                 // ヘッダ情報\r
1170                                 if (key == null) {\r
1171                                         header += h.get(key).get(0)+"\n";\r
1172                                         Matcher ma = Pattern.compile(" 200 ").matcher(h.get(key).get(0).toString());\r
1173                                         if (ma.find()) {\r
1174                                                 getSuccess = true;\r
1175                                         }\r
1176                                 }\r
1177                                 else {\r
1178                                         header += key+": "+h.get(key).get(0)+"\n";\r
1179                                 }\r
1180                         }\r
1181                         if (debug) {\r
1182                                 System.out.println("# Header");\r
1183                                 System.out.println(header);\r
1184                                 dump.res_header("# Header\n"+header);\r
1185                         }\r
1186                         if (getSuccess == false) {\r
1187                                 // コネクション切断はfinallyで\r
1188                                 return(new String[] {header,null});\r
1189                         }\r
1190                         \r
1191                         // データ部\r
1192                         sr = new InputStreamReader(conn.getInputStream(),encoding);\r
1193                         reader = new BufferedReader(sr);\r
1194                         \r
1195                         String s = null;\r
1196                         StringBuilder sb = new StringBuilder();\r
1197                         while ((s = reader.readLine()) != null) {\r
1198                                 sb.append(s);\r
1199                                 sb.append("\n");\r
1200                         }\r
1201                         \r
1202                         response = sb.toString();\r
1203 \r
1204                         // コネクション切断はfinallyで\r
1205 \r
1206                     if (debug) {\r
1207                                 //System.out.printf("# RESPONSE\n%s\n", response);\r
1208                         System.out.println("# DUMP TO FILE: "+dump.res_body("<!-- # RESPONSE -->\n"+response));\r
1209                         }\r
1210                     \r
1211                      return(new String[] {header,response});\r
1212                 }\r
1213                 catch (UnsupportedEncodingException e) {\r
1214                         System.err.println("[ERROR] レコーダへのアクセスで問題が発生しました(GET): "+e.toString());\r
1215                         if (getSuccess == true) {\r
1216                                 return(new String[] {header,null});\r
1217                         }\r
1218                 }\r
1219                 catch (IOException e) {\r
1220                         System.err.println("[ERROR] レコーダへのアクセスで問題が発生しました(GET): "+e.toString());\r
1221                         if (getSuccess == true) {\r
1222                                 return(new String[] {header,null});\r
1223                         }\r
1224                 }\r
1225                 finally {\r
1226                         CommonUtils.closing(reader);\r
1227                         CommonUtils.closing(sr);\r
1228                         CommonUtils.closing(conn);\r
1229                 }\r
1230                 \r
1231                 return(new String[] {null,null});\r
1232         }\r
1233 \r
1234         // POST\r
1235         public String[] reqPOST(String uri, String pstr, Hashtable<String, String>property) {\r
1236                 return reqPOST(uri, pstr, property, "MS932");\r
1237         }\r
1238         public String[] reqPOST(String uri, String pstr, Hashtable<String, String>property, String encoding)\r
1239         {\r
1240         //CookieManager manager = new CookieManager();\r
1241         //CookieHandler.setDefault(manager);\r
1242 \r
1243                 boolean postSuccess = false;\r
1244                 String header = "";\r
1245                 String response = "";\r
1246                 \r
1247                 HttpURLConnection conn = null;\r
1248                 OutputStreamWriter writer = null;\r
1249                 BufferedReader reader = null;\r
1250                 InputStreamReader sr = null;\r
1251                 try {\r
1252                         if (debug) {\r
1253                                 System.out.println("# POST: "+uri+"?"+pstr);\r
1254                                 dump.request("# POST: "+uri+"?"+pstr);\r
1255                         }\r
1256 \r
1257                         URL url = new URL(uri);\r
1258                         conn = (HttpURLConnection)url.openConnection();\r
1259                         conn.setRequestMethod("POST");\r
1260                         conn.setConnectTimeout(5*1000);\r
1261                         conn.setReadTimeout(15*1000);\r
1262                         conn.setDoOutput(true);\r
1263                         conn.addRequestProperty("User-Agent", userAgent);\r
1264                         if (property != null) {\r
1265                                 for (String key : property.keySet()) {\r
1266                                         conn.setRequestProperty(key, property.get(key));\r
1267                                 }\r
1268                         }\r
1269                         \r
1270                         //conn.connect();\r
1271                         \r
1272                         writer = new OutputStreamWriter(conn.getOutputStream(),encoding);\r
1273                         writer.write(pstr);\r
1274                         writer.close();\r
1275                         writer = null;\r
1276 \r
1277                         Map<String, List<String>> h = conn.getHeaderFields();\r
1278                         for ( String key : h.keySet() ) {\r
1279                                 // ヘッダ情報\r
1280                                 if (key == null) {\r
1281                                         header += h.get(key).get(0)+"\n";\r
1282                                         Matcher ma = Pattern.compile(" 200 ").matcher(h.get(key).get(0).toString());\r
1283                                         if (ma.find()) {\r
1284                                                 postSuccess = true;\r
1285                                         }\r
1286                                 }\r
1287                                 else {\r
1288                                         header += key+": "+h.get(key).get(0)+"\n";\r
1289                                 }\r
1290                         }\r
1291                         if (debug) {\r
1292                                 System.out.println("# Header");\r
1293                                 System.out.println(header);\r
1294                                 dump.res_header("# Header\n"+header);\r
1295                         }\r
1296                         if (postSuccess == false) {\r
1297                                 // コネクション切断はfinallyで\r
1298                                 return(new String[] {header,null});\r
1299                         }\r
1300                         \r
1301                         sr = new InputStreamReader(conn.getInputStream(),encoding);\r
1302                         reader = new BufferedReader(sr);\r
1303                         \r
1304                         String s = null;\r
1305                         StringBuilder sb = new StringBuilder();\r
1306                         while ((s = reader.readLine()) != null) {\r
1307                                 sb.append(s);\r
1308                                 sb.append("\n");\r
1309                         }\r
1310 \r
1311                         response = sb.toString();\r
1312 \r
1313                         // コネクション切断はfinallyで\r
1314                     \r
1315                     if (debug) {\r
1316                                 //System.out.printf("# RESPONSE\n%s\n", response);\r
1317                         System.out.println("# DUMP TO FILE: "+dump.res_body("<!-- # RESPONSE -->\n"+response));\r
1318                         }\r
1319 \r
1320                         return(new String[] {header,response});\r
1321                 }\r
1322                 catch (UnsupportedEncodingException e) {\r
1323                         System.err.println("[ERROR] レコーダへのアクセスで問題が発生しました(POST): "+e.toString());\r
1324                         if (postSuccess == true) {\r
1325                                 return(new String[] {header,null});\r
1326                         }\r
1327                 }\r
1328                 catch (IOException e) {\r
1329                         System.err.println("[ERROR] レコーダへのアクセスで問題が発生しました(POST): "+e.toString());\r
1330                         if (postSuccess == true) {\r
1331                                 return(new String[] {header,null});\r
1332                         }\r
1333                 }\r
1334                 finally {\r
1335                         CommonUtils.closing(writer);\r
1336                         CommonUtils.closing(reader);\r
1337                         CommonUtils.closing(sr);\r
1338                         CommonUtils.closing(conn);\r
1339                 }\r
1340                 \r
1341                 return(new String[] {null,null});\r
1342         }\r
1343         \r
1344         /*******************************************************************************\r
1345          * ここから下は該当機能が無効なプラグイン用のダミー\r
1346          ******************************************************************************/\r
1347         \r
1348         @Override\r
1349         public RecType getType() {\r
1350                 return null;\r
1351         }\r
1352         @Override\r
1353         public ChannelCode getChCode() {\r
1354                 return null;\r
1355         }\r
1356         @Override\r
1357         public boolean ChangeChannel(String Channel) {\r
1358                 return false;\r
1359         }\r
1360         @Override\r
1361         public boolean GetRdSettings(boolean force) {\r
1362                 return true;\r
1363         }\r
1364         @Override\r
1365         public boolean GetRdReserve(boolean force) {\r
1366                 return true;\r
1367         }\r
1368         @Override\r
1369         public boolean GetRdAutoReserve(boolean force) {\r
1370                 return true;\r
1371         }\r
1372         @Deprecated\r
1373         @Override\r
1374         public boolean GetRdReserveDetails() {\r
1375                 return false;\r
1376         }\r
1377         @Override\r
1378         public boolean GetRdRecorded(boolean force) {\r
1379                 return true;\r
1380         }\r
1381         @Override\r
1382         public boolean PostRdEntry(ReserveList r) {\r
1383                 return false;\r
1384         }\r
1385         @Override\r
1386         public boolean UpdateRdEntry(ReserveList o, ReserveList r) {\r
1387                 return false;\r
1388         }\r
1389         @Override\r
1390         public ReserveList RemoveRdEntry(String delno) {\r
1391                 return null;\r
1392         }\r
1393         @Override\r
1394         public String getErrmsg() {\r
1395                 return null;\r
1396         }\r
1397 }\r