diff options
author | watcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2012-01-19 12:21:27 +0000 |
---|---|---|
committer | watcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2012-01-19 12:21:27 +0000 |
commit | e94c705bb01c662d934c0096480bc9a732d0e1ec (patch) | |
tree | a07c6aa2174cf87d62ecfccdde8dbfa56185d78f /FacebookRM/json.cpp | |
parent | 9b2d93c613db59b7d47327899a0850d370d6ea5e (diff) |
FacebookRM: Version bump
Version 0.0.7.0
+ Support for group chats (EXPERIMENTAL!) - enable it in options
! Fixed loading contact list
! Fixed potential freeze.
Total downloads: (None or statistics not available yet)
Version 0.0.6.1a
Reuploaded.
Total downloads: (None or statistics not available yet)
Version 0.0.6.1
+ Returned option to close chat windows (on website)
+ New option to map non-standard statuses to Invisible (insetad of Online)
+ New option to load contacts, which have "On the Phone" status
! Fixed changing chat visibility
! Very long messages are no longer received duplicitely
! Changes and fixes related to multiuser messages and messages from people, which are not in server-list
Total downloads: (None or statistics not available yet)
git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@261 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb
Diffstat (limited to 'FacebookRM/json.cpp')
-rw-r--r-- | FacebookRM/json.cpp | 248 |
1 files changed, 206 insertions, 42 deletions
diff --git a/FacebookRM/json.cpp b/FacebookRM/json.cpp index 1c57f00..bd69c75 100644 --- a/FacebookRM/json.cpp +++ b/FacebookRM/json.cpp @@ -62,8 +62,32 @@ int facebook_json_parser::parse_buddy_list( void* data, List::List< facebook_use i->data->status_id = ID_STATUS_OFFLINE;
}
- const Object& nowAvailableList = objRoot["payload"]["buddy_list"]["nowAvailableList"];
+ // Find mobile friends
+ if (DBGetContactSettingByte(NULL,proto->m_szModuleName,FACEBOOK_KEY_LOAD_MOBILE, DEFAULT_LOAD_MOBILE)) {
+ const Array& mobileFriends = objRoot["payload"]["buddy_list"]["mobile_friends"];
+
+ for ( Array::const_iterator buddy( mobileFriends.Begin() ); buddy != mobileFriends.End(); ++buddy) {
+ const Number& member = *buddy;
+ char was_id[32];
+ lltoa( member.Value(), was_id, 10 );
+
+ std::string id = was_id;
+ if (!id.empty()) {
+ current = buddy_list->find( id );
+
+ if ( current == NULL) {
+ buddy_list->insert( std::make_pair( id, new facebook_user( ) ) );
+ current = buddy_list->find( id );
+ current->user_id = id;
+ }
+
+ current->status_id = ID_STATUS_ONTHEPHONE;
+ }
+ }
+ }
+ const Object& nowAvailableList = objRoot["payload"]["buddy_list"]["nowAvailableList"];
+ // Find now awailable contacts
for (Object::const_iterator itAvailable(nowAvailableList.Begin());
itAvailable != nowAvailableList.End(); ++itAvailable)
{
@@ -78,13 +102,13 @@ int facebook_json_parser::parse_buddy_list( void* data, List::List< facebook_use buddy_list->insert( std::make_pair( member.name, new facebook_user( ) ) );
current = buddy_list->find( member.name );
current->user_id = current->real_name = member.name;
- }
+ }
current->status_id = (idle ? ID_STATUS_OFFLINE : ID_STATUS_ONLINE);
}
const Object& userInfosList = objRoot["payload"]["buddy_list"]["userInfos"];
-
+ // Get aditional informations about contacts (if available)
for (Object::const_iterator itUserInfo(userInfosList.Begin());
itUserInfo != userInfosList.End(); ++itUserInfo)
{
@@ -121,6 +145,83 @@ int facebook_json_parser::parse_buddy_list( void* data, List::List< facebook_use return EXIT_SUCCESS;
}
+int facebook_json_parser::parse_facepiles( void* data, std::map< std::string, std::string > *facepiles )
+{
+ using namespace json;
+
+ try
+ {
+ std::string buddyData = static_cast< std::string* >( data )->substr( 9 );
+ std::istringstream sDocument( buddyData );
+ Object objDocument;
+ Reader::Read(objDocument, sDocument);
+ std::map< std::string, std::string >::iterator it;
+
+ const Object& objRoot = objDocument;
+/* const Array& infos = objRoot["payload"]["facepile_click_info"];
+
+ for ( Array::const_iterator info( infos.Begin() );
+ info != infos.End(); ++info)
+ {
+ const Object& objMember = *info;
+
+ if (objMember.Find("uid") != objMember.End()) {
+ const Number& id = objMember["uid"];
+ char was_id[32];
+ lltoa( id.Value(), was_id, 10 );
+
+ const String& name = objMember["name"];
+ std::string user_name = utils::text::slashu_to_utf8(
+ utils::text::special_expressions_decode( name.Value() ) );
+
+ it = facepiles->find( std::string( was_id ) );
+ if ( it == facepiles->end() ) {
+ facepiles->insert( std::make_pair( was_id, user_name ) );
+ }
+ }
+ } */
+
+ // Contacts in chat are getting by parsing html response. Don't know if it will work also for many people in chat room.
+ const String& response_html = objRoot["payload"]["response_html"];
+ std::string contacts = utils::text::slashu_to_utf8( utils::text::special_expressions_decode( response_html.Value( ) ) );
+
+ std::string::size_type pos = 0;
+ while ((pos = contacts.find("<li", pos)) != std::string::npos) {
+ std::string row = contacts.substr(pos, contacts.find("</li>") - pos);
+
+ std::string status = utils::text::source_get_value2( &row, "chat", "\" " ); // "Online" or "Idle"
+ std::string name = utils::text::source_get_value( &row, 2, "title=\"", "\"" );
+ std::string id = utils::text::source_get_value( &row, 3, "href=\"", "/profile.php?id=", "\"" );
+ if (id.empty())
+ id = utils::text::source_get_value( &row, 3, "href=\"", "facebook.com/", "\"" );
+
+ it = facepiles->find( id );
+ if ( it == facepiles->end() ) {
+ facepiles->insert( std::make_pair( id, name ) );
+ }
+
+ pos++;
+ }
+
+ }
+ catch (Reader::ParseException& e)
+ {
+ proto->Log( "!!!!! Caught json::ParseException: %s", e.what() );
+ proto->Log( " Line/offset: %d/%d", e.m_locTokenBegin.m_nLine + 1, e.m_locTokenBegin.m_nLineOffset + 1 );
+ }
+ catch (const Exception& e)
+ {
+ proto->Log( "!!!!! Caught json::Exception: %s", e.what() );
+ }
+ catch (const std::exception& e)
+ {
+ proto->Log( "!!!!! Caught std::exception: %s", e.what() );
+ }
+
+ return EXIT_SUCCESS;
+}
+
+
int facebook_json_parser::parse_friends( void* data, std::map< std::string, facebook_user* >* friends )
{
using namespace json;
@@ -256,7 +357,7 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess const String& type = objMember["type"];
- if ( type.Value( ) == "msg" ) // chat message
+ if ( type.Value( ) == "msg" || type.Value() == "offline_msg" ) // direct message
{
const Number& from = objMember["from"];
char was_id[32];
@@ -264,20 +365,22 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess const Object& messageContent = objMember["msg"];
const String& text = messageContent["text"];
+ //"tab_type":"friend", objMember["tab_type"]
//const Number& time_sent = messageContent["time"];
-
// proto->Log("????? Checking time %15.2f > %15.2f", time_sent.Value(), proto->facy.last_message_time_);
- if (last_msg != text.Value())
-/* if (time_sent.Value() > proto->facy.last_message_time_
- || (time_sent.Value() < 0 && proto->facy.last_message_time_ >= 0)) // Check agains duplicit messages*/
- {
+ if ((messageContent.Find("truncated") != messageContent.End())
+ && (((const Number &)messageContent["truncated"]).Value() == 1)) {
+ // If we got truncated message, we can ignore it, because we should get it again as "messaging" type
+ std::string msg = "????? We got truncated message so we ignore it\n";
+ msg += utils::text::special_expressions_decode(utils::text::slashu_to_utf8(text.Value()));
+ proto->Log(msg.c_str());
+ } else if (last_msg != text.Value()) {
last_msg = text.Value();
- //proto->facy.last_message_time_ = time_sent.Value();
facebook_message* message = new facebook_message( );
- message->message_text= utils::text::special_expressions_decode(
+ message->message_text = utils::text::special_expressions_decode(
utils::text::slashu_to_utf8( text.Value( ) ) );
message->time = ::time( NULL );
message->user_id = was_id;
@@ -289,7 +392,7 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess proto->Log(msg.c_str());
}
}
- else if ( type.Value( ) == "messaging" ) // inbox message
+ else if ( type.Value( ) == "messaging" ) // inbox message (multiuser or direct)
{
const String& type = objMember["event"];
@@ -299,32 +402,69 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess const Number& from = messageContent["sender_fbid"];
char was_id[32];
lltoa( from.Value(), was_id, 10 );
+
+
+ // Ignore if message is from self user
+ if (was_id == proto->facy.self_.user_id)
+ continue;
+
const String& text = messageContent["body"];
+ //std::string tid = ((const String&)messageContent["tid"]).Value();
+
+ const String& sender_name = messageContent["sender_name"];
- // TODO RM: include sender name
- // const String& name = messageContent["sender_name"];
+ std::string row = ((const String &)objMember["thread_row"]).Value();
//const Number& time_sent = messageContent["timestamp"];
//proto->Log("????? Checking time %15.2f > %15.2f", time_sent.Value(), proto->facy.last_message_time_);
- if (last_msg != text.Value())
-/* if (time_sent.Value() > proto->facy.last_message_time_
- || (time_sent.Value() < 0 && proto->facy.last_message_time_ >= 0)) // Check agains duplicit messages*/
- {
+ if (last_msg != text.Value()) {
last_msg = text.Value();
- //proto->facy.last_message_time_ = time_sent.Value();
facebook_message* message = new facebook_message( );
- message->message_text= utils::text::special_expressions_decode(
+ message->message_text = utils::text::special_expressions_decode(
utils::text::slashu_to_utf8( text.Value( ) ) );
- message->time = ::time( NULL );
+ message->sender_name = utils::text::special_expressions_decode(
+ utils::text::slashu_to_utf8( sender_name.Value( ) ) );
+
+ message->time = ::time( NULL );
+ message->user_id = was_id; // TODO: Check if we have contact with this ID in friendlist and then do something different?
- message->user_id = was_id;
+ if (row.find("uiSplitPic",0) != std::string::npos) {
+ // This is multiuser message
+
+ std::string authors = utils::text::special_expressions_decode(
+ utils::text::slashu_to_utf8( row ) );
+ authors = utils::text::source_get_value(&authors, 2, "<strong class=\"authors\">", "<");
- messages->push_back( message );
+ const String& to_id = messageContent["tid"];
+
+ std::string popup_text = message->sender_name;
+ popup_text += ": ";
+ popup_text += message->message_text;
+
+ std::string title = Translate("Multichat");
+ title += ": ";
+ title += authors;
+
+ std::string url = "/?action=read&sk=inbox&page&query&tid=";
+ url += to_id.Value();
+
+ proto->Log(" Got multichat message");
+
+ TCHAR* szTitle = mir_a2t_cp(title.c_str(), CP_UTF8);
+ TCHAR* szText = mir_a2t_cp(popup_text.c_str(), CP_UTF8);
+ TCHAR* szUrl = mir_a2t_cp(url.c_str(), CP_UTF8);
+ proto->NotifyEvent(szTitle,szText,NULL,FACEBOOK_EVENT_OTHER, szUrl);
+ mir_free(szTitle);
+ mir_free(szText);
+
+ } else {
+ messages->push_back( message );
+ }
} else {
std::string msg = "????? Got duplicit inbox message?\n";
msg += utils::text::special_expressions_decode(utils::text::slashu_to_utf8(text.Value()));
@@ -334,13 +474,10 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess }
else if ( type.Value( ) == "group_msg" ) // chat message
{
- if ( (::time(NULL) - proto->facy.last_grpmessage_time_) < 15 ) // TODO RM: remove dont notify more than once every 15 secs
+ if (!DBGetContactSettingByte(NULL,proto->m_szModuleName,FACEBOOK_KEY_ENABLE_GROUPCHATS, DEFAULT_ENABLE_GROUPCHATS))
continue;
-
- proto->facy.last_grpmessage_time_ = ::time(NULL);
-
+
const String& from_name = objMember["from_name"];
- const String& group_name = objMember["to_name"];
const Number& to = objMember["to"];
char group_id[32];
@@ -350,6 +487,32 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess char was_id[32];
lltoa( from.Value(), was_id, 10 );
+ const Object& messageContent = objMember["msg"];
+ const String& text = messageContent["text"];
+
+ std::string msg = utils::text::special_expressions_decode(
+ utils::text::slashu_to_utf8( text.Value( ) ) );
+
+ std::string name = utils::text::special_expressions_decode(
+ utils::text::slashu_to_utf8( from_name.Value( ) ) );
+
+ // Add contact into chat, if isn't there already
+ if (!proto->IsChatContact(group_id, was_id))
+ proto->AddChatContact(group_id, was_id, name.c_str());
+
+ // Add message into chat
+ proto->UpdateChat(group_id, was_id, name.c_str(), msg.c_str());
+ }
+ else if ( type.Value( ) == "thread_msg" ) // multiuser message
+ {
+ const String& from_name = objMember["from_name"];
+ const String& to_name = objMember["to_name"]["__html"];
+ const String& to_id = objMember["to"];
+
+ const Number& from = objMember["from"];
+ char was_id[32];
+ lltoa( from.Value(), was_id, 10 );
+
// Ignore if message is from self user
if (was_id == proto->facy.self_.user_id)
continue;
@@ -357,24 +520,25 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess const Object& messageContent = objMember["msg"];
const String& text = messageContent["text"];
- std::string popup_text = utils::text::remove_html(
- utils::text::special_expressions_decode(
- utils::text::slashu_to_utf8( from_name.Value( ) ) ) );
+
+ last_msg = text.Value();
+
+
+ std::string popup_text = utils::text::special_expressions_decode(
+ utils::text::slashu_to_utf8( from_name.Value( ) ) );
popup_text += ": ";
- popup_text += utils::text::remove_html(
- utils::text::special_expressions_decode(
- utils::text::slashu_to_utf8( text.Value( ) ) ) );
+ popup_text += utils::text::special_expressions_decode(
+ utils::text::slashu_to_utf8( text.Value( ) ) );
- std::string title = Translate("Groupchat");
+ std::string title = Translate("Multichat");
title += ": ";
- title += utils::text::remove_html(
- utils::text::special_expressions_decode(
- utils::text::slashu_to_utf8( group_name.Value( ) ) ) );
-
- std::string url = "/home.php?sk=group_";
- url += group_id;
+ title += utils::text::special_expressions_decode(
+ utils::text::slashu_to_utf8( to_name.Value( ) ) );
+
+ std::string url = "/?action=read&sk=inbox&page&query&tid=";
+ url += to_id.Value();
- proto->Log(" Got groupchat message");
+ proto->Log(" Got multichat message");
TCHAR* szTitle = mir_a2t_cp(title.c_str(), CP_UTF8);
TCHAR* szText = mir_a2t_cp(popup_text.c_str(), CP_UTF8);
|