From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/Plugins/Library/ml_wire/RSSCOM.cpp | 232 +++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 Src/Plugins/Library/ml_wire/RSSCOM.cpp (limited to 'Src/Plugins/Library/ml_wire/RSSCOM.cpp') diff --git a/Src/Plugins/Library/ml_wire/RSSCOM.cpp b/Src/Plugins/Library/ml_wire/RSSCOM.cpp new file mode 100644 index 00000000..2db9a2bf --- /dev/null +++ b/Src/Plugins/Library/ml_wire/RSSCOM.cpp @@ -0,0 +1,232 @@ +#include "main.h" +#include "./rssCOM.h" +#include "./util.h" +#include "api__ml_wire.h" +#include "./cloud.h" +#include "./feedUtil.h" +#include "./defaults.h" +#include "./errors.h" + +#include "../winamp/jsapi.h" + +#include "./rssCOM.h" + +#include + +extern Cloud cloud; + + +#define DISPTABLE_CLASS RssCOM + +DISPTABLE_BEGIN() + DISPENTRY_ADD(DISPATCH_SUBSCRIBE, L"subscribe", OnSubscribe) +DISPTABLE_END + +#undef DISPTABLE_CLASS + + + +RssCOM::RssCOM() +{} + +RssCOM::~RssCOM() +{} + +HRESULT RssCOM::CreateInstance(RssCOM **instance) +{ + if (NULL == instance) return E_POINTER; + + *instance = new RssCOM(); + if (NULL == *instance) return E_OUTOFMEMORY; + + return S_OK; +} + +STDMETHODIMP_(ULONG) RssCOM::AddRef(void) +{ + return _ref.fetch_add( 1 ); +} + +STDMETHODIMP_(ULONG) RssCOM::Release(void) +{ + if (0 == _ref.load() ) + return _ref.load(); + + LONG r = _ref.fetch_sub( 1 ); + if (0 == r) + delete(this); + + return r; +} + +STDMETHODIMP RssCOM::QueryInterface(REFIID riid, PVOID *ppvObject) +{ + if (NULL == ppvObject) return E_POINTER; + + if (IsEqualIID(riid, IID_IDispatch)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IUnknown)) + *ppvObject = static_cast(this); + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + AddRef(); + return S_OK; +} + + +HRESULT RssCOM::OnSubscribe(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr) +{ + JSAPI_VERIFY_METHOD(wFlags); + JSAPI_VERIFY_PARAMCOUNT(pdispparams, 1); + + BSTR url; + + JSAPI_GETSTRING(url, pdispparams, 1, puArgErr); + + SubscribeUrl(url, pvarResult); + + return S_OK; +} + +struct SubscribeThreadData +{ + LPWSTR url; +}; +static LPCWSTR FormatLangString(LPWSTR pszBuffer, INT cchBufferMax, LPWSTR pszFormat, INT cchFormatMax, INT formatId, ...) +{ + HRESULT hr; + va_list argList; + va_start(argList, formatId); + + if(NULL != WASABI_API_LNGSTRINGW_BUF(formatId, pszFormat, cchFormatMax)) + { + hr = StringCchVPrintfExW(pszBuffer, cchBufferMax, NULL, NULL, STRSAFE_IGNORE_NULLS, pszFormat, argList); + } + else + { + hr = E_FAIL; + } + + va_end(argList); + + return (SUCCEEDED(hr)) ? pszBuffer : NULL; +} + +static DWORD WINAPI SubscribeThreadProc(void *param) +{ + SubscribeThreadData *data = (SubscribeThreadData *)param; + Channel newFeed; + newFeed.updateTime = updateTime; + newFeed.autoUpdate = autoUpdate; + newFeed.autoDownload = autoDownload; + newFeed.autoDownloadEpisodes = autoDownloadEpisodes; + newFeed.SetURL(data->url); + newFeed.needsRefresh = true; + + WCHAR szBuffer1[2048] = {0}, szBuffer2[2048] = {0}; + LPCWSTR pszMessage = NULL, pszTitle = NULL; + + switch (DownloadFeedInformation(newFeed)) + { + case DOWNLOAD_SUCCESS: + { + Nullsoft::Utility::AutoLock lock (channels LOCKNAME("AddURL")); + newFeed.autoDownload = ::autoDownload; + if (channels.AddChannel(newFeed)) + cloud.Pulse(); + } + break; + + case DOWNLOAD_DUPLICATE: + pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_ALREADY_SUBSCRIBED, newFeed.title, data->url); + break; + + case DOWNLOAD_404: + pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_FILE_NOT_FOUND, data->url); + break; + + case DOWNLOAD_TIMEOUT: + pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_CONNECTION_TIMED_OUT, data->url); + break; + + case DOWNLOAD_ERROR_PARSING_XML: + pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_ERROR_PARSING_XML, data->url); + break; + + case DOWNLOAD_NOTRSS: + pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_INVALID_RSS_FEED, data->url); + break; + + case DOWNLOAD_CONNECTIONRESET: + pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_CONNECTION_RESET, data->url); + break; + + case DOWNLOAD_NOHTTP: + pszMessage = WASABI_API_LNGSTRINGW_BUF(IDS_NO_JNETLIB, szBuffer1, ARRAYSIZE(szBuffer1)); + pszTitle = WASABI_API_LNGSTRINGW_BUF(IDS_JNETLIB_MISSING, szBuffer2, ARRAYSIZE(szBuffer2)); + break; + + case DOWNLOAD_NOPARSER: + pszMessage = WASABI_API_LNGSTRINGW_BUF(IDS_NO_EXPAT, szBuffer1, ARRAYSIZE(szBuffer1)); + pszTitle = WASABI_API_LNGSTRINGW_BUF(IDS_EXPAT_MISSING, szBuffer2, ARRAYSIZE(szBuffer2)); + break; + + + } + + if(NULL != pszMessage) + { + if (NULL == pszTitle) + pszTitle = WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SUBSCRIBING_TO_PODCAST, szBuffer2, ARRAYSIZE(szBuffer2)); + + MessageBox(plugin.hwndLibraryParent, pszMessage, pszTitle, MB_ICONERROR | MB_OK); + } + + Plugin_FreeString(data->url); + free(data); + return 0; +} + +LPCWSTR RssCOM::GetName() +{ + return L"Podcast"; +} + +HRESULT RssCOM::SubscribeUrl(BSTR url, VARIANT FAR *result) +{ + HRESULT hr; + SubscribeThreadData *data = (SubscribeThreadData*)malloc(sizeof(SubscribeThreadData)); + if (NULL != data) + { + data->url = Plugin_CopyString(url); + DWORD threadId; + HANDLE hThread = CreateThread(NULL, NULL, SubscribeThreadProc, (void*)data, NULL, &threadId); + if (NULL == hThread) + { + DWORD error = GetLastError(); + hr = HRESULT_FROM_WIN32(error); + Plugin_FreeString(data->url); + free(data); + } + else + { + CloseHandle(hThread); + hr = S_OK; + } + } + else + hr = E_OUTOFMEMORY; + + if (NULL != result) + { + VariantInit(result); + V_VT(result) = VT_BOOL; + V_BOOL(result) = (SUCCEEDED(hr) ? VARIANT_TRUE : VARIANT_FALSE); + } + + return hr; +} \ No newline at end of file -- cgit