diff --git a/src/YoutubeApi.cpp b/src/YoutubeApi.cpp index 0dda5b1..59977c3 100644 --- a/src/YoutubeApi.cpp +++ b/src/YoutubeApi.cpp @@ -27,156 +27,148 @@ #include "YoutubeApi.h" -YoutubeApi::YoutubeApi(String apiKey, Client &client) { - int strLen = apiKey.length() + 1; - char tempStr[strLen]; - apiKey.toCharArray(tempStr, strLen); - - YoutubeApi(tempStr, client); -} - -YoutubeApi::YoutubeApi(char *apiKey, Client &client) { - _apiKey = apiKey; - this->client = &client; -} - -int YoutubeApi::sendGetToYoutube(char *command) { - client->flush(); - client->setTimeout(YTAPI_TIMEOUT); - if (!client->connect(YTAPI_HOST, YTAPI_SSL_PORT)) - { - Serial.println(F("Connection failed")); - return false; - } +YoutubeApi::YoutubeApi(const char* key, Client &client) + : apiKey(key), client(client) +{} + +YoutubeApi::YoutubeApi(const String &apiKey, Client &client) + : YoutubeApi(apiKey.c_str(), client) // passing the key as c-string to force a copy +{} + +int YoutubeApi::sendGetToYoutube(const char *command) { + client.flush(); + client.setTimeout(YTAPI_TIMEOUT); + if (!client.connect(YTAPI_HOST, YTAPI_SSL_PORT)) + { + Serial.println(F("Connection failed")); + return false; + } // give the esp a breather - yield(); + yield(); - // Send HTTP request - client->print(F("GET ")); - client->print(command); - client->println(F(" HTTP/1.1")); + // Send HTTP request + client.print(F("GET ")); + client.print(command); + client.println(F(" HTTP/1.1")); //Headers - client->print(F("Host: ")); - client->println(YTAPI_HOST); + client.print(F("Host: ")); + client.println(YTAPI_HOST); - client->println(F("Cache-Control: no-cache")); + client.println(F("Cache-Control: no-cache")); - if (client->println() == 0) - { - Serial.println(F("Failed to send request")); - return -1; - } + if (client.println() == 0) + { + Serial.println(F("Failed to send request")); + return -1; + } int statusCode = getHttpStatusCode(); - - // Let the caller of this method parse the JSon from the client - skipHeaders(); - return statusCode; -} - -bool YoutubeApi::getChannelStatistics(String channelId){ - int strLen = channelId.length() + 1; - char tempStr[strLen]; - channelId.toCharArray(tempStr, strLen); + // Let the caller of this method parse the JSon from the client + skipHeaders(); + return statusCode; +} - return getChannelStatistics(tempStr); +int YoutubeApi::sendGetToYoutube(const String& command) { + return sendGetToYoutube(command.c_str()); } -bool YoutubeApi::getChannelStatistics(char *channelId){ +bool YoutubeApi::getChannelStatistics(const char *channelId) { char command[150] = YTAPI_CHANNEL_ENDPOINT; - char params[120]; - sprintf(params, "?part=statistics&id=%s&key=%s", channelId, _apiKey); - strcat(command, params); + char params[120]; + sprintf(params, "?part=statistics&id=%s&key=%s", channelId, apiKey.c_str()); + strcat(command, params); - if (_debug) - { - Serial.println(command); - } + if (_debug) + { + Serial.println(command); + } bool wasSuccessful = false; - // Get from https://arduinojson.org/v6/assistant/ - const size_t bufferSize = JSON_ARRAY_SIZE(1) - + JSON_OBJECT_SIZE(2) - + 2*JSON_OBJECT_SIZE(4) - + JSON_OBJECT_SIZE(5) - + 330; + // Get from https://arduinojson.org/v6/assistant/ + const size_t bufferSize = JSON_ARRAY_SIZE(1) + + JSON_OBJECT_SIZE(2) + + 2*JSON_OBJECT_SIZE(4) + + JSON_OBJECT_SIZE(5) + + 330; - int httpStatus = sendGetToYoutube(command); + int httpStatus = sendGetToYoutube(command); - if (httpStatus == 200) - { - // Allocate DynamicJsonDocument - DynamicJsonDocument doc(bufferSize); + if (httpStatus == 200) + { + // Allocate DynamicJsonDocument + DynamicJsonDocument doc(bufferSize); - // Parse JSON object - DeserializationError error = deserializeJson(doc, *client); - if (!error) - { + // Parse JSON object + DeserializationError error = deserializeJson(doc, client); + if (!error) + { wasSuccessful = true; - JsonObject itemStatistics = doc["items"][0]["statistics"]; + JsonObject itemStatistics = doc["items"][0]["statistics"]; channelStats.viewCount = itemStatistics["viewCount"].as(); channelStats.subscriberCount = itemStatistics["subscriberCount"].as(); channelStats.commentCount = itemStatistics["commentCount"].as(); channelStats.hiddenSubscriberCount = itemStatistics["hiddenSubscriberCount"].as(); channelStats.videoCount = itemStatistics["videoCount"].as(); - } - else - { - Serial.print(F("deserializeJson() failed with code ")); - Serial.println(error.c_str()); - } - } else { - Serial.print("Unexpected HTTP Status Code: "); - Serial.println(httpStatus); - } - closeClient(); + } + else + { + Serial.print(F("deserializeJson() failed with code ")); + Serial.println(error.c_str()); + } + } else { + Serial.print("Unexpected HTTP Status Code: "); + Serial.println(httpStatus); + } + closeClient(); return wasSuccessful; } -void YoutubeApi::skipHeaders() -{ - // Skip HTTP headers - char endOfHeaders[] = "\r\n\r\n"; - if (!client->find(endOfHeaders)) - { - Serial.println(F("Invalid response")); - return; - } - - // Was getting stray characters between the headers and the body - // This should toss them away - while (client->available() && client->peek() != '{') - { - char c = 0; - client->readBytes(&c, 1); - if (_debug) - { - Serial.print("Tossing an unexpected character: "); - Serial.println(c); - } - } +bool YoutubeApi::getChannelStatistics(const String& channelId) { + return getChannelStatistics(channelId.c_str()); +} + +void YoutubeApi::skipHeaders() { + // Skip HTTP headers + char endOfHeaders[] = "\r\n\r\n"; + if (!client.find(endOfHeaders)) + { + Serial.println(F("Invalid response")); + return; + } + + // Was getting stray characters between the headers and the body + // This should toss them away + while (client.available() && client.peek() != '{') + { + char c = 0; + client.readBytes(&c, 1); + if (_debug) + { + Serial.print("Tossing an unexpected character: "); + Serial.println(c); + } + } } -int YoutubeApi::getHttpStatusCode() -{ - // Check HTTP status - if(client->find("HTTP/1.1")){ - int statusCode = client->parseInt(); - return statusCode; - } +int YoutubeApi::getHttpStatusCode() { + // Check HTTP status + if(client.find("HTTP/1.1")){ + int statusCode = client.parseInt(); + return statusCode; + } - return -1; + return -1; } void YoutubeApi::closeClient() { - if(client->connected()) { + if(client.connected()) { if(_debug) { Serial.println(F("Closing client")); } - client->stop(); + client.stop(); } } diff --git a/src/YoutubeApi.h b/src/YoutubeApi.h index f958db3..28169ad 100644 --- a/src/YoutubeApi.h +++ b/src/YoutubeApi.h @@ -37,31 +37,32 @@ #define YTAPI_CHANNEL_ENDPOINT "/youtube/v3/channels" -struct channelStatistics{ - long viewCount; - long commentCount; /* DEPRECATED */ - long subscriberCount; - bool hiddenSubscriberCount; - long videoCount; +struct channelStatistics { + long viewCount; + long commentCount; /* DEPRECATED */ + long subscriberCount; + bool hiddenSubscriberCount; + long videoCount; }; class YoutubeApi { - public: - YoutubeApi (char *apiKey, Client &client); - YoutubeApi (String apiKey, Client &client); - int sendGetToYoutube(char *command); - bool getChannelStatistics(char *channelId); - bool getChannelStatistics(String channelId); - channelStatistics channelStats; - bool _debug = false; + public: + YoutubeApi(const char *key, Client &client); + YoutubeApi(const String& apiKey, Client& client); + int sendGetToYoutube(const char *command); + int sendGetToYoutube(const String& command); + bool getChannelStatistics(const char *channelId); + bool getChannelStatistics(const String& channelId); + channelStatistics channelStats; + bool _debug = false; - private: - char *_apiKey; - Client *client; - int getHttpStatusCode(); - void skipHeaders(); - void closeClient(); + private: + const String apiKey; + Client &client; + int getHttpStatusCode(); + void skipHeaders(); + void closeClient(); }; #endif