From 4ae19a4155e936aa1d243360581f9511eb061336 Mon Sep 17 00:00:00 2001 From: "ROBYER@gmail.com" Date: Sun, 20 Nov 2011 18:39:38 +0000 Subject: Added Facebook RM git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@191 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- FacebookRM/process.cpp | 542 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 542 insertions(+) create mode 100644 FacebookRM/process.cpp (limited to 'FacebookRM/process.cpp') diff --git a/FacebookRM/process.cpp b/FacebookRM/process.cpp new file mode 100644 index 0000000..e6c965c --- /dev/null +++ b/FacebookRM/process.cpp @@ -0,0 +1,542 @@ +/* + +Facebook plugin for Miranda Instant Messenger +_____________________________________________ + +Copyright � 2009-11 Michal Zelinka + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +File name : $HeadURL: http://eternityplugins.googlecode.com/svn/trunk/facebook/process.cpp $ +Revision : $Revision: 92 $ +Last change by : $Author: n3weRm0re.ewer $ +Last change on : $Date: 2011-01-20 21:38:59 +0100 (čt, 20 1 2011) $ + +*/ + +#include "common.h" + +void FacebookProto::ProcessBuddyList( void* data ) +{ + if ( data == NULL ) + return; + + ScopedLock s( facy.buddies_lock_ ); + + std::string* resp = (std::string*)data; + + if ( isOffline() ) + goto exit; + + LOG("***** Starting processing buddy list"); + + CODE_BLOCK_TRY + + facebook_json_parser* p = new facebook_json_parser( this ); + p->parse_buddy_list( data, &facy.buddies ); + delete p; + + for ( List::Item< facebook_user >* i = facy.buddies.begin( ); i != NULL; ) + { + LOG(" Now %s: %s", (i->data->status_id == ID_STATUS_OFFLINE ? "offline" : "online"), i->data->real_name.c_str()); + + facebook_user* fbu; + + if ( i->data->status_id == ID_STATUS_OFFLINE ) + { + fbu = i->data; + + if (fbu->handle) + DBWriteContactSettingWord(fbu->handle, m_szModuleName, "Status", ID_STATUS_OFFLINE); + + std::string to_delete( i->key ); + i = i->next; + facy.buddies.erase( to_delete ); + } else { + fbu = i->data; + i = i->next; + + if (!fbu->handle) { // just been added + fbu->handle = AddToContactList(fbu); + + DBWriteContactSettingUTF8String(fbu->handle,m_szModuleName,FACEBOOK_KEY_NAME,fbu->real_name.c_str()); + DBWriteContactSettingUTF8String(fbu->handle,m_szModuleName,"Nick",fbu->real_name.c_str()); + } + + if (DBGetContactSettingWord(fbu->handle,m_szModuleName,"Status", 0) != ID_STATUS_ONLINE) { + DBWriteContactSettingWord(fbu->handle,m_szModuleName,"Status", ID_STATUS_ONLINE ); + } + + + // Check avatar change + CheckAvatarChange(fbu->handle, fbu->image_url); + } + } + + LOG("***** Buddy list processed"); + + CODE_BLOCK_CATCH + + LOG("***** Error processing buddy list: %s", e.what()); + + CODE_BLOCK_END + +exit: + delete resp; +} + +void FacebookProto::ProcessFriendList( void* data ) +{ + if ( data == NULL ) + return; + + std::string* resp = (std::string*)data; + + LOG("***** Starting processing friend list"); + + CODE_BLOCK_TRY + + std::map friends; + + facebook_json_parser* p = new facebook_json_parser( this ); + p->parse_friends( data, &friends ); + delete p; + + + // Check and update old contacts + for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + hContact; + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0) ) + { + if(!IsMyContact(hContact)) + continue; + + DBVARIANT dbv; + facebook_user *fbu; + if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) { + std::string id = dbv.pszVal; + DBFreeVariant(&dbv); + + std::map< std::string, facebook_user* >::iterator iter; + + if ((iter = friends.find(id)) != friends.end()) { + // Found contact, update it and remove from map + fbu = iter->second; + + DBVARIANT dbv; + bool update_required = true; + + // TODO RM: remove, because contacts cant change it, so its only for "first run" + // Update gender + if ( DBGetContactSettingByte(hContact, m_szModuleName, "Gender", 0) != fbu->gender ) + DBWriteContactSettingByte(hContact, m_szModuleName, "Gender", fbu->gender ); + + // Update real name + if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) + { + update_required = strcmp( dbv.pszVal, fbu->real_name.c_str() ) != 0; + DBFreeVariant(&dbv); + } + if ( update_required ) + { + DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, fbu->real_name.c_str()); + DBWriteContactSettingUTF8String(hContact, m_szModuleName, "Nick", fbu->real_name.c_str()); + } + + // Wasn't contact removed from "server-list" someday? + if ( DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) ) { + DBDeleteContactSetting(hContact, m_szModuleName, FACEBOOK_KEY_DELETED); + + std::string url = FACEBOOK_URL_PROFILE + fbu->user_id; + + TCHAR* szTitle = mir_a2t_cp(fbu->real_name.c_str(), CP_UTF8); + TCHAR* szUrl = mir_a2t_cp(url.c_str(), CP_UTF8); + NotifyEvent(szTitle, TranslateT("Contact is back on server-list."), hContact, FACEBOOK_EVENT_CLIENT, szUrl); + mir_free( szTitle ); + // mir_free( szUrl ); // url is free'd in popup procedure + } + + // Check avatar change + CheckAvatarChange(hContact, fbu->image_url); + + delete fbu; + friends.erase(iter); + } else { + // Contact was removed from "server-list", notify it + + // Wasnt we already been notified about this contact? + if ( !DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) ) { + DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL)); + + std::string contactname = id; + if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) { + contactname = dbv.pszVal; + DBFreeVariant(&dbv); + } + + std::string url = FACEBOOK_URL_PROFILE + id; + + TCHAR* szTitle = mir_a2t_cp(contactname.c_str(), CP_UTF8); + TCHAR* szUrl = mir_a2t_cp(url.c_str(), CP_UTF8); + NotifyEvent(szTitle, TranslateT("Contact is no longer on server-list."), hContact, FACEBOOK_EVENT_CLIENT, szUrl); + mir_free( szTitle ); + // mir_free( szUrl ); // url is free'd in popup procedure + } + } + } + } + + // Check remain contacts in map and add it to contact list + for ( std::map< std::string, facebook_user* >::iterator iter = friends.begin(); iter != friends.end(); ++iter ) + { + facebook_user *fbu = iter->second; + + HANDLE hContact = AddToContactList(fbu, true); // This contact is surely new + + DBWriteContactSettingByte(hContact, m_szModuleName, "Gender", fbu->gender ); + DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, fbu->real_name.c_str()); + DBWriteContactSettingUTF8String(hContact, m_szModuleName, "Nick", fbu->real_name.c_str()); + DBWriteContactSettingString(hContact, m_szModuleName, FACEBOOK_KEY_AV_URL, fbu->image_url.c_str()); +// DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE ); + } + + LOG("***** Friend list processed"); + + CODE_BLOCK_CATCH + + LOG("***** Error processing friend list: %s", e.what()); + + CODE_BLOCK_END + + delete resp; +} + +void FacebookProto::ProcessUnreadMessages( void* ) +{ + facy.handle_entry( "messages" ); + + std::string data = "sk=inbox&query=is%3Aunread"; + + // Get unread inbox threads + http::response resp = facy.flap( FACEBOOK_REQUEST_ASYNC_GET, &data ); + + // Process result data + facy.validate_response(&resp); + + if (resp.code != HTTP_CODE_OK) { + facy.handle_error( "messages" ); + return; + } + + std::string threadlist = utils::text::slashu_to_utf8(resp.data); + + std::string::size_type pos = 0; + + while ( ( pos = threadlist.find( "
  • ", "<\\/div" ); + message_text = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::remove_html( message_text ) ) ); + + PROTORECVEVENT recv = {0}; + CCSDATA ccs = {0}; + + recv.flags = PREF_UTF; + recv.szMessage = const_cast(message_text.c_str()); + recv.timestamp = static_cast(::time(NULL)); + + ccs.hContact = hContact; + ccs.szProtoService = PSR_MESSAGE; + ccs.lParam = reinterpret_cast(&recv); + CallService(MS_PROTO_CHAINRECV,0,reinterpret_cast(&ccs)); + + pos2++; + } + + + } + +} + +void FacebookProto::ProcessMessages( void* data ) +{ + if ( data == NULL ) + return; + + std::string* resp = (std::string*)data; + + if ( isOffline() ) + goto exit; + + LOG("***** Starting processing messages"); + + CODE_BLOCK_TRY + + std::vector< facebook_message* > messages; + std::vector< facebook_notification* > notifications; + + facebook_json_parser* p = new facebook_json_parser( this ); + p->parse_messages( data, &messages, ¬ifications ); + delete p; + + for(std::vector::size_type i=0; iuser_id != facy.self_.user_id ) + { + LOG(" Got message: %s", messages[i]->message_text.c_str()); + facebook_user fbu; + fbu.user_id = messages[i]->user_id; + + HANDLE hContact = AddToContactList(&fbu); + + PROTORECVEVENT recv = {0}; + CCSDATA ccs = {0}; + + recv.flags = PREF_UTF; + recv.szMessage = const_cast(messages[i]->message_text.c_str()); + recv.timestamp = static_cast(messages[i]->time); + + ccs.hContact = hContact; + ccs.szProtoService = PSR_MESSAGE; + ccs.lParam = reinterpret_cast(&recv); + CallService(MS_PROTO_CHAINRECV,0,reinterpret_cast(&ccs)); + } + delete messages[i]; + } + messages.clear(); + + for(std::vector::size_type i=0; itext.c_str()); + TCHAR* szTitle = mir_a2t_cp(this->m_szModuleName, CP_UTF8); + TCHAR* szText = mir_a2t_cp(notifications[i]->text.c_str(), CP_UTF8); + TCHAR* szUrl = mir_a2t_cp(notifications[i]->link.c_str(), CP_UTF8); + NotifyEvent( szTitle, szText, ContactIDToHContact(notifications[i]->user_id), FACEBOOK_EVENT_NOTIFICATION, szUrl ); + mir_free( szTitle ); + mir_free( szText ); +// mir_free( szUrl ); // URL is free'd in popup procedure + + delete notifications[i]; + } + notifications.clear(); + + LOG("***** Messages processed"); + + CODE_BLOCK_CATCH + + LOG("***** Error processing messages: %s", e.what()); + + CODE_BLOCK_END + +exit: + delete resp; +} + +void FacebookProto::ProcessNotifications( void* ) +{ + if ( isOffline() ) + return; + + if (!getByte( FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE, DEFAULT_EVENT_NOTIFICATIONS_ENABLE )) + return; + + facy.handle_entry( "notifications" ); + + // Get notifications + http::response resp = facy.flap( FACEBOOK_REQUEST_NOTIFICATIONS ); + + // Process result data + facy.validate_response(&resp); + + if (resp.code != HTTP_CODE_OK) { + facy.handle_error( "notifications" ); + return; + } + + + // Process notifications + LOG("***** Starting processing notifications"); + + CODE_BLOCK_TRY + + std::vector< facebook_notification* > notifications; + + facebook_json_parser* p = new facebook_json_parser( this ); + p->parse_notifications( &(resp.data), ¬ifications ); + delete p; + + for(std::vector::size_type i=0; itext.c_str()); + TCHAR* szTitle = mir_a2t_cp(this->m_szModuleName, CP_UTF8); + TCHAR* szText = mir_a2t_cp(notifications[i]->text.c_str(), CP_UTF8); + TCHAR* szUrl = mir_a2t_cp(notifications[i]->link.c_str(), CP_UTF8); + NotifyEvent( szTitle, szText, ContactIDToHContact(notifications[i]->user_id), FACEBOOK_EVENT_NOTIFICATION, szUrl ); + mir_free( szTitle ); + mir_free( szText ); +// mir_free( szUrl ); // URL is free'd in popup procedure + + delete notifications[i]; + } + notifications.clear(); + + LOG("***** Notifications processed"); + + CODE_BLOCK_CATCH + + LOG("***** Error processing notifications: %s", e.what()); + + CODE_BLOCK_END +} + + +void FacebookProto::ProcessFeeds( void* data ) +{ + if ( data == NULL ) + return; + + std::string* resp = (std::string*)data; + + if (!isOnline()) + goto exit; + + CODE_BLOCK_TRY + + LOG("***** Starting processing feeds"); + + std::vector< facebook_newsfeed* > news; + + std::string::size_type pos = 0; + UINT limit = 0; + + *resp = utils::text::slashu_to_utf8(*resp); + + // TODO RM: first parse against
  • ...
  • ? + while ( ( pos = resp->find( "find( "find( "<\\/h6", pos ); + + std::string post_content = resp->substr( pos, pos2 - pos ); + std::string rest_content; + + if ( (pos2 = post_content.find( "class=\\\"uiStreamSource\\\"" ), pos) != std::string::npos ) + rest_content = post_content.substr( pos2, post_content.find( "", "<\\/a" ); + nf->user_id = utils::text::source_get_value( &post_content, 2, "user.php?id=", "\\\"" ); + + if ( (pos2 = post_content.find( "<\\/a>" )) != std::string::npos ) + nf->text = post_content.substr( pos2, post_content.length() - pos2 ); + nf->text = nf->text.substr(0, nf->text.find("link = utils::text::source_get_value( &rest_content, 2, "href=\\\"", "\\\">" ); + + nf->title = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::remove_html( nf->title ) ) ); + + nf->text = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::remove_html( + utils::text::edit_html( nf->text ) ) ) ); + + nf->link = utils::text::special_expressions_decode( nf->link ); + + if ( !nf->title.length() || !nf->text.length() ) + { + delete nf; + continue; + } + + if (nf->text.length() > 500) + { + nf->text = nf->text.substr(0, 500); + nf->text += "..."; + } + + news.push_back( nf ); + pos++; + limit++; + } + + for(std::vector::size_type i=0; ititle.c_str(), news[i]->text.c_str()); + TCHAR* szTitle = mir_a2t_cp(news[i]->title.c_str(), CP_UTF8); + TCHAR* szText = mir_a2t_cp(news[i]->text.c_str(), CP_UTF8); + TCHAR* szUrl = mir_a2t_cp(news[i]->link.c_str(), CP_UTF8); + NotifyEvent(szTitle,szText,this->ContactIDToHContact(news[i]->user_id),FACEBOOK_EVENT_NEWSFEED, szUrl); + mir_free(szTitle); + mir_free(szText); +// mir_free(szUrl); // URL is free'd in popup procedure + delete news[i]; + } + news.clear(); + + this->facy.last_feeds_update_ = ::time(NULL); + + LOG("***** Feeds processed"); + + CODE_BLOCK_CATCH + + LOG("***** Error processing feeds: %s", e.what()); + + CODE_BLOCK_END + +exit: + delete resp; +} -- cgit v1.2.3