26 #include <KIO/Scheduler>
28 #include <QDomDocument>
30 class PicofthedayFactory :
public DecorationFactory
41 KConfigGroup config( &_config,
"Picture of the Day Plugin" );
42 mThumbSize = config.readEntry(
"InitialThumbnailSize",
QSize( 120, 60 ) );
57 return i18n(
"<qt>This plugin provides the Wikipedia "
58 "<i>Picture of the Day</i>.</qt>" );
63 Element::List elements;
66 elements.append( element );
74 const QSize &initialThumbSize )
75 :
StoredElement( id ), mDate( date ), mThumbSize( initialThumbSize ),
76 mFirstStepCompleted( false ),
77 mSecondStepCompleted( false ),
78 mFirstStepJob( 0 ), mSecondStepJob( 0 ), mThirdStepJob( 0 )
80 setShortText( i18n(
"Loading..." ) );
81 setLongText( i18n(
"<qt>Loading <i>Picture of the Day</i>...</qt>" ) );
83 mTimer =
new QTimer(
this );
93 if ( !mFirstStepCompleted && !mFirstStepJob ) {
94 KUrl url = KUrl(
QLatin1String(
"http://en.wikipedia.org/w/index.php?title=Template:POTD/") +
98 mFirstStepJob = KIO::storedGet( url, KIO::NoReload, KIO::HideProgressInfo );
99 KIO::Scheduler::setJobPriority( mFirstStepJob, 1 );
101 connect( mFirstStepJob, SIGNAL(result(
KJob*)),
102 this, SLOT(step1Result(
KJob*)) );
112 void POTDElement::step1Result(
KJob *job )
114 if ( job->error() ) {
115 kWarning() <<
"POTD:" << mDate <<
": could not get POTD file name:" << job->errorString();
116 kDebug() <<
"POTD:" << mDate <<
": file name:" << mFileName;
117 kDebug() <<
"POTD:" << mDate <<
": full-size image:" << mFullSizeImageUrl.url();
118 kDebug() <<
"POTD:" << mDate <<
": thumbnail:" << mThumbUrl.url();
119 mFirstStepCompleted =
false;
124 KIO::StoredTransferJob *
const transferJob =
static_cast<KIO::StoredTransferJob*
>( job );
128 Q_FOREACH(
const QString &line, lines ) {
136 Q_FOREACH(
const QString &line, lines ) {
143 if ( !mDescription.
isEmpty() ) {
144 mLongText = mDescription;
146 mLongText = mFileName;
148 mLongText = i18n(
"Wikipedia POTD: %1", mLongText );
151 kDebug() <<
"FILENAME=" << mFileName;
152 kDebug() <<
"DESCRIPTION=" << mDescription;
154 mFirstStepCompleted =
true;
162 if ( !mSecondStepCompleted && !mSecondStepJob ) {
163 mUrl = KUrl(
QLatin1String(
"http://en.wikipedia.org/wiki/File:") + mFileName );
167 mShortText = i18n(
"Picture Page" );
170 mSecondStepJob = KIO::storedGet( mUrl, KIO::NoReload, KIO::HideProgressInfo );
171 KIO::Scheduler::setJobPriority( mSecondStepJob, 1 );
173 connect( mSecondStepJob, SIGNAL(result(
KJob*)),
174 this, SLOT(step2Result(
KJob*)) );
183 void POTDElement::step2Result(
KJob *job )
185 if ( job->error() ) {
186 kWarning() <<
"POTD:" << mDate <<
": could not get POTD image page:" << job->errorString();
187 kDebug() <<
"POTD:" << mDate <<
": file name:" << mFileName;
188 kDebug() <<
"POTD:" << mDate <<
": full-size image:" << mFullSizeImageUrl.url();
189 kDebug() <<
"POTD:" << mDate <<
": thumbnail:" << mThumbUrl.url();
190 mSecondStepCompleted =
false;
196 KIO::StoredTransferJob *
const transferJob =
static_cast<KIO::StoredTransferJob*
>( job );
200 transferJob->data().size() ) ) ) {
201 kWarning() <<
"POTD:" << mDate <<
": Wikipedia returned an invalid XML page for image"
208 for ( uint i=0; i<links.
length(); ++i ) {
211 QLatin1String(
"//upload.wikimedia.org/wikipedia/commons/" ) ) ) {
212 mFullSizeImageUrl = href;
220 for ( uint i=0; i<links.
length(); ++i ) {
234 kDebug() <<
"POTD:" << mDate <<
": h/w ratio:" << mHWRatio;
235 kDebug() <<
"POTD:" << mDate <<
": got POTD image page source:" << mFullSizeImageUrl;
237 if ( !mFullSizeImageUrl.isEmpty() ) {
238 mSecondStepCompleted =
true;
246 QString thumbUrl = fullSizeUrl.url();
249 QLatin1String(
"//upload.wikimedia.org/wikipedia/commons/thumb/\\1/\\2/") +
254 QLatin1String(
"//upload.wikimedia.org/wikipedia/commons/thumb/\\1/\\2") );
257 return KUrl( thumbUrl );
263 if ( mThirdStepJob ) {
264 mThirdStepJob->kill();
268 int thumbWidth = mThumbSize.
width();
269 int thumbHeight =
static_cast<int>( thumbWidth * mHWRatio );
270 if ( mThumbSize.
height() < thumbHeight ) {
275 thumbWidth /= ( thumbHeight / mThumbSize.
height() );
276 thumbHeight =
static_cast<int>( thumbWidth * mHWRatio );
278 mDlThumbSize =
QSize( thumbWidth, thumbHeight );
279 kDebug() <<
"POTD:" << mDate <<
": will download thumbnail of size" << mDlThumbSize;
282 thumbnailUrl( mFullSizeImageUrl, thumbWidth ).url().toLatin1() );
284 kDebug() <<
"POTD:" << mDate <<
": got POTD thumbnail URL:" << thumbUrl;
285 mThumbUrl = thumbUrl;
287 mThirdStepJob = KIO::storedGet( thumbUrl, KIO::NoReload, KIO::HideProgressInfo );
288 kDebug() <<
"POTD:" << mDate <<
": get" << thumbUrl;
289 KIO::Scheduler::setJobPriority( mThirdStepJob, 1 );
291 connect( mThirdStepJob, SIGNAL(result(
KJob*)),
292 this, SLOT(step3Result(
KJob*)) );
299 void POTDElement::step3Result(
KJob *job )
301 if ( job != mThirdStepJob ) {
306 if ( job->error() ) {
307 kWarning() <<
"POTD:" << mDate <<
": could not get POTD:" << job->errorString();
308 kDebug() <<
"POTD:" << mDate <<
": file name:" << mFileName;
309 kDebug() <<
"POTD:" << mDate <<
": full-size image:" << mFullSizeImageUrl.url();
310 kDebug() <<
"POTD:" << mDate <<
": thumbnail:" << mThumbUrl.url();
315 KIO::StoredTransferJob*
const transferJob =
static_cast<KIO::StoredTransferJob*
>( job );
316 if ( mPixmap.loadFromData( transferJob->data() ) ) {
317 kDebug() <<
"POTD:" << mDate <<
": got POTD.";
318 emit
gotNewPixmap( mPixmap.scaled( mThumbSize, Qt::KeepAspectRatio,
319 Qt::SmoothTransformation ) );
326 kDebug() <<
"POTD:" << mDate <<
": called for a new pixmap size ("
327 << size <<
"instead of" << mThumbSize <<
", stored pixmap:"
328 << mPixmap.size() <<
")";
331 if ( !mFirstStepCompleted ) {
333 }
else if ( ( mDlThumbSize.
width() < size.
width() ) &&
335 if ( mThirdStepJob ) {
341 }
else if ( mFirstStepJob || mSecondStepJob ) {
348 disconnect( mTimer, SIGNAL(timeout()),
350 connect( mTimer, SIGNAL(timeout()),
353 mTimer->
start( 1000 );
361 if ( mPixmap.isNull() ) {
364 return mPixmap.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
POTDElement(const QString &id, const QDate &date, const QSize &initialThumbSize)
QDomNode item(int index) const
QString toString(Qt::DateFormat format) const
QString nodeValue() const
void step1StartDownload()
First step of three in the download process.
void step1Success() const
QString & remove(int position, int n)
QString number(int n, int base)
QString fromUtf8(const char *str, int size)
void configure(QWidget *parent)
void gotNewShortText(const QString &) const
int toInt(bool *ok, int base) const
QDomNodeList elementsByTagName(const QString &tagname) const
void step3GetThumbnail()
Third step of three in the downloading process.
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
void gotNewPixmap(const QPixmap &) const
void gotNewUrl(const KUrl &) const
QString fromPercentEncoding(const QByteArray &input)
QDomNode namedItem(const QString &name) const
void step2GetImagePage()
Second step of three in the download process.
QPixmap newPixmap(const QSize &size)
QString & replace(int position, int n, QChar after)
float toFloat(bool *ok) const
void gotNewLongText(const QString &) const
K_EXPORT_PLUGIN(KOrganizerFactory(createAboutData())) KOrganizerPart
void setThumbnailSize(const QSize &size)
void step2Success() const
KUrl thumbnailUrl(const KUrl &fullSizeUrl, const int width=0) const
Returns the thumbnail URL for a given width corresponding to a full-size image URL.
void step3Success() const
Element::List createDayElements(const QDate &)
QDomNamedNodeMap attributes() const
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
void setSingleShot(bool singleShot)