Added URL path support. (#13436)
Changes: Fix: Now using KTOR instead of building the url by simple string concad. This fixes the https and port 443 bug that existed prier to this change. (https://example.com would look like: https://example.com:443) Added: Support for jellyfins Base URL option. This allows the addon to be used on installations were jellyfin uses a base path. Signed-off-by: tliese <mail@tobiasliese.me>pull/13476/head
parent
cc50497f31
commit
8b4607a4f1
|
@ -33,41 +33,42 @@ In order to assist you with this process the binding expose a simple login form
|
||||||
|
|
||||||
## Server Thing Configuration
|
## Server Thing Configuration
|
||||||
|
|
||||||
| Config | Type | description |
|
| Config | Type | description |
|
||||||
|----------|----------|------------------------------|
|
|---------------------------|---------|----------------------------------------------------------------------------------------------|
|
||||||
| hostname | text | Hostname or IP address of the server (required) |
|
| hostname | text | Hostname or IP address of the server (required) |
|
||||||
| port | integer | Port of the server (required) |
|
| port | integer | Port of the server (required) |
|
||||||
| ssl | boolean | Connect through https (required) |
|
| ssl | boolean | Connect through https (required) |
|
||||||
| refreshSeconds | integer | Interval to pull devices state from the server |
|
| path | text | Base path of the server |
|
||||||
|
| refreshSeconds | integer | Interval to pull devices state from the server |
|
||||||
| clientActiveWithInSeconds | integer | Amount off seconds allowed since the last client activity to assert it's online (0 disabled) |
|
| clientActiveWithInSeconds | integer | Amount off seconds allowed since the last client activity to assert it's online (0 disabled) |
|
||||||
| userId | text | The user id |
|
| userId | text | The user id |
|
||||||
| token | text | The user access token |
|
| token | text | The user access token |
|
||||||
|
|
||||||
## Channels
|
## Channels
|
||||||
|
|
||||||
| channel | type | description |
|
| channel | type | description |
|
||||||
|----------|--------|------------------------------|
|
|----------------------------|--------|-----------------------------------------------------------------------------------------------------------------|
|
||||||
| send-notification | String | Display message in client |
|
| send-notification | String | Display message in client |
|
||||||
| media-control | Player | Control media playback |
|
| media-control | Player | Control media playback |
|
||||||
| playing-item-id | String | Id of the item currently playing (readonly) |
|
| playing-item-id | String | Id of the item currently playing (readonly) |
|
||||||
| playing-item-name | String | Name of the item currently playing (readonly) |
|
| playing-item-name | String | Name of the item currently playing (readonly) |
|
||||||
| playing-item-series-name | String | Name of the item's series currently playing, only have value when item is an episode (readonly) |
|
| playing-item-series-name | String | Name of the item's series currently playing, only have value when item is an episode (readonly) |
|
||||||
| playing-item-season-name | String | Name of the item's season currently playing, only have value when item is an episode (readonly) |
|
| playing-item-season-name | String | Name of the item's season currently playing, only have value when item is an episode (readonly) |
|
||||||
| playing-item-season | Number | Number of the item's season currently playing, only have value when item is an episode (readonly) |
|
| playing-item-season | Number | Number of the item's season currently playing, only have value when item is an episode (readonly) |
|
||||||
| playing-item-episode | Number | Number of the episode item currently playing, only have value when item is an episode (readonly) |
|
| playing-item-episode | Number | Number of the episode item currently playing, only have value when item is an episode (readonly) |
|
||||||
| playing-item-genders | String | Coma separate list genders of the item currently playing (readonly) |
|
| playing-item-genders | String | Coma separate list genders of the item currently playing (readonly) |
|
||||||
| playing-item-type | String | Type of the item currently playing (readonly) |
|
| playing-item-type | String | Type of the item currently playing (readonly) |
|
||||||
| playing-item-percentage | Dimmer | Played percentage for the item currently playing, allow seek |
|
| playing-item-percentage | Dimmer | Played percentage for the item currently playing, allow seek |
|
||||||
| playing-item-second | Number | Current second for the item currently playing, allow seek |
|
| playing-item-second | Number | Current second for the item currently playing, allow seek |
|
||||||
| playing-item-total-seconds | Number | Total seconds for the item currently playing (readonly) |
|
| playing-item-total-seconds | Number | Total seconds for the item currently playing (readonly) |
|
||||||
| play-by-terms | String | Play media by terms, works for series, episodes and movies; terms search is explained bellow |
|
| play-by-terms | String | Play media by terms, works for series, episodes and movies; terms search is explained bellow |
|
||||||
| play-next-by-terms | String | Add to playback queue as next by terms, works for series, episodes and movies; terms search is explained bellow |
|
| play-next-by-terms | String | Add to playback queue as next by terms, works for series, episodes and movies; terms search is explained bellow |
|
||||||
| play-last-by-terms | String | Add to playback queue as last by terms, works for series, episodes and movies; terms search is explained bellow |
|
| play-last-by-terms | String | Add to playback queue as last by terms, works for series, episodes and movies; terms search is explained bellow |
|
||||||
| browse-by-terms | String | Browse media by terms, works for series, episodes and movies; terms search is explained bellow |
|
| browse-by-terms | String | Browse media by terms, works for series, episodes and movies; terms search is explained bellow |
|
||||||
| play-by-id | String | Play media by id, works for series, episodes and movies; id search is explained bellow |
|
| play-by-id | String | Play media by id, works for series, episodes and movies; id search is explained bellow |
|
||||||
| play-next-by-id | String | Add to playback queue as next by id, works for series, episodes and movies |
|
| play-next-by-id | String | Add to playback queue as next by id, works for series, episodes and movies |
|
||||||
| play-last-by-id | String | Add to playback queue as last by id, works for series, episodes and movies |
|
| play-last-by-id | String | Add to playback queue as last by id, works for series, episodes and movies |
|
||||||
| browse-by-id | String | Browse media by id, works for series, episodes and movies |
|
| browse-by-id | String | Browse media by id, works for series, episodes and movies |
|
||||||
### Terms search:
|
### Terms search:
|
||||||
|
|
||||||
The terms search has a default behavior that can be modified sending some predefined prefixes.
|
The terms search has a default behavior that can be modified sending some predefined prefixes.
|
||||||
|
|
|
@ -33,6 +33,10 @@ public class JellyfinServerConfiguration {
|
||||||
* Use Https
|
* Use Https
|
||||||
*/
|
*/
|
||||||
public Boolean ssl = true;
|
public Boolean ssl = true;
|
||||||
|
/**
|
||||||
|
* Jellyfin base url
|
||||||
|
*/
|
||||||
|
public String path = "";
|
||||||
/**
|
/**
|
||||||
* Interval to pull devices state from the server
|
* Interval to pull devices state from the server
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -107,19 +107,22 @@ public class JellyfinServerDiscoveryService extends AbstractDiscoveryService {
|
||||||
new SystemApi(jellyClient).getPublicSystemInfo(asyncResponse);
|
new SystemApi(jellyClient).getPublicSystemInfo(asyncResponse);
|
||||||
try {
|
try {
|
||||||
var publicSystemInfo = asyncResponse.awaitContent();
|
var publicSystemInfo = asyncResponse.awaitContent();
|
||||||
discoverServer(uri.getHost(), uri.getPort(), uri.getScheme().equalsIgnoreCase("https"), publicSystemInfo);
|
discoverServer(uri.getHost(), uri.getPort(), uri.getScheme().equalsIgnoreCase("https"), uri.getPath(),
|
||||||
|
publicSystemInfo);
|
||||||
} catch (SyncCallback.SyncCallbackError | ApiClientException e) {
|
} catch (SyncCallback.SyncCallbackError | ApiClientException e) {
|
||||||
logger.warn("Discovery error: {}", e.getMessage());
|
logger.warn("Discovery error: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void discoverServer(String hostname, int port, boolean ssl, PublicSystemInfo publicSystemInfo) {
|
private void discoverServer(String hostname, int port, boolean ssl, String path,
|
||||||
|
PublicSystemInfo publicSystemInfo) {
|
||||||
logger.debug("Server discovered: [{}:{}] {}", hostname, port, publicSystemInfo.getServerName());
|
logger.debug("Server discovered: [{}:{}] {}", hostname, port, publicSystemInfo.getServerName());
|
||||||
var id = Objects.requireNonNull(publicSystemInfo.getId());
|
var id = Objects.requireNonNull(publicSystemInfo.getId());
|
||||||
Map<String, Object> properties = new HashMap<>();
|
Map<String, Object> properties = new HashMap<>();
|
||||||
properties.put("hostname", hostname);
|
properties.put("hostname", hostname);
|
||||||
properties.put("port", port);
|
properties.put("port", port);
|
||||||
properties.put("ssl", ssl);
|
properties.put("ssl", ssl);
|
||||||
|
properties.put("path", path);
|
||||||
properties.put(Thing.PROPERTY_SERIAL_NUMBER, id);
|
properties.put(Thing.PROPERTY_SERIAL_NUMBER, id);
|
||||||
var productName = publicSystemInfo.getProductName();
|
var productName = publicSystemInfo.getProductName();
|
||||||
if (productName != null) {
|
if (productName != null) {
|
||||||
|
|
|
@ -65,6 +65,9 @@ import org.openhab.core.types.Command;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.ktor.http.URLBuilder;
|
||||||
|
import io.ktor.http.URLProtocol;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link JellyfinServerHandler} is responsible for handling commands, which are
|
* The {@link JellyfinServerHandler} is responsible for handling commands, which are
|
||||||
* sent to one of the channels.
|
* sent to one of the channels.
|
||||||
|
@ -119,7 +122,16 @@ public class JellyfinServerHandler extends BaseBridgeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerUrl() {
|
public String getServerUrl() {
|
||||||
return (config.ssl ? "https" : "http") + "://" + config.hostname + ":" + config.port;
|
var builder = new URLBuilder();
|
||||||
|
builder.setHost(config.hostname);
|
||||||
|
if (config.ssl) {
|
||||||
|
builder.setProtocol(URLProtocol.Companion.getHTTPS());
|
||||||
|
} else {
|
||||||
|
builder.setProtocol(URLProtocol.Companion.getHTTP());
|
||||||
|
}
|
||||||
|
builder.setPort(config.port);
|
||||||
|
builder.setEncodedPath(config.path);
|
||||||
|
return builder.buildString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOnline() {
|
public boolean isOnline() {
|
||||||
|
|
|
@ -18,6 +18,8 @@ thing-type.config.jellyfin.server.hostname.label = Hostname/IP
|
||||||
thing-type.config.jellyfin.server.hostname.description = Hostname or IP address of the server
|
thing-type.config.jellyfin.server.hostname.description = Hostname or IP address of the server
|
||||||
thing-type.config.jellyfin.server.port.label = Port
|
thing-type.config.jellyfin.server.port.label = Port
|
||||||
thing-type.config.jellyfin.server.port.description = Port of the server
|
thing-type.config.jellyfin.server.port.description = Port of the server
|
||||||
|
thing-type.config.jellyfin.server.path.label = Base Path
|
||||||
|
thing-type.config.jellyfin.server.path.description = Base path of the server
|
||||||
thing-type.config.jellyfin.server.refreshSeconds.label = Refresh Seconds
|
thing-type.config.jellyfin.server.refreshSeconds.label = Refresh Seconds
|
||||||
thing-type.config.jellyfin.server.refreshSeconds.description = Interval to pull devices state from the server
|
thing-type.config.jellyfin.server.refreshSeconds.description = Interval to pull devices state from the server
|
||||||
thing-type.config.jellyfin.server.ssl.label = SSL
|
thing-type.config.jellyfin.server.ssl.label = SSL
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
<description>Connect through https</description>
|
<description>Connect through https</description>
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
<parameter name="path" type="text" required="false">
|
||||||
|
<label>Base Path</label>
|
||||||
|
<description>Base path of the server</description>
|
||||||
|
</parameter>
|
||||||
<parameter name="refreshSeconds" type="integer" min="10" max="300" required="true">
|
<parameter name="refreshSeconds" type="integer" min="10" max="300" required="true">
|
||||||
<label>Refresh Seconds</label>
|
<label>Refresh Seconds</label>
|
||||||
<description>Interval to pull devices state from the server</description>
|
<description>Interval to pull devices state from the server</description>
|
||||||
|
|
Loading…
Reference in New Issue