Skip to content
Snippets Groups Projects
Commit e3e1a527 authored by Merov Linden's avatar Merov Linden
Browse files

DRTVWR-354 : Rewrite Responders for Twitter and Flickr to conform to new...

DRTVWR-354 : Rewrite Responders for Twitter and Flickr to conform to new LLHTTPClient interface. Fix merge error in Facebook connect as well
parent c4c8debf
No related branches found
No related tags found
No related merge requests found
...@@ -181,7 +181,7 @@ class LLFacebookShareResponder : public LLHTTPClient::Responder ...@@ -181,7 +181,7 @@ class LLFacebookShareResponder : public LLHTTPClient::Responder
/* virtual */ void httpSuccess() /* virtual */ void httpSuccess()
{ {
toast_user_for_success(); toast_user_for_facebook_success();
LL_DEBUGS("FacebookConnect") << "Post successful. " << dumpResponse() << LL_ENDL; LL_DEBUGS("FacebookConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTED); LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTED);
} }
...@@ -327,9 +327,16 @@ class LLFacebookInfoResponder : public LLHTTPClient::Responder ...@@ -327,9 +327,16 @@ class LLFacebookInfoResponder : public LLHTTPClient::Responder
{ {
if ( HTTP_FOUND == getStatus() ) if ( HTTP_FOUND == getStatus() )
{ {
LL_INFOS() << "Facebook: Info received" << LL_ENDL; const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
LL_DEBUGS("FacebookConnect") << "Getting Facebook info successful. info: " << getContent() << LL_ENDL; if (location.empty())
LLFacebookConnect::instance().storeInfo(getContent()); {
LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
<< "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
}
else
{
LLFacebookConnect::instance().openFacebookWeb(location);
}
} }
else else
{ {
......
...@@ -77,28 +77,36 @@ class LLFlickrConnectResponder : public LLHTTPClient::Responder ...@@ -77,28 +77,36 @@ class LLFlickrConnectResponder : public LLHTTPClient::Responder
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS); LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{ {
if (isGoodStatus(status)) LL_DEBUGS("FlickrConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
}
/* virtual */ void httpFailure()
{
if ( HTTP_FOUND == getStatus() )
{ {
LL_DEBUGS("FlickrConnect") << "Connect successful. content: " << content << LL_ENDL; const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
if (location.empty())
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED); {
LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
<< "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
}
else
{
LLFlickrConnect::instance().openFlickrWeb(location);
}
} }
else if (status != 302) else
{ {
LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED); LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
log_flickr_connect_error("Connect", status, reason, content.get("error_code"), content.get("error_description")); const LLSD& content = getContent();
log_flickr_connect_error("Connect", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
} }
} }
void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
if (status == 302)
{
LLFlickrConnect::instance().openFlickrWeb(content["location"]);
}
}
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
...@@ -113,33 +121,41 @@ class LLFlickrShareResponder : public LLHTTPClient::Responder ...@@ -113,33 +121,41 @@ class LLFlickrShareResponder : public LLHTTPClient::Responder
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTING); LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTING);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{ {
if (isGoodStatus(status)) toast_user_for_flickr_success();
LL_DEBUGS("FlickrConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTED);
}
/* virtual */ void httpFailure()
{
if ( HTTP_FOUND == getStatus() )
{ {
toast_user_for_flickr_success(); const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
LL_DEBUGS("FlickrConnect") << "Post successful. content: " << content << LL_ENDL; if (location.empty())
{
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTED); LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
<< "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
}
else
{
LLFlickrConnect::instance().openFlickrWeb(location);
}
} }
else if (status == 404) else if ( HTTP_NOT_FOUND == getStatus() )
{ {
LLFlickrConnect::instance().connectToFlickr(); LLFlickrConnect::instance().connectToFlickr();
} }
else else
{ {
LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED); LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED);
log_flickr_connect_error("Share", status, reason, content.get("error_code"), content.get("error_description")); const LLSD& content = getContent();
log_flickr_connect_error("Share", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
} }
} }
void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
if (status == 302)
{
LLFlickrConnect::instance().openFlickrWeb(content["location"]);
}
}
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
...@@ -163,24 +179,27 @@ class LLFlickrDisconnectResponder : public LLHTTPClient::Responder ...@@ -163,24 +179,27 @@ class LLFlickrDisconnectResponder : public LLHTTPClient::Responder
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED); LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{
LL_DEBUGS("FlickrConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
setUserDisconnected();
}
/* virtual */ void httpFailure()
{ {
if (isGoodStatus(status))
{
LL_DEBUGS("FlickrConnect") << "Disconnect successful. content: " << content << LL_ENDL;
setUserDisconnected();
}
//User not found so already disconnected //User not found so already disconnected
else if(status == 404) if ( HTTP_NOT_FOUND == getStatus() )
{ {
LL_DEBUGS("FlickrConnect") << "Already disconnected. content: " << content << LL_ENDL; LL_DEBUGS("FlickrConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
setUserDisconnected(); setUserDisconnected();
} }
else else
{ {
LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED); LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED);
log_flickr_connect_error("Disconnect", status, reason, content.get("error_code"), content.get("error_description")); const LLSD& content = getContent();
log_flickr_connect_error("Disconnect", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
} }
} }
}; };
...@@ -197,33 +216,34 @@ class LLFlickrConnectedResponder : public LLHTTPClient::Responder ...@@ -197,33 +216,34 @@ class LLFlickrConnectedResponder : public LLHTTPClient::Responder
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS); LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{
LL_DEBUGS("FlickrConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
}
/* virtual */ void httpFailure()
{ {
if (isGoodStatus(status)) // show the facebook login page if not connected yet
if ( HTTP_NOT_FOUND == getStatus() )
{ {
LL_DEBUGS("FlickrConnect") << "Connect successful. content: " << content << LL_ENDL; LL_DEBUGS("FlickrConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
if (mAutoConnect)
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED); {
LLFlickrConnect::instance().connectToFlickr();
}
else
{
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
}
} }
else else
{ {
// show the flickr login page if not connected yet LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
if (status == 404) LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
{ const LLSD& content = getContent();
if (mAutoConnect) log_flickr_connect_error("Connected", getStatus(), getReason(),
{ content.get("error_code"), content.get("error_description"));
LLFlickrConnect::instance().connectToFlickr();
}
else
{
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
}
}
else
{
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
log_flickr_connect_error("Connected", status, reason, content.get("error_code"), content.get("error_description"));
}
} }
} }
...@@ -238,25 +258,34 @@ class LLFlickrInfoResponder : public LLHTTPClient::Responder ...@@ -238,25 +258,34 @@ class LLFlickrInfoResponder : public LLHTTPClient::Responder
LOG_CLASS(LLFlickrInfoResponder); LOG_CLASS(LLFlickrInfoResponder);
public: public:
virtual void completed(U32 status, const std::string& reason, const LLSD& info) /* virtual */ void httpSuccess()
{
LL_INFOS("FlickrConnect") << "Flickr: Info received" << LL_ENDL;
LL_DEBUGS("FlickrConnect") << "Getting Flickr info successful. " << dumpResponse() << LL_ENDL;
LLFlickrConnect::instance().storeInfo(getContent());
}
/* virtual */ void httpFailure()
{ {
if (isGoodStatus(status)) if ( HTTP_FOUND == getStatus() )
{ {
llinfos << "Flickr: Info received" << llendl; const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
LL_DEBUGS("FlickrConnect") << "Getting Flickr info successful. info: " << info << LL_ENDL; if (location.empty())
LLFlickrConnect::instance().storeInfo(info); {
LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
<< "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
}
else
{
LLFlickrConnect::instance().openFlickrWeb(location);
}
} }
else else
{ {
log_flickr_connect_error("Info", status, reason, info.get("error_code"), info.get("error_description")); LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
} const LLSD& content = getContent();
} log_flickr_connect_error("Info", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
if (status == 302)
{
LLFlickrConnect::instance().openFlickrWeb(content["location"]);
} }
} }
}; };
......
...@@ -77,28 +77,36 @@ class LLTwitterConnectResponder : public LLHTTPClient::Responder ...@@ -77,28 +77,36 @@ class LLTwitterConnectResponder : public LLHTTPClient::Responder
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS); LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{ {
if (isGoodStatus(status)) LL_DEBUGS("TwitterConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
}
/* virtual */ void httpFailure()
{
if ( HTTP_FOUND == getStatus() )
{ {
LL_DEBUGS("TwitterConnect") << "Connect successful. content: " << content << LL_ENDL; const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
if (location.empty())
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED); {
LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
<< "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
}
else
{
LLTwitterConnect::instance().openTwitterWeb(location);
}
} }
else if (status != 302) else
{ {
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED); LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
log_twitter_connect_error("Connect", status, reason, content.get("error_code"), content.get("error_description")); LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
const LLSD& content = getContent();
log_twitter_connect_error("Connect", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
} }
} }
void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
if (status == 302)
{
LLTwitterConnect::instance().openTwitterWeb(content["location"]);
}
}
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
...@@ -113,33 +121,41 @@ class LLTwitterShareResponder : public LLHTTPClient::Responder ...@@ -113,33 +121,41 @@ class LLTwitterShareResponder : public LLHTTPClient::Responder
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTING); LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTING);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{ {
if (isGoodStatus(status)) toast_user_for_twitter_success();
LL_DEBUGS("TwitterConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTED);
}
/* virtual */ void httpFailure()
{
if ( HTTP_FOUND == getStatus() )
{ {
toast_user_for_twitter_success(); const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
LL_DEBUGS("TwitterConnect") << "Post successful. content: " << content << LL_ENDL; if (location.empty())
{
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTED); LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
<< "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
}
else
{
LLTwitterConnect::instance().openTwitterWeb(location);
}
} }
else if (status == 404) else if ( HTTP_NOT_FOUND == getStatus() )
{ {
LLTwitterConnect::instance().connectToTwitter(); LLTwitterConnect::instance().connectToTwitter();
} }
else else
{ {
LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED); LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED);
log_twitter_connect_error("Share", status, reason, content.get("error_code"), content.get("error_description")); const LLSD& content = getContent();
log_twitter_connect_error("Share", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
} }
} }
void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
if (status == 302)
{
LLTwitterConnect::instance().openTwitterWeb(content["location"]);
}
}
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
...@@ -163,24 +179,27 @@ class LLTwitterDisconnectResponder : public LLHTTPClient::Responder ...@@ -163,24 +179,27 @@ class LLTwitterDisconnectResponder : public LLHTTPClient::Responder
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED); LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{
LL_DEBUGS("TwitterConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
setUserDisconnected();
}
/* virtual */ void httpFailure()
{ {
if (isGoodStatus(status))
{
LL_DEBUGS("TwitterConnect") << "Disconnect successful. content: " << content << LL_ENDL;
setUserDisconnected();
}
//User not found so already disconnected //User not found so already disconnected
else if(status == 404) if ( HTTP_NOT_FOUND == getStatus() )
{ {
LL_DEBUGS("TwitterConnect") << "Already disconnected. content: " << content << LL_ENDL; LL_DEBUGS("TwitterConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
setUserDisconnected(); setUserDisconnected();
} }
else else
{ {
LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED); LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED);
log_twitter_connect_error("Disconnect", status, reason, content.get("error_code"), content.get("error_description")); const LLSD& content = getContent();
log_twitter_connect_error("Disconnect", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
} }
} }
}; };
...@@ -197,33 +216,34 @@ class LLTwitterConnectedResponder : public LLHTTPClient::Responder ...@@ -197,33 +216,34 @@ class LLTwitterConnectedResponder : public LLHTTPClient::Responder
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS); LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
} }
virtual void completed(U32 status, const std::string& reason, const LLSD& content) /* virtual */ void httpSuccess()
{
LL_DEBUGS("TwitterConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
}
/* virtual */ void httpFailure()
{ {
if (isGoodStatus(status)) // show the facebook login page if not connected yet
if ( HTTP_NOT_FOUND == getStatus() )
{ {
LL_DEBUGS("TwitterConnect") << "Connect successful. content: " << content << LL_ENDL; LL_DEBUGS("TwitterConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
if (mAutoConnect)
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED); {
LLTwitterConnect::instance().connectToTwitter();
}
else
{
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
}
} }
else else
{ {
// show the twitter login page if not connected yet LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
if (status == 404) LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
{ const LLSD& content = getContent();
if (mAutoConnect) log_twitter_connect_error("Connected", getStatus(), getReason(),
{ content.get("error_code"), content.get("error_description"));
LLTwitterConnect::instance().connectToTwitter();
}
else
{
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
}
}
else
{
LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
log_twitter_connect_error("Connected", status, reason, content.get("error_code"), content.get("error_description"));
}
} }
} }
...@@ -238,25 +258,34 @@ class LLTwitterInfoResponder : public LLHTTPClient::Responder ...@@ -238,25 +258,34 @@ class LLTwitterInfoResponder : public LLHTTPClient::Responder
LOG_CLASS(LLTwitterInfoResponder); LOG_CLASS(LLTwitterInfoResponder);
public: public:
virtual void completed(U32 status, const std::string& reason, const LLSD& info) /* virtual */ void httpSuccess()
{
LL_INFOS("TwitterConnect") << "Twitter: Info received" << LL_ENDL;
LL_DEBUGS("TwitterConnect") << "Getting Twitter info successful. " << dumpResponse() << LL_ENDL;
LLTwitterConnect::instance().storeInfo(getContent());
}
/* virtual */ void httpFailure()
{ {
if (isGoodStatus(status)) if ( HTTP_FOUND == getStatus() )
{ {
llinfos << "Twitter: Info received" << llendl; const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
LL_DEBUGS("TwitterConnect") << "Getting Twitter info successful. info: " << info << LL_ENDL; if (location.empty())
LLTwitterConnect::instance().storeInfo(info); {
LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
<< "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
}
else
{
LLTwitterConnect::instance().openTwitterWeb(location);
}
} }
else else
{ {
log_twitter_connect_error("Info", status, reason, info.get("error_code"), info.get("error_description")); LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
} const LLSD& content = getContent();
} log_twitter_connect_error("Info", getStatus(), getReason(),
content.get("error_code"), content.get("error_description"));
void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
if (status == 302)
{
LLTwitterConnect::instance().openTwitterWeb(content["location"]);
} }
} }
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment