cleaned up FBC snapshot feature and made it work with new direct upload route on FBC API

meow-7.2.2
Cho 2013-06-12 01:16:27 +01:00
parent e3f093a871
commit 933debfc10
8 changed files with 105 additions and 62 deletions

View File

@ -35,19 +35,23 @@
#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llurlaction.h"
#include "llimagepng.h"
// Local function
void prompt_user_for_error(U32 status, const std::string& reason)
void prompt_user_for_error(U32 status, const std::string& reason, const std::string& code, const std::string& description)
{
// Note: 302 (redirect) is *not* an error that warrants prompting the user
if (status != 302)
{
LLSD args(LLSD::emptyMap());
std::stringstream msg;
msg << reason << " (Code " << status << ")";
args["FAIL_REASON"] = msg.str();
LLNotificationsUtil::add("FacebookCannotConnect",args);
msg << status;
args["STATUS"] = msg.str();
args["REASON"] = reason;
args["CODE"] = code;
args["DESCRIPTION"] = description;
LLNotificationsUtil::add("FacebookCannotConnect", args);
}
}
@ -96,7 +100,7 @@ public:
}
else
{
prompt_user_for_error(status,reason);
prompt_user_for_error(status, reason, content.get("error_code"), content.get("error_description"));
LL_WARNS("FacebookConnect") << "Failed to get a response. reason: " << reason << " status: " << status << LL_ENDL;
}
}
@ -113,11 +117,14 @@ public:
///////////////////////////////////////////////////////////////////////////////
//
class LLFacebookPostResponder : public LLHTTPClient::Responder
class LLFacebookShareResponder : public LLHTTPClient::Responder
{
LOG_CLASS(LLFacebookPostResponder);
LOG_CLASS(LLFacebookShareResponder);
public:
LLFacebookShareResponder() {}
LLFacebookShareResponder(LLFacebookConnect::share_callback_t cb) : mShareCallback(cb) {}
virtual void completed(U32 status, const std::string& reason, const LLSD& content)
{
if (isGoodStatus(status))
@ -126,9 +133,14 @@ public:
}
else
{
prompt_user_for_error(status,reason);
prompt_user_for_error(status, reason, content.get("error_code"), content.get("error_description"));
LL_WARNS("FacebookConnect") << "Failed to get a post response. reason: " << reason << " status: " << status << LL_ENDL;
}
if (mShareCallback)
{
mShareCallback(isGoodStatus(status));
}
}
void completedHeader(U32 status, const std::string& reason, const LLSD& content)
@ -139,6 +151,8 @@ public:
}
}
private:
LLFacebookConnect::share_callback_t mShareCallback;
};
///////////////////////////////////////////////////////////////////////////////
@ -160,7 +174,7 @@ public:
}
else
{
prompt_user_for_error(status,reason);
prompt_user_for_error(status, reason, content.get("error_code"), content.get("error_description"));
LL_WARNS("FacebookConnect") << "Failed to get a response. reason: " << reason << " status: " << status << LL_ENDL;
}
}
@ -196,7 +210,7 @@ public:
}
else
{
prompt_user_for_error(status,reason);
prompt_user_for_error(status, reason, content.get("error_code"), content.get("error_description"));
}
}
}
@ -221,7 +235,7 @@ public:
}
else
{
prompt_user_for_error(status,reason);
prompt_user_for_error(status, reason, content.get("error_code"), content.get("error_description"));
LL_WARNS("FacebookConnect") << "Failed to get a response. reason: " << reason << " status: " << status << LL_ENDL;
}
}
@ -314,27 +328,7 @@ void LLFacebookConnect::postCheckin(const std::string& location, const std::stri
body["message"] = message;
// Note: we can use that route for different publish action. We should be able to use the same responder.
LLHTTPClient::post(getFacebookConnectURL("/share/checkin"), body, new LLFacebookPostResponder());
}
void LLFacebookConnect::postCheckinMessage(const std::string& message, const std::string& link, const std::string& name, const std::string& caption, const std::string& description, const std::string& picture)
{
LLSD body;
if (!message.empty())
body["message"] = message;
if (!link.empty())
body["link"] = link;
if (!name.empty())
body["name"] = name;
if (!caption.empty())
body["caption"] = caption;
if (!description.empty())
body["description"] = description;
if (!picture.empty())
body["picture"] = picture;
// Note: we can use that route for different publish action. We should be able to use the same responder.
LLHTTPClient::post(getFacebookConnectURL("/share/wall"), body, new LLFacebookPostResponder());
LLHTTPClient::post(getFacebookConnectURL("/share/checkin"), body, new LLFacebookShareResponder(mPostCheckinCallback));
}
void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
@ -344,7 +338,52 @@ void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::stri
body["caption"] = caption;
// Note: we can use that route for different publish action. We should be able to use the same responder.
LLHTTPClient::post(getFacebookConnectURL("/share/photo"), body, new LLFacebookPostResponder());
LLHTTPClient::post(getFacebookConnectURL("/share/photo"), body, new LLFacebookShareResponder());
}
void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
{
// All this code is mostly copied from LLWebProfile::post()
if (dynamic_cast<LLImagePNG*>(image.get()) == 0)
{
llwarns << "Image to upload is not a PNG" << llendl;
llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0);
return;
}
const std::string boundary = "----------------------------0123abcdefab";
LLSD headers;
headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
std::ostringstream body;
// *NOTE: The order seems to matter.
body << "--" << boundary << "\r\n"
<< "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
<< caption << "\r\n";
body << "--" << boundary << "\r\n"
<< "Content-Disposition: form-data; name=\"image\"; filename=\"snapshot.png\"\r\n"
<< "Content-Type: image/png\r\n\r\n";
// Insert the image data.
// *FIX: Treating this as a string will probably screw it up ...
U8* image_data = image->getData();
for (S32 i = 0; i < image->getDataSize(); ++i)
{
body << image_data[i];
}
body << "\r\n--" << boundary << "--\r\n";
// postRaw() takes ownership of the buffer and releases it later.
size_t size = body.str().size();
U8 *data = new U8[size];
memcpy(data, body.str().data(), size);
// Note: we can use that route for different publish action. We should be able to use the same responder.
LLHTTPClient::postRaw(getFacebookConnectURL("/share/photo"), data, size, new LLFacebookShareResponder(mSharePhotoCallback), headers);
}
void LLFacebookConnect::updateStatus(const std::string& message)
@ -353,7 +392,7 @@ void LLFacebookConnect::updateStatus(const std::string& message)
body["message"] = message;
// Note: we can use that route for different publish action. We should be able to use the same responder.
LLHTTPClient::post(getFacebookConnectURL("/share/wall"), body, new LLFacebookPostResponder());
LLHTTPClient::post(getFacebookConnectURL("/share/wall"), body, new LLFacebookShareResponder(mUpdateStatusCallback));
}
void LLFacebookConnect::storeContent(const LLSD& content)

View File

@ -29,6 +29,7 @@
#define LL_LLFACEBOOKCONNECT_H
#include "llsingleton.h"
#include "llimage.h"
/**
* @class LLFacebookConnect
@ -40,6 +41,8 @@ class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
{
LOG_CLASS(LLFacebookConnect);
public:
typedef boost::function<void(bool ok)> share_callback_t;
void connectToFacebook(const std::string& auth_code = "");
void disconnectFromFacebook();
void tryToReconnectToFacebook();
@ -47,9 +50,13 @@ public:
void loadFacebookFriends();
void postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& picture, const std::string& message);
void postCheckinMessage(const std::string& message, const std::string& link, const std::string& name, const std::string& caption, const std::string& description, const std::string& picture);
void sharePhoto(const std::string& image_url, const std::string& caption);
void sharePhoto(const std::string& image_url, const std::string& caption);
void sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption);
void updateStatus(const std::string& message);
void setPostCheckinCallback(share_callback_t cb) { mPostCheckinCallback = cb; }
void setSharePhotoCallback(share_callback_t cb) { mSharePhotoCallback = cb; }
void setUpdateStatusCallback(share_callback_t cb) { mUpdateStatusCallback = cb; }
void clearContent();
void storeContent(const LLSD& content);
@ -60,6 +67,7 @@ public:
S32 generation() { return mGeneration; }
void openFacebookWeb(std::string url);
private:
friend class LLSingleton<LLFacebookConnect>;
@ -71,6 +79,10 @@ private:
bool mConnectedToFbc;
LLSD mContent;
S32 mGeneration;
share_callback_t mPostCheckinCallback;
share_callback_t mSharePhotoCallback;
share_callback_t mUpdateStatusCallback;
};
#endif // LL_LLFACEBOOKCONNECT_H

View File

@ -2038,7 +2038,8 @@ BOOL LLFloaterSnapshot::postBuild()
getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
LLFacebookConnect::instance().setSharePhotoCallback(boost::bind(&LLFloaterSnapshot::Impl::onSnapshotUploadFinished, _1));
LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSnapshotUploadFinished, _1));
LLPostCard::setPostResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSendingPostcardFinished, _1));

View File

@ -571,7 +571,6 @@ LLPanelPeople::LLPanelPeople()
mCommitCallbackRegistrar.add("People.sendFBC", boost::bind(&LLPanelPeople::onFacebookAppSendClicked, this));
mCommitCallbackRegistrar.add("People.testaddFBC", boost::bind(&LLPanelPeople::onFacebookTestAddClicked, this));
mCommitCallbackRegistrar.add("People.testaddFBCFolderView", boost::bind(&LLPanelPeople::addTestParticipant, this));
mCommitCallbackRegistrar.add("People.testFBCCheckin", boost::bind(&LLPanelPeople::onFacebookCheckinClicked, this));
mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
mCommitCallbackRegistrar.add("People.AddFriendWizard", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this));
@ -1760,15 +1759,6 @@ void LLPanelPeople::onLoginFbcButtonClicked()
}
}
void LLPanelPeople::onFacebookCheckinClicked()
{
// Get the local SLURL
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
LLFacebookConnect::instance().postCheckinMessage("Here I am in SL!", slurl.getSLURLString(), slurl.getRegion(), "", "", "");
}
void LLPanelPeople::onFacebookAppRequestClicked()
{
}

View File

@ -124,7 +124,6 @@ private:
void onFacebookAppRequestClicked();
void onFacebookAppSendClicked();
void onFacebookTestAddClicked();
void onFacebookCheckinClicked();
bool onFriendsViewSortMenuItemCheck(const LLSD& userdata);
bool onRecentViewSortMenuItemCheck(const LLSD& userdata);

View File

@ -39,6 +39,8 @@
#include "llwebprofile.h"
#include "llfacebookconnect.h"
#include "llslurl.h"
#include "llagentui.h"
/**
* Posts a snapshot to the resident Facebook account.
@ -113,12 +115,19 @@ void LLPanelSnapshotFacebook::onSend()
{
std::string caption = getChild<LLUICtrl>("caption")->getValue().asString();
bool add_location = getChild<LLUICtrl>("add_location_cb")->getValue().asBoolean();
LLWebProfile::uploadImage(LLFloaterSnapshot::getImageData(), caption, add_location, boost::bind(&LLPanelSnapshotFacebook::onImageUploaded, this, caption, _1));
if (add_location)
{
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
if (caption.empty())
caption = slurl.getSLURLString();
else
caption = caption + " " + slurl.getSLURLString();
}
LLFacebookConnect::instance().sharePhoto(LLFloaterSnapshot::getImageData(), caption);
//LLWebProfile::uploadImage(LLFloaterSnapshot::getImageData(), caption, add_location, boost::bind(&LLPanelSnapshotFacebook::onImageUploaded, this, caption, _1));
LLFloaterSnapshot::postSave();
// test with a placeholder image, until we can figure out a way to grab the uploaded image url
LLFacebookConnect::instance().sharePhoto("http://fc02.deviantart.net/fs43/i/2009/125/a/9/Future_of_Frog_by_axcho.jpg", caption);
}
void LLPanelSnapshotFacebook::onImageUploaded(const std::string& caption, const std::string& image_url)

View File

@ -40,12 +40,5 @@
name="Facebook App Add">
<menu_item_check.on_click
function="People.testaddFBCFolderView"/>
</menu_item_check>
<menu_item_check
label="Facebook post checkin message"
layout="topleft"
name="Facebook Checkin">
<menu_item_check.on_click
function="People.testFBCCheckin"/>
</menu_item_check>
</toggleable_menu>
</toggleable_menu>

View File

@ -5444,7 +5444,7 @@ Sorry, the settings couldn't be applied to the region. Leaving the region and t
icon="alertmodal.tga"
name="FacebookCannotConnect"
type="alertmodal">
Connection to Facebook failed. Reason: [FAIL_REASON].
Connection to Facebook failed. Reason: [STATUS] [REASON] ([CODE] - [DESCRIPTION])
<usetemplate
name="okbutton"
yestext="OK"/>