forked from openhab/openhab-addons
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[sonos] Added support of RadioApp music service (openhab#13235)
* [sonos] Added support of RadioApp music service * Extract artist and song title from TITLE * Extract code in methods to reduce the size of the method updateMediaInformation * Create new class and add tests Fix openhab#13208 Signed-off-by: Laurent Garnier <lg.hc@free.fr>
- Loading branch information
Showing
3 changed files
with
496 additions
and
77 deletions.
There are no files selected for viewing
202 changes: 202 additions & 0 deletions
202
...sonos/src/main/java/org/openhab/binding/sonos/internal/handler/SonosMediaInformation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
/** | ||
* Copyright (c) 2010-2022 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.sonos.internal.handler; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.openhab.binding.sonos.internal.SonosMetaData; | ||
import org.openhab.binding.sonos.internal.SonosXMLParser; | ||
import org.openhab.core.io.net.http.HttpUtil; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* The {@link SonosMediaInformation} is responsible for extracting media information from XML metadata | ||
* | ||
* @author Laurent Garnier - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class SonosMediaInformation { | ||
|
||
private static final int HTTP_TIMEOUT = 5000; | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(SonosMediaInformation.class); | ||
|
||
private @Nullable String artist; | ||
private @Nullable String album; | ||
private @Nullable String title; | ||
private @Nullable String combinedInfo; | ||
private boolean needsUpdate; | ||
|
||
public SonosMediaInformation() { | ||
this(false); | ||
} | ||
|
||
public SonosMediaInformation(boolean needsUpdate) { | ||
this(null, null, null, null, needsUpdate); | ||
} | ||
|
||
public SonosMediaInformation(@Nullable String artist, @Nullable String album, @Nullable String title, | ||
@Nullable String combinedInfo, boolean needsUpdate) { | ||
this.artist = artist; | ||
this.album = album; | ||
this.title = title; | ||
this.combinedInfo = combinedInfo; | ||
this.needsUpdate = needsUpdate; | ||
} | ||
|
||
public @Nullable String getArtist() { | ||
return artist; | ||
} | ||
|
||
public @Nullable String getAlbum() { | ||
return album; | ||
} | ||
|
||
public @Nullable String getTitle() { | ||
return title; | ||
} | ||
|
||
public @Nullable String getCombinedInfo() { | ||
return combinedInfo; | ||
} | ||
|
||
public boolean needsUpdate() { | ||
return needsUpdate; | ||
} | ||
|
||
public static SonosMediaInformation parseTuneInMediaInfo(@Nullable String opmlUrl, @Nullable String radioTitle, | ||
@Nullable SonosMetaData trackMetaData) { | ||
String title = null; | ||
String combinedInfo = null; | ||
if (opmlUrl != null) { | ||
String response = null; | ||
try { | ||
response = HttpUtil.executeUrl("GET", opmlUrl, HTTP_TIMEOUT); | ||
} catch (IOException e) { | ||
LOGGER.debug("Request to device failed", e); | ||
} | ||
|
||
if (response != null) { | ||
List<String> fields = SonosXMLParser.getRadioTimeFromXML(response); | ||
|
||
if (!fields.isEmpty()) { | ||
combinedInfo = ""; | ||
for (String field : fields) { | ||
if (combinedInfo.isEmpty()) { | ||
// radio name should be first field | ||
title = field; | ||
} else { | ||
combinedInfo += " - "; | ||
} | ||
combinedInfo += field; | ||
} | ||
return new SonosMediaInformation(null, null, title, combinedInfo, true); | ||
} | ||
} | ||
} | ||
if (radioTitle != null && !radioTitle.isEmpty()) { | ||
title = radioTitle; | ||
combinedInfo = title; | ||
if (trackMetaData != null && !trackMetaData.getStreamContent().isEmpty()) { | ||
combinedInfo += " - " + trackMetaData.getStreamContent(); | ||
} | ||
return new SonosMediaInformation(null, null, title, combinedInfo, true); | ||
} | ||
return new SonosMediaInformation(false); | ||
} | ||
|
||
public static SonosMediaInformation parseRadioAppMediaInfo(@Nullable String radioTitle, | ||
@Nullable SonosMetaData trackMetaData) { | ||
if (radioTitle != null && !radioTitle.isEmpty()) { | ||
String artist = null; | ||
String album = null; | ||
String title = radioTitle; | ||
String combinedInfo = title; | ||
if (trackMetaData != null) { | ||
String[] contents = trackMetaData.getStreamContent().split("\\|"); | ||
String contentTitle = null; | ||
for (int i = 0; i < contents.length; i++) { | ||
if (contents[i].startsWith("TITLE ")) { | ||
contentTitle = contents[i].substring(6).trim(); | ||
} | ||
if (contents[i].startsWith("ARTIST ")) { | ||
artist = contents[i].substring(7).trim(); | ||
} | ||
if (contents[i].startsWith("ALBUM ")) { | ||
album = contents[i].substring(6).trim(); | ||
} | ||
} | ||
if ((artist == null || artist.isEmpty()) && contentTitle != null && !contentTitle.isEmpty() | ||
&& !contentTitle.startsWith("Advertisement_")) { | ||
// Try to extract artist and song title from contentTitle | ||
int idx = contentTitle.indexOf(" - "); | ||
if (idx > 0) { | ||
artist = contentTitle.substring(0, idx); | ||
title = contentTitle.substring(idx + 3); | ||
} | ||
} else if (artist != null && !artist.isEmpty() && album != null && !album.isEmpty() | ||
&& contentTitle != null && !contentTitle.isEmpty()) { | ||
title = contentTitle; | ||
} | ||
if (artist != null && !artist.isEmpty()) { | ||
combinedInfo += " - " + artist; | ||
} | ||
if (album != null && !album.isEmpty()) { | ||
combinedInfo += " - " + album; | ||
} | ||
if (!radioTitle.equals(title)) { | ||
combinedInfo += " - " + title; | ||
} else if (contentTitle != null && !contentTitle.isEmpty() | ||
&& !contentTitle.startsWith("Advertisement_")) { | ||
combinedInfo += " - " + contentTitle; | ||
} | ||
} | ||
return new SonosMediaInformation(artist, album, title, combinedInfo, true); | ||
} | ||
return new SonosMediaInformation(false); | ||
} | ||
|
||
public static SonosMediaInformation parseTrack(@Nullable SonosMetaData trackMetaData) { | ||
if (trackMetaData != null) { | ||
List<String> infos = new ArrayList<>(); | ||
String artist = !trackMetaData.getAlbumArtist().isEmpty() ? trackMetaData.getAlbumArtist() | ||
: trackMetaData.getCreator(); | ||
if (!artist.isEmpty()) { | ||
infos.add(artist); | ||
} | ||
String album = trackMetaData.getAlbum(); | ||
if (!album.isEmpty()) { | ||
infos.add(album); | ||
} | ||
String title = trackMetaData.getTitle(); | ||
if (!title.isEmpty()) { | ||
infos.add(title); | ||
} | ||
return new SonosMediaInformation(artist, album, title, String.join(" - ", infos), true); | ||
} | ||
return new SonosMediaInformation(false); | ||
} | ||
|
||
public static SonosMediaInformation parseTrackTitle(@Nullable SonosMetaData trackMetaData) { | ||
if (trackMetaData != null) { | ||
String title = trackMetaData.getTitle(); | ||
return new SonosMediaInformation(null, null, title, title, true); | ||
} | ||
return new SonosMediaInformation(false); | ||
} | ||
} |
Oops, something went wrong.