OSDN Git Service

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