Simple C++ TVDBApi for Windows.

A place for developers to advertise their TheTVDB.com enabled app and get help from other developers with the API.
Post Reply
Fleuve
Posts: 1
Joined: Thu Mar 12, 2020 9:10 am

Tue Mar 17, 2020 4:51 pm

Hello,

There is a simple C++ TVDBApi for Windows.

Main.cpp

Code: Select all

#include <windows.h>
#include <stdio.h>
#include <RDTVDBApi.h>

int main(void)
{
    CRDTVDBApi TheTVDB; 

    TheTVDB.Login("YOURAPIKEY", "YOURUSERKEY", "YOURUSERNAME");

    int TVID = TheTVDB.GetSeriesID(L"Alias");

    printf("Header: \n%ls", TheTVDB.GetLastOutputHeaders());
    printf("Contents: \n%s", TheTVDB.GetLastOutput());

    TheTVDB.GetSeries(TVID);
    
    printf("Header: \n%ls", TheTVDB.GetLastOutputHeaders());
    printf("Contents: \n%s", TheTVDB.GetLastOutput());

    TheTVDB.GetSeriesEpisodes(TVID);

    printf("Header: \n%ls", TheTVDB.GetLastOutputHeaders());
    printf("Contents: \n%s", TheTVDB.GetLastOutput());
    
    TheTVDB.Logout();
}
RDHTTPRequest.h

Code: Select all

//*** Macro definition ****************************************************
#ifndef _RELENTLESS_X_RDHTTPREQUEST_H__
	#define _RELENTLESS_X_RDHTTPREQUEST_H__

//*** Define **************************************************************
#pragma once

//*** Include **************************************************************
#include <winhttp.h>

//***************************************************************************
//* Output        : #pragma
//* Function name : comment
//* Description   : 
//* Input         : lib
//*                 "winhttp.lib"
//***************************************************************************
#pragma comment(lib,"winhttp.lib")

//*** Class definition *****************************************************
class CRDHTTPRequest
{
	public:
		CRDHTTPRequest();
		void Connect(wchar_t* UserAgent, wchar_t* Server);
		void SendRequest(wchar_t* Verb, wchar_t* VerbParam, wchar_t* Headers, char* Data, char*& Output, wchar_t*& OutputHeader);

		void Disconnect();

	private:
		HINTERNET hSession;
		HINTERNET hConnect;
		HINTERNET hRequest;
};

//*** End macro definition *************************************************
#endif

//*** Macro definition ****************************************************
#ifndef _RELENTLESS_X_RDHTTPREQUEST_CPP__
	#define	_RELENTLESS_X_RDHTTPREQUEST_CPP__

//*** Include **************************************************************
//#include "RDHTTPRequest.h"

//***************************************************************************
//* Class name    : CRDHTTPRequest
//* Function name : CRDHTTPRequest
//* Description   : Constructeur
//***************************************************************************
CRDHTTPRequest::CRDHTTPRequest()
{
    hSession = NULL;
    hConnect = NULL;
    hRequest = NULL;
}

//***************************************************************************
//* Class name    : CRDHTTPRequest
//* Output        : void
//* Function name : Connect
//* Description   : 
//* Input         : wchar_t* UserAgent
//*                 wchar_t* Server
//***************************************************************************
void CRDHTTPRequest::Connect(wchar_t* UserAgent, wchar_t* Server)
{
    hSession = WinHttpOpen(UserAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);

    if (hSession)
        hConnect = WinHttpConnect(hSession, Server, INTERNET_DEFAULT_HTTPS_PORT, 0);
}

//***************************************************************************
//* Class name    : CRDHTTPRequest
//* Output        : void
//* Function name : SendRequest
//* Description   : 
//* Input         : wchar_t* Verb
//*                 wchar_t* VerbParam
//*                 wchar_t* Headers
//*                 char* Data
//*                 char*& Output
//*                 wchar_t*& OutputHeader
//***************************************************************************
void CRDHTTPRequest::SendRequest(wchar_t* Verb, wchar_t* VerbParam, wchar_t* Headers, char* Data, char*& Output, wchar_t*& OutputHeader)
{
    if (Output)
    {
        free(Output);
        Output = NULL;
    }

    if (Output == NULL)
    {
        Output = (char*)malloc(1);
        strcpy_s(Output, 1, "");
    }

    if (OutputHeader)
    {
        free(OutputHeader);
        OutputHeader = NULL;
    }

    if (hConnect)
    {
        hRequest = WinHttpOpenRequest(hConnect, Verb, VerbParam, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);

        if (hRequest)
        {
            unsigned long CommandSize = 0;
            if (Data != NULL)
                CommandSize = (unsigned long)strlen(Data);

            WinHttpSendRequest(hRequest, Headers, (unsigned long)wcslen(Headers), (void*)Data, CommandSize, CommandSize, 0);

            if (WinHttpReceiveResponse(hRequest, NULL))
            {
                unsigned long dwSize = 0;

                if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX))
                {
                    OutputHeader = (wchar_t*)malloc(dwSize * sizeof(wchar_t*));
                    WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, OutputHeader, &dwSize, WINHTTP_NO_HEADER_INDEX);
                }

                do
                {
                    WinHttpQueryDataAvailable(hRequest, &dwSize);

                    int iSize = (int)dwSize + 1;
                    char* Buffer = (char*)malloc(iSize);

                    if (Buffer)
                    {
                        ZeroMemory(Buffer, iSize);

                        unsigned long dwDownloaded = 0;
                        WinHttpReadData(hRequest, (void*)Buffer, dwSize, &dwDownloaded);

                        if (dwDownloaded)
                        {
                            iSize += (int)strlen(Output);
                            char* Merged = (char*)malloc(iSize);

                            if (Merged)
                            {
                                strcpy_s(Merged, iSize, Output);
                                strcat_s(Merged, iSize, Buffer);

                                free(Output);
                                Output = Merged;
                            }
                        }

                        free(Buffer);
                    }
                    else
                        dwSize = 0;

                } while (dwSize > 0);
            }

            WinHttpCloseHandle(hRequest);
        }
    }
}

//***************************************************************************
//* Class name    : CRDHTTPRequest
//* Output        : void
//* Function name : CloseConnect
//* Description   : 
//***************************************************************************
void CRDHTTPRequest::Disconnect()
{
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);
}

//*** End macro definition *************************************************
#endif
RDTVDBApi.h

Code: Select all

//*** Macro definition ****************************************************
#ifndef _RELENTLESS_X_RDTVDBAPI_H__
	#define _RELENTLESS_X_RDTVDBAPI_H__

//*** Define **************************************************************
#pragma once

//*** Include **************************************************************
#include <RDHTTPRequest.h>

//*** Class definition *****************************************************
class CRDTVDBApi
{
	public:
		CRDTVDBApi();

		void Login(char* APIKey, char* UserKey, char* UserName);
		void Logout();

		unsigned long GetSeriesID(wchar_t* SerieName);
		void GetSeries(unsigned long TVID);
		void GetSeriesEpisodes(unsigned long TVID);

		char* GetLastOutput();
		wchar_t* GetLastOutputHeaders();

	private:
		CRDHTTPRequest* HTTPRequest;
		wchar_t Headers[1024];
		wchar_t* LastOutputHeaders;
		char* LastOutput;
};

//*** End macro definition *************************************************
#endif

//*** Macro definition ****************************************************
#ifndef _RELENTLESS_X_RDTVDBAPI_CPP__
	#define	_RELENTLESS_X_RDTVDBAPI_CPP__

//*** Include **************************************************************
//#include "RDTVDBApi.h"

//***************************************************************************
//* Class name    : CRDTVDBApi
//* Function name : CRDTVDBApi
//* Description   : Constructeur
//***************************************************************************
CRDTVDBApi::CRDTVDBApi()
{
	HTTPRequest = new CRDHTTPRequest();
	wcscpy_s(Headers, 1024, L"");
	LastOutputHeaders = NULL;
	LastOutput = NULL;
}

//***************************************************************************
//* Class name    : CRDTVDBApi
//* Output        : void
//* Function name : Login
//* Description   : 
//* Input         : char* APIKey
//*                 char* UserKey
//*                 char* UserName
//***************************************************************************
void CRDTVDBApi::Login(char* APIKey, char* UserKey, char* UserName)
{
	wcscpy_s(Headers, 1024, L"Content-Type: application/json\r\n");
	wcscat_s(Headers, 1024, L"Accept-Language: fr\r\n");

	char* Output = NULL;
	wchar_t* OutputHeader = NULL;

	char Data[1024];
	sprintf_s(Data, 1024, "{\r\n  \"apikey\": \"%s\",\r\n  \"userkey\": \"%s\",\r\n  \"username\": \"%s\"\r\n}\r\n", APIKey, UserKey, UserName);

	HTTPRequest->Connect(L"Relentless HTTP Request", L"api.thetvdb.com");
	HTTPRequest->SendRequest(L"POST", L"/login", Headers, Data, Output, OutputHeader);

	printf("Header: \n%ls", OutputHeader);
	printf("Contents: \n%s", Output);

	char Token[1024] = "";
	sscanf_s(Output, "{\"token\":\"%s", &Token, 1024);
	Token[strlen(Token) - 2] = 0x00;
		
	swprintf_s(Headers, 1024, L"%sAuthorization: Bearer %S\r\n", Headers, Token);
}

//***************************************************************************
//* Class name    : long CRDTVDBApi
//* Output        : unsigned
//* Function name : GetSeriesID
//* Description   : 
//* Input         : wchar_t* SerieName
//***************************************************************************
unsigned long CRDTVDBApi::GetSeriesID(wchar_t* SerieName)
{
	wchar_t Request[1024] = L"";
	swprintf_s(Request, 1024, L"/search/series?name=%s", SerieName);
	HTTPRequest->SendRequest(L"GET", Request, Headers, NULL, LastOutput, LastOutputHeaders);

	char* Pos = strstr(LastOutput, "\"id\":");
	unsigned long TVID = 0;
	sscanf_s(Pos, "\"id\":%lu", &TVID);
	
	return TVID;
}

//***************************************************************************
//* Class name    : CRDTVDBApi
//* Output        : void
//* Function name : GetSeries
//* Description   : 
//* Input         : unsigned long TVID
//***************************************************************************
void CRDTVDBApi::GetSeries(unsigned long TVID)
{
	wchar_t Request[1024] = L"";
	swprintf_s(Request, 1024, L"/series/%d", TVID);
	HTTPRequest->SendRequest(L"GET", Request, Headers, NULL, LastOutput, LastOutputHeaders);
}

//***************************************************************************
//* Class name    : CRDTVDBApi
//* Output        : void
//* Function name : GetSeriesEpisodes
//* Description   : 
//* Input         : unsigned long TVID
//***************************************************************************
void CRDTVDBApi::GetSeriesEpisodes(unsigned long TVID)
{
	wchar_t Request[1024] = L"";
	swprintf_s(Request, 1024, L"/series/%d/episodes", TVID);
	HTTPRequest->SendRequest(L"GET", Request, Headers, NULL, LastOutput, LastOutputHeaders);
}

//***************************************************************************
//* Class name    : CRDTVDBApi
//* Output        : void
//* Function name : Logout
//* Description   : 
//***************************************************************************
void CRDTVDBApi::Logout()
{
	HTTPRequest->Disconnect();
}

//***************************************************************************
//* Class name    : CRDTVDBApi
//* Output        : char*
//* Function name : GetLastOutput
//* Description   : 
//***************************************************************************
char* CRDTVDBApi::GetLastOutput()
{
	return LastOutput;
}

//***************************************************************************
//* Class name    : CRDTVDBApi
//* Output        : wchar_t*
//* Function name : GetLastOutputHeaders
//* Description   : 
//***************************************************************************
wchar_t* CRDTVDBApi::GetLastOutputHeaders()
{
	return LastOutputHeaders;
}

//*** End macro definition *************************************************
#endif
Now, you have a base for your c++ library.

Hope that can be helpful.

Mathieu.
Post Reply