File Source: VlcMediaSourcePlugin.java
/*
P/P * Method: com.dmdirc.addons.mediasource_vlc.VlcMediaSourcePlugin__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 package com.dmdirc.addons.mediasource_vlc;
24
25 import com.dmdirc.addons.nowplaying.MediaSource;
26 import com.dmdirc.addons.nowplaying.MediaSourceState;
27 import com.dmdirc.config.IdentityManager;
28 import com.dmdirc.config.prefs.PreferencesCategory;
29 import com.dmdirc.config.prefs.PreferencesManager;
30 import com.dmdirc.config.prefs.PreferencesSetting;
31 import com.dmdirc.config.prefs.PreferencesType;
32 import com.dmdirc.plugins.Plugin;
33 import com.dmdirc.util.Downloader;
34
35 import java.io.File;
36 import java.io.IOException;
37 import java.net.MalformedURLException;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41
42 /**
43 * Retrieves information from VLC using its HTTP interface.
44 *
45 * @author chris
46 */
/*
P/P * Method: void com.dmdirc.addons.mediasource_vlc.VlcMediaSourcePlugin()
*
* Postconditions:
* this.information == &new HashMap(VlcMediaSourcePlugin#1)
* new HashMap(VlcMediaSourcePlugin#1) num objects == 1
*/
47 public class VlcMediaSourcePlugin extends Plugin implements MediaSource {
48
49 /** The information obtained from VLC. */
50 private final Map<String, String> information
51 = new HashMap<String, String>();
52
53 /** {@inheritDoc} */
54 @Override
55 public MediaSourceState getState() {
/*
P/P * Method: MediaSourceState getState()
*
* Preconditions:
* this.information != null
*
* Presumptions:
* java.util.Map:get(...)@57 != null
*
* Postconditions:
* return_value in Addr_Set{&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#1),&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#5),&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#3),&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#4),&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#2)}
*
* Test Vectors:
* java.lang.String:equalsIgnoreCase(...)@58: {0}, {1}
* java.lang.String:equalsIgnoreCase(...)@60: {0}, {1}
* java.lang.String:equalsIgnoreCase(...)@62: {0}, {1}
*/
56 if (fetchInformation()) {
57 final String output = information.get("state");
58 if (output.equalsIgnoreCase("stop")) {
59 return MediaSourceState.STOPPED;
60 } else if (output.equalsIgnoreCase("playing")) {
61 return MediaSourceState.PLAYING;
62 } else if (output.equalsIgnoreCase("paused")) {
63 return MediaSourceState.PAUSED;
64 } else {
65 return MediaSourceState.NOTKNOWN;
66 }
67 } else {
68 return MediaSourceState.CLOSED;
69 }
70 }
71
72 /** {@inheritDoc} */
73 @Override
74 public String getAppName() {
/*
P/P * Method: String getAppName()
*
* Postconditions:
* return_value == &"VLC"
*/
75 return "VLC";
76 }
77
78 /** {@inheritDoc} */
79 @Override
80 public String getArtist() {
/*
P/P * Method: String getArtist()
*
* Preconditions:
* this.information != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* java.util.Map:containsKey(...)@81: {0}, {1}
*/
81 return information.containsKey("artist") ? information.get("artist") :
82 getFallbackArtist();
83 }
84
85 /**
86 * Retrieves the fallback artist (parsed from the file name).
87 *
88 * @return The fallback artist
89 */
90 private String getFallbackArtist() {
/*
P/P * Method: String getFallbackArtist()
*
* Preconditions:
* this.information != null
*
* Presumptions:
* init'ed(java.io.File.separator)
* init'ed(java.io.File.separatorChar)
* java.util.Map:get(...)@96 != null
*
* Postconditions:
* return_value == &"unknown"
*
* Test Vectors:
* java.util.Map:containsKey(...)@93: {0}, {1}
*/
91 String result = "unknown";
92
93 if (information.containsKey("playlist_current")) {
94 try {
95 final int item = Integer.parseInt(information.get("playlist_current"));
96 String[] bits = information.get("playlist_item_" + item).split(
97 (File.separatorChar=='\\' ? "\\\\" : File.separator));
98 result = bits[bits.length-1];
99 bits = result.split("-");
100 if (bits.length > 1) {
101 result = bits[0];
102 } else {
103 // Whole filename is the title, so no artist is known.
104 result = "unknown";
105 }
106 } catch (NumberFormatException nfe) {
107 // DO nothing
108 }
109 }
110
111 return result;
112 }
113
114 /** {@inheritDoc} */
115 @Override
116 public String getTitle() {
/*
P/P * Method: String getTitle()
*
* Preconditions:
* this.information != null
*
* Postconditions:
* java.lang.String:substring(...)._tainted == 0
* init'ed(return_value)
*
* Test Vectors:
* java.util.Map:containsKey(...)@117: {0}, {1}
*/
117 return information.containsKey("title") ? information.get("title")
118 : getFallbackTitle();
119 }
120
121 /**
122 * Retrieves the fallback title (parsed from the file name).
123 *
124 * @return The fallback title
125 */
126 private String getFallbackTitle() {
/*
P/P * Method: String getFallbackTitle()
*
* Preconditions:
* this.information != null
*
* Presumptions:
* init'ed(java.io.File.separatorChar)
* java.lang.String:indexOf(...)@140 <= 232-2
* java.util.Map:get(...)@133 != null
*
* Postconditions:
* java.lang.String:substring(...)._tainted == 0
* return_value != null
*
* Test Vectors:
* java.lang.String:indexOf(...)@140: {-231..-1}, {0..232-2}
* java.util.Map:containsKey(...)@130: {0}, {1}
*/
127 String result = "unknown";
128
129 // Title is unknown, lets guess using the filename
130 if (information.containsKey("playlist_current")) {
131 try {
132 final int item = Integer.parseInt(information.get("playlist_current"));
133 result = information.get("playlist_item_" + item);
134
135 final int sepIndex = result.lastIndexOf(File.separatorChar);
136 final int extIndex = result.lastIndexOf('.');
137 result = result.substring(sepIndex,
138 extIndex > sepIndex ? extIndex : result.length());
139
140 final int offset = result.indexOf('-');
141 if (offset > -1) {
142 result = result.substring(offset + 1).trim();
143 }
144 } catch (NumberFormatException nfe) {
145 // Do nothing
146 }
147 }
148
149 return result;
150 }
151
152 /** {@inheritDoc} */
153 @Override
154 public String getAlbum() {
/*
P/P * Method: String getAlbum()
*
* Preconditions:
* this.information != null
*
* Postconditions:
* init'ed(return_value)
*/
155 return information.containsKey("album/movie/show title")
156 ? information.get("album/movie/show title") : "unknown";
157 }
158
159 /** {@inheritDoc} */
160 @Override
161 public String getLength() {
162 // This is just seconds, could do with formatting.
/*
P/P * Method: String getLength()
*
* Preconditions:
* this.information != null
*
* Postconditions:
* init'ed(return_value)
*/
163 return information.containsKey("length") ? information.get("length")
164 : "unknown";
165 }
166
167 /** {@inheritDoc} */
168 @Override
169 public String getTime() {
170 // This is just seconds, could do with formatting.
/*
P/P * Method: String getTime()
*
* Preconditions:
* this.information != null
*
* Postconditions:
* init'ed(return_value)
*/
171 return information.containsKey("time") ? information.get("time")
172 : "unknown";
173 }
174
175 /** {@inheritDoc} */
176 @Override
177 public String getFormat() {
/*
P/P * Method: String getFormat()
*
* Preconditions:
* this.information != null
*
* Postconditions:
* init'ed(return_value)
*/
178 return information.containsKey("codec") ? information.get("codec")
179 : "unknown";
180 }
181
182 /** {@inheritDoc} */
183 @Override
184 public String getBitrate() {
/*
P/P * Method: String getBitrate()
*
* Preconditions:
* this.information != null
*
* Postconditions:
* init'ed(return_value)
*/
185 return information.containsKey("bitrate") ? information.get("bitrate")
186 : "unknown";
187 }
188
189 /** {@inheritDoc} */
190 @Override
191 public void onLoad() {
192 // Do nothing
/*
P/P * Method: void onLoad()
*/
193 }
194
195 /** {@inheritDoc} */
196 @Override
197 public void onUnload() {
198 // Do nothing
/*
P/P * Method: void onUnload()
*/
199 }
200
201 /** {@inheritDoc} */
202 @Override
203 public void showConfig(final PreferencesManager manager) {
/*
P/P * Method: void showConfig(PreferencesManager)
*
* Preconditions:
* manager != null
*
* Presumptions:
* com.dmdirc.config.prefs.PreferencesManager:getCategory(...)@213 != null
* init'ed(com.dmdirc.config.prefs.PreferencesType.TEXT)
*/
204 final PreferencesCategory general = new PreferencesCategory("VLC Media Source",
205 "", "category-vlc");
206 final PreferencesCategory instr = new PreferencesCategory("Instructions",
207 "", new InstructionsPanel());
208
209 general.addSetting(new PreferencesSetting(PreferencesType.TEXT,
210 getDomain(), "host", "Hostname and port",
211 "The host and port that VLC listens on for web connections"));
212
213 manager.getCategory("Plugins").addSubCategory(general);
214 general.addSubCategory(instr.setInline());
215 }
216
217 /**
218 * Attempts to fetch information from VLC's web interface.
219 *
220 * @return True on success, false otherwise
221 */
222 private boolean fetchInformation() {
/*
P/P * Method: bool fetchInformation()
*
* Preconditions:
* this.information != null
*
* Presumptions:
* com.dmdirc.config.IdentityManager:getGlobalConfig(...)@228 != null
* com.dmdirc.config.IdentityManager:getGlobalConfig(...)@231 != null
* com.dmdirc.util.Downloader:getPage(...)@228 != null
* com.dmdirc.util.Downloader:getPage(...)@231 != null
*
* Postconditions:
* init'ed(return_value)
*/
223 information.clear();
224 List<String> res;
225 List<String> res2;
226
227 try {
228 res = Downloader.getPage("http://" +
229 IdentityManager.getGlobalConfig().getOption(getDomain(),
230 "host") + "/old/info.html");
231 res2 = Downloader.getPage("http://" +
232 IdentityManager.getGlobalConfig().getOption(getDomain(),
233 "host") + "/old/");
234 } catch (MalformedURLException ex) {
235 return false;
236 } catch (IOException ex) {
237 return false;
238 }
239
240 parseInformation(res, res2);
241
242 return true;
243 }
244
245 /**
246 * Parses the information from the two pages obtained from VLC's web
247 * interface.
248 *
249 * @param res The first page of VLC info (/old/info.html)
250 * @param res2 The second page of VLC info (/old/)
251 */
252 protected void parseInformation(final List<String> res,
253 final List<String> res2) {
/*
P/P * Method: void parseInformation(List, List)
*
* Preconditions:
* res != null
* res2 != null
* (soft) this.information != null
*
* Presumptions:
* java.lang.String:indexOf(...)@258 <= 232-2
* java.lang.String:indexOf(...)@302 <= 232-2
* java.util.Iterator:next(...)@254 != null
* java.util.Iterator:next(...)@270 != null
*
* Test Vectors:
* java.lang.String:endsWith(...)@285: {0}, {1}
* java.lang.String:equalsIgnoreCase(...)@277: {0}, {1}
* java.lang.String:equalsIgnoreCase(...)@279: {0}, {1}
* java.lang.String:equalsIgnoreCase(...)@297: {0}, {1}
* java.lang.String:isEmpty(...)@288: {1}, {0}
* java.lang.String:startsWith(...)@257: {0}, {1}
* java.lang.String:startsWith(...)@274: {0}, {1}
* java.lang.String:startsWith(...)@281: {0}, {1}
* java.lang.String:startsWith(...)@299: {0}, {1}
* java.lang.String:startsWith(...)@301: {0}, {1}
* ...
*/
254 for (String line : res) {
255 final String tline = line.trim();
256
257 if (tline.startsWith("<li>")) {
258 final int colon = tline.indexOf(':');
259 final String key = tline.substring(5, colon).trim().toLowerCase();
260 final String value = tline.substring(colon + 1, tline.length() - 5).trim();
261
262 information.put(key, value);
263 }
264 }
265
266 boolean isPlaylist = false;
267 boolean isCurrent = false;
268 boolean isItem = false;
269 int playlistItem = 0;
270 for (String line : res2) {
271 final String tline = line.trim();
272
273 if (isPlaylist) {
274 if (tline.startsWith("</ul>")) {
275 isPlaylist = false;
276 information.put("playlist_items", Integer.toString(playlistItem));
277 } else if (tline.equalsIgnoreCase("<strong>")) {
278 isCurrent = true;
279 } else if (tline.equalsIgnoreCase("</strong>")) {
280 isCurrent = false;
281 } else if (tline.startsWith("<a href=\"?control=play&")) {
282 isItem = true;
283 } else if (isItem) {
284 String itemname = tline;
285 if (itemname.endsWith("</a>")) {
286 itemname = itemname.substring(0, itemname.length()-4);
287 }
288 if (!itemname.isEmpty()) {
289 if (isCurrent) {
290 information.put("playlist_current", Integer.toString(playlistItem));
291 }
292 information.put("playlist_item_"+Integer.toString(playlistItem++),
293 itemname);
294 }
295 isItem = false;
296 }
297 } else if (tline.equalsIgnoreCase("<!-- Playlist -->")) {
298 isPlaylist = true;
299 } else if (tline.startsWith("State:")) {
300 information.put("state", tline.substring(6, tline.indexOf('<')).trim());
301 } else if (tline.startsWith("got_")) {
302 final int equals = tline.indexOf('=');
303
304 information.put(tline.substring(4, equals).trim(),
305 tline.substring(equals + 1, tline.length() - 1).trim());
306 }
307 }
308 }
309
310 }
SofCheck Inspector Build Version : 2.17854
| VlcMediaSourcePlugin.java |
2009-Jun-25 01:54:24 |
| VlcMediaSourcePlugin.class |
2009-Sep-02 17:04:15 |