~ubuntu-branches/ubuntu/karmic/choqok/karmic

« back to all changes in this revision

Viewing changes to src/twittersearch.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi, Alessandro Ghersi, Christian Mangold
  • Date: 2009-08-11 22:29:59 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090811222959-7tnr98ptcnyx3pjg
Tags: 0.6.6-0ubuntu1
[Alessandro Ghersi]
* New upstream release
  - Bump Standards-Version to 3.8.2
  - Long description formatted to fit in 80 characters

[Christian Mangold]
* Improve long description
* Update Maintainer, package is in main now
* Add a watch file

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    This file is part of Choqok, the KDE micro-blogging client
3
 
 
4
 
    Copyright (C) 2008-2009 Mehrdad Momeny <mehrdad.momeny@gmail.com>
5
 
 
6
 
    This program is free software; you can redistribute it and/or
7
 
    modify it under the terms of the GNU General Public License as
8
 
    published by the Free Software Foundation; either version 2 of
9
 
    the License or (at your option) version 3 or any later version
10
 
    accepted by the membership of KDE e.V. (or its successor approved
11
 
    by the membership of KDE e.V.), which shall act as a proxy
12
 
    defined in Section 14 of version 3 of the license.
13
 
 
14
 
 
15
 
    This program is distributed in the hope that it will be useful,
16
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 
    GNU General Public License for more details.
19
 
 
20
 
    You should have received a copy of the GNU General Public License
21
 
    along with this program; if not, see http://www.gnu.org/licenses/
22
 
 
23
 
*/
24
 
 
25
 
#include "twittersearch.h"
26
 
 
27
 
#include <KDE/KLocale>
28
 
#include <QDomDocument>
29
 
#include <kio/jobclasses.h>
30
 
#include <kio/job.h>
31
 
#include <kurl.h>
32
 
#include <kio/netaccess.h>
33
 
#include <kdebug.h>
34
 
 
35
 
#include "backend.h"
36
 
 
37
 
TwitterSearch::TwitterSearch( Account* account, const QString searchUrl, QObject *parent ) :
38
 
        Search(account, searchUrl, parent)
39
 
{
40
 
    kDebug();
41
 
    mSearchTypes[CustomSearch].first = i18n( "Custom Search" );
42
 
    mSearchTypes[CustomSearch].second = true;
43
 
 
44
 
    mSearchTypes[ToUser].first = i18nc( "Tweets are Twitter posts",  "Tweets To This User" );
45
 
    mSearchTypes[ToUser].second = true;
46
 
 
47
 
    mSearchTypes[FromUser].first = i18nc( "Tweets are Twitter posts", "Tweets From This User" );
48
 
    mSearchTypes[FromUser].second = true;
49
 
 
50
 
    mSearchTypes[ReferenceUser].first = i18nc( "Tweets are Twitter posts", "Tweets Including This User's Name" );
51
 
    mSearchTypes[ReferenceUser].second = true;
52
 
 
53
 
    mSearchTypes[ReferenceHashtag].first = i18nc( "Tweets are Twitter posts", "Tweets Including This Hashtag" );
54
 
    mSearchTypes[ReferenceHashtag].second = true;
55
 
}
56
 
 
57
 
TwitterSearch::~TwitterSearch()
58
 
{
59
 
    kDebug();
60
 
}
61
 
 
62
 
KUrl TwitterSearch::buildUrl( QString query, int option, qulonglong sinceStatusId, qulonglong count, qulonglong page )
63
 
{
64
 
    kDebug();
65
 
    QString formattedQuery;
66
 
    switch ( option ) {
67
 
        case CustomSearch:
68
 
            formattedQuery = query;
69
 
            break;
70
 
        case ToUser:
71
 
            formattedQuery = "to:" + query;
72
 
            break;
73
 
        case FromUser:
74
 
            formattedQuery = "from:" + query;
75
 
            break;
76
 
        case ReferenceUser:
77
 
            formattedQuery = '@' + query;
78
 
            break;
79
 
        case ReferenceHashtag:
80
 
            formattedQuery = "#" + query;
81
 
            break;
82
 
        default:
83
 
            formattedQuery = query;
84
 
            break;
85
 
    };
86
 
    KUrl url( "http://search.twitter.com/search.atom" );
87
 
    url.addQueryItem("q", formattedQuery);
88
 
    if( sinceStatusId )
89
 
        url.addQueryItem( "since_id", QString::number( sinceStatusId ) );
90
 
    if( count && count <= 100 )
91
 
        url.addQueryItem( "rpp", QString::number( count ) );
92
 
    url.addQueryItem( "page", QString::number( page ) );
93
 
 
94
 
    return url;
95
 
}
96
 
 
97
 
void TwitterSearch::requestSearchResults( QString query, int option, qulonglong sinceStatusId, qulonglong count, qulonglong page )
98
 
{
99
 
    kDebug();
100
 
 
101
 
    KUrl url = buildUrl( query, option, sinceStatusId, count, page );
102
 
 
103
 
    KIO::StoredTransferJob *job = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo );
104
 
    if( !job ) {
105
 
        kDebug() << "Cannot create a http GET request!";
106
 
        emit error( i18n( "Unable to fetch search results." ) );
107
 
        return;
108
 
    }
109
 
 
110
 
    connect( job, SIGNAL( result( KJob* ) ), this, SLOT( searchResultsReturned( KJob* ) ) );
111
 
    job->start();
112
 
}
113
 
 
114
 
void TwitterSearch::searchResultsReturned( KJob* job )
115
 
{
116
 
    kDebug();
117
 
    if( job == 0 ) {
118
 
        kDebug() << "job is a null pointer";
119
 
        emit error( i18n( "Unable to fetch search results." ) );
120
 
        return;
121
 
    }
122
 
 
123
 
    if( job->error() ) {
124
 
        kError() << "Error: " << job->errorString();
125
 
        emit error( i18n( "Unable to fetch search results: %1", job->errorString() ) );
126
 
        return;
127
 
    }
128
 
    KIO::StoredTransferJob *jj = qobject_cast<KIO::StoredTransferJob *>( job );
129
 
    QList<Status>* statusList = parseAtom( jj->data() );
130
 
 
131
 
    emit searchResultsReceived( *statusList );
132
 
}
133
 
 
134
 
QList<Status>* TwitterSearch::parseAtom( const QByteArray &buffer )
135
 
{
136
 
    kDebug();
137
 
    QDomDocument document;
138
 
    QList<Status> *statusList = new QList<Status>;
139
 
 
140
 
    document.setContent( buffer );
141
 
 
142
 
    QDomElement root = document.documentElement();
143
 
 
144
 
    if ( root.tagName() != "feed" ) {
145
 
        kDebug() << "There is no feed element in Atom feed " << buffer.data();
146
 
        return statusList;
147
 
    }
148
 
 
149
 
    QDomNode node = root.firstChild();
150
 
    QString timeStr;
151
 
    while ( !node.isNull() ) {
152
 
        if ( node.toElement().tagName() != "entry" ) {
153
 
            node = node.nextSibling();
154
 
            continue;
155
 
        }
156
 
 
157
 
        QDomNode entryNode = node.firstChild();
158
 
        Status status;
159
 
        status.isDMessage = false;
160
 
 
161
 
        while ( !entryNode.isNull() ) {
162
 
            if ( entryNode.toElement().tagName() == "id" ) {
163
 
                // Fomatting example: "tag:search.twitter.com,2005:1235016836"
164
 
                int id = 0;
165
 
                sscanf( qPrintable( entryNode.toElement().text() ),
166
 
                        "tag:search.twitter.com,%*d:%d", &id);
167
 
                status.statusId = id;
168
 
            } else if ( entryNode.toElement().tagName() == "published" ) {
169
 
                // Formatting example: "2009-02-21T19:42:39Z"
170
 
                // Need to extract date in similar fashion to dateFromString
171
 
                int year, month, day, hour, minute, second;
172
 
                sscanf( qPrintable( entryNode.toElement().text() ),
173
 
                        "%d-%d-%dT%d:%d:%d%*s", &year, &month, &day, &hour, &minute, &second);
174
 
                QDateTime recognized( QDate( year, month, day), QTime( hour, minute, second ) );
175
 
                recognized.setTimeSpec( Qt::UTC );
176
 
                status.creationDateTime = recognized;
177
 
            } else if ( entryNode.toElement().tagName() == "title" ) {
178
 
                status.content = entryNode.toElement().text();
179
 
            } else if ( entryNode.toElement().tagName() == "twitter:source" ) {
180
 
                status.source = entryNode.toElement().text();
181
 
            } else if ( entryNode.toElement().tagName() == "link" &&
182
 
                        entryNode.toElement().attributeNode( "rel" ).value() == "image") {
183
 
 
184
 
                QDomAttr imageAttr = entryNode.toElement().attributeNode( "href" );
185
 
                status.user.profileImageUrl = imageAttr.value();
186
 
 
187
 
            } else if ( entryNode.toElement().tagName() == "author") {
188
 
 
189
 
                QDomNode userNode = entryNode.firstChild();
190
 
                while ( !userNode.isNull() )
191
 
                {
192
 
                    if ( userNode.toElement().tagName() == "name" )
193
 
                    {
194
 
                        QString fullName = userNode.toElement().text();
195
 
                        int bracketPos = fullName.indexOf( " ", 0 );
196
 
 
197
 
                        QString screenName = fullName.left( bracketPos );
198
 
                        QString name = fullName.right ( fullName.size() - bracketPos - 2 );
199
 
                        name.chop( 1 );
200
 
 
201
 
                        status.user.name = name;
202
 
                        status.user.screenName = screenName;
203
 
                    }
204
 
                    userNode = userNode.nextSibling();
205
 
                }
206
 
 
207
 
            }
208
 
 
209
 
            entryNode = entryNode.nextSibling();
210
 
        }
211
 
        status.isFavorited = false;
212
 
        status.isTruncated = false;
213
 
        status.replyToStatusId = 0;
214
 
        statusList->insert( 0, status );
215
 
        node = node.nextSibling();
216
 
    }
217
 
 
218
 
    return statusList;
219
 
}