]> git.basschouten.com Git - openhab-addons.git/blob
264e867e5953c903b861461afb41d98a1a875ba9
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.sonos.internal.handler;
14
15 import java.io.IOException;
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.sonos.internal.SonosMetaData;
22 import org.openhab.binding.sonos.internal.SonosXMLParser;
23 import org.openhab.core.io.net.http.HttpUtil;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * The {@link SonosMediaInformation} is responsible for extracting media information from XML metadata
29  *
30  * @author Laurent Garnier - Initial contribution
31  */
32 @NonNullByDefault
33 public class SonosMediaInformation {
34
35     private static final int HTTP_TIMEOUT = 5000;
36
37     private static final Logger LOGGER = LoggerFactory.getLogger(SonosMediaInformation.class);
38
39     private @Nullable String artist;
40     private @Nullable String album;
41     private @Nullable String title;
42     private @Nullable String combinedInfo;
43     private boolean needsUpdate;
44
45     public SonosMediaInformation() {
46         this(false);
47     }
48
49     public SonosMediaInformation(boolean needsUpdate) {
50         this(null, null, null, null, needsUpdate);
51     }
52
53     public SonosMediaInformation(@Nullable String artist, @Nullable String album, @Nullable String title,
54             @Nullable String combinedInfo, boolean needsUpdate) {
55         this.artist = artist;
56         this.album = album;
57         this.title = title;
58         this.combinedInfo = combinedInfo;
59         this.needsUpdate = needsUpdate;
60     }
61
62     public @Nullable String getArtist() {
63         return artist;
64     }
65
66     public @Nullable String getAlbum() {
67         return album;
68     }
69
70     public @Nullable String getTitle() {
71         return title;
72     }
73
74     public @Nullable String getCombinedInfo() {
75         return combinedInfo;
76     }
77
78     public boolean needsUpdate() {
79         return needsUpdate;
80     }
81
82     public static SonosMediaInformation parseTuneInMediaInfo(@Nullable String opmlUrl, @Nullable String radioTitle,
83             @Nullable SonosMetaData trackMetaData) {
84         String title = null;
85         String combinedInfo = null;
86         if (opmlUrl != null) {
87             String response = null;
88             try {
89                 response = HttpUtil.executeUrl("GET", opmlUrl, HTTP_TIMEOUT);
90             } catch (IOException e) {
91                 LOGGER.debug("Request to device failed", e);
92             }
93
94             if (response != null) {
95                 List<String> fields = SonosXMLParser.getRadioTimeFromXML(response);
96
97                 if (!fields.isEmpty()) {
98                     combinedInfo = "";
99                     for (String field : fields) {
100                         if (combinedInfo.isEmpty()) {
101                             // radio name should be first field
102                             title = field;
103                         } else {
104                             combinedInfo += " - ";
105                         }
106                         combinedInfo += field;
107                     }
108                     return new SonosMediaInformation(null, null, title, combinedInfo, true);
109                 }
110             }
111         }
112         if (radioTitle != null && !radioTitle.isEmpty()) {
113             title = radioTitle;
114             combinedInfo = title;
115             if (trackMetaData != null && !trackMetaData.getStreamContent().isEmpty()) {
116                 combinedInfo += " - " + trackMetaData.getStreamContent();
117             }
118             return new SonosMediaInformation(null, null, title, combinedInfo, true);
119         }
120         return new SonosMediaInformation(false);
121     }
122
123     public static SonosMediaInformation parseRadioAppMediaInfo(@Nullable String radioTitle,
124             @Nullable SonosMetaData trackMetaData) {
125         if (radioTitle != null && !radioTitle.isEmpty()) {
126             String artist = null;
127             String album = null;
128             String title = radioTitle;
129             String combinedInfo = title;
130             if (trackMetaData != null) {
131                 String[] contents = trackMetaData.getStreamContent().split("\\|");
132                 String contentTitle = null;
133                 for (int i = 0; i < contents.length; i++) {
134                     if (contents[i].startsWith("TITLE ")) {
135                         contentTitle = contents[i].substring(6).trim();
136                     }
137                     if (contents[i].startsWith("ARTIST ")) {
138                         artist = contents[i].substring(7).trim();
139                     }
140                     if (contents[i].startsWith("ALBUM ")) {
141                         album = contents[i].substring(6).trim();
142                     }
143                 }
144                 if ((artist == null || artist.isEmpty()) && contentTitle != null && !contentTitle.isEmpty()
145                         && !contentTitle.startsWith("Advertisement_")) {
146                     // Try to extract artist and song title from contentTitle
147                     int idx = contentTitle.indexOf(" - ");
148                     if (idx > 0) {
149                         artist = contentTitle.substring(0, idx);
150                         title = contentTitle.substring(idx + 3);
151                     }
152                 } else if (artist != null && !artist.isEmpty() && album != null && !album.isEmpty()
153                         && contentTitle != null && !contentTitle.isEmpty()) {
154                     title = contentTitle;
155                 }
156                 if (artist != null && !artist.isEmpty()) {
157                     combinedInfo += " - " + artist;
158                 }
159                 if (album != null && !album.isEmpty()) {
160                     combinedInfo += " - " + album;
161                 }
162                 if (!radioTitle.equals(title)) {
163                     combinedInfo += " - " + title;
164                 } else if (contentTitle != null && !contentTitle.isEmpty()
165                         && !contentTitle.startsWith("Advertisement_")) {
166                     combinedInfo += " - " + contentTitle;
167                 }
168             }
169             return new SonosMediaInformation(artist, album, title, combinedInfo, true);
170         }
171         return new SonosMediaInformation(false);
172     }
173
174     public static SonosMediaInformation parseTrack(@Nullable SonosMetaData trackMetaData) {
175         if (trackMetaData != null) {
176             List<String> infos = new ArrayList<>();
177             String artist = !trackMetaData.getAlbumArtist().isEmpty() ? trackMetaData.getAlbumArtist()
178                     : trackMetaData.getCreator();
179             if (!artist.isEmpty()) {
180                 infos.add(artist);
181             }
182             String album = trackMetaData.getAlbum();
183             if (!album.isEmpty()) {
184                 infos.add(album);
185             }
186             String title = trackMetaData.getTitle();
187             if (!title.isEmpty()) {
188                 infos.add(title);
189             }
190             return new SonosMediaInformation(artist, album, title, String.join(" - ", infos), true);
191         }
192         return new SonosMediaInformation(false);
193     }
194
195     public static SonosMediaInformation parseTrackTitle(@Nullable SonosMetaData trackMetaData) {
196         if (trackMetaData != null) {
197             String title = trackMetaData.getTitle();
198             return new SonosMediaInformation(null, null, title, title, true);
199         }
200         return new SonosMediaInformation(false);
201     }
202 }