TwitterCommBundle.cpp

Go to the documentation of this file.
00001 /** @file    TwitterCommBundle.cpp
00002  *  @author  Alessandro Polo
00003  *  @version $Id: TwitterCommBundle.cpp 3775 2011-01-01 16:38:17Z alex $
00004  *  @brief
00005  * File containing methods for the wosh::bundles::TwitterCommBundle class.
00006  * The header for this class can be found in TwitterCommBundle.h, check that file
00007  * for class description.
00008  ****************************************************************************/
00009 /* Copyright (c) 2007-2011, WOSH - Wide Open Smart Home 
00010  * by Alessandro Polo - OpenSmartHome.com
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *     * Redistributions of source code must retain the above copyright
00016  *       notice, this list of conditions and the following disclaimer.
00017  *     * Redistributions in binary form must reproduce the above copyright
00018  *       notice, this list of conditions and the following disclaimer in the
00019  *       documentation and/or other materials provided with the distribution.
00020  *     * Neither the name of the OpenSmartHome.com WOSH nor the
00021  *       names of its contributors may be used to endorse or promote products
00022  *       derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
00025  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
00028  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  ****************************************************************************/
00035 
00036  #include "TwitterCommBundle.h"
00037  #include "TwitterCommWorkerCurl.h"
00038  #include <core/ObjectAllocator.h>
00039  #include <core/MethodsCommon.h>
00040  #include <core/MessageFilter.h>
00041  #include <core/Utilities.h>
00042  #include <core/Fact.h>
00043  #include <core/List.h>
00044  #include <core/Table.h>
00045  #include <core/ThreadManager.h>
00046  #include <core/DeviceManager.h>
00047  #include <core/SystemInfo.h>
00048  #include <core/WoshKernel.h>
00049 
00050 
00051 using namespace std;
00052 namespace wosh {
00053  namespace bundles {
00054 
00055  WOSH_REGISTER(wosh::bundles::TwitterCommBundle, wosh::interfaces::communication::TwitterComm, _TwitterCommBundle_VERSION, bundles_TwitterCommBundle1)
00056  WOSH_REGISTER(wosh::bundles::TwitterCommBundle, wosh::BundleGeneric, _TwitterCommBundle_VERSION, bundles_TwitterCommBundle2)
00057 
00058 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00059 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00060 
00061 TwitterCommBundle::TwitterCommBundle( const std::string& name )
00062     : BundleGeneric() {
00063     if ( name.size() > 0 )  BundleGeneric::setName( name, false );
00064     else                    BundleGeneric::setName( _TwitterCommBundle_NAME, false );
00065     Properties.update( _KEY_Version, _TwitterCommBundle_VERSION );
00066 
00067 Log.setLevel(LOG_VERBOSE);
00068 
00069     Log(LOG_DEBUG, " Configuring Twitter worker.." );
00070     this->twitterWorker = new TwitterCommWorkerCurl(*this);
00071     this->twitterWorker->setListener(this);
00072 
00073     Log(LOG_DEBUG, " Setting default properties and permissions.." );
00074     Properties.set( _TwitterComm_KEY_UserName,              "", Permission::RW_RW_R__() );
00075     Properties.set( _TwitterComm_KEY_UserPassword,          "", Permission::RW_RW_R__() );
00076     Properties.set( _TwitterComm_KEY_ServerAuthority,       "twitter.com", Permission::RW_RW_R__() );
00077     Properties.set( _TwitterComm_KEY_ServerAddressPort,     "http://www.twitter.com", Permission::RW_RW_R__() );
00078     Properties.monitor(_TwitterComm_KEY_UserName);
00079     Properties.monitor(_TwitterComm_KEY_UserPassword);
00080 
00081     Log(LOG_DEBUG, " Registering methods.." );
00082     MethodRequest* mmPostMessage = Methods.create<MethodRequest>( _TwitterComm_METHOD_post, "post status message", Permission::R_XR__R__() );
00083     mmPostMessage->setMethod( this, (MethodRequestPtr)&TwitterCommBundle::mmDoPostMessage );
00084 
00085 
00086     setBundleState(Bundle::STATE_CREATED, false);
00087  }
00088 
00089 TwitterCommBundle::~TwitterCommBundle() {
00090     Log(LOG_VERBOSE, " Destroying.." );
00091     if ( isBundleRunning() ) {
00092         Log(LOG_WARNING, "~TwitterCommBundle() : Destroying while Bundle is running! Trying to stop.." );
00093         bundleStop();
00094      }
00095     if ( this->twitterWorker->isThreadRunning() ) {
00096         Log(LOG_WARNING, "~TwitterCommBundle() : Destroying while RUNNING! Trying to stop.." );
00097         this->twitterWorker->quitThread(30000);
00098      }
00099     delete this->twitterWorker; this->twitterWorker = NULL;
00100     Log(LOG_VERBOSE, ":~TwitterCommBundle() : Destroyed." );
00101  }
00102 
00103 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00105 ////////////////////////////////////////////////////////////////////////////////////////////// BUNDLE CONTROL
00106 
00107 WRESULT TwitterCommBundle::bundleStart() {
00108     if ( !BundleGeneric::bundleValidate_StartStop(Bundle::STATE_STARTING) ) return WRET_ERR_WRONG_STATE;
00109     WRESULT ret = BundleGeneric::start_SynchThread( this->twitterWorker );
00110     // BUNDLE-STATE (STARTED) will be updated async by WORKER, through call: IThreadListener::thread_event()
00111     return ret;
00112  }
00113 
00114 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00115 
00116 WRESULT TwitterCommBundle::bundleStop() {
00117     if ( !BundleGeneric::bundleValidate_StartStop(Bundle::STATE_STOPPING) ) return WRET_ERR_WRONG_STATE;
00118     WRESULT ret = BundleGeneric::stop_SynchThread( this->twitterWorker );
00119     // BUNDLE-STATE (STOPPED) will be updated async by WORKER, through call: IThreadListener::thread_event()
00120     return ret;
00121  }
00122 
00123 WRESULT TwitterCommBundle::bundleDiagnostic() {
00124     Log(LOG_VERBOSE, ":bundleDiagnostic() : Starting TwitterCommBundle-Diagnostic" );
00125     WRESULT ret = BundleGeneric::bundleDiagnostic();
00126     Log(LOG_INFO, ":bundleDiagnostic() : Finished TwitterCommBundle-Diagnostic [%d]", ret );
00127     return ret;
00128  }
00129 
00130 ////////////////////////////////////////////////////////////////////////////////////////////// BUNDLE CONTROL
00131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00132 //////////////////////////////////////////////////////////////////////////////////////////////// BUS MESSAGES
00133 
00134 void TwitterCommBundle::busMessage( const Message& message, const Bus* source ) {
00135     BundleGeneric::busMessage(message, source);
00136     
00137  }
00138 
00139 //////////////////////////////////////////////////////////////////////////////////////////////// BUS MESSAGES
00140 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00141 //////////////////////////////////////////////////////////////////////////////////////////// GENERATED EVENTS
00142 
00143 //////////////////////////////////////////////////////////////////////////////////////////// GENERATED EVENTS
00144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00145 ///////////////////////////////////////////////////////////////////////////////////////////// PROPERTY EVENTS
00146 
00147 bool TwitterCommBundle::readingProperty( Property* property_curr, const PropertiesProvider* ) {
00148     if ( property_curr == NULL ) return true;
00149     return true;
00150  }
00151 
00152 bool TwitterCommBundle::updatingProperty( bool& do_update, const Variant& value_proposed, Property& property_current, const PropertiesProvider* source ) {
00153     if ( property_current.getKey() == _TwitterComm_KEY_UserName ) {
00154         this->twitterWorker->setAccountUserName( value_proposed.toString() );
00155         return true;
00156      }
00157     else if ( property_current.getKey() == _TwitterComm_KEY_UserPassword ) {
00158         this->twitterWorker->setAccountPassword( value_proposed.toString() );
00159         property_current.setValue("*********");
00160         do_update = false;
00161         return true;
00162      }
00163 
00164 else if ( property_current.getKey() == _TwitterComm_KEY_ServerAuthority )
00165     return ( WSUCCEEDED(this->CredentialsIO.setAuthorityName( value_proposed.toString() )) );
00166 
00167     else // forward processing to base class
00168         return BundleGeneric::updatingProperty(do_update, value_proposed, property_current, source);
00169  }
00170 
00171 ///////////////////////////////////////////////////////////////////////////////////////////// PROPERTY EVENTS
00172 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00173 
00174 const std::string& TwitterCommBundle::getServerAddress() const      { return this->twitterWorker->getServerAddress(); }
00175 int TwitterCommBundle::getServerPort() const                        { return this->twitterWorker->getServerPort(); }
00176 const std::string& TwitterCommBundle::getAccountName() const        { return this->twitterWorker->getAccountName(); }
00177 
00178 bool TwitterCommBundle::setServer( const std::string& address, int port ) {
00179 
00180  }
00181 
00182 bool TwitterCommBundle::setAccount( const std::string& username, const std::string& password ) {
00183 
00184  }
00185 
00186 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00187 ////////////////////////////////////////////////////////////////////////////////////////////// TWITTER EVENTS
00188 
00189 void TwitterCommBundle::twitter_error( int , TwitterCommWorker* ) {
00190 
00191  }
00192 
00193 ////////////////////////////////////////////////////////////////////////////////////////////// TWITTER EVENTS
00194 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00195 
00196 std::string TwitterCommBundle::getUsernameFromAccountName( const std::string& accountname ) const {
00197     std::string wosh_username;
00198     wosh::security::AuthenticationSecret3rdParty s3p;
00199     s3p.authority = Properties.getValueOf(_TwitterComm_KEY_ServerAuthority).toString();
00200     s3p.username = accountname;
00201     WRESULT found = this->CredentialsIO.findUser(&s3p, wosh_username);
00202     if ( WFAILED(found) || wosh_username.size() < 3 ) {
00203         Log(LOG_WARNING, ":getUsernameFromAccountName() : User '%s' (%s) not recognized! [%s]", accountname.c_str(), s3p.authority.c_str(), wosh_username.c_str() );
00204         return "";
00205      }
00206     return wosh_username;
00207  }
00208 
00209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00210 
00211 std::string TwitterCommBundle::getAccountNameFromUsername( const std::string& username ) const {
00212     std::string account_name;
00213     WRESULT found = this->CredentialsIO.findAccountOf(username, account_name);
00214     if ( WFAILED(found) || account_name.empty() ) {
00215         Log(LOG_WARNING, ":getAccountNameFromUsername() : wosh-User '%s' not recognized! [not found]", username.c_str() );
00216         return "";
00217      }
00218     return account_name;
00219  }
00220 
00221 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00222 ////////////////////////////////////////////////////////////////////////////////////// COMMUNICATOR INTERFACE
00223 
00224 bool TwitterCommBundle::isUserReachable( const std::string& username ) const {
00225     std::string accountname = getAccountNameFromUsername(username);
00226     if ( accountname == "" ) return false;
00227 //  MutexLockerRead mL(this->contacts.getMutex());
00228 //  ContactInfo* info = this->contacts.find(accountname);
00229 //  if ( info == NULL ) return false;
00230 //  // negative means he is offline from abs(.)
00231 //  if ( info->isOffline() ) return false;
00232 //  return true;
00233     return false;
00234  }
00235 
00236 bool TwitterCommBundle::isUserRegistered( const std::string& username ) const {
00237     std::string accountname = getAccountNameFromUsername(username);
00238     if ( accountname == "" ) return false;
00239 //  if ( !this->contacts.exists(accountname) ) return false;
00240 //  return true;
00241     return false;
00242  }
00243 
00244 int64 TwitterCommBundle::getUserLastSeen( const std::string& username ) const {
00245     std::string accountname = getAccountNameFromUsername(username);
00246     if ( accountname == "" ) return 0LL;
00247 //  MutexLockerRead mL(this->contacts.getMutex());
00248 //  ContactInfo* info = this->contacts.find(accountname);
00249 //  if ( info == NULL ) return 0LL;
00250 //  // negative means he is offline from abs(.)
00251 //  if ( info->isOffline() ) return -info->getLastSeen();
00252 //  return info->getLastSeen();
00253     return 0LL;
00254  }
00255 
00256 WRESULT TwitterCommBundle::sendMessageToUser( const std::string& userWosh, const std::string& message ) {
00257     std::string accountname = getAccountNameFromUsername(userWosh);
00258     if ( accountname == "" ) {
00259         SystemInfo::raise(this, &Log, SystemInfo::TYPE_ERROR, SystemInfo::MODE_PERMANENT, SystemInfo::SCOPE_SYSTEM, SystemInfo::PRIORITY_FAILURE,
00260                             "Unable to send message",
00261                             "sendMessageToUser(%s) FAILED mapping user %s", userWosh.c_str() );
00262         return WRET_ERR_PARAM;
00263      }
00264     return sendMessageTo( accountname, message );
00265  }
00266 
00267 WRESULT TwitterCommBundle::sendMessageTo( const std::string& userID, const std::string& message ) {
00268     if ( userID == "" ) return WRET_ERR_PARAM;
00269 //  bool sent = this->jabbWorker->sendMessage( userID, message );
00270 //  if ( !sent ) {
00271 //      SystemInfo::raise(this, &Log, SystemInfo::TYPE_ERROR, SystemInfo::MODE_PERMANENT, SystemInfo::SCOPE_SYSTEM, SystemInfo::PRIORITY_FAILURE,
00272 //                          "Unable to send message",
00273 //                          "sendMessageTo(%s) failed sending message", userID.c_str() );
00274         return WRET_ERR_INTERNAL;
00275 //   }
00276 //  return WRET_OK;
00277  }
00278 
00279 WRESULT TwitterCommBundle::notify( const Notification* notification, const Message* ) {
00280     if ( notification == NULL ) return WRET_ERR_PARAM;
00281 //  if ( notification->isForAnyone() || notification->getRecipent_User().empty() ) {
00282 //      Log(LOG_WARNING, "notify(%ld) to ANYONE", notification->getID(), notification->getRecipent_User().c_str() );
00283 //      WRESULT ret = WRET_OK;
00284 //      this->contacts.transactionBeginRead();
00285 //      tStrContactInfoMap::ConstIterator it;
00286 //      const tStrContactInfoMap::ConstIterator it_end = this->contacts.end();
00287 //      for ( it=this->contacts.begin(); it!=it_end; ++it ) {
00288 //          ret += sendMessageTo( it->first, notification->getPlain() );
00289 //       }
00290 //      this->contacts.transactionEnd();
00291 //      return ret;
00292 //   }
00293 //  Log(LOG_INFO, "notify(%ld) to %s", notification->getID(), notification->getRecipent_User().c_str() );
00294 //  return sendMessageToUser( notification->getRecipent_User(), notification->getPlain() );
00295     return WRET_ERR_INTERNAL;
00296  }
00297 
00298 ////////////////////////////////////////////////////////////////////////////////////// COMMUNICATOR INTERFACE
00299 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00300 /////////////////////////////////////////////////////////////////////////////////////////////// OTHER METHODS
00301 
00302 Response* TwitterCommBundle::mmDoPostMessage( const Request* request ) {
00303     if ( request == NULL ) return NULL;
00304     string message = request->getArgument().toString();
00305     Log(LOG_VERBOSE, "mmDoPostMessage(%s)", message.c_str() );
00306     WRESULT ret = this->twitterWorker->sendMessage( message );
00307     if ( WSUCCEEDED(ret) )
00308         return request->replyResponse(WRET_OK, "Status message sent");
00309     return request->replyResponse(ret, "posting failed");
00310  }
00311 
00312 ///////////////////////////////////////////////////////////////////////////////////////////////////// METHODS
00313 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00314 
00315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00316 
00317  }; // namespace bundles
00318 }; // namespace wosh

Generated on Tue Feb 8 2011 09:33:08 for WOSH system 0.8.888 [wolf] by Alessandro Polo, using DoxyGen 1.7.2 hosted by WOSH Framework