2010-03-10 16:38:26 -05:00
/***************************************************************************
* Copyright ( C ) 2009 *
* *
* 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 , write to the *
* Free Software Foundation , Inc . , *
* 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <iostream>
# include <QStringList>
2010-03-22 15:46:58 -04:00
# include <QRegExp>
# include <QApplication>
# include <QMimeData>
# include <QClipboard>
2010-07-15 07:25:34 -04:00
# include <QDesktopServices>
# include <QMessageBox>
# include <QIcon>
# include <QObject>
2010-03-10 16:38:26 -05:00
# include "RetroShareLink.h"
2011-04-19 15:42:44 -04:00
# include "MainWindow.h"
# include "ForumsDialog.h"
# include "ChannelFeed.h"
2011-05-04 06:22:49 -04:00
# include "SearchDialog.h"
2011-05-07 19:14:09 -04:00
# include "msgs/MessageComposer.h"
2010-08-06 11:31:30 -04:00
# include "util/misc.h"
2010-09-28 16:33:34 -04:00
# include "common/PeerDefs.h"
2011-12-10 16:38:38 -05:00
# include "common/RsCollectionFile.h"
2012-01-18 15:31:30 -05:00
# include "gui/connect/ConnectFriendWizard.h"
2011-05-18 17:23:26 -04:00
# include "gui/connect/ConfCertDialog.h"
2010-03-10 16:38:26 -05:00
2010-08-06 05:40:23 -04:00
# include <retroshare/rsfiles.h>
# include <retroshare/rspeers.h>
2011-04-19 15:42:44 -04:00
# include <retroshare/rsforums.h>
# include <retroshare/rschannels.h>
2010-07-15 07:25:34 -04:00
2012-01-18 15:31:30 -05:00
# define DEBUG_RSLINK 1
2010-03-10 16:38:26 -05:00
2012-01-18 15:31:30 -05:00
# define HOST_FILE "file"
# define HOST_PERSON "person"
# define HOST_FORUM "forum"
# define HOST_CHANNEL "channel"
# define HOST_MESSAGE "message"
# define HOST_SEARCH "search"
# define HOST_CERTIFICATE "certificate"
# define HOST_REGEXP "file|person|forum|channel|search|message|certificate"
2010-11-18 11:31:44 -05:00
# define FILE_NAME "name"
# define FILE_SIZE "size"
# define FILE_HASH "hash"
# define PERSON_NAME "name"
# define PERSON_HASH "hash"
2010-03-10 16:38:26 -05:00
2011-04-19 15:42:44 -04:00
# define FORUM_NAME "name"
# define FORUM_ID "id"
# define FORUM_MSGID "msgid"
# define CHANNEL_NAME "name"
# define CHANNEL_ID "id"
# define CHANNEL_MSGID "msgid"
2011-05-07 19:14:09 -04:00
# define MESSAGE_ID "id"
# define MESSAGE_SUBJECT "subject"
2012-01-18 15:31:30 -05:00
# define SEARCH_KEYWORDS "keywords"
# define CERTIFICATE_SSLID "sslid"
# define CERTIFICATE_GPG_ID "gpgid"
# define CERTIFICATE_GPG_BASE64 "gpgbase64"
# define CERTIFICATE_GPG_CHECKSUM "gpgchecksum"
# define CERTIFICATE_LOCATION "location"
# define CERTIFICATE_NAME "name"
2011-05-04 06:22:49 -04:00
2010-03-10 18:09:35 -05:00
RetroShareLink : : RetroShareLink ( const QUrl & url )
2010-03-10 16:38:26 -05:00
{
2010-11-18 11:31:44 -05:00
fromUrl ( url ) ;
2010-07-15 07:25:34 -04:00
}
RetroShareLink : : RetroShareLink ( const QString & url )
{
fromString ( url ) ;
}
void RetroShareLink : : fromString ( const QString & url )
{
2010-11-18 11:31:44 -05:00
clear ( ) ;
2010-07-15 07:25:34 -04:00
// parse
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " got new RS link \" " < < url . toStdString ( ) < < " \" " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
if ( ( url . startsWith ( QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_FILE ) ) & & url . count ( " | " ) = = 3 ) | |
( url . startsWith ( QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_PERSON ) ) & & url . count ( " | " ) = = 2 ) ) {
/* Old link, we try it */
QStringList list = url . split ( " | " ) ;
if ( list . size ( ) > = 1 ) {
if ( list . size ( ) = = 4 & & list [ 0 ] = = QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_FILE ) ) {
bool ok ;
2010-03-10 16:38:26 -05:00
2010-11-18 11:31:44 -05:00
_type = TYPE_FILE ;
_name = list [ 1 ] ;
_size = list [ 2 ] . toULongLong ( & ok ) ;
_hash = list [ 3 ] . left ( 40 ) ; // normally not necessary, but it's a security.
2010-03-10 16:38:26 -05:00
2010-11-18 11:31:44 -05:00
if ( ok ) {
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-11-18 11:31:44 -05:00
std : : cerr < < " New RetroShareLink forged: " < < std : : endl ;
std : : cerr < < " name = \" " < < _name . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " hash = \" " < < _hash . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " size = " < < _size < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
check ( ) ;
return ;
}
} else if ( list . size ( ) = = 3 & & list [ 0 ] = = QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_PERSON ) ) {
_type = TYPE_PERSON ;
_name = list [ 1 ] ;
_hash = list [ 2 ] . left ( 40 ) ; // normally not necessary, but it's a security.
_size = 0 ;
2010-07-15 07:25:34 -04:00
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
// bad link
}
}
/* Now try QUrl */
2011-10-08 13:49:06 -04:00
fromUrl ( QUrl : : fromEncoded ( url . toUtf8 ( ) . constData ( ) ) ) ;
2010-11-18 11:31:44 -05:00
}
void RetroShareLink : : fromUrl ( const QUrl & url )
{
clear ( ) ;
// parse
# ifdef DEBUG_RSLINK
std : : cerr < < " got new RS link \" " < < url . toString ( ) . toStdString ( ) < < " \" " < < std : : endl ;
# endif
if ( url . scheme ( ) ! = RSLINK_SCHEME ) {
/* No RetroShare-Link */
return ;
}
if ( url . host ( ) = = HOST_FILE ) {
bool ok ;
_type = TYPE_FILE ;
_name = url . queryItemValue ( FILE_NAME ) ;
_size = url . queryItemValue ( FILE_SIZE ) . toULongLong ( & ok ) ;
_hash = url . queryItemValue ( FILE_HASH ) . left ( 40 ) ; // normally not necessary, but it's a security.
if ( ok ) {
# ifdef DEBUG_RSLINK
std : : cerr < < " New RetroShareLink forged: " < < std : : endl ;
std : : cerr < < " name = \" " < < _name . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " hash = \" " < < _hash . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " size = " < < _size < < std : : endl ;
# endif
2010-07-15 07:25:34 -04:00
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
}
2010-07-15 07:25:34 -04:00
2010-11-18 11:31:44 -05:00
if ( url . host ( ) = = HOST_PERSON ) {
_type = TYPE_PERSON ;
_name = url . queryItemValue ( PERSON_NAME ) ;
_hash = url . queryItemValue ( PERSON_HASH ) . left ( 40 ) ; // normally not necessary, but it's a security.
check ( ) ;
return ;
2010-07-15 07:25:34 -04:00
}
2010-03-10 16:38:26 -05:00
2011-04-19 15:42:44 -04:00
if ( url . host ( ) = = HOST_FORUM ) {
_type = TYPE_FORUM ;
_name = url . queryItemValue ( FORUM_NAME ) ;
_hash = url . queryItemValue ( FORUM_ID ) ;
_msgId = url . queryItemValue ( FORUM_MSGID ) ;
check ( ) ;
return ;
}
if ( url . host ( ) = = HOST_CHANNEL ) {
_type = TYPE_CHANNEL ;
_name = url . queryItemValue ( CHANNEL_NAME ) ;
_hash = url . queryItemValue ( CHANNEL_ID ) ;
_msgId = url . queryItemValue ( CHANNEL_MSGID ) ;
2011-05-04 06:22:49 -04:00
check ( ) ;
return ;
}
if ( url . host ( ) = = HOST_SEARCH ) {
_type = TYPE_SEARCH ;
_name = url . queryItemValue ( SEARCH_KEYWORDS ) ;
2011-04-19 15:42:44 -04:00
check ( ) ;
return ;
}
2011-05-07 19:14:09 -04:00
if ( url . host ( ) = = HOST_MESSAGE ) {
_type = TYPE_MESSAGE ;
std : : string id = url . queryItemValue ( MESSAGE_ID ) . toStdString ( ) ;
createMessage ( id , url . queryItemValue ( MESSAGE_SUBJECT ) ) ;
return ;
}
2012-01-18 15:31:30 -05:00
if ( url . host ( ) = = HOST_CERTIFICATE ) {
_type = TYPE_CERTIFICATE ;
_SSLid = url . queryItemValue ( CERTIFICATE_SSLID ) ;
_name = url . queryItemValue ( CERTIFICATE_NAME ) ;
_location = url . queryItemValue ( CERTIFICATE_LOCATION ) ;
_GPGBase64String = url . queryItemValue ( CERTIFICATE_GPG_BASE64 ) ;
_GPGid = url . queryItemValue ( CERTIFICATE_GPG_ID ) ;
_GPGBase64CheckSum = url . queryItemValue ( CERTIFICATE_GPG_CHECKSUM ) ;
std : : cerr < < " Got a certificate link!! " < < std : : endl ;
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
// bad link
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " Wrongly formed RS link. Can't process. " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
clear ( ) ;
2010-03-10 16:38:26 -05:00
}
2011-05-04 06:22:49 -04:00
RetroShareLink : : RetroShareLink ( )
2010-03-10 16:38:26 -05:00
{
2011-05-04 06:22:49 -04:00
clear ( ) ;
}
bool RetroShareLink : : createFile ( const QString & name , uint64_t size , const QString & hash )
{
clear ( ) ;
_name = name ;
_size = size ;
_hash = hash ;
2010-07-15 07:25:34 -04:00
_type = TYPE_FILE ;
2011-05-04 06:22:49 -04:00
check ( ) ;
return valid ( ) ;
2010-03-10 16:38:26 -05:00
}
2011-05-12 15:37:13 -04:00
bool RetroShareLink : : createPerson ( const std : : string & id )
2010-03-10 16:38:26 -05:00
{
2011-05-04 06:22:49 -04:00
clear ( ) ;
2011-05-12 15:37:13 -04:00
RsPeerDetails detail ;
if ( rsPeers - > getPeerDetails ( id , detail ) = = false ) {
std : : cerr < < " RetroShareLink::createPerson() Couldn't find peer id " < < id < < std : : endl ;
return false ;
}
_hash = QString : : fromStdString ( id ) ;
_name = QString : : fromUtf8 ( detail . name . c_str ( ) ) ;
2011-05-04 06:22:49 -04:00
2010-07-15 07:25:34 -04:00
_type = TYPE_PERSON ;
2011-05-04 06:22:49 -04:00
check ( ) ;
return valid ( ) ;
2010-07-15 07:25:34 -04:00
}
2010-03-10 16:38:26 -05:00
2012-01-18 15:31:30 -05:00
bool RetroShareLink : : createCertificate ( const std : : string & ssl_id )
{
std : : string invite = rsPeers - > GetRetroshareInvite ( ssl_id , false ) ;
if ( invite = = " " )
{
std : : cerr < < " RetroShareLink::createPerson() Couldn't get retroshare invite for ssl id: " < < ssl_id < < std : : endl ;
return false ;
}
RsPeerDetails detail ;
if ( rsPeers - > getPeerDetails ( ssl_id , detail ) = = false ) {
std : : cerr < < " RetroShareLink::createPerson() Couldn't find peer id " < < ssl_id < < std : : endl ;
return false ;
}
//_ssl_id = QString::fromStdString(id);
_name = QString : : fromUtf8 ( detail . name . c_str ( ) ) ;
QString gpg_cert = QString : : fromStdString ( invite ) ;
QString gpg_base_64 = QString : : fromStdString ( invite ) . section ( " \n \n " , 1 ) . section ( " ----- " , 0 , 0 ) ;
_GPGBase64CheckSum = gpg_base_64 . section ( " = " , - 1 , - 1 ) . section ( " \n " , 0 , 0 ) ;
gpg_base_64 = gpg_base_64 . section ( " \n = " , 0 , 0 ) ;
_type = TYPE_CERTIFICATE ;
_GPGid = QString : : fromStdString ( detail . gpg_id ) . right ( 8 ) ;
_SSLid = QString : : fromStdString ( ssl_id ) ;
_GPGBase64String = gpg_base_64 . replace ( " \n " , " " ) ;
_location = QString : : fromStdString ( detail . location ) ;
_name = QString : : fromStdString ( detail . name ) ;
//_external_ipp = QString::fromStdString(invite).section("--EXT--",1,1) ;
QString lst = QString : : fromStdString ( invite ) . section ( " --EXT-- " , 0 , 0 ) ;
//_local_ipp = lst.section("--LOCAL--",1,1) ;
std : : cerr < < " Found gpg base 64 string = " < < _GPGBase64String . toStdString ( ) < < std : : endl ;
std : : cerr < < " Found gpg base 64 checksum = " < < _GPGBase64CheckSum . toStdString ( ) < < std : : endl ;
std : : cerr < < " Found SSLId = " < < _SSLid . toStdString ( ) < < std : : endl ;
std : : cerr < < " Found GPGId = " < < _GPGid . toStdString ( ) < < std : : endl ;
//std::cerr << "Found External IP+Port = " << _external_ipp.toStdString() << std::endl;
//std::cerr << "Found External IP+Port = " << _local_ipp.toStdString() << std::endl;
std : : cerr < < " Found Location = " < < _location . toStdString ( ) < < std : : endl ;
}
2011-05-08 19:11:27 -04:00
bool RetroShareLink : : createForum ( const std : : string & id , const std : : string & msgId )
2011-04-19 15:42:44 -04:00
{
2011-05-08 19:11:27 -04:00
clear ( ) ;
if ( ! id . empty ( ) ) {
_hash = QString : : fromStdString ( id ) ;
_msgId = QString : : fromStdString ( msgId ) ;
_type = TYPE_FORUM ;
if ( msgId . empty ( ) ) {
ForumInfo fi ;
if ( rsForums - > getForumInfo ( id , fi ) ) {
_name = QString : : fromStdWString ( fi . forumName ) ;
}
} else {
ForumMsgInfo mi ;
if ( rsForums - > getForumMessage ( id , msgId , mi ) ) {
_name = QString : : fromStdWString ( mi . title ) ;
}
}
}
check ( ) ;
return valid ( ) ;
2011-05-04 06:22:49 -04:00
}
2011-05-08 19:11:27 -04:00
bool RetroShareLink : : createChannel ( const std : : string & id , const std : : string & msgId )
2011-05-04 06:22:49 -04:00
{
2011-05-08 19:11:27 -04:00
clear ( ) ;
if ( ! id . empty ( ) ) {
_hash = QString : : fromStdString ( id ) ;
_msgId = QString : : fromStdString ( msgId ) ;
_type = TYPE_CHANNEL ;
if ( msgId . empty ( ) ) {
ChannelInfo ci ;
if ( rsChannels - > getChannelInfo ( id , ci ) ) {
_name = QString : : fromStdWString ( ci . channelName ) ;
}
} else {
ChannelMsgInfo mi ;
if ( rsChannels - > getChannelMessage ( id , msgId , mi ) ) {
_name = QString : : fromStdWString ( mi . subject ) ;
}
}
}
check ( ) ;
return valid ( ) ;
2011-05-04 06:22:49 -04:00
}
bool RetroShareLink : : createSearch ( const QString & keywords )
{
clear ( ) ;
_name = keywords ;
_type = TYPE_SEARCH ;
check ( ) ;
return valid ( ) ;
2011-04-19 15:42:44 -04:00
}
2011-05-07 19:14:09 -04:00
bool RetroShareLink : : createMessage ( const std : : string & peerId , const QString & subject )
{
clear ( ) ;
_hash = QString : : fromStdString ( peerId ) ;
PeerDefs : : rsidFromId ( peerId , & _name ) ;
_subject = subject ;
_type = TYPE_MESSAGE ;
check ( ) ;
return valid ( ) ;
}
2010-11-18 11:31:44 -05:00
void RetroShareLink : : clear ( )
{
_valid = false ;
_type = TYPE_UNKNOWN ;
_hash = " " ;
_size = 0 ;
_name = " " ;
}
2010-07-15 07:25:34 -04:00
void RetroShareLink : : check ( )
{
2011-05-07 19:14:09 -04:00
_valid = true ;
2010-07-15 07:25:34 -04:00
2011-05-07 19:14:09 -04:00
switch ( _type ) {
case TYPE_UNKNOWN :
_valid = false ;
break ;
case TYPE_FILE :
if ( _size > ( ( ( uint64_t ) 1 ) < < 40 ) ) // 1TB. Who has such large files?
_valid = false ;
2010-07-15 07:25:34 -04:00
2011-05-07 19:14:09 -04:00
if ( ! checkName ( _name ) )
_valid = false ;
2010-07-15 07:25:34 -04:00
2011-05-07 19:14:09 -04:00
if ( ! checkHash ( _hash ) )
_valid = false ;
break ;
case TYPE_PERSON :
if ( _size ! = 0 )
_valid = false ;
2010-07-15 07:25:34 -04:00
2011-05-07 19:14:09 -04:00
if ( _name . isEmpty ( ) )
_valid = false ;
2010-07-15 07:25:34 -04:00
2011-05-07 19:14:09 -04:00
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_FORUM :
if ( _size ! = 0 )
_valid = false ;
2011-04-19 15:42:44 -04:00
2011-05-07 19:14:09 -04:00
if ( _name . isEmpty ( ) )
_valid = false ;
2011-04-19 15:42:44 -04:00
2011-05-07 19:14:09 -04:00
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_CHANNEL :
if ( _size ! = 0 )
_valid = false ;
2011-04-19 15:42:44 -04:00
2011-05-07 19:14:09 -04:00
if ( _name . isEmpty ( ) )
_valid = false ;
2011-04-19 15:42:44 -04:00
2011-05-07 19:14:09 -04:00
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_SEARCH :
if ( _size ! = 0 )
_valid = false ;
2011-05-04 06:22:49 -04:00
2011-05-07 19:14:09 -04:00
if ( _name . isEmpty ( ) )
_valid = false ;
2011-05-04 06:22:49 -04:00
2011-05-07 19:14:09 -04:00
if ( ! _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_MESSAGE :
if ( _size ! = 0 )
_valid = false ;
2010-07-15 07:25:34 -04:00
2011-05-07 19:14:09 -04:00
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
}
if ( ! _valid ) {
clear ( ) ;
}
2010-03-10 16:38:26 -05:00
}
2011-05-01 18:26:41 -04:00
QString RetroShareLink : : title ( ) const
{
if ( ! valid ( ) ) {
return " " ;
}
switch ( _type ) {
case TYPE_UNKNOWN :
break ;
case TYPE_FILE :
return QString ( " %1 (%2) " ).arg(hash()).arg(misc::friendlyUnit(size())) ;
case TYPE_PERSON :
2011-05-18 17:23:26 -04:00
return PeerDefs : : rsidFromId ( hash ( ) . toStdString ( ) ) ;
2011-05-01 18:26:41 -04:00
case TYPE_FORUM :
case TYPE_CHANNEL :
2011-05-04 06:22:49 -04:00
case TYPE_SEARCH :
2011-05-01 18:26:41 -04:00
break ;
2011-05-07 19:14:09 -04:00
case TYPE_MESSAGE :
return PeerDefs : : rsidFromId ( hash ( ) . toStdString ( ) ) ;
2012-01-18 15:31:30 -05:00
case TYPE_CERTIFICATE :
return QObject : : tr ( " Click to add this RetroShare cert to your GPG keyring \n and open the Make Friend Wizard. \n " ) + QString ( " GPG Id = " ) + GPGId ( ) + QString ( " \n SSLId = " ) + SSLId ( ) ;
2011-05-01 18:26:41 -04:00
}
return " " ;
}
2011-10-22 07:15:30 -04:00
static QString encodeItem ( QString item )
{
return item . replace ( " " , " %20 " ) ;
}
2011-10-08 13:49:06 -04:00
QString RetroShareLink : : toString ( ) const
2010-03-10 16:38:26 -05:00
{
2010-07-15 07:25:34 -04:00
switch ( _type ) {
case TYPE_UNKNOWN :
break ;
case TYPE_FILE :
2010-11-18 11:31:44 -05:00
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_FILE ) ;
2011-10-22 07:15:30 -04:00
url . addQueryItem ( FILE_NAME , encodeItem ( _name ) ) ;
2010-11-18 11:31:44 -05:00
url . addQueryItem ( FILE_SIZE , QString : : number ( _size ) ) ;
url . addQueryItem ( FILE_HASH , _hash ) ;
return url . toString ( ) ;
}
2010-07-15 07:25:34 -04:00
case TYPE_PERSON :
2010-11-18 11:31:44 -05:00
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_PERSON ) ;
2011-10-22 07:15:30 -04:00
url . addQueryItem ( PERSON_NAME , encodeItem ( _name ) ) ;
2010-11-18 11:31:44 -05:00
url . addQueryItem ( PERSON_HASH , _hash ) ;
2011-04-19 15:42:44 -04:00
return url . toString ( ) ;
}
case TYPE_FORUM :
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_FORUM ) ;
2011-10-22 07:15:30 -04:00
url . addQueryItem ( FORUM_NAME , encodeItem ( _name ) ) ;
2011-04-19 15:42:44 -04:00
url . addQueryItem ( FORUM_ID , _hash ) ;
if ( ! _msgId . isEmpty ( ) ) {
url . addQueryItem ( FORUM_MSGID , _msgId ) ;
}
return url . toString ( ) ;
}
case TYPE_CHANNEL :
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_CHANNEL ) ;
2011-10-22 07:15:30 -04:00
url . addQueryItem ( CHANNEL_NAME , encodeItem ( _name ) ) ;
2011-04-19 15:42:44 -04:00
url . addQueryItem ( CHANNEL_ID , _hash ) ;
if ( ! _msgId . isEmpty ( ) ) {
url . addQueryItem ( CHANNEL_MSGID , _msgId ) ;
}
2011-05-04 06:22:49 -04:00
return url . toString ( ) ;
}
case TYPE_SEARCH :
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_SEARCH ) ;
2011-10-22 07:15:30 -04:00
url . addQueryItem ( SEARCH_KEYWORDS , encodeItem ( _name ) ) ;
2011-05-04 06:22:49 -04:00
2011-05-07 19:14:09 -04:00
return url . toString ( ) ;
}
case TYPE_MESSAGE :
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_MESSAGE ) ;
url . addQueryItem ( MESSAGE_ID , _hash ) ;
if ( _subject . isEmpty ( ) = = false ) {
2011-10-22 07:15:30 -04:00
url . addQueryItem ( MESSAGE_SUBJECT , encodeItem ( _subject ) ) ;
2011-05-07 19:14:09 -04:00
}
2010-11-18 11:31:44 -05:00
return url . toString ( ) ;
}
2012-01-18 15:31:30 -05:00
case TYPE_CERTIFICATE :
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_CERTIFICATE ) ;
url . addQueryItem ( CERTIFICATE_SSLID , _SSLid ) ;
url . addQueryItem ( CERTIFICATE_GPG_ID , _GPGid ) ;
url . addQueryItem ( CERTIFICATE_GPG_BASE64 , _GPGBase64String ) ;
url . addQueryItem ( CERTIFICATE_GPG_CHECKSUM , _GPGBase64CheckSum ) ;
url . addQueryItem ( CERTIFICATE_LOCATION , encodeItem ( _location ) ) ;
url . addQueryItem ( CERTIFICATE_NAME , encodeItem ( _name ) ) ;
return url . toString ( ) ;
}
2010-07-15 07:25:34 -04:00
}
return " " ;
2010-03-10 16:38:26 -05:00
}
2010-07-15 07:25:34 -04:00
QString RetroShareLink : : niceName ( ) const
{
if ( type ( ) = = TYPE_PERSON ) {
2011-07-17 19:07:29 -04:00
return PeerDefs : : rsid ( name ( ) . toUtf8 ( ) . constData ( ) , hash ( ) . toStdString ( ) ) ;
2010-07-15 07:25:34 -04:00
}
2012-01-18 15:31:30 -05:00
if ( type ( ) = = TYPE_CERTIFICATE )
return QString ( " RetroShare Certificate ( " ) + _name + " , @ " + _location + " ) " ; // should add SSL id there
2010-07-15 07:25:34 -04:00
return name ( ) ;
}
2010-03-15 08:57:08 -04:00
QString RetroShareLink : : toHtml ( ) const
2010-03-22 15:46:58 -04:00
{
2011-10-08 13:49:06 -04:00
QString html = " <a href= \" " + toString ( ) + " \" " ;
2011-05-01 18:26:41 -04:00
QString linkTitle = title ( ) ;
if ( ! linkTitle . isEmpty ( ) ) {
html + = " title= \" " + linkTitle + " \" " ;
}
2011-05-06 11:04:35 -04:00
html + = " > " + niceName ( ) + " </a> " ;
2011-05-01 18:26:41 -04:00
return html ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
2010-03-22 15:46:58 -04:00
QString RetroShareLink : : toHtmlFull ( ) const
2010-03-15 08:57:08 -04:00
{
2011-10-08 13:49:06 -04:00
return QString ( " <a href= \" " ) + toString ( ) + " \" > " + toString ( ) + " </a> " ;
2010-03-15 08:57:08 -04:00
}
2010-03-10 16:38:26 -05:00
2010-08-06 11:31:30 -04:00
QString RetroShareLink : : toHtmlSize ( ) const
{
2011-12-10 16:38:38 -05:00
QString size = QString ( " (%1) " ) . arg ( misc : : friendlyUnit ( _size ) ) ;
2011-12-10 16:59:42 -05:00
if ( type ( ) = = TYPE_FILE & & RsCollectionFile : : isCollectionFile ( name ( ) ) ) {
2011-12-10 16:38:38 -05:00
FileInfo finfo ;
if ( rsFiles - > FileDetails ( hash ( ) . toStdString ( ) , RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL , finfo ) ) {
RsCollectionFile collection ;
if ( collection . load ( QString : : fromUtf8 ( finfo . path . c_str ( ) ) , false ) ) {
size + = QString ( " [%1] " ) . arg ( misc : : friendlyUnit ( collection . size ( ) ) ) ;
}
}
}
QString link = QString ( " <a href= \" %1 \" >%2</a> <font color= \" blue \" >%3</font> " ) . arg ( toString ( ) ) . arg ( name ( ) ) . arg ( size ) ;
return link ;
2010-08-06 11:31:30 -04:00
}
2010-03-10 16:38:26 -05:00
bool RetroShareLink : : checkName ( const QString & name )
{
2010-07-15 07:25:34 -04:00
if ( name = = " " )
return false ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
for ( int i = 0 ; i < name . length ( ) ; + + i )
{
QChar : : Category cat ( name [ i ] . category ( ) ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
if ( cat = = QChar : : Separator_Line
| | cat = = QChar : : Other_NotAssigned
)
{
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " Unwanted category " < < cat < < " at place " < < i < < " in string \" " < < name . toStdString ( ) < < " \" " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-07-15 07:25:34 -04:00
return false ;
}
}
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
return true ;
2010-03-10 16:38:26 -05:00
}
2010-03-10 18:09:35 -05:00
QUrl RetroShareLink : : toUrl ( ) const
{
2011-10-08 13:49:06 -04:00
return QUrl : : fromEncoded ( toString ( ) . toUtf8 ( ) . constData ( ) ) ;
2010-03-10 18:09:35 -05:00
}
2010-03-10 16:38:26 -05:00
bool RetroShareLink : : checkHash ( const QString & hash )
{
2010-07-15 07:25:34 -04:00
if ( hash . length ( ) ! = 40 )
return false ;
QByteArray qb ( hash . toAscii ( ) ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
for ( int i = 0 ; i < qb . length ( ) ; + + i )
{
unsigned char b ( qb [ i ] ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
if ( ! ( ( b > 47 & & b < 58 ) | | ( b > 96 & & b < 103 ) ) )
return false ;
}
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
return true ;
}
2010-03-10 16:38:26 -05:00
2011-09-11 18:07:24 -04:00
static void processList ( QStringList & list , const QString & textSingular , const QString & textPlural , QString & result )
2010-07-15 07:25:34 -04:00
{
2011-09-11 18:07:24 -04:00
if ( list . size ( ) = = 0 ) {
return ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
if ( list . size ( ) = = 1 ) {
result + = " " + textSingular + " : " ;
} else {
result + = " " + textPlural + " : " ;
}
result + = " <p style='margin-left: 5px; margin-top: 0px'> " ;
QStringList : : iterator it ;
for ( it = list . begin ( ) ; it ! = list . end ( ) ; + + it ) {
if ( it ! = list . begin ( ) ) {
result + = " , " ;
}
result + = * it ;
}
result + = " </p> " ;
}
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
/*static*/ int RetroShareLink : : process ( QList < RetroShareLink > & linksIn , uint flag /*= RSLINK_PROCESS_NOTIFY_ALL*/ )
{
QList < RetroShareLink > : : iterator linkIt ;
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
/* filter dublicate links */
QList < RetroShareLink > links ;
for ( linkIt = linksIn . begin ( ) ; linkIt ! = linksIn . end ( ) ; linkIt + + ) {
if ( links . contains ( * linkIt ) ) {
continue ;
}
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
links . append ( * linkIt ) ;
}
2010-09-24 17:01:13 -04:00
2011-09-11 18:07:24 -04:00
if ( flag & RSLINK_PROCESS_NOTIFY_ASK ) {
/* ask for some types of link */
QStringList fileAdd ;
QStringList personAdd ;
for ( linkIt = links . begin ( ) ; linkIt ! = links . end ( ) ; linkIt + + ) {
RetroShareLink & link = * linkIt ;
if ( link . valid ( ) = = false ) {
continue ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
switch ( link . type ( ) ) {
case TYPE_UNKNOWN :
case TYPE_FORUM :
case TYPE_CHANNEL :
case TYPE_SEARCH :
case TYPE_MESSAGE :
// no need to ask
break ;
case TYPE_FILE :
fileAdd . append ( link . name ( ) ) ;
break ;
case TYPE_PERSON :
personAdd . append ( PeerDefs : : rsid ( link . name ( ) . toUtf8 ( ) . constData ( ) , link . hash ( ) . toStdString ( ) ) ) ;
break ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
}
2011-05-07 19:14:09 -04:00
2011-09-11 18:07:24 -04:00
QString content ;
if ( fileAdd . size ( ) ) {
processList ( fileAdd , QObject : : tr ( " Add file " ) , QObject : : tr ( " Add files " ) , content ) ;
}
if ( personAdd . size ( ) ) {
processList ( personAdd , QObject : : tr ( " Add friend " ) , QObject : : tr ( " Add friends " ) , content ) ;
}
if ( content . isEmpty ( ) = = false ) {
QString question = " <html><body> " ;
if ( links . size ( ) = = 1 ) {
question + = QObject : : tr ( " Do you want to process the link ? " ) ;
} else {
question + = QObject : : tr ( " Do you want to process %1 links ? " ) . arg ( links . size ( ) ) ;
}
question + = " <br><br> " + content + " </body></html> " ;
QMessageBox mb ( QObject : : tr ( " Confirmation " ) , question , QMessageBox : : Question , QMessageBox : : Yes , QMessageBox : : No , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
if ( mb . exec ( ) = = QMessageBox : : No ) {
return 0 ;
2011-05-07 19:14:09 -04:00
}
}
2011-09-11 18:07:24 -04:00
}
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
int countInvalid = 0 ;
int countUnknown = 0 ;
bool needNotifySuccess = false ;
// file
QStringList fileAdded ;
QStringList fileExist ;
// person
QStringList personAdded ;
QStringList personExist ;
QStringList personFailed ;
QStringList personNotFound ;
// forum
QStringList forumFound ;
QStringList forumMsgFound ;
QStringList forumUnknown ;
QStringList forumMsgUnknown ;
// forum
QStringList channelFound ;
QStringList channelMsgFound ;
QStringList channelUnknown ;
QStringList channelMsgUnknown ;
// search
QStringList searchStarted ;
// message
QStringList messageStarted ;
QStringList messageReceipientNotAccepted ;
QStringList messageReceipientUnknown ;
2012-01-18 15:31:30 -05:00
// Certificate
QStringList GPGBase64Strings ;
QStringList SSLIds ;
2011-09-11 18:07:24 -04:00
// summary
QList < QStringList * > processedList ;
QList < QStringList * > errorList ;
processedList < < & fileAdded < < & personAdded < < & forumFound < < & channelFound < < & searchStarted < < & messageStarted ;
errorList < < & fileExist < < & personExist < < & personFailed < < & personNotFound < < & forumUnknown < < & forumMsgUnknown < < & channelUnknown < < & channelMsgUnknown < < & messageReceipientNotAccepted < < & messageReceipientUnknown ;
// not needed: forumFound, channelFound, messageStarted
for ( linkIt = links . begin ( ) ; linkIt ! = links . end ( ) ; linkIt + + ) {
RetroShareLink & link = * linkIt ;
if ( link . valid ( ) = = false ) {
std : : cerr < < " RetroShareLink::process invalid request " < < std : : endl ;
countInvalid + + ;
continue ;
}
2012-01-18 15:31:30 -05:00
switch ( link . type ( ) )
{
case TYPE_UNKNOWN :
countUnknown + + ;
break ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_CERTIFICATE :
{
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process certificate. " < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2012-01-18 15:31:30 -05:00
needNotifySuccess = true ;
2010-07-15 07:25:34 -04:00
2012-01-18 15:31:30 -05:00
QString RS_Certificate ;
RS_Certificate + = " -----BEGIN PGP PUBLIC KEY BLOCK----- \n " ;
RS_Certificate + = " Version: Retroshare Generated cert. \n " ;
RS_Certificate + = " \n " ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
QString radix = link . GPGRadix64Key ( ) ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
while ( radix . size ( ) > 64 )
{
RS_Certificate + = radix . left ( 64 ) + " \n " ;
radix = radix . right ( radix . size ( ) - 64 ) ;
}
RS_Certificate + = radix . left ( 64 ) + " \n " ;
RS_Certificate + = " = " + link . GPGBase64CheckSum ( ) + " \n " ;
RS_Certificate + = " -----END PGP PUBLIC KEY BLOCK----- \n " ;
RS_Certificate + = " --SSLID-- " + link . SSLId ( ) + " ;--LOCATION-- " + link . location ( ) + " ; \n " ;
std : : cerr < < " Usign this certificate: " < < std : : endl ;
std : : cerr < < RS_Certificate . toStdString ( ) < < std : : endl ;
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
ConnectFriendWizard ( NULL , RS_Certificate ) . exec ( ) ;
needNotifySuccess = false ;
2011-05-07 19:14:09 -04:00
}
2012-01-18 15:31:30 -05:00
break ;
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_FILE :
{
2011-09-11 18:07:24 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process FileRequest : fileName : " < < link . name ( ) . toUtf8 ( ) . constData ( ) < < " . fileHash : " < < link . hash ( ) . toStdString ( ) < < " . fileSize : " < < link . size ( ) < < std : : endl ;
2011-09-11 18:07:24 -04:00
# endif
2012-01-18 15:31:30 -05:00
needNotifySuccess = true ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
// Get a list of available direct sources, in case the file is browsable only.
std : : list < std : : string > srcIds ;
FileInfo finfo ;
rsFiles - > FileDetails ( link . hash ( ) . toStdString ( ) , RS_FILE_HINTS_REMOTE , finfo ) ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
for ( std : : list < TransferInfo > : : const_iterator it ( finfo . peers . begin ( ) ) ; it ! = finfo . peers . end ( ) ; + + it )
{
# ifdef DEBUG_RSLINK
std : : cerr < < " adding peerid " < < ( * it ) . peerId < < std : : endl ;
# endif
srcIds . push_back ( ( * it ) . peerId ) ;
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
if ( rsFiles - > FileRequest ( link . name ( ) . toUtf8 ( ) . constData ( ) , link . hash ( ) . toStdString ( ) , link . size ( ) , " " , RS_FILE_HINTS_NETWORK_WIDE , srcIds ) ) {
fileAdded . append ( link . name ( ) ) ;
} else {
fileExist . append ( link . name ( ) ) ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2012-01-18 15:31:30 -05:00
case TYPE_PERSON :
{
2011-04-19 15:42:44 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process FriendRequest : name : " < < link . name ( ) . toStdString ( ) < < " . id : " < < link . hash ( ) . toStdString ( ) < < std : : endl ;
2011-04-19 15:42:44 -04:00
# endif
2012-01-18 15:31:30 -05:00
needNotifySuccess = true ;
RsPeerDetails detail ;
if ( rsPeers - > getPeerDetails ( link . hash ( ) . toStdString ( ) , detail ) ) {
if ( detail . gpg_id = = rsPeers - > getGPGOwnId ( ) ) {
// it's me, do nothing
break ;
}
if ( detail . accept_connection ) {
// peer connection is already accepted
personExist . append ( PeerDefs : : rsid ( detail ) ) ;
break ;
}
if ( rsPeers - > addFriend ( " " , link . hash ( ) . toStdString ( ) ) ) {
ConfCertDialog : : loadAll ( ) ;
personAdded . append ( PeerDefs : : rsid ( detail ) ) ;
break ;
}
personFailed . append ( PeerDefs : : rsid ( link . name ( ) . toUtf8 ( ) . constData ( ) , link . hash ( ) . toStdString ( ) ) ) ;
break ;
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
personNotFound . append ( PeerDefs : : rsid ( link . name ( ) . toUtf8 ( ) . constData ( ) , link . hash ( ) . toStdString ( ) ) ) ;
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2012-01-18 15:31:30 -05:00
case TYPE_FORUM :
{
# ifdef DEBUG_RSLINK
std : : cerr < < " RetroShareLink::process ForumRequest : name : " < < link . name ( ) . toStdString ( ) < < " . id : " < < link . hash ( ) . toStdString ( ) < < " . msgId : " < < link . msgId ( ) . toStdString ( ) < < std : : endl ;
# endif
ForumInfo fi ;
if ( ! rsForums - > getForumInfo ( link . id ( ) . toStdString ( ) , fi ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
forumUnknown . append ( link . name ( ) ) ;
} else {
forumMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
ForumMsgInfo msg ;
if ( ! link . msgId ( ) . isEmpty ( ) ) {
if ( ! rsForums - > getForumMessage ( fi . forumId , link . msgId ( ) . toStdString ( ) , msg ) ) {
forumMsgUnknown . append ( link . name ( ) ) ;
break ;
}
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
MainWindow : : showWindow ( MainWindow : : Forums ) ;
ForumsDialog * forumsDialog = dynamic_cast < ForumsDialog * > ( MainWindow : : getPage ( MainWindow : : Forums ) ) ;
if ( ! forumsDialog ) {
return false ;
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
if ( forumsDialog - > navigate ( fi . forumId , msg . msgId ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
forumFound . append ( link . name ( ) ) ;
} else {
forumMsgFound . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
} else {
2012-01-18 15:31:30 -05:00
if ( link . msgId ( ) . isEmpty ( ) ) {
forumUnknown . append ( link . name ( ) ) ;
} else {
forumMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
break ;
2011-09-11 18:07:24 -04:00
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_CHANNEL :
{
2011-04-19 15:42:44 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process ChannelRequest : name : " < < link . name ( ) . toStdString ( ) < < " . id : " < < link . hash ( ) . toStdString ( ) < < " . msgId : " < < link . msgId ( ) . toStdString ( ) < < std : : endl ;
2011-04-19 15:42:44 -04:00
# endif
2012-01-18 15:31:30 -05:00
ChannelInfo ci ;
if ( ! rsChannels - > getChannelInfo ( link . id ( ) . toStdString ( ) , ci ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
channelUnknown . append ( link . name ( ) ) ;
} else {
channelMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
ChannelMsgInfo msg ;
if ( ! link . msgId ( ) . isEmpty ( ) ) {
if ( ! rsChannels - > getChannelMessage ( ci . channelId , link . msgId ( ) . toStdString ( ) , msg ) ) {
channelMsgUnknown . append ( link . name ( ) ) ;
break ;
}
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
MainWindow : : showWindow ( MainWindow : : Channels ) ;
ChannelFeed * channelFeed = dynamic_cast < ChannelFeed * > ( MainWindow : : getPage ( MainWindow : : Channels ) ) ;
if ( ! channelFeed ) {
return false ;
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
if ( channelFeed - > navigate ( ci . channelId , msg . msgId ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
channelFound . append ( link . name ( ) ) ;
} else {
channelMsgFound . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
} else {
2012-01-18 15:31:30 -05:00
if ( link . msgId ( ) . isEmpty ( ) ) {
channelUnknown . append ( link . name ( ) ) ;
} else {
channelMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
break ;
2011-09-11 18:07:24 -04:00
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_SEARCH :
{
2011-05-07 19:14:09 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process SearchRequest : string : " < < link . name ( ) . toStdString ( ) < < std : : endl ;
2011-05-07 19:14:09 -04:00
# endif
2011-04-19 15:42:44 -04:00
2012-01-18 15:31:30 -05:00
MainWindow : : showWindow ( MainWindow : : Search ) ;
SearchDialog * searchDialog = dynamic_cast < SearchDialog * > ( MainWindow : : getPage ( MainWindow : : Search ) ) ;
if ( ! searchDialog ) {
break ;
}
searchDialog - > searchKeywords ( link . name ( ) ) ;
searchStarted . append ( link . name ( ) ) ;
2011-09-11 18:07:24 -04:00
break ;
}
2011-04-19 15:42:44 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_MESSAGE :
{
2011-05-04 06:22:49 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process MessageRequest : id : " < < link . hash ( ) . toStdString ( ) < < " , subject : " < < link . name ( ) . toStdString ( ) < < std : : endl ;
2011-05-04 06:22:49 -04:00
# endif
2012-01-18 15:31:30 -05:00
RsPeerDetails detail ;
if ( rsPeers - > getPeerDetails ( link . hash ( ) . toStdString ( ) , detail ) ) {
if ( detail . accept_connection | | detail . id = = rsPeers - > getOwnId ( ) | | detail . id = = rsPeers - > getGPGOwnId ( ) ) {
MessageComposer * msg = MessageComposer : : newMsg ( ) ;
msg - > addRecipient ( MessageComposer : : TO , detail . id , false ) ;
if ( link . subject ( ) . isEmpty ( ) = = false ) {
msg - > insertTitleText ( link . subject ( ) ) ;
}
msg - > show ( ) ;
messageStarted . append ( PeerDefs : : nameWithLocation ( detail ) ) ;
} else {
messageReceipientNotAccepted . append ( PeerDefs : : nameWithLocation ( detail ) ) ;
2011-09-11 18:07:24 -04:00
}
} else {
2012-01-18 15:31:30 -05:00
messageReceipientUnknown . append ( PeerDefs : : rsidFromId ( link . hash ( ) . toStdString ( ) ) ) ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
break ;
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
default :
std : : cerr < < " RetroShareLink::process unknown type: " < < link . type ( ) < < std : : endl ;
countUnknown + + ;
2011-05-07 19:14:09 -04:00
}
}
2011-05-04 06:22:49 -04:00
2011-09-11 18:07:24 -04:00
int countProcessed = 0 ;
int countError = 0 ;
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
QList < QStringList * > : : iterator listIt ;
for ( listIt = processedList . begin ( ) ; listIt ! = processedList . end ( ) ; + + listIt ) {
countProcessed + = ( * listIt ) - > size ( ) ;
}
for ( listIt = errorList . begin ( ) ; listIt ! = errorList . end ( ) ; + + listIt ) {
countError + = ( * listIt ) - > size ( ) ;
}
// success notify needed ?
if ( needNotifySuccess = = false ) {
flag & = ~ RSLINK_PROCESS_NOTIFY_SUCCESS ;
}
// error notify needed ?
if ( countError = = 0 ) {
flag & = ~ RSLINK_PROCESS_NOTIFY_ERROR ;
}
QString result ;
if ( flag & ( RSLINK_PROCESS_NOTIFY_SUCCESS | RSLINK_PROCESS_NOTIFY_ERROR ) ) {
result + = ( links . count ( ) = = 1 ? QObject : : tr ( " %1 of %2 RetroShare link processed. " ) : QObject : : tr ( " %1 of %2 RetroShare links processed. " ) ) . arg ( countProcessed ) . arg ( links . count ( ) ) + " <br><br> " ;
}
// file
if ( flag & RSLINK_PROCESS_NOTIFY_SUCCESS ) {
if ( fileAdded . size ( ) ) {
processList ( fileAdded , QObject : : tr ( " File added " ) , QObject : : tr ( " Files added " ) , result ) ;
}
}
2011-05-07 19:14:09 -04:00
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
2011-09-11 18:07:24 -04:00
if ( fileExist . size ( ) ) {
processList ( fileExist , QObject : : tr ( " File exist " ) , QObject : : tr ( " Files exist " ) , result ) ;
}
}
// person
if ( flag & RSLINK_PROCESS_NOTIFY_SUCCESS ) {
if ( personAdded . size ( ) ) {
processList ( personAdded , QObject : : tr ( " Friend added " ) , QObject : : tr ( " Friends added " ) , result ) ;
}
}
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( personExist . size ( ) ) {
processList ( personExist , QObject : : tr ( " Friend exist " ) , QObject : : tr ( " Friends exist " ) , result ) ;
}
if ( personFailed . size ( ) ) {
processList ( personFailed , QObject : : tr ( " Friend not added " ) , QObject : : tr ( " Friends not added " ) , result ) ;
}
if ( personNotFound . size ( ) ) {
processList ( personNotFound , QObject : : tr ( " Friend not found " ) , QObject : : tr ( " Friends not found " ) , result ) ;
}
}
// forum
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( forumUnknown . size ( ) ) {
processList ( forumUnknown , QObject : : tr ( " Forum not found " ) , QObject : : tr ( " Forums not found " ) , result ) ;
}
if ( forumMsgUnknown . size ( ) ) {
processList ( forumMsgUnknown , QObject : : tr ( " Forum message not found " ) , QObject : : tr ( " Forum messages not found " ) , result ) ;
}
}
// channel
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( channelUnknown . size ( ) ) {
processList ( channelUnknown , QObject : : tr ( " Channel not found " ) , QObject : : tr ( " Channels not found " ) , result ) ;
}
if ( channelMsgUnknown . size ( ) ) {
processList ( channelMsgUnknown , QObject : : tr ( " Channel message not found " ) , QObject : : tr ( " Channel messages not found " ) , result ) ;
}
}
// message
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( messageReceipientNotAccepted . size ( ) ) {
processList ( messageReceipientNotAccepted , QObject : : tr ( " Receipient not accepted " ) , QObject : : tr ( " Receipients not accepted " ) , result ) ;
}
if ( messageReceipientUnknown . size ( ) ) {
processList ( messageReceipientUnknown , QObject : : tr ( " Unkown receipient " ) , QObject : : tr ( " Unkown receipients " ) , result ) ;
}
}
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( countUnknown ) {
result + = QString ( " <br>%1: %2 " ) . arg ( QObject : : tr ( " Malformed links " ) ) . arg ( countUnknown ) ;
}
if ( countInvalid ) {
result + = QString ( " <br>%1: %2 " ) . arg ( QObject : : tr ( " Invalid links " ) ) . arg ( countInvalid ) ;
}
}
if ( result . isEmpty ( ) = = false ) {
QMessageBox mb ( QObject : : tr ( " Result " ) , " <html><body> " + result + " </body></html> " , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
2011-05-07 19:14:09 -04:00
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
2011-09-11 18:07:24 -04:00
return 0 ;
2010-03-10 16:38:26 -05:00
}
2011-09-11 18:07:24 -04:00
/*static*/ int RetroShareLink : : process ( QStringList & urls , RetroShareLink : : enumType type /*= RetroShareLink::TYPE_UNKNOWN*/ , uint flag /*= RSLINK_PROCESS_NOTIFY_ALL*/ )
2011-05-15 16:21:14 -04:00
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2011-05-15 16:21:14 -04:00
for ( QStringList : : iterator it = urls . begin ( ) ; it ! = urls . end ( ) ; it + + ) {
RetroShareLink link ( * it ) ;
if ( link . valid ( ) & & ( type = = RetroShareLink : : TYPE_UNKNOWN | | link . type ( ) = = type ) ) {
2011-09-11 18:07:24 -04:00
links . append ( link ) ;
2011-05-15 16:21:14 -04:00
}
}
2011-09-11 18:07:24 -04:00
return process ( links , flag ) ;
2011-05-15 16:21:14 -04:00
}
2011-09-11 18:07:24 -04:00
void RSLinkClipboard : : copyLinks ( const QList < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
QString res ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2010-07-15 07:25:34 -04:00
res + = links [ i ] . toString ( ) + " \n " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QApplication : : clipboard ( ) - > setText ( res ) ;
2010-03-22 15:46:58 -04:00
}
2011-09-11 18:07:24 -04:00
void RSLinkClipboard : : pasteLinks ( QList < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
return parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
}
2011-09-11 18:07:24 -04:00
void RSLinkClipboard : : parseClipboard ( QList < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
// parse clipboard for links.
//
links . clear ( ) ;
QString text = QApplication : : clipboard ( ) - > text ( ) ;
std : : cerr < < " Parsing clipboard: " < < text . toStdString ( ) < < std : : endl ;
2011-04-19 15:42:44 -04:00
QRegExp rx ( QString ( " retroshare://(%1) [ ^ \ r \ n ] + " ).arg(HOST_REGEXP)) ;
2010-07-15 07:25:34 -04:00
int pos = 0 ;
while ( ( pos = rx . indexIn ( text , pos ) ) ! = - 1 )
{
QString url ( text . mid ( pos , rx . matchedLength ( ) ) ) ;
RetroShareLink link ( url ) ;
if ( link . valid ( ) )
{
// check that the link is not already in the list:
bool already = false ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2010-07-15 07:25:34 -04:00
if ( links [ i ] = = link )
{
2011-09-11 18:07:24 -04:00
already = true ;
break ;
}
2010-07-15 07:25:34 -04:00
if ( ! already )
{
links . push_back ( link ) ;
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " captured link: " < < link . toString ( ) . toStdString ( ) < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
}
}
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
else
std : : cerr < < " invalid link " < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
pos + = rx . matchedLength ( ) ;
}
2010-03-22 15:46:58 -04:00
}
QString RSLinkClipboard : : toString ( )
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2010-07-15 07:25:34 -04:00
res + = links [ i ] . toString ( ) + " \n " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
QString RSLinkClipboard : : toHtml ( )
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2011-10-05 12:57:33 -04:00
res + = links [ i ] . toHtml ( ) + " <br> " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
2010-03-22 15:46:58 -04:00
QString RSLinkClipboard : : toHtmlFull ( )
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2011-10-05 12:57:33 -04:00
res + = links [ i ] . toHtmlFull ( ) + " <br> " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
bool RSLinkClipboard : : empty ( RetroShareLink : : enumType type /*= RetroShareLink::TYPE_UNKNOWN*/ )
2010-03-22 15:46:58 -04:00
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
parseClipboard ( links ) ;
if ( type = = RetroShareLink : : TYPE_UNKNOWN ) {
return links . empty ( ) ;
}
2011-09-11 18:07:24 -04:00
for ( QList < RetroShareLink > : : iterator link = links . begin ( ) ; link ! = links . end ( ) ; link + + ) {
2010-07-15 07:25:34 -04:00
if ( link - > type ( ) = = type ) {
return false ;
}
}
return true ;
2010-03-22 15:46:58 -04:00
}
2011-09-11 18:07:24 -04:00
/*static*/ int RSLinkClipboard : : process ( RetroShareLink : : enumType type /*= RetroShareLink::TYPE_UNKNOWN*/ , uint flag /*= RSLINK_PROCESS_NOTIFY_ALL*/ )
2010-07-15 07:25:34 -04:00
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
pasteLinks ( links ) ;
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > linksToProcess ;
for ( int i = 0 ; i < links . size ( ) ; i + + ) {
2010-07-15 07:25:34 -04:00
if ( links [ i ] . valid ( ) & & ( type = = RetroShareLink : : TYPE_UNKNOWN | | links [ i ] . type ( ) = = type ) ) {
2011-09-11 18:07:24 -04:00
linksToProcess . append ( links [ i ] ) ;
2010-07-15 07:25:34 -04:00
}
}
2011-09-11 18:07:24 -04:00
if ( linksToProcess . size ( ) = = 0 ) {
return 0 ;
}
return RetroShareLink : : process ( linksToProcess , flag ) ;
2010-07-15 07:25:34 -04:00
}
2012-01-18 15:31:30 -05:00