Merge branch 'server_url' into unstable
This commit is contained in:
commit
c268a53ed5
|
@ -306,13 +306,19 @@ function CreateServerGroup()
|
||||||
dialog.title = tr("Connecting to Server")
|
dialog.title = tr("Connecting to Server")
|
||||||
m.scene.dialog = dialog
|
m.scene.dialog = dialog
|
||||||
|
|
||||||
serverUrl = standardize_jellyfin_url(screen.serverUrl)
|
serverUrl = inferServerUrl(screen.serverUrl)
|
||||||
|
|
||||||
isConnected = session.server.UpdateURL(serverUrl)
|
isConnected = session.server.UpdateURL(serverUrl)
|
||||||
serverInfoResult = invalid
|
serverInfoResult = invalid
|
||||||
if isConnected
|
if isConnected
|
||||||
set_setting("server", serverUrl)
|
set_setting("server", serverUrl)
|
||||||
serverInfoResult = ServerInfo()
|
serverInfoResult = ServerInfo()
|
||||||
|
'If this is a different server from what we know, reset username/password setting
|
||||||
|
if m.global.session.server.url <> serverUrl
|
||||||
|
set_setting("username", "")
|
||||||
|
set_setting("password", "")
|
||||||
|
end if
|
||||||
|
set_setting("server", serverUrl)
|
||||||
end if
|
end if
|
||||||
dialog.close = true
|
dialog.close = true
|
||||||
|
|
||||||
|
@ -323,6 +329,7 @@ function CreateServerGroup()
|
||||||
screen.errorMessage = tr("Server not found, is it online?")
|
screen.errorMessage = tr("Server not found, is it online?")
|
||||||
SignOut(false)
|
SignOut(false)
|
||||||
else
|
else
|
||||||
|
|
||||||
if isValid(serverInfoResult.Error) and serverInfoResult.Error
|
if isValid(serverInfoResult.Error) and serverInfoResult.Error
|
||||||
' If server redirected received, update the URL
|
' If server redirected received, update the URL
|
||||||
if isValid(serverInfoResult.UpdatedUrl)
|
if isValid(serverInfoResult.UpdatedUrl)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import "pkg:/source/utils/config.brs"
|
||||||
|
|
||||||
function isNodeEvent(msg, field as string) as boolean
|
function isNodeEvent(msg, field as string) as boolean
|
||||||
return type(msg) = "roSGNodeEvent" and msg.getField() = field
|
return type(msg) = "roSGNodeEvent" and msg.getField() = field
|
||||||
end function
|
end function
|
||||||
|
@ -162,31 +164,103 @@ function option_dialog(options, message = "", defaultSelection = 0) as integer
|
||||||
return show_dialog(message, options, defaultSelection)
|
return show_dialog(message, options, defaultSelection)
|
||||||
end function
|
end function
|
||||||
|
|
||||||
'
|
' take an incomplete url string and use it to make educated guesses about
|
||||||
' Take a jellyfin hostname and ensure it's a full url.
|
' the complete url. then tests these guesses to see if it can find a jf server
|
||||||
' prepend http or https and append default ports, and remove excess slashes
|
' returns the url of the server it found, or an empty string
|
||||||
'
|
function inferServerUrl(url as string) as string
|
||||||
function standardize_jellyfin_url(url as string)
|
' if this server is already stored, just use the value directly
|
||||||
'Append default ports
|
' the server had to get resolved in the first place to get into the registry
|
||||||
maxSlashes = 0
|
saved = get_setting("saved_servers")
|
||||||
if left(url, 8) = "https://" or left(url, 7) = "http://"
|
if isValid(saved)
|
||||||
maxSlashes = 2
|
savedServers = ParseJson(saved)
|
||||||
|
if isValid(savedServers.lookup(url)) then return url
|
||||||
end if
|
end if
|
||||||
'Check to make sure entry has no extra slashes before adding default ports.
|
|
||||||
if Instr(0, url, "/") = maxSlashes
|
port = CreateObject("roMessagePort")
|
||||||
if url.len() > 5 and mid(url, url.len() - 4, 1) <> ":" and mid(url, url.len() - 5, 1) <> ":"
|
hosts = CreateObject("roAssociativeArray")
|
||||||
if left(url, 5) = "https"
|
reqs = []
|
||||||
url = url + ":8920"
|
candidates = urlCandidates(url)
|
||||||
else
|
for each endpoint in candidates
|
||||||
url = url + ":8096"
|
req = CreateObject("roUrlTransfer")
|
||||||
end if
|
reqs.push(req) ' keep in scope outside of loop, else -10001
|
||||||
|
req.seturl(endpoint + "/system/info/public")
|
||||||
|
req.setMessagePort(port)
|
||||||
|
hosts.addreplace(req.getidentity().ToStr(), endpoint)
|
||||||
|
if endpoint.Left(8) = "https://"
|
||||||
|
req.setCertificatesFile("common:/certs/ca-bundle.crt")
|
||||||
end if
|
end if
|
||||||
|
req.AsyncGetToString()
|
||||||
|
end for
|
||||||
|
handled = 0
|
||||||
|
timeout = CreateObject("roTimespan")
|
||||||
|
if hosts.count() > 0
|
||||||
|
while timeout.totalseconds() < 15
|
||||||
|
resp = wait(0, port)
|
||||||
|
if type(resp) = "roUrlEvent"
|
||||||
|
' TODO
|
||||||
|
' if response code is a 300 redirect then we should return the redirect url
|
||||||
|
' Make sure this happens or make it happen
|
||||||
|
if resp.GetResponseCode() = 200 and isJellyfinServer(resp.GetString())
|
||||||
|
selectedUrl = hosts.lookup(resp.GetSourceIdentity().ToStr())
|
||||||
|
print "Successfully inferred server URL: " selectedUrl
|
||||||
|
return selectedUrl
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
handled += 1
|
||||||
|
if handled = reqs.count()
|
||||||
|
print "inferServerUrl in utils/misc.brs failed to find a server from the string " url " but did not timeout."
|
||||||
|
return ""
|
||||||
|
end if
|
||||||
|
end while
|
||||||
|
print "inferServerUrl in utils/misc.brs failed to find a server from the string " url " because it timed out."
|
||||||
end if
|
end if
|
||||||
'Append http:// to server
|
return ""
|
||||||
if left(url, 4) <> "http"
|
end function
|
||||||
url = "http://" + url
|
|
||||||
|
' this is the "educated guess" logic for inferServerUrl that generates a list of complete url's as candidates
|
||||||
|
' for the tests in inferServerUrl. takes an incomplete url as an arg and returns a list of extrapolated
|
||||||
|
' full urls.
|
||||||
|
function urlCandidates(input as string)
|
||||||
|
if input.endswith("/") then input = input.Left(len(input) - 1)
|
||||||
|
url = parseUrl(input)
|
||||||
|
if url[1] = invalid
|
||||||
|
' a proto wasn't declared
|
||||||
|
url = parseUrl("none://" + input)
|
||||||
end if
|
end if
|
||||||
return url
|
' if the proto is still invalid then the string is not valid
|
||||||
|
if url[1] = invalid then return []
|
||||||
|
proto = url[1]
|
||||||
|
host = url[2]
|
||||||
|
port = url[3]
|
||||||
|
path = url[4]
|
||||||
|
protoCandidates = []
|
||||||
|
supportedProtos = ["http:", "https:"] ' appending colons because the regex does
|
||||||
|
if proto = "none:" ' the user did not declare a protocol
|
||||||
|
' try every supported proto
|
||||||
|
for each supportedProto in supportedProtos
|
||||||
|
protoCandidates.push(supportedProto + "//" + host)
|
||||||
|
end for
|
||||||
|
else
|
||||||
|
protoCandidates.push(proto + "//" + host) ' but still allow arbitrary protocols if they are declared
|
||||||
|
end if
|
||||||
|
finalCandidates = []
|
||||||
|
if isValid(port) and port <> "" ' if the port is defined just use that
|
||||||
|
for each candidate in protoCandidates
|
||||||
|
finalCandidates.push(candidate + port + path)
|
||||||
|
end for
|
||||||
|
else ' the port wasnt declared so use default jellyfin and proto ports
|
||||||
|
for each candidate in protoCandidates:
|
||||||
|
' proto default
|
||||||
|
finalCandidates.push(candidate + path)
|
||||||
|
' jellyfin defaults
|
||||||
|
if candidate.startswith("https")
|
||||||
|
finalCandidates.push(candidate + ":8920" + path)
|
||||||
|
else if candidate.startswith("http")
|
||||||
|
finalCandidates.push(candidate + ":8096" + path)
|
||||||
|
end if
|
||||||
|
end for
|
||||||
|
end if
|
||||||
|
return finalCandidates
|
||||||
end function
|
end function
|
||||||
|
|
||||||
sub setFieldTextValue(field, value)
|
sub setFieldTextValue(field, value)
|
||||||
|
@ -228,7 +302,7 @@ function isValidAndNotEmpty(input as dynamic) as boolean
|
||||||
end if
|
end if
|
||||||
end function
|
end function
|
||||||
|
|
||||||
' Returns an array from a url - [ url, proto, host, port, subdir/params ]
|
' Returns an array from a url = [ url, proto, host, port, subdir+params ]
|
||||||
' If port or subdir are not found, an empty string will be added to the array
|
' If port or subdir are not found, an empty string will be added to the array
|
||||||
' Proto must be declared or array will be empty
|
' Proto must be declared or array will be empty
|
||||||
function parseUrl(url as string) as object
|
function parseUrl(url as string) as object
|
||||||
|
@ -383,6 +457,16 @@ sub stopLoadingSpinner()
|
||||||
end if
|
end if
|
||||||
end sub
|
end sub
|
||||||
|
|
||||||
|
' accepts the raw json string of /system/info/public and returns
|
||||||
|
' a boolean indicating if ProductName is "Jellyfin Server"
|
||||||
|
function isJellyfinServer(systemInfo as object) as boolean
|
||||||
|
d = ParseJson(systemInfo)
|
||||||
|
if isValid(d) and isValid(d.ProductName)
|
||||||
|
return d.ProductName = "Jellyfin Server"
|
||||||
|
end if
|
||||||
|
return False
|
||||||
|
end function
|
||||||
|
|
||||||
' Check if a specific value is inside of an array
|
' Check if a specific value is inside of an array
|
||||||
function arrayHasValue(arr as object, value as dynamic) as boolean
|
function arrayHasValue(arr as object, value as dynamic) as boolean
|
||||||
for each entry in arr
|
for each entry in arr
|
||||||
|
|
Loading…
Reference in New Issue
Block a user