libyahoo2 avatars supprot
This commit is contained in:
parent
6b88ad945d
commit
d53b3a5433
4 changed files with 236 additions and 3 deletions
159
backends/libyahoo2/httpfetch.cpp
Normal file
159
backends/libyahoo2/httpfetch.cpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
|
||||
#include "httpfetch.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
DEFINE_LOGGER(logger, "HTTPFetch");
|
||||
|
||||
static int url_to_host_port_path(const char *url,
|
||||
char *host, int *port, char *path, int *ssl)
|
||||
{
|
||||
char *urlcopy = NULL;
|
||||
char *slash = NULL;
|
||||
char *colon = NULL;
|
||||
|
||||
/*
|
||||
* http://hostname
|
||||
* http://hostname/
|
||||
* http://hostname/path
|
||||
* http://hostname/path:foo
|
||||
* http://hostname:port
|
||||
* http://hostname:port/
|
||||
* http://hostname:port/path
|
||||
* http://hostname:port/path:foo
|
||||
* and https:// variants of the above
|
||||
*/
|
||||
|
||||
if (strstr(url, "http://") == url) {
|
||||
urlcopy = strdup(url + 7);
|
||||
} else if (strstr(url, "https://") == url) {
|
||||
urlcopy = strdup(url + 8);
|
||||
*ssl = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
slash = strchr(urlcopy, '/');
|
||||
colon = strchr(urlcopy, ':');
|
||||
|
||||
if (!colon || (slash && slash < colon)) {
|
||||
if (*ssl)
|
||||
*port = 443;
|
||||
else
|
||||
*port = 80;
|
||||
} else {
|
||||
*colon = 0;
|
||||
*port = atoi(colon + 1);
|
||||
}
|
||||
|
||||
if (!slash) {
|
||||
strcpy(path, "/");
|
||||
} else {
|
||||
strcpy(path, slash);
|
||||
*slash = 0;
|
||||
}
|
||||
|
||||
strcpy(host, urlcopy);
|
||||
|
||||
free(urlcopy);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
HTTPFetch::HTTPFetch(Swift::BoostIOServiceThread *ioService, Swift::ConnectionFactory *factory) : m_ioService(ioService), m_factory(factory) {
|
||||
m_afterHeader = false;
|
||||
}
|
||||
|
||||
HTTPFetch::~HTTPFetch() {
|
||||
}
|
||||
|
||||
void HTTPFetch::_connected(boost::shared_ptr<Swift::Connection> conn, const std::string url, bool error) {
|
||||
if (error) {
|
||||
_disconnected(conn);
|
||||
}
|
||||
else {
|
||||
char host[255];
|
||||
int port = 80;
|
||||
char path[255];
|
||||
int ssl = 0;
|
||||
if (!url_to_host_port_path(url.c_str(), host, &port, path, &ssl))
|
||||
return;
|
||||
|
||||
static char buff[2048];
|
||||
snprintf(buff, sizeof(buff),
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"User-Agent: Mozilla/4.5 [en] (1/1)\r\n"
|
||||
"Accept: */*\r\n"
|
||||
"%s" "\r\n", path, host,
|
||||
"Connection: close\r\n");
|
||||
LOG4CXX_INFO(logger, "Sending " << buff << "\n");
|
||||
conn->write(Swift::createSafeByteArray(buff));
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPFetch::_disconnected(boost::shared_ptr<Swift::Connection> conn) {
|
||||
conn->onConnectFinished.disconnect_all_slots();
|
||||
conn->onDisconnected.disconnect_all_slots();
|
||||
conn->onDataRead.disconnect_all_slots();
|
||||
|
||||
if (m_buffer.size() == 0) {
|
||||
onURLFetched("");
|
||||
}
|
||||
else {
|
||||
std::string img = m_buffer.substr(m_buffer.find("\r\n\r\n") + 4);
|
||||
onURLFetched(img);
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPFetch::_read(boost::shared_ptr<Swift::Connection> conn, boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
std::string d(data->begin(), data->end());
|
||||
// std::cout << d << "\n";
|
||||
std::string img = d.substr(d.find("\r\n\r\n") + 4);
|
||||
if (d.find("Location: ") == std::string::npos) {
|
||||
m_buffer += d;
|
||||
}
|
||||
else {
|
||||
d = d.substr(d.find("Location: ") + 10);
|
||||
if (d.find("\r") == std::string::npos) {
|
||||
d = d.substr(0, d.find("\n"));
|
||||
}
|
||||
else {
|
||||
d = d.substr(0, d.find("\r"));
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Next url is '" << d << "'");
|
||||
fetchURL(d);
|
||||
conn->onConnectFinished.disconnect_all_slots();
|
||||
conn->onDisconnected.disconnect_all_slots();
|
||||
conn->onDataRead.disconnect_all_slots();
|
||||
}
|
||||
}
|
||||
|
||||
bool HTTPFetch::fetchURL(const std::string &url) {
|
||||
char host[255];
|
||||
int port = 80;
|
||||
char path[255];
|
||||
char buff[1024];
|
||||
int ssl = 0;
|
||||
if (!url_to_host_port_path(url.c_str(), host, &port, path, &ssl)) {
|
||||
LOG4CXX_ERROR(logger, "Invalid URL " << url);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, "Connecting to " << host << ":" << port);
|
||||
|
||||
boost::asio::ip::tcp::resolver resolver(*m_ioService->getIOService());
|
||||
boost::asio::ip::tcp::resolver::query query(host, "");
|
||||
boost::asio::ip::address address;
|
||||
for(boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); i != boost::asio::ip::tcp::resolver::iterator(); ++i) {
|
||||
boost::asio::ip::tcp::endpoint end = *i;
|
||||
address = end.address();
|
||||
break;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Connection> conn = m_factory->createConnection();
|
||||
conn->onConnectFinished.connect(boost::bind(&HTTPFetch::_connected, this, conn, url, _1));
|
||||
conn->onDisconnected.connect(boost::bind(&HTTPFetch::_disconnected, this, conn));
|
||||
conn->onDataRead.connect(boost::bind(&HTTPFetch::_read, this, conn, _1));
|
||||
conn->connect(Swift::HostAddressPort(Swift::HostAddress(address), port));
|
||||
return true;
|
||||
}
|
43
backends/libyahoo2/httpfetch.h
Normal file
43
backends/libyahoo2/httpfetch.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
|
||||
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
class HTTPFetch {
|
||||
public:
|
||||
HTTPFetch(Swift::BoostIOServiceThread *ioSerice, Swift::ConnectionFactory *factory);
|
||||
virtual ~HTTPFetch();
|
||||
|
||||
bool fetchURL(const std::string &url);
|
||||
|
||||
boost::signal<void (const std::string &data)> onURLFetched;
|
||||
|
||||
private:
|
||||
void _connected(boost::shared_ptr<Swift::Connection> conn, const std::string url, bool error);
|
||||
void _disconnected(boost::shared_ptr<Swift::Connection> conn);
|
||||
void _read(boost::shared_ptr<Swift::Connection> conn, boost::shared_ptr<Swift::SafeByteArray> data);
|
||||
|
||||
Swift::BoostIOServiceThread *m_ioService;
|
||||
Swift::ConnectionFactory *m_factory;
|
||||
std::string m_buffer;
|
||||
bool m_afterHeader;
|
||||
};
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "yahoohandler.h"
|
||||
#include "yahoolocalaccount.h"
|
||||
#include "httpfetch.h"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
|
@ -155,6 +156,26 @@ class YahooPlugin : public NetworkPlugin {
|
|||
handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE);
|
||||
}
|
||||
|
||||
void _avatar_fetched(HTTPFetch *fetch, int account_id, unsigned int id, const std::string &img) {
|
||||
handleVCard(m_ids[account_id], id, "", "", "", img);
|
||||
delete fetch;
|
||||
}
|
||||
|
||||
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
|
||||
YahooLocalAccount *account = m_users[user];
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (account->urls.find(legacyName) == account->urls.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPFetch *fetch = new HTTPFetch(&m_boostIOServiceThread, m_factories->getConnectionFactory());
|
||||
fetch->onURLFetched.connect(boost::bind(&YahooPlugin::_avatar_fetched, this, fetch, account->id, id, _1));
|
||||
fetch->fetchURL(account->urls[legacyName]);
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
|
||||
}
|
||||
|
@ -356,6 +377,7 @@ static void ext_yahoo_status_changed(int id, const char *who, int stat, const ch
|
|||
}
|
||||
|
||||
yahoo_buddyicon_request(id, who);
|
||||
np->_yahoo_write_ready(account);
|
||||
|
||||
np->handleBuddyChanged(account->user, who, "", std::vector<std::string>(), status, msg ? msg : "");
|
||||
}
|
||||
|
@ -375,7 +397,7 @@ static void ext_yahoo_got_buddies(int id, YList * buds) {
|
|||
np->handleBuddyChanged(account->user, bud->id, bud->real_name ? bud->real_name : "", groups, pbnetwork::STATUS_NONE);
|
||||
}
|
||||
|
||||
yahoo_set_away(id, YAHOO_STATUS_AVAILABLE, "", 1);
|
||||
// yahoo_set_away(id, YAHOO_STATUS_AVAILABLE, "", 1);
|
||||
np->_yahoo_write_ready(account);
|
||||
np->handleConnected(account->user);
|
||||
}
|
||||
|
@ -602,19 +624,27 @@ static void ext_yahoo_got_search_result(int id, int found, int start, int total,
|
|||
}
|
||||
|
||||
static void ext_yahoo_got_buddyicon_checksum(int id, const char *a, const char *b, int checksum) {
|
||||
LOG4CXX_INFO(logger, "got buddyicon_checksum");
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddy_change_group(int id, const char *me, const char *who, const char *old_group, const char *new_group) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddyicon(int id, const char *a, const char *b, const char *c, int checksum) {
|
||||
LOG4CXX_INFO(logger, "got buddyicon " << c);
|
||||
static void ext_yahoo_got_buddyicon(int id, const char *me, const char *who, const char *url, int checksum) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, account->user << ": got buddyicon of " << who);
|
||||
account->urls[who] = url;
|
||||
}
|
||||
|
||||
static void ext_yahoo_buddyicon_uploaded(int id, const char *url) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who) {
|
||||
LOG4CXX_INFO(logger, "got buddyicon_request");
|
||||
}
|
||||
|
||||
static int ext_yahoo_log(const char *fmt,...)
|
||||
|
|
|
@ -48,6 +48,7 @@ class YahooLocalAccount {
|
|||
int conn_tag;
|
||||
std::map<int, YahooHandler *> handlers;
|
||||
std::map<int, std::map<int, YahooHandler *> > handlers_per_conn;
|
||||
std::map<std::string, std::string> urls;
|
||||
int handler_tag;
|
||||
int status;
|
||||
std::string msg;
|
||||
|
|
Loading…
Add table
Reference in a new issue