diff options
author | George Hazan <george.hazan@gmail.com> | 2014-07-20 14:54:37 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2014-07-20 14:54:37 +0000 |
commit | 91d312baa652df4977bf1195053e28480970e20f (patch) | |
tree | a5d55eda73ccba6dd68f3a8711b4764fe6eb5ac6 | |
parent | 5163941eb4fcc1e90dcbda60e0a2496b55d36303 (diff) |
support for the FavContacts's gadget
git-svn-id: http://svn.miranda-ng.org/main/trunk@9891 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r-- | plugins/FavContacts/favcontacts_10.vcxproj | 6 | ||||
-rw-r--r-- | plugins/FavContacts/favcontacts_10.vcxproj.filters | 18 | ||||
-rw-r--r-- | plugins/FavContacts/favcontacts_12.vcxproj | 6 | ||||
-rw-r--r-- | plugins/FavContacts/favcontacts_12.vcxproj.filters | 18 | ||||
-rw-r--r-- | plugins/FavContacts/src/Version.h | 2 | ||||
-rw-r--r-- | plugins/FavContacts/src/cserver.cpp | 68 | ||||
-rw-r--r-- | plugins/FavContacts/src/cserver.h | 42 | ||||
-rw-r--r-- | plugins/FavContacts/src/csocket.cpp | 21 | ||||
-rw-r--r-- | plugins/FavContacts/src/csocket.h | 16 | ||||
-rw-r--r-- | plugins/FavContacts/src/http_api.cpp | 165 | ||||
-rw-r--r-- | plugins/FavContacts/src/http_api.h | 7 | ||||
-rw-r--r-- | plugins/FavContacts/src/main.cpp | 5 |
12 files changed, 373 insertions, 1 deletions
diff --git a/plugins/FavContacts/favcontacts_10.vcxproj b/plugins/FavContacts/favcontacts_10.vcxproj index a43efec15f..1e9a259df4 100644 --- a/plugins/FavContacts/favcontacts_10.vcxproj +++ b/plugins/FavContacts/favcontacts_10.vcxproj @@ -179,6 +179,9 @@ </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\contact_cache.cpp" />
+ <ClCompile Include="src\cserver.cpp" />
+ <ClCompile Include="src\csocket.cpp" />
+ <ClCompile Include="src\http_api.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\menu.cpp" />
<ClCompile Include="src\options.cpp" />
@@ -189,8 +192,11 @@ </ItemGroup>
<ItemGroup>
<ClInclude Include="src\contact_cache.h" />
+ <ClInclude Include="src\cserver.h" />
+ <ClInclude Include="src\csocket.h" />
<ClInclude Include="src\favlist.h" />
<ClInclude Include="src\headers.h" />
+ <ClInclude Include="src\http_api.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\Version.h" />
</ItemGroup>
diff --git a/plugins/FavContacts/favcontacts_10.vcxproj.filters b/plugins/FavContacts/favcontacts_10.vcxproj.filters index 87c0bb1dc3..60d8eb3689 100644 --- a/plugins/FavContacts/favcontacts_10.vcxproj.filters +++ b/plugins/FavContacts/favcontacts_10.vcxproj.filters @@ -33,6 +33,15 @@ <ClCompile Include="src\services.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\cserver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\csocket.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\http_api.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\contact_cache.h">
@@ -50,6 +59,15 @@ <ClInclude Include="src\resource.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\cserver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\csocket.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\http_api.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\resource.rc">
diff --git a/plugins/FavContacts/favcontacts_12.vcxproj b/plugins/FavContacts/favcontacts_12.vcxproj index 7c12a92107..5e362e62f9 100644 --- a/plugins/FavContacts/favcontacts_12.vcxproj +++ b/plugins/FavContacts/favcontacts_12.vcxproj @@ -182,6 +182,9 @@ </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\contact_cache.cpp" />
+ <ClCompile Include="src\cserver.cpp" />
+ <ClCompile Include="src\csocket.cpp" />
+ <ClCompile Include="src\http_api.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\menu.cpp" />
<ClCompile Include="src\options.cpp" />
@@ -192,8 +195,11 @@ </ItemGroup>
<ItemGroup>
<ClInclude Include="src\contact_cache.h" />
+ <ClInclude Include="src\cserver.h" />
+ <ClInclude Include="src\csocket.h" />
<ClInclude Include="src\favlist.h" />
<ClInclude Include="src\headers.h" />
+ <ClInclude Include="src\http_api.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\Version.h" />
</ItemGroup>
diff --git a/plugins/FavContacts/favcontacts_12.vcxproj.filters b/plugins/FavContacts/favcontacts_12.vcxproj.filters index e82f9659cd..c6327a32f9 100644 --- a/plugins/FavContacts/favcontacts_12.vcxproj.filters +++ b/plugins/FavContacts/favcontacts_12.vcxproj.filters @@ -33,6 +33,15 @@ <ClCompile Include="src\menu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\cserver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\csocket.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\http_api.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\contact_cache.h">
@@ -50,6 +59,15 @@ <ClInclude Include="src\resource.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\cserver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\csocket.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\http_api.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\resource.rc">
diff --git a/plugins/FavContacts/src/Version.h b/plugins/FavContacts/src/Version.h index 4b36aad0ac..3c3e44aeb3 100644 --- a/plugins/FavContacts/src/Version.h +++ b/plugins/FavContacts/src/Version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0
#define __MINOR_VERSION 1
#define __RELEASE_NUM 0
-#define __BUILD_NUM 2
+#define __BUILD_NUM 3
#include <stdver.h>
diff --git a/plugins/FavContacts/src/cserver.cpp b/plugins/FavContacts/src/cserver.cpp new file mode 100644 index 0000000000..d3a7ff5a0a --- /dev/null +++ b/plugins/FavContacts/src/cserver.cpp @@ -0,0 +1,68 @@ +#include "headers.h"
+
+#include "csocket.h"
+#include "cserver.h"
+
+void CServer::Start(int port, IConnectionProcessorFactory *connectionProcessorFactory, bool background)
+{
+ m_socket = socket(AF_INET, SOCK_STREAM, 0);
+ if (m_socket == INVALID_SOCKET) return;
+
+ sockaddr_in addr = { 0 };
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ addr.sin_port = htons((WORD)port);
+ if (bind(m_socket, (sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
+ closesocket(m_socket);
+ m_socket = INVALID_SOCKET;
+ return;
+ }
+
+ listen(m_socket, SOMAXCONN);
+
+ m_connectionProcessorFactory = connectionProcessorFactory;
+
+ if (background)
+ mir_forkthread(GlobalConnectionAcceptThread, this);
+ else
+ ConnectionAcceptThread();
+}
+
+void CServer::Stop()
+{
+ shutdown(m_socket, SD_BOTH);
+ closesocket(m_socket);
+}
+
+DWORD CServer::ConnectionAcceptThread()
+{
+ while (1) {
+ SOCKET s = accept(m_socket, NULL, NULL);
+ if (s == INVALID_SOCKET) break;
+
+ mir_forkthread(GlobalConnectionProcessThread, new GlobalConnectionProcessThreadArgs(this, s));
+ }
+ return 0;
+}
+
+DWORD CServer::ConnectionProcessThread(SOCKET s)
+{
+ CSocket sock(s);
+ IConnectionProcessor *processor = m_connectionProcessorFactory->Create(&sock);
+ processor->ProcessConnection();
+ delete processor;
+ return 0;
+}
+
+void CServer::GlobalConnectionAcceptThread(void *arg)
+{
+ CServer *server = (CServer *)arg;
+ server->ConnectionAcceptThread();
+}
+
+void CServer::GlobalConnectionProcessThread(void *arg)
+{
+ GlobalConnectionProcessThreadArgs *args = (GlobalConnectionProcessThreadArgs *)arg;
+ args->m_server->ConnectionProcessThread(args->m_socket);
+ delete args;
+}
diff --git a/plugins/FavContacts/src/cserver.h b/plugins/FavContacts/src/cserver.h new file mode 100644 index 0000000000..f96c87b2c1 --- /dev/null +++ b/plugins/FavContacts/src/cserver.h @@ -0,0 +1,42 @@ +#ifndef cserver_h__
+#define cserver_h__
+
+class IConnectionProcessor
+{
+public:
+ virtual ~IConnectionProcessor() {}
+ virtual void ProcessConnection() = 0;
+};
+
+class IConnectionProcessorFactory
+{
+public:
+ virtual IConnectionProcessor *Create(CSocket *s) = 0;
+};
+
+class CServer
+{
+private:
+ SOCKET m_socket;
+ IConnectionProcessorFactory *m_connectionProcessorFactory;
+
+ DWORD ConnectionAcceptThread();
+ DWORD ConnectionProcessThread(SOCKET s);
+
+ static void GlobalConnectionAcceptThread(void *arg);
+
+ struct GlobalConnectionProcessThreadArgs
+ {
+ CServer *m_server;
+ SOCKET m_socket;
+
+ GlobalConnectionProcessThreadArgs(CServer *server, SOCKET s): m_server(server), m_socket(s) {}
+ };
+ static void GlobalConnectionProcessThread(void *arg);
+
+public:
+ void Start(int port, IConnectionProcessorFactory *connectionProcessorFactory, bool background);
+ void Stop();
+};
+
+#endif // cserver_h__
diff --git a/plugins/FavContacts/src/csocket.cpp b/plugins/FavContacts/src/csocket.cpp new file mode 100644 index 0000000000..8b31467c61 --- /dev/null +++ b/plugins/FavContacts/src/csocket.cpp @@ -0,0 +1,21 @@ +#include "headers.h"
+
+#include "csocket.h"
+
+int CSocket::Recv(char *buf, int count)
+{
+ return recv(m_socket, buf, count, 0);
+}
+
+int CSocket::Send(char *buf, int count)
+{
+ if (count < 0)
+ count = (int)strlen(buf);
+ return send(m_socket, buf, count, 0);
+}
+
+void CSocket::Close()
+{
+ shutdown(m_socket, SD_BOTH);
+ closesocket(m_socket);
+}
diff --git a/plugins/FavContacts/src/csocket.h b/plugins/FavContacts/src/csocket.h new file mode 100644 index 0000000000..3fa1c87852 --- /dev/null +++ b/plugins/FavContacts/src/csocket.h @@ -0,0 +1,16 @@ +#ifndef csocket_h__
+#define csocket_h__
+
+class CSocket
+{
+protected:
+ SOCKET m_socket;
+
+public:
+ CSocket(SOCKET socket = INVALID_SOCKET): m_socket(socket) {}
+ int Recv(char *buf, int count);
+ int Send(char *buf, int count = -1);
+ void Close();
+};
+
+#endif // csocket_h__
diff --git a/plugins/FavContacts/src/http_api.cpp b/plugins/FavContacts/src/http_api.cpp new file mode 100644 index 0000000000..bacc6b05b0 --- /dev/null +++ b/plugins/FavContacts/src/http_api.cpp @@ -0,0 +1,165 @@ +#include "headers.h"
+
+#include "csocket.h"
+#include "cserver.h"
+#include "http_api.h"
+
+#define MS_FAVCONTACTS_OPEN_CONTACT "FavContacts/OpenContact"
+
+class CHttpProcessor: public IConnectionProcessor
+{
+private:
+ CSocket *m_socket;
+
+ char *FetchURL(char *s)
+ {
+ char *p;
+ if (p = strstr(s, "\r\n")) *p = 0;
+ if (p = strrchr(s, ' ')) *p = 0;
+ if (p = strchr(s, ' ')) while (*p && *p == ' ') p++;
+ return mir_strdup(p);
+ }
+
+public:
+ CHttpProcessor(CSocket *s): m_socket(s) {}
+
+ void ProcessConnection()
+ {
+ char buf[1024];
+ int n = m_socket->Recv(buf, sizeof(buf));
+ buf[n] = 0;
+
+ char *s = FetchURL(buf);
+
+ if (!strncmp(s, "/fav/list/", 10))
+ {
+ SendList();
+ } else
+ if (!strncmp(s, "/fav/open/", 10))
+ {
+ OpenContact(s);
+ }
+
+ mir_free(s);
+ m_socket->Close();
+ }
+
+ void OpenContact(char *s)
+ {
+ m_socket->Send("HTTP 200 OK\r\n\r\n");
+
+ int hContact;
+ sscanf(s, "/fav/open/%d", &hContact);
+ if (CallService(MS_DB_CONTACT_IS, hContact, 0))
+ CallServiceSync(MS_FAVCONTACTS_OPEN_CONTACT, hContact, 0);
+ }
+
+ void SendList()
+ {
+ TFavContacts favList;
+ favList.build();
+
+ m_socket->Send(
+ "HTTP 200 OK\r\n"
+ "Content-Type: text/javascript\r\n"
+ "\r\n");
+
+ Send("try {\r\n");
+ Send("SetContactCount(");
+ Send(favList.getCount());
+ Send(");\r\n");
+
+ for (int i = 0; i < favList.getCount(); ++i)
+ {
+ MCONTACT hContact = favList[i]->getHandle();
+ TCHAR *name = (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, hContact, GCDNF_TCHAR);
+ AVATARCACHEENTRY *avatar = (AVATARCACHEENTRY *)CallService(MS_AV_GETAVATARBITMAP, hContact, 0);
+ int status = db_get_w(hContact, GetContactProto(hContact), "Status", ID_STATUS_OFFLINE);
+
+ Send("SetContact(");
+ Send(i);
+ Send(", ");
+ Send((int)hContact);
+ Send(", '");
+ SendQuoted(name);
+ Send("', ");
+ Send(status);
+ Send(", '");
+ SendQuoted(avatar ? avatar->szFilename : _T(""));
+ Send("');\r\n");
+ }
+ Send("} catch(e) {}\r\n");
+ }
+
+ void Send(char *s)
+ {
+ m_socket->Send(s);
+ }
+
+
+ void Send(WCHAR *ws)
+ {
+ char *s = mir_utf8encodeW(ws);
+ m_socket->Send(s);
+ mir_free(s);
+ }
+
+
+ void Send(int i)
+ {
+ char buf[32];
+ mir_snprintf(buf, SIZEOF(buf), "%d", i);
+ Send(buf);
+ }
+
+ template<class XCHAR>
+ void SendQuoted(const XCHAR *s)
+ {
+ int length = 0;
+ const XCHAR *p;
+ for (p = s; *p; p++)
+ {
+ if (*p == '\'' || *p == '\\' || *p == '\"')
+ length++;
+ length++;
+ }
+ XCHAR *buf = (XCHAR *)mir_alloc(sizeof(XCHAR) * (length + 1));
+ XCHAR *q = buf;
+ for (p = s; *p; p++)
+ {
+ if (*p == '\'' || *p == '\\' || *p == '\"')
+ {
+ *q = '\\';
+ q++;
+ }
+ *q = *p;
+ q++;
+ }
+ *q = 0;
+ Send(buf);
+ mir_free(buf);
+ }
+};
+
+class CHttpProcessorFactory: public IConnectionProcessorFactory
+{
+public:
+ IConnectionProcessor *Create(CSocket *s)
+ {
+ return new CHttpProcessor(s);
+ }
+};
+
+static CHttpProcessorFactory g_httpProcessorFactory;
+static CServer g_httpServer;
+
+void LoadHttpApi()
+{
+ g_httpServer.Start(60888, &g_httpProcessorFactory, true);
+}
+
+int UnloadHttpApi()
+{
+ g_httpServer.Stop();
+ return 0;
+}
diff --git a/plugins/FavContacts/src/http_api.h b/plugins/FavContacts/src/http_api.h new file mode 100644 index 0000000000..599ba4c4d4 --- /dev/null +++ b/plugins/FavContacts/src/http_api.h @@ -0,0 +1,7 @@ +#ifndef http_api_h__
+#define http_api_h__
+
+void LoadHttpApi();
+int UnloadHttpApi();
+
+#endif // http_api_h__
diff --git a/plugins/FavContacts/src/main.cpp b/plugins/FavContacts/src/main.cpp index e9847b6821..6051d2ad7c 100644 --- a/plugins/FavContacts/src/main.cpp +++ b/plugins/FavContacts/src/main.cpp @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "headers.h"
+#include "http_api.h"
+
CLIST_INTERFACE *pcli;
HINSTANCE g_hInst;
@@ -77,6 +79,8 @@ extern "C" __declspec(dllexport) int Load(void) /////////////////////////////////////////////////////////////////////////////////////
Icon_Register(g_hInst, LPGEN("Favorites"), iconList, SIZEOF(iconList));
+
+ LoadHttpApi();
return 0;
}
@@ -84,6 +88,7 @@ extern "C" __declspec(dllexport) int Unload(void) {
UninitServices();
UninitMenu();
+ UnloadHttpApi();
if (g_Options.hfntName) DeleteObject(g_Options.hfntName);
if (g_Options.hfntSecond) DeleteObject(g_Options.hfntSecond);
|