diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | MediaContainer.cpp | 4 | ||||
-rw-r--r-- | MediaContainer.h | 4 | ||||
-rw-r--r-- | PVideo.cpp | 6 | ||||
-rw-r--r-- | PlexServer.cpp | 108 | ||||
-rw-r--r-- | PlexServer.h | 38 | ||||
-rw-r--r-- | Plexservice.cpp | 156 | ||||
-rw-r--r-- | Plexservice.h | 8 | ||||
-rw-r--r-- | SubscriptionManager.cpp | 56 | ||||
-rw-r--r-- | browserGrid.cpp | 2 | ||||
-rw-r--r-- | device.cpp | 61 | ||||
-rw-r--r-- | device.h | 59 | ||||
-rw-r--r-- | hlsPlayer.cpp | 69 | ||||
-rw-r--r-- | hlsPlayer.h | 5 | ||||
-rw-r--r-- | mpvWrapper.cpp | 4 | ||||
-rw-r--r-- | mpvWrapper.h | 2 | ||||
-rw-r--r-- | pictureCache.cpp | 2 | ||||
-rw-r--r-- | plex.cpp | 35 | ||||
-rw-r--r-- | plexgdm.cpp | 38 | ||||
-rw-r--r-- | plexgdm.h | 2 | ||||
-rw-r--r-- | po/de_DE.mo | bin | 2980 -> 4189 bytes | |||
-rw-r--r-- | po/de_DE.po | 2 |
22 files changed, 510 insertions, 154 deletions
@@ -95,7 +95,8 @@ OBJS = $(PLUGIN).o \ browserGrid.o \ viewHeader.o \ detailView.o \ - pictureCache.o + pictureCache.o \ + device.o SRCS = $(wildcard $(OBJS:.o=.c)) $(PLUGIN).cpp diff --git a/MediaContainer.cpp b/MediaContainer.cpp index ba46fe8..10096ce 100644 --- a/MediaContainer.cpp +++ b/MediaContainer.cpp @@ -3,6 +3,8 @@ namespace plexclient { +MediaContainer::MediaContainer(std::istream* response) : MediaContainer(response, NULL) {} + MediaContainer::MediaContainer(std::istream* response, PlexServer* Server) { m_pServer = Server; @@ -43,6 +45,8 @@ MediaContainer::MediaContainer(std::istream* response, PlexServer* Server) m_vDirectories.push_back(Directory(pNode, m_pServer, this)); } else if(Poco::icompare(pNode->nodeName(), "Video") == 0) { m_vVideos.push_back(Video(pNode, m_pServer, this)); + } else if(Poco::icompare(pNode->nodeName(), "Device") == 0) { + m_vDevices.push_back(Device(pNode, this)); } pNode = it.nextNode(); diff --git a/MediaContainer.h b/MediaContainer.h index 947a647..02b8b96 100644 --- a/MediaContainer.h +++ b/MediaContainer.h @@ -19,6 +19,7 @@ #include "PVideo.h" #include "PlexServer.h" #include "Config.h" +#include "device.h" using Poco::XML::DOMParser; using Poco::XML::InputSource; @@ -33,11 +34,13 @@ namespace plexclient { class Video; class Directory; +class Device; class MediaContainer: XmlObject { public: MediaContainer(std::istream *response, PlexServer* Server); + MediaContainer(std::istream *response); protected: @@ -45,6 +48,7 @@ protected: public: std::vector<Directory> m_vDirectories; std::vector<Video> m_vVideos; + std::vector<Device> m_vDevices; bool m_bAllowSync; std::string m_sArt; @@ -163,7 +163,7 @@ std::string Video::GetTitle() bool Video::SetStream(Stream* stream) { try { - Poco::Net::HTTPClientSession session(m_pServer->GetIpAdress(), m_pServer->GetPort()); + Poco::Net::HTTPClientSession session(m_pServer->GetHost(), m_pServer->GetPort()); std::string uri = Poco::format("/library/parts/%d?%s", m_Media.m_iPartId, stream->GetSetStreamQuery()); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, uri); @@ -186,7 +186,7 @@ bool Video::SetStream(Stream* stream) bool Video::SetUnwatched() { try { - Poco::Net::HTTPClientSession session(m_pServer->GetIpAdress(), m_pServer->GetPort()); + Poco::Net::HTTPClientSession session(m_pServer->GetHost(), m_pServer->GetPort()); std::string uri = Poco::format("/:/unscrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); @@ -209,7 +209,7 @@ bool Video::SetUnwatched() bool Video::SetWatched() { try { - Poco::Net::HTTPClientSession session(m_pServer->GetIpAdress(), m_pServer->GetPort()); + Poco::Net::HTTPClientSession session(m_pServer->GetHost(), m_pServer->GetPort()); std::string uri = Poco::format("/:/scrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); diff --git a/PlexServer.cpp b/PlexServer.cpp index 6b3f0ae..1039b1f 100644 --- a/PlexServer.cpp +++ b/PlexServer.cpp @@ -1,17 +1,49 @@ #include <vdr/tools.h> #include "PlexServer.h" +#include "Config.h" +#include "plex.h" namespace plexclient { + +PlexServer::PlexServer(std::string ip, int port) +{ + m_httpSession = NULL; + + Poco::URI uri; + uri.setHost(ip); + uri.setPort(port); + uri.setScheme("http"); + m_uri = uri.toString(); +} PlexServer::PlexServer(std::string data, std::string ip) { + m_httpSession = NULL; ParseData(data, ip); } +PlexServer::PlexServer(std::string uri, std::string name, std::string uuid, std::string accessToken, bool owned, bool local) +{ + m_httpSession = NULL; + m_sServerName = name; + m_sUuid = uuid; + m_nOwned = owned; + m_bLocal = local; + m_authToken = accessToken; + + m_uri = uri; +} + +PlexServer::~PlexServer() +{ + delete m_httpSession; + m_httpSession = NULL; +} + void PlexServer::ParseData(std::string data, std::string ip) { - m_sIpAddress = ip; + int port = 0; std::istringstream f(data); std::string s; Offline = false; @@ -27,7 +59,7 @@ void PlexServer::ParseData(std::string data, std::string ip) } else if (name == "Name") { m_sServerName = val; } else if (name == "Port") { - m_nPort = atoi(val.c_str()); + port = atoi(val.c_str()); } else if (name == "Updated-At") { m_nUpdated = atol(val.c_str()); } else if (name == "Version") { @@ -35,17 +67,81 @@ void PlexServer::ParseData(std::string data, std::string ip) } } } + + m_bLocal = true; + + Poco::URI uri; + + uri.setHost(ip); + uri.setPort(port); + uri.setScheme("http"); + + m_uri = uri.toString(); } -PlexServer::PlexServer(std::string ip, int port) +std::string PlexServer::GetHost() +{ + Poco::URI uri(m_uri); + return uri.getHost(); +} + +int PlexServer::GetPort() +{ + Poco::URI uri(m_uri); + return uri.getPort(); +} + +Poco::Net::HTTPClientSession* PlexServer::GetClientSession() +{ + Poco::URI uri(m_uri); + if(m_httpSession == NULL) { + if(uri.getScheme().find("https") != std::string::npos) { + m_httpSession = new Poco::Net::HTTPSClientSession(uri.getHost(), uri.getPort()); + } + else { + m_httpSession = new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort()); + } + } + return m_httpSession; +} + +std::istream& PlexServer::MakeRequest(Poco::Net::HTTPResponse& response, std::string path, const std::map<std::string, std::string>& queryParameters) { - m_sIpAddress = ip; - m_nPort = port; + Poco::URI uri(path); + // Create a request with an optional query + if(queryParameters.size()) { + for (auto const& pair : queryParameters) { + // addQueryParameter does the encode already + uri.addQueryParameter(pair.first, pair.second); + } + } + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); + + request.add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17"); + request.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID()); + request.add("X-Plex-Device", "PC"); + request.add("X-Plex-Device-Name", Config::GetInstance().GetHostname()); + request.add("X-Plex-Language", Config::GetInstance().GetLanguage()); + request.add("X-Plex-Model", "Linux"); + request.add("X-Plex-Platform", "VDR"); + request.add("X-Plex-Product", "plex for vdr"); + request.add("X-Plex-Provides", "player"); + request.add("X-Plex-Version", VERSION); + + if(Config::GetInstance().UsePlexAccount && !GetAuthToken().empty()) { + // Add PlexToken to Header + request.add("X-Plex-Token", GetAuthToken()); + } + + GetClientSession()->sendRequest(request); + + return GetClientSession()->receiveResponse(response); + } std::string PlexServer::GetUri() { - return std::string("http://") + m_sIpAddress + ":" + std::string(itoa(m_nPort)); + return m_uri; } } diff --git a/PlexServer.h b/PlexServer.h index 0a36adb..45ef7d6 100644 --- a/PlexServer.h +++ b/PlexServer.h @@ -7,10 +7,13 @@ #include <iostream> #include <vector> #include <memory> +#include <map> #include <Poco/String.h> #include <Poco/Net/HTTPClientSession.h> +#include <Poco/Net/HTTPSClientSession.h> #include <Poco/Net/HTTPRequest.h> +#include <Poco/Net/HTTPResponse.h> #include <Poco/Net/MessageHeader.h> #include <Poco/URI.h> @@ -21,17 +24,17 @@ class PlexServer { friend class plexgdm; -public: + public: + PlexServer(std::string uri, std::string name, std::string uuid, std::string accessToken, bool owned, bool local); + ~PlexServer(); + int GetMaster() const { return m_nMaster; } - int GetOwned() const { + int IsOwned() const { return m_nOwned; } - int GetPort() const { - return m_nPort; - } const std::string& GetContentType() const { return m_sContentType; } @@ -53,11 +56,24 @@ public: const std::string& GetVersion() const { return m_sVersion; } - const std::string& GetIpAdress() const { - return m_sIpAddress; + const std::string& GetAuthToken() const { + return m_authToken; } - + const bool& IsLocal() const { + return m_bLocal; + } + void SetAuthToken(std::string token) { + m_authToken = token; + } + + std::istream& MakeRequest(Poco::Net::HTTPResponse& response, std::string path, const std::map<std::string, std::string>& queryParameters = std::map<std::string, std::string>()); + + std::string GetHost(); + int GetPort(); + std::string GetUri(); + + Poco::Net::HTTPClientSession* GetClientSession(); void DiscoverSettings(); bool Offline; @@ -73,15 +89,17 @@ private: std::string m_sDiscovery; int m_nOwned; + bool m_bLocal; int m_nMaster; std::string m_sRole; std::string m_sContentType; std::string m_sUuid; std::string m_sServerName; - std::string m_sIpAddress; - int m_nPort; + std::string m_uri; + std::string m_authToken; long m_nUpdated; std::string m_sVersion; + Poco::Net::HTTPClientSession* m_httpSession; }; diff --git a/Plexservice.cpp b/Plexservice.cpp index bae8ed2..1177c70 100644 --- a/Plexservice.cpp +++ b/Plexservice.cpp @@ -34,12 +34,9 @@ std::string Plexservice::GetMyPlexToken() b64.close(); std::string tempToken = ss.str(); - Poco::Net::Context::Ptr context = new Poco::Net::Context( - Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE, // VERIFY_NONE...?! - 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); try { - Poco::Net::HTTPSClientSession plexSession("plex.tv", 443, context); + Poco::Net::HTTPSClientSession plexSession("plex.tv", 443); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/users/sign_in.xml", Poco::Net::HTTPMessage::HTTP_1_1); PlexHelper::AddHttpHeader(request); @@ -53,6 +50,7 @@ std::string Plexservice::GetMyPlexToken() // parse the XML Response user u(&rs); myToken = u.authenticationToken; + isyslog("[plex] plex.tv login successfull."); } else { esyslog("[plex] plex.tv Login failed, check you creditials."); } @@ -74,7 +72,7 @@ void Plexservice::Authenticate() std::string token = GetMyPlexToken(); auto pRequest = CreateRequest("/?X-Plex-Token=" + token); - Poco::Net::HTTPClientSession session(pServer->GetIpAdress(), pServer->GetPort()); + Poco::Net::HTTPClientSession session(pServer->GetHost(), pServer->GetPort()); session.sendRequest(*pRequest); Poco::Net::HTTPResponse response; /*std::istream &rs = */ @@ -87,6 +85,59 @@ void Plexservice::Authenticate() } } +void Plexservice::UpdateResources() +{ + // We must be autenticated + // https://plex.tv/api/resources?includeHttps=1 + if(!Config::GetInstance().UsePlexAccount) { + isyslog("[plex] To access remote servers, please login with your plex.tv account."); + return; // Plugin is used without plex.tv login + } + isyslog("[plex] Updating remote resources..."); + + + std::shared_ptr<MediaContainer> pContainer = nullptr; + try { + Poco::URI fileuri("https://plex.tv/api/resources?includeHttps=1"); + + Poco::Net::HTTPSClientSession session(fileuri.getHost(), 443); + + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); + PlexHelper::AddHttpHeader(request); + request.add("X-Plex-Token", GetMyPlexToken() ); + + session.sendRequest(request); + Poco::Net::HTTPResponse response; + std::istream &rs = session.receiveResponse(response); + + //Poco::StreamCopier::copyStream(rs, std::cout); + + pContainer = std::shared_ptr<MediaContainer>(new MediaContainer(&rs)); + + } catch (Poco::Net::NetException &exc) { + std::cout << exc.displayText() << std::endl; + return; + } + + for(std::vector<Device>::iterator d_it = pContainer->m_vDevices.begin(); d_it != pContainer->m_vDevices.end(); ++d_it) { + + // check device is a server + if(d_it->m_sProvides.find("server") != std::string::npos) { + // is it a remote server? + if(d_it->m_bPublicAddressMatches == false) { + // pick remote connection + for(std::vector<Connection>::iterator c_it = d_it->m_vConnections.begin(); c_it != d_it->m_vConnections.end(); ++c_it) { + if(c_it->m_bLocal == false) { + dsyslog("[plex] Found remote server: %s", d_it->m_sName.c_str()); + // a remote Server + plexgdm::GetInstance().AddServer(PlexServer(c_it->m_sUri, d_it->m_sName, d_it->m_sClientIdentifier, d_it->m_sAccessToken, d_it->m_bOwned, c_it->m_bLocal)); + } + } + } + } + } +} + PlexServer* Plexservice::GetServer() { return pServer; @@ -107,16 +158,13 @@ std::shared_ptr<MediaContainer> Plexservice::GetSection(std::string section, boo m_vUriStack.push(uri); } - Poco::Net::HTTPClientSession session(pServer->GetIpAdress(), pServer->GetPort()); - session.sendRequest(*pRequest); + dsyslog("[plex] URI: %s%s", pServer->GetUri().c_str(), uri.c_str()); + Poco::Net::HTTPResponse response; - std::istream &rs = session.receiveResponse(response); - - dsyslog("[plex] URI: http://%s:%d%s", pServer->GetIpAdress().c_str(), pServer->GetPort(), uri.c_str()); + std::istream &rs = pServer->MakeRequest(response, uri);; std::shared_ptr<MediaContainer> pAllsections(new MediaContainer(&rs, pServer)); - session.abort(); return pAllsections; } catch (Poco::Net::NetException &exc) { @@ -153,8 +201,13 @@ std::unique_ptr<Poco::Net::HTTPRequest> Plexservice::CreateRequest(std::string p if(Config::GetInstance().UsePlexAccount) { // Add PlexToken to Header std::string token = GetMyPlexToken(); - if(!token.empty()) + if(pServer && !pServer->GetAuthToken().empty()) { + pRequest->add("X-Plex-Token", pServer->GetAuthToken()); + dsyslog("[plex] Using server access token"); + } else if(!token.empty()) { pRequest->add("X-Plex-Token", token); + dsyslog("[plex] Using global access token"); + } } return pRequest; @@ -162,68 +215,75 @@ std::unique_ptr<Poco::Net::HTTPRequest> Plexservice::CreateRequest(std::string p std::shared_ptr<MediaContainer> Plexservice::GetMediaContainer(std::string fullUrl) { + PlexServer* pServer = NULL; try { Poco::URI fileuri(fullUrl); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); - PlexHelper::AddHttpHeader(request); + dsyslog("[plex] GetMediaContainer: %s", fullUrl.c_str()); - Poco::Net::HTTPClientSession session(fileuri.getHost(), fileuri.getPort()); - - session.sendRequest(request); + pServer = plexgdm::GetInstance().GetServer(fileuri.getHost(), fileuri.getPort()); + Poco::Net::HTTPResponse response; - std::istream &rs = session.receiveResponse(response); + std::istream &rs = pServer->MakeRequest(response, fileuri.getPathAndQuery()); - std::shared_ptr<MediaContainer> pAllsections(new MediaContainer(&rs, plexgdm::GetInstance().GetServer(fileuri.getHost(), fileuri.getPort()))); + //Poco::StreamCopier::copyStream(rs, std::cout); - session.abort(); + std::shared_ptr<MediaContainer> pAllsections = std::shared_ptr<MediaContainer>(new MediaContainer(&rs, pServer)); return pAllsections; } catch (Poco::Net::NetException &exc) { + std::cout << exc.displayText() << std::endl; return 0; } } - +/* std::string Plexservice::encode(std::string message) { std::string temp; Poco::URI::encode(message, " !\"#$%&'()*+,/:;=?@[]", temp); return temp; } - -std::string Plexservice::GetUniversalTranscodeUrl(Video* video, int offset, PlexServer* server) +*/ +std::string Plexservice::GetUniversalTranscodeUrl(Video* video, int offset, PlexServer* server, bool http) { PlexServer* pSrv = server ? server : video->m_pServer; - std::stringstream params; - params << "/video/:/transcode/universal/start.m3u8?"; - params << "path=" << encode(pSrv->GetUri() + video->m_sKey); - params << "&mediaIndex=0"; - params << "&partIndex=0"; - params << "&protocol=hls"; - params << "&offset=" << offset; - params << "&fastSeek=0"; - params << "&directPlay=0"; - params << "&directStream=1"; - params << "&maxVideoBitrate=20000"; - params << "&subtitles=burn"; - //params << "&subtitleSize=90"; - //params << "&skipSubtitles=1"; - //params << "&audioBoost=100"; - params << "&videoResolution=1920x1080"; - params << "&videoQuality=100"; - params << "&session=" << encode(Config::GetInstance().GetUUID()); // TODO: generate Random SessionID + Poco::URI transcodeUri(pSrv->GetUri()); + transcodeUri.setPath("/video/:/transcode/universal/start.m3u8"); + + // Force set localhost and http + Poco::URI pathUri(pSrv->GetUri()+video->m_sKey); + pathUri.setHost("127.0.0.1"); + pathUri.setScheme("http"); - params << "&includeCodecs=1"; - params << "©ts=1"; + transcodeUri.addQueryParameter("path", pathUri.toString()); + transcodeUri.addQueryParameter("mediaIndex", "0"); + transcodeUri.addQueryParameter("partIndex", "0"); + transcodeUri.addQueryParameter("protocol", "hls"); + transcodeUri.addQueryParameter("offset", std::to_string(offset) ); + transcodeUri.addQueryParameter("fastSeek", "1"); + transcodeUri.addQueryParameter("directPlay", "0"); + transcodeUri.addQueryParameter("directStream", "1"); + transcodeUri.addQueryParameter("subtitles", "burn"); + transcodeUri.addQueryParameter("audioBoost", "100"); + if(pSrv->IsLocal()) { + transcodeUri.addQueryParameter("videoResolution", "1920x1080"); + transcodeUri.addQueryParameter("maxVideoBitrate", "20000"); + transcodeUri.addQueryParameter("videoQuality", "100"); + } else { + transcodeUri.addQueryParameter("videoResolution", "1280x720"); + transcodeUri.addQueryParameter("maxVideoBitrate", "8000"); + transcodeUri.addQueryParameter("videoQuality", "100"); + } + transcodeUri.addQueryParameter("session", Config::GetInstance().GetUUID()); // TODO: generate Random SessionID + transcodeUri.addQueryParameter("includeCodecs", "1"); + transcodeUri.addQueryParameter("copyts", "1"); + if(Config::GetInstance().UseAc3) { - params << "&X-Plex-Client-Profile-Extra="; - if(Config::GetInstance().UseAc3) - params << encode("add-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=hls&audioCodec=ac3)"); - + transcodeUri.addQueryParameter("X-Plex-Client-Profile-Extra", "add-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=hls&audioCodec=ac3"); //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=lowerBound&name=video.height&value=1080)"); //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=lowerBound&name=video.frameRate&value=25)"); //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=upperBound&name=video.frameRate&value=25)"); } - return pSrv->GetUri() + params.str(); + return transcodeUri.toString(); } } diff --git a/Plexservice.h b/Plexservice.h index 5f3567b..097106f 100644 --- a/Plexservice.h +++ b/Plexservice.h @@ -46,14 +46,14 @@ public: std::shared_ptr<MediaContainer> GetSection(std::string section, bool putOnStack = true); std::shared_ptr<MediaContainer> GetLastSection(bool current = false); bool IsRoot(); - void GetAuthDetails(); - void Authenticate(); PlexServer* GetServer(); + void Authenticate(); - static std::string GetUniversalTranscodeUrl(Video* video, int offset = 0, PlexServer* server = 0); + static std::string GetUniversalTranscodeUrl(Video* video, int offset = 0, PlexServer* server = 0, bool http = false); static std::string GetMyPlexToken(); static std::shared_ptr<MediaContainer> GetMediaContainer(std::string fullUrl); - static std::string encode(std::string message); + //static std::string encode(std::string message); + static void UpdateResources(); std::string StartUri; diff --git a/SubscriptionManager.cpp b/SubscriptionManager.cpp index aa10077..061f823 100644 --- a/SubscriptionManager.cpp +++ b/SubscriptionManager.cpp @@ -59,14 +59,15 @@ void SubscriptionManager::ReportProgress() std::string state = "playing"; if (m_pStatus->PlayerStopped) state = "stopped"; else if(!play) state = "paused"; - - Poco::Net::HTTPClientSession session(m_pStatus->pVideo->m_pServer->GetIpAdress(), m_pStatus->pVideo->m_pServer->GetPort()); - std::string uri = "/:/progress?key=" + std::string(itoa(m_pStatus->pVideo->m_iRatingKey)) + "&identifier=com.plexapp.plugins.library&time=" + std::string(itoa(current)) + "&state=" + state; - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); - session.sendRequest(req); + std::map<std::string, std::string> queryMap; + queryMap["key"] = std::to_string(m_pStatus->pVideo->m_iRatingKey); + queryMap["identifier"] = "com.plexapp.plugins.library"; + queryMap["time"] = std::to_string(current); + queryMap["state"] = state; + Poco::Net::HTTPResponse resp; - session.receiveResponse(resp); + m_pStatus->pVideo->m_pServer->MakeRequest(resp, "/:/progress", queryMap); } catch (Poco::Exception&) {} } @@ -88,40 +89,33 @@ void SubscriptionManager::NotifyServer() return; } - std::string server; - int port; + PlexServer* pServer; if(pVid) { - server = pVid->m_pServer->GetIpAdress(); - port = pVid->m_pServer->GetPort(); + pServer = pVid->m_pServer; } else if ( plexgdm::GetInstance().GetPlexservers().size() > 0) { - server = plexgdm::GetInstance().GetPlexservers().at(0).GetIpAdress(); - port = plexgdm::GetInstance().GetPlexservers().at(0).GetPort(); + pServer = &plexgdm::GetInstance().GetPlexservers().at(0); } else { // no plexservers in network return; } + + std::map<std::string, std::string> queryMap; - std::stringstream uri; - uri << "/:/timeline"; - uri << "?containerKey=" << Plexservice::encode(pVid ? pVid->m_sKey : "/library/metadata/900000"); - uri << "&key=" << Plexservice::encode(pVid ? pVid->m_sKey : "/library/metadata/900000"); - uri << "&ratingKey=" << (pVid ? pVid->m_iRatingKey : 900000); - uri << "&state="; - if (m_pStatus->PlayerStopped) uri << "stopped"; - else if(!play) uri << "paused"; - else uri << "playing"; - uri << "&time=" << current; - uri << "&duration=" << total; - - Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, uri.str(), Poco::Net::HTTPMessage::HTTP_1_1); + queryMap["containerKey"] = pVid ? pVid->m_sKey : "/library/metadata/900000"; + queryMap["key"] = pVid ? pVid->m_sKey : "/library/metadata/900000"; + queryMap["ratingKey"] = pVid ? std::to_string(pVid->m_iRatingKey) : "900000"; - PlexHelper::AddHttpHeader(Request); - - Poco::Net::HTTPClientSession session(server, port); + if (m_pStatus->PlayerStopped) queryMap["state"] = "stopped"; + else if(!play) queryMap["state"] = "paused"; + else queryMap["state"] = "playing"; + + queryMap["time"] = std::to_string(current); + queryMap["duration"] = std::to_string(total); - session.sendRequest(Request); + Poco::Net::HTTPResponse response; - session.receiveResponse(response); + pServer->MakeRequest(response, "/:/timeline", queryMap); + if(m_pStatus->PlayerStopped) { m_bStoppedSent = true; @@ -198,7 +192,7 @@ std::string SubscriptionManager::GetTimelineXml() msg << " controllable=\"true\""; msg << " machineIdentifier=\"" << (pVid ? pVid->m_pServer->GetUuid() : "") << "\""; msg << " protocol=\"http\""; - msg << " address=\"" << (pVid ? pVid->m_pServer->GetIpAdress() : "") << "\""; + msg << " address=\"" << (pVid ? pVid->m_pServer->GetHost() : "") << "\""; msg << " port=\"" << (pVid ? pVid->m_pServer->GetPort() : 0) << "\""; msg << " guid=\"" << Config::GetInstance().GetUUID() << "\""; msg << " containerKey=\"" << (pVid ? pVid->m_sKey : "/library/metadata/900000") << "\""; diff --git a/browserGrid.cpp b/browserGrid.cpp index f9bb026..8504ced 100644 --- a/browserGrid.cpp +++ b/browserGrid.cpp @@ -482,7 +482,7 @@ void cServerElement::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> gri grid->AddIntToken("isserver", 1); grid->AddStringToken("title", m_pServer->GetServerName()); grid->AddStringToken("serverstartpointname", m_sStartName); - grid->AddStringToken("serverip", m_pServer->GetIpAdress()); + grid->AddStringToken("serverip", m_pServer->GetHost()); grid->AddIntToken("serverport", m_pServer->GetPort()); grid->AddStringToken("serverversion", m_pServer->GetVersion()); grid->AddIntToken("viewmode", Config::GetInstance().DefaultViewMode); diff --git a/device.cpp b/device.cpp new file mode 100644 index 0000000..8ff82a7 --- /dev/null +++ b/device.cpp @@ -0,0 +1,61 @@ +#include "device.h" + +namespace plexclient +{ + +Connection::Connection(Poco::XML::Node* pNode, Device* parent) +{ + m_pParent = parent; + + NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL); + Poco::XML::Node* pChildNode = it.nextNode(); + + while(pChildNode) { + if(Poco::icompare(pChildNode->nodeName(), "Connection") == 0) { + Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes(); + + m_sProtocol = GetNodeValue(pAttribs->getNamedItem("protocol")); + m_sAddress = GetNodeValue(pAttribs->getNamedItem("address")); + m_iPort = GetNodeValueAsInt(pAttribs->getNamedItem("port")); + m_sUri = GetNodeValue(pAttribs->getNamedItem("uri")); + m_bLocal = GetNodeValueAsBool(pAttribs->getNamedItem("local")); + + pAttribs->release(); + } + pChildNode = it.nextNode(); + } +} + +Device::Device(Poco::XML::Node* pNode, MediaContainer* parent) +{ + m_pParent = parent; + + NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL); + Poco::XML::Node* pChildNode = it.nextNode(); + + while(pChildNode) { + if(Poco::icompare(pChildNode->nodeName(), "Device") == 0) { + Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes(); + + m_sName = GetNodeValue(pAttribs->getNamedItem("name")); + m_sProduct = GetNodeValue(pAttribs->getNamedItem("product")); + m_sProvides = GetNodeValue(pAttribs->getNamedItem("provides")); + m_sClientIdentifier = GetNodeValue(pAttribs->getNamedItem("clientIdentifier")); + m_bOwned = GetNodeValueAsBool(pAttribs->getNamedItem("owned")); + m_sAccessToken = GetNodeValue(pAttribs->getNamedItem("accessToken")); + m_bHttpsRequired = GetNodeValueAsBool(pAttribs->getNamedItem("httpsRequired")); + m_bPublicAddressMatches = GetNodeValueAsBool(pAttribs->getNamedItem("publicAddressMatches")); + m_bPresence = GetNodeValueAsBool(pAttribs->getNamedItem("presence")); + m_sSourceTitle = GetNodeValue(pAttribs->getNamedItem("sourceTitle")); + + pAttribs->release(); + } else if(Poco::icompare(pChildNode->nodeName(), "Connection") == 0) { + m_vConnections.push_back(Connection(pChildNode, this)); + } + + pChildNode = it.nextNode(); + } +} + + +} diff --git a/device.h b/device.h new file mode 100644 index 0000000..5b28047 --- /dev/null +++ b/device.h @@ -0,0 +1,59 @@ +#ifndef DEVICE_H +#define DEVICE_H + +#include <Poco/DOM/DOMParser.h> +#include <Poco/DOM/Document.h> +#include <Poco/DOM/NamedNodeMap.h> +#include <Poco/DOM/NodeIterator.h> +#include <Poco/DOM/NodeFilter.h> +#include <Poco/DOM/AutoPtr.h> +#include <Poco/Exception.h> +#include <Poco/Timestamp.h> +#include <Poco/String.h> + +#include "XmlObject.h" +#include "MediaContainer.h" + +namespace plexclient +{ +class Device; + +class Connection: private XmlObject +{ +public: + Connection(Poco::XML::Node* pNode, Device* parent); + + std::string m_sProtocol; + std::string m_sAddress; + int m_iPort; + std::string m_sUri; + bool m_bLocal; + + Device* m_pParent; + +}; + +class Device: private XmlObject +{ +public: + Device(Poco::XML::Node* pNode, MediaContainer* parent); + + std::string m_sName; + std::string m_sProduct; + std::string m_sProvides; + std::string m_sClientIdentifier; + bool m_bOwned; + std::string m_sAccessToken; + bool m_bHttpsRequired; + bool m_bPublicAddressMatches; + bool m_bPresence; + std::string m_sSourceTitle; + + std::vector<Connection> m_vConnections; + + MediaContainer* m_pParent; +}; + +} + +#endif // DEVICE_H diff --git a/hlsPlayer.cpp b/hlsPlayer.cpp index 5b650e3..60bc7aa 100644 --- a/hlsPlayer.cpp +++ b/hlsPlayer.cpp @@ -3,6 +3,7 @@ #include <vdr/tools.h> #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> +#include <Poco/Net/HTTPSClientSession.h> #include <Poco/Exception.h> #include <pcrecpp.h> @@ -10,6 +11,7 @@ #include <fstream> #include "Plexservice.h" +#include "plexgdm.h" #include "XmlObject.h" #include "Media.h" #include "Stream.h" @@ -18,8 +20,9 @@ static cMutex hlsMutex; //--- cHlsSegmentLoader -cHlsSegmentLoader::cHlsSegmentLoader(std::string startm3u8) +cHlsSegmentLoader::cHlsSegmentLoader(std::string startm3u8, plexclient::Video* pVideo) { + m_pVideo = pVideo; m_newList = false; m_bufferFilled = false; m_lastLoadedSegment = 0; @@ -74,7 +77,7 @@ void cHlsSegmentLoader::Action(void) m_ringBufferSize = MEGABYTE(estSize*m_segmentsToBuffer); isyslog("[plex]%s Create Ringbuffer %d MB", __FUNCTION__, estSize*m_segmentsToBuffer); - + m_pRingbuffer = new cRingBufferLinear(m_ringBufferSize, 2*TS_SIZE); while(Running()) { @@ -137,6 +140,7 @@ bool cHlsSegmentLoader::LoadIndexList(void) if(responseStart.getStatus() != 200) { esyslog("[plex]%s Response Not Valid", __FUNCTION__); + Poco::StreamCopier::copyStream(indexFile, std::cout); return res; } m_indexParser = cM3u8Parser(); @@ -175,6 +179,7 @@ bool cHlsSegmentLoader::LoadStartList(void) bool res = false; ConnectToServer(); try { + dsyslog("[plex]%s %s", __FUNCTION__, m_startUri.toString().c_str()); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, m_startUri.getPathAndQuery()); AddHeader(request); m_pClientSession->sendRequest(request); @@ -184,6 +189,7 @@ bool cHlsSegmentLoader::LoadStartList(void) if(responseStart.getStatus() != 200) { esyslog("[plex]%s Response Not Valid", __FUNCTION__); + Poco::StreamCopier::copyStream(startFile, std::cout); return res; } @@ -232,7 +238,7 @@ bool cHlsSegmentLoader::LoadSegment(std::string segmentUri) } Poco::Net::HTTPResponse segmentResponse; std::istream& segmentFile = m_pClientSession->receiveResponse(segmentResponse); - + if(segmentResponse.getStatus() != 200) { // error esyslog("[plex] %s; %s failed.", __FUNCTION__, segmentUri.c_str()); @@ -240,8 +246,7 @@ bool cHlsSegmentLoader::LoadSegment(std::string segmentUri) } dsyslog("[plex] %s: %s successfully.", __FUNCTION__, segmentUri.c_str()); - // copy response - + // copy response int m = 0; segmentFile.read(reinterpret_cast<char*>(m_pBuffer), sizeof(m_pBuffer)); std::streamsize n = segmentFile.gcount(); @@ -295,8 +300,14 @@ void cHlsSegmentLoader::CloseConnection(void) bool cHlsSegmentLoader::ConnectToServer(void) { dsyslog("[plex]%s", __FUNCTION__); - if(!m_pClientSession) - m_pClientSession = new Poco::Net::HTTPClientSession(m_startUri.getHost(), m_startUri.getPort()); + if(!m_pClientSession) { + if(m_startUri.getScheme().find("https") != std::string::npos) { + m_pClientSession = new Poco::Net::HTTPSClientSession(m_startUri.getHost(), m_startUri.getPort()); + } + else { + m_pClientSession = new Poco::Net::HTTPClientSession(m_startUri.getHost(), m_startUri.getPort()); + } + } return m_pClientSession->connected(); } @@ -324,10 +335,8 @@ bool cHlsSegmentLoader::DoLoad(void) recover = true; std::string stopUri = "/video/:/transcode/universal/stop?session=" + m_sessionCookie; try { - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, stopUri); - m_pClientSession->sendRequest(req); Poco::Net::HTTPResponse reqResponse; - m_pClientSession->receiveResponse(reqResponse); + m_pVideo->m_pServer->MakeRequest(reqResponse, stopUri); int tmp = m_lastLoadedSegment; int tmp2 = m_lastSegmentSize; CloseConnection(); @@ -361,10 +370,9 @@ bool cHlsSegmentLoader::StopLoader(void) dsyslog("[plex]%s", __FUNCTION__); try { std::string stopUri = "/video/:/transcode/universal/stop?session=" + m_sessionCookie; - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, stopUri); - m_pClientSession->sendRequest(req); + Poco::Net::HTTPResponse reqResponse; - m_pClientSession->receiveResponse(reqResponse); + m_pVideo->m_pServer->MakeRequest(reqResponse, stopUri); Cancel(); @@ -386,6 +394,11 @@ void cHlsSegmentLoader::AddHeader(Poco::Net::HTTPRequest& req) req.add("X-Plex-Product", "Plex Home Theater"); req.add("X-Plex-Platform", "Plex Home Theater"); } + + if(Config::GetInstance().UsePlexAccount && !m_pVideo->m_pServer->GetAuthToken().empty()) { + // Add PlexToken to Header + req.add("X-Plex-Token", m_pVideo->m_pServer->GetAuthToken()); + } } bool cHlsSegmentLoader::Active(void) @@ -398,11 +411,9 @@ void cHlsSegmentLoader::Ping(void) dsyslog("[plex]%s", __FUNCTION__); try { std::string uri = "/video/:/transcode/universal/ping?session=" + Config::GetInstance().GetUUID(); - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); - AddHeader(req); - m_pClientSession->sendRequest(req); + Poco::Net::HTTPResponse reqResponse; - m_pClientSession->receiveResponse(reqResponse); + m_pVideo->m_pServer->MakeRequest(reqResponse, uri); } catch(Poco::Exception& exc) { esyslog("[plex]%s %s ", __FUNCTION__, exc.displayText().c_str()); @@ -438,7 +449,6 @@ int cHlsSegmentLoader::GetStreamLenght() cHlsPlayer::cHlsPlayer(std::string startm3u8, plexclient::Video Video, int offset) { dsyslog("[plex]: '%s'", __FUNCTION__); - m_pSegmentLoader = new cHlsSegmentLoader(startm3u8); m_Video = Video; m_timeOffset = offset; m_jumpOffset = 0; @@ -447,8 +457,9 @@ cHlsPlayer::cHlsPlayer(std::string startm3u8, plexclient::Video Video, int offse m_isBuffering = false; AudioIndexOffset = 1000; // Just a magic number m_tTimer.Set(1); + m_pSegmentLoader = new cHlsSegmentLoader(startm3u8, &m_Video); + m_pDebugFile = NULL; - //m_pDebugFile = new std::ofstream(); //m_pDebugFile->open("debug.ts", std::ios::out); } @@ -581,7 +592,6 @@ bool cHlsPlayer::GetIndex(int& Current, int& Total, bool SnapToIFrame __attribut Total = m_pSegmentLoader->GetStreamLenght() * FramesPerSecond(); } Current = GetPlayedSeconds() * FramesPerSecond(); - std::cout << "FPS: " << FramesPerSecond() << "STC: " << this->DeviceGetSTC() << std::endl; return true; } @@ -667,15 +677,10 @@ void cHlsPlayer::SetAudioTrack(eTrackType Type __attribute__((unused)), const tT } // Then do the request if(streamId > 0) { - Poco::Net::HTTPClientSession session(m_Video.m_pServer->GetIpAdress(), m_Video.m_pServer->GetPort()); - std::string uri = "/library/parts/" + std::string(itoa(m_Video.m_Media.m_iPartId)) + "?audioStreamID=" + std::string(itoa(streamId)); - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, uri); - session.sendRequest(req); Poco::Net::HTTPResponse resp; - session.receiveResponse(resp); - + m_Video.m_pServer->MakeRequest(resp, uri); if(resp.getStatus() == 200) { DeviceSetCurrentAudioTrack(eTrackType(ttDolby + 0)); // hacky DeviceSetAvailableTrack(ttDolby, 0, 0, TrackId->language); @@ -719,13 +724,10 @@ void cHlsPlayer::ReportProgress(bool stopped) } try { - Poco::Net::HTTPClientSession session(m_Video.m_pServer->GetIpAdress(), m_Video.m_pServer->GetPort()); std::string uri = "/:/progress?key=" + std::string(itoa(m_Video.m_iRatingKey)) + "&identifier=com.plexapp.plugins.library&time=" + std::string(itoa(GetPlayedSeconds()*1000)) + "&state=" + state; - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); - session.sendRequest(req); Poco::Net::HTTPResponse resp; - session.receiveResponse(resp); + m_Video.m_pServer->MakeRequest(resp, uri); if(resp.getStatus() == 200) { dsyslog("[plex] %s", __FUNCTION__); @@ -736,14 +738,11 @@ void cHlsPlayer::ReportProgress(bool stopped) void cHlsPlayer::SetWatched(void) { - Poco::Net::HTTPClientSession session(m_Video.m_pServer->GetIpAdress(), m_Video.m_pServer->GetPort()); std::string uri = "/:/scrobble?key=" + std::string(itoa(m_Video.m_iRatingKey)) + "&identifier=com.plexapp.plugins.library"; - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); - session.sendRequest(req); Poco::Net::HTTPResponse resp; - session.receiveResponse(resp); - + m_Video.m_pServer->MakeRequest(resp, uri); + if(resp.getStatus() == 200) { dsyslog("[plex] %s", __FUNCTION__); } diff --git a/hlsPlayer.h b/hlsPlayer.h index 1e88deb..ed5a80e 100644 --- a/hlsPlayer.h +++ b/hlsPlayer.h @@ -33,11 +33,12 @@ private: uchar* m_pBuffer; Poco::Net::HTTPClientSession* m_pClientSession; + plexclient::Video* m_pVideo; Poco::URI m_startUri; std::string m_sessionUriPart; std::string m_segmentUriPart; std::string m_sessionCookie; - + cM3u8Parser m_startParser; cM3u8Parser m_indexParser; @@ -59,7 +60,7 @@ protected: bool DoLoad(void); public: - cHlsSegmentLoader(std::string startm3u8); + cHlsSegmentLoader(std::string startm3u8, plexclient::Video* pVideo); ~cHlsSegmentLoader(); cRingBufferLinear* m_pRingbuffer; diff --git a/mpvWrapper.cpp b/mpvWrapper.cpp index 4986705..48aa025 100644 --- a/mpvWrapper.cpp +++ b/mpvWrapper.cpp @@ -4,7 +4,3 @@ cMpvWrapper::cMpvWrapper() { } -cMpvWrapper::~cMpvWrapper() -{ -} - diff --git a/mpvWrapper.h b/mpvWrapper.h index 890a27f..207494c 100644 --- a/mpvWrapper.h +++ b/mpvWrapper.h @@ -5,8 +5,6 @@ class cMpvWrapper { public: cMpvWrapper(); - ~cMpvWrapper(); - }; #endif // CMPVWRAPPER_H diff --git a/pictureCache.cpp b/pictureCache.cpp index 299bd8e..556a75d 100644 --- a/pictureCache.cpp +++ b/pictureCache.cpp @@ -122,7 +122,7 @@ std::string cPictureCache::TranscodeUri(std::string uri, int width, int height) std::string host = u.getHost(); auto plServer = plexclient::plexgdm::GetInstance().GetFirstServer(); if (plServer) { - host = plServer->GetIpAdress(); + host = plServer->GetHost(); port = plServer->GetPort(); } @@ -7,6 +7,11 @@ #include "services.h" #include <libskindesignerapi/skindesignerapi.h> +#include <Poco/Net/SSLManager.h> +#include <Poco/SharedPtr.h> +#include <Poco/Net/Context.h> +#include <Poco/Net/AcceptCertificateHandler.h> +#include <Poco/Net/ConsoleCertificateHandler.h> ////////////////////////////////////////////////////////////////////////////// // cPlugin @@ -98,6 +103,24 @@ bool cMyPlugin::Start(void) */ bool cMyPlugin::Initialize(void) { + // Initialize SSL + { + using namespace Poco; + using namespace Poco::Net; + using Poco::Net::SSLManager; + using Poco::Net::Context; + using Poco::Net::AcceptCertificateHandler; + using Poco::Net::PrivateKeyPassphraseHandler; + using Poco::Net::InvalidCertificateHandler; + using Poco::Net::ConsoleCertificateHandler; + + //SharedPtr<PrivateKeyPassphraseHandler> pConsoleHandler = new PrivateKeyPassphraseHandler; + SharedPtr<InvalidCertificateHandler> pInvalidCertHandler = new AcceptCertificateHandler(false); + Context::Ptr pContext = new Poco::Net::Context( + Context::CLIENT_USE, "", "", "", Context::VERIFY_NONE, // VERIFY_NONE...?! + 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + SSLManager::instance().initializeClient(NULL, pInvalidCertHandler, pContext); + } // First Startup? Save UUID SetupStore("UUID", Config::GetInstance().GetUUID().c_str()); @@ -105,7 +128,7 @@ bool cMyPlugin::Initialize(void) plexclient::plexgdm::GetInstance().Start(); plexclient::ControlServer::GetInstance().Start(); cPictureCache::GetInstance().Start(); - + return true; } @@ -188,8 +211,14 @@ void cMyPlugin::PlayFile(plexclient::Video Vid) Mpv_PlayFile req; Mpv_SetTitle reqTitle; - char* file = (char*)(Vid.m_pServer->GetUri() + Vid.m_Media.m_sPartKey).c_str(); - + char* file; + if(Config::GetInstance().UsePlexAccount && Vid.m_pServer->IsLocal() == false) { + file = (char*)plexclient::Plexservice::GetUniversalTranscodeUrl(&Vid, Vid.m_iMyPlayOffset, NULL, true).c_str(); + } + else { + file = (char*)(Vid.m_pServer->GetUri() + Vid.m_Media.m_sPartKey).c_str(); + } + req.Filename = file; mpvPlugin->Service(MPV_PLAY_FILE, &req); diff --git a/plexgdm.cpp b/plexgdm.cpp index cdc1339..e76279d 100644 --- a/plexgdm.cpp +++ b/plexgdm.cpp @@ -2,6 +2,7 @@ #include "plexgdm.h" #include "Config.h" #include <ctime> +#include "Plexservice.h" namespace plexclient { @@ -61,8 +62,15 @@ void plexgdm::Action() if(Config::GetInstance().UseConfiguredServer) { // Adds a Server to vector GetServer(Config::GetInstance().s_serverHost, Config::GetInstance().ServerPort); + + if(Config::GetInstance().UsePlexAccount) { + GetServer(Config::GetInstance().s_serverHost, Config::GetInstance().ServerPort)->SetAuthToken(Plexservice::GetMyPlexToken()); + } } + // Get remote Resources + Plexservice::UpdateResources(); + char buffer[1024]; m_registrationIsRunning = true; m_discoveryIsRunning = true; @@ -164,7 +172,7 @@ void plexgdm::discover() bool flag = true; // Check for duplicates for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) { - if(s_it->GetIpAdress() == host) { + if(s_it->GetHost() == host) { flag = false; s_it->ParseData(data, host); dsyslog("[plex] Server Updated: %s", host.c_str()); @@ -172,6 +180,10 @@ void plexgdm::discover() } if(flag) { m_vServers.push_back(PlexServer(data, host)); + // Set token for local servers + if(Config::GetInstance().UsePlexAccount) { + m_vServers[m_vServers.size()-1].SetAuthToken(Plexservice::GetMyPlexToken()); + } isyslog("[plex] New Server Discovered: %s", host.c_str()); } } @@ -194,7 +206,7 @@ void plexgdm::stopRegistration() PlexServer* plexgdm::GetServer(std::string ip, int port) { for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) { - if(s_it->GetIpAdress() == ip && s_it->GetPort() == port) { + if(s_it->GetHost() == ip && s_it->GetPort() == port) { return &(*s_it); } } @@ -208,4 +220,26 @@ PlexServer* plexgdm::GetFirstServer() else return NULL; } +PlexServer* plexgdm::GetServer(std::string uuid) +{ + for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) { + if(s_it->GetUuid() == uuid ){ + return &(*s_it); + } + } + return NULL; +} + +void plexgdm::AddServer(PlexServer server) +{ + for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) { + if(s_it->GetUuid() == server.GetUuid() ){ + dsyslog("[plex] Server already in list: %s", server.GetUri().c_str()); + return; + } + } + m_vServers.push_back(server); + isyslog("[plex] New Server Added: %s", server.GetUri().c_str()); +} + } // namespace @@ -34,6 +34,8 @@ public: std::string getClientDetails(); PlexServer* getServerList(); PlexServer* GetServer(std::string ip, int port); + PlexServer* GetServer(std::string uuid); + void AddServer(PlexServer server); PlexServer* GetFirstServer(); void discover(); void checkClientRegistration(); diff --git a/po/de_DE.mo b/po/de_DE.mo Binary files differindex 0a3f556..db25a05 100644 --- a/po/de_DE.mo +++ b/po/de_DE.mo diff --git a/po/de_DE.po b/po/de_DE.po index 4c68b43..265d9b6 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-plex 0.1.0\n" "Report-Msgid-Bugs-To: <see README>\n" -"POT-Creation-Date: 2015-11-07 16:19+0100\n" +"POT-Creation-Date: 2015-12-15 20:56+0100\n" "PO-Revision-Date: 2015-11-07 16:38+0200\n" "Last-Translator: Chris <zerov83@gmail.com>\n" "Language-Team: LANGUAGE <LL@li.org>\n" |