libtdepim

tdeabcresourcecached.cpp
1 /*
2  This file is part of libtdepim.
3  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include <tqfile.h>
22 
23 #include <tdeabc/vcardconverter.h>
24 #include <kdebug.h>
25 #include <tdelocale.h>
26 #include <kstandarddirs.h>
27 
28 #include "tdeabcresourcecached.h"
29 
30 using namespace TDEABC;
31 
32 ResourceCached::ResourceCached( const TDEConfig *config )
33  : TDEABC::Resource( config ), mIdMapper( "tdeabc/uidmaps/" ),
34  mReloadPolicy( ReloadInterval ), mReloadInterval( 10 ),
35  mKABCReloadTimer( 0, "mKABCReloadTimer" ), mReloaded( false ),
36  mSavePolicy( SaveDelayed ), mSaveInterval( 10 ),
37  mKABCSaveTimer( 0, "mKABCSaveTimer" )
38 {
39  connect( &mKABCReloadTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotKABCReload() ) );
40  connect( &mKABCSaveTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotKABCSave() ) );
41 
42  if (config)
43  this->readConfig(const_cast<TDEConfig *>(config));
44 }
45 
46 ResourceCached::~ResourceCached()
47 {
48 }
49 
50 void ResourceCached::setReloadPolicy( int i )
51 {
52  mReloadPolicy = i;
53 
54  setupReloadTimer();
55 }
56 
57 int ResourceCached::reloadPolicy() const
58 {
59  return mReloadPolicy;
60 }
61 
62 void ResourceCached::setReloadInterval( int minutes )
63 {
64  mReloadInterval = minutes;
65 }
66 
67 int ResourceCached::reloadInterval() const
68 {
69  return mReloadInterval;
70 }
71 
72 void ResourceCached::setSavePolicy( int i )
73 {
74  mSavePolicy = i;
75 
76  setupSaveTimer();
77 }
78 
79 int ResourceCached::savePolicy() const
80 {
81  return mSavePolicy;
82 }
83 
84 void ResourceCached::setSaveInterval( int minutes )
85 {
86  mSaveInterval = minutes;
87 }
88 
89 int ResourceCached::saveInterval() const
90 {
91  return mSaveInterval;
92 }
93 
94 void ResourceCached::writeConfig( TDEConfig *config )
95 {
96  config->writeEntry( "ReloadPolicy", mReloadPolicy );
97  config->writeEntry( "ReloadInterval", mReloadInterval );
98 
99  config->writeEntry( "SavePolicy", mSavePolicy );
100  config->writeEntry( "SaveInterval", mSaveInterval );
101 
102  config->writeEntry( "LastLoad", mLastLoad );
103  config->writeEntry( "LastSave", mLastSave );
104 
105  TDEABC::Resource::writeConfig( config );
106 }
107 
108 void ResourceCached::readConfig( TDEConfig *config )
109 {
110  mReloadPolicy = config->readNumEntry( "ReloadPolicy", ReloadNever );
111  mReloadInterval = config->readNumEntry( "ReloadInterval", 10 );
112 
113  mSaveInterval = config->readNumEntry( "SaveInterval", 10 );
114  mSavePolicy = config->readNumEntry( "SavePolicy", SaveNever );
115 
116  mLastLoad = config->readDateTimeEntry( "LastLoad" );
117  mLastSave = config->readDateTimeEntry( "LastSave" );
118 
119  setupSaveTimer();
120  setupReloadTimer();
121 }
122 
123 void ResourceCached::setupSaveTimer()
124 {
125  if ( mSavePolicy == SaveInterval ) {
126  kdDebug(5800) << "ResourceCached::setSavePolicy(): start save timer (interval "
127  << mSaveInterval << " minutes)." << endl;
128  mKABCSaveTimer.start( mSaveInterval * 60 * 1000 ); // n minutes
129  } else {
130  mKABCSaveTimer.stop();
131  }
132 }
133 
134 void ResourceCached::setupReloadTimer()
135 {
136  if ( mReloadPolicy == ReloadInterval ) {
137  kdDebug(5800) << "ResourceCached::setSavePolicy(): start reload timer "
138  "(interval " << mReloadInterval << " minutes)" << endl;
139  mKABCReloadTimer.start( mReloadInterval * 60 * 1000 ); // n minutes
140  } else {
141  mKABCReloadTimer.stop();
142  }
143 }
144 
145 void ResourceCached::slotKABCReload()
146 {
147  if ( !isActive() ) return;
148 
149  kdDebug(5800) << "ResourceCached::slotKABCReload()" << endl;
150 
151  load();
152 }
153 
154 void ResourceCached::slotKABCSave()
155 {
156  if ( !isActive() ) return;
157 
158  kdDebug(5800) << "ResourceCached::slotKABCSave()" << endl;
159 
160  TDEABC::Ticket *ticket = requestSaveTicket();
161  if ( ticket ) {
162  save( ticket );
163  }
164 }
165 
166 void ResourceCached::insertAddressee( const Addressee &addr )
167 {
168  if ( !mAddrMap.contains( addr.uid() ) ) { // new contact
169  if ( mDeletedAddressees.contains( addr.uid() ) ) {
170  // it was first removed, then added, so it's an update...
171  mDeletedAddressees.remove( addr.uid() );
172 
173  mAddrMap.insert( addr.uid(), addr );
174  mChangedAddressees.insert( addr.uid(), addr );
175  return;
176  }
177 
178  mAddrMap.insert( addr.uid(), addr );
179  mAddedAddressees.insert( addr.uid(), addr );
180  } else {
181  TDEABC::Addressee oldAddressee = mAddrMap.find( addr.uid() ).data();
182  if ( oldAddressee != addr ) {
183  mAddrMap.remove( addr.uid() );
184  mAddrMap.insert( addr.uid(), addr );
185  mChangedAddressees.insert( addr.uid(), addr );
186  }
187  }
188 }
189 
190 void ResourceCached::removeAddressee( const Addressee &addr )
191 {
192  if ( mAddedAddressees.contains( addr.uid() ) ) {
193  mAddedAddressees.remove( addr.uid() );
194  return;
195  }
196 
197  if ( mDeletedAddressees.find( addr.uid() ) == mDeletedAddressees.end() )
198  mDeletedAddressees.insert( addr.uid(), addr );
199 
200  mAddrMap.remove( addr.uid() );
201 }
202 
203 void ResourceCached::loadCache()
204 {
205  mAddrMap.clear();
206 
207  setIdMapperIdentifier();
208  mIdMapper.load();
209 
210  // load cache
211  TQFile file( cacheFile() );
212  if ( !file.open( IO_ReadOnly ) )
213  return;
214 
215 
216  TDEABC::VCardConverter converter;
217 #if defined(KABC_VCARD_ENCODING_FIX)
218  TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
219 #else
220  TQTextStream s( &file );
221  s.setEncoding( TQTextStream::UnicodeUTF8 );
222  TDEABC::Addressee::List list = converter.parseVCards( s.read() );
223 #endif
224  TDEABC::Addressee::List::Iterator it;
225 
226  for ( it = list.begin(); it != list.end(); ++it ) {
227  (*it).setResource( this );
228  (*it).setChanged( false );
229  mAddrMap.insert( (*it).uid(), *it );
230  }
231 
232  file.close();
233 }
234 
235 void ResourceCached::saveCache()
236 {
237  setIdMapperIdentifier();
238  mIdMapper.save();
239 
240  // save cache
241  TQFile file( cacheFile() );
242  if ( !file.open( IO_WriteOnly ) )
243  return;
244 
245  TDEABC::Addressee::List list = mAddrMap.values();
246 
247  TDEABC::VCardConverter converter;
248 #if defined(KABC_VCARD_ENCODING_FIX)
249  TQCString vCard = converter.createVCardsRaw( list );
250  file.writeBlock( vCard, vCard.length() );
251 #else
252  TQString vCard = converter.createVCards( list );
253  file.writeBlock( vCard.utf8(), vCard.utf8().length() );
254 #endif
255  file.close();
256 }
257 
258 void ResourceCached::clearCache()
259 {
260  // TEST ME
261  mAddrMap.clear();
262 }
263 
264 void ResourceCached::cleanUpCache( const TDEABC::Addressee::List &addrList )
265 {
266  // load cache
267  TQFile file( cacheFile() );
268  if ( !file.open( IO_ReadOnly ) )
269  return;
270 
271 
272  TDEABC::VCardConverter converter;
273 #if defined(KABC_VCARD_ENCODING_FIX)
274  TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
275 #else
276  TQTextStream s( &file );
277  s.setEncoding( TQTextStream::UnicodeUTF8 );
278  TDEABC::Addressee::List list = converter.parseVCards( s.read() );
279 #endif
280  TDEABC::Addressee::List::Iterator cacheIt;
281  TDEABC::Addressee::List::ConstIterator it;
282 
283  for ( cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt ) {
284  bool found = false;
285  for ( it = addrList.begin(); it != addrList.end(); ++it ) {
286  if ( (*it).uid() == (*cacheIt).uid() )
287  found = true;
288  }
289 
290  if ( !found ) {
291  mIdMapper.removeRemoteId( mIdMapper.remoteId( (*cacheIt).uid() ) );
292  mAddrMap.remove( (*cacheIt).uid() );
293  }
294  }
295 
296  file.close();
297 }
298 
299 KPIM::IdMapper& ResourceCached::idMapper()
300 {
301  return mIdMapper;
302 }
303 
304 bool ResourceCached::hasChanges() const
305 {
306  return !( mAddedAddressees.isEmpty() &&
307  mChangedAddressees.isEmpty() &&
308  mDeletedAddressees.isEmpty() );
309 }
310 
311 void ResourceCached::clearChanges()
312 {
313  mAddedAddressees.clear();
314  mChangedAddressees.clear();
315  mDeletedAddressees.clear();
316 }
317 
318 void ResourceCached::clearChange( const TDEABC::Addressee &addr )
319 {
320  mAddedAddressees.remove( addr.uid() );
321  mChangedAddressees.remove( addr.uid() );
322  mDeletedAddressees.remove( addr.uid() );
323 }
324 
325 void ResourceCached::clearChange( const TQString &uid )
326 {
327  mAddedAddressees.remove( uid );
328  mChangedAddressees.remove( uid );
329  mDeletedAddressees.remove( uid );
330 }
331 
332 TDEABC::Addressee::List ResourceCached::addedAddressees() const
333 {
334  return mAddedAddressees.values();
335 }
336 
337 TDEABC::Addressee::List ResourceCached::changedAddressees() const
338 {
339  return mChangedAddressees.values();
340 }
341 
342 TDEABC::Addressee::List ResourceCached::deletedAddressees() const
343 {
344  return mDeletedAddressees.values();
345 }
346 
347 TQString ResourceCached::cacheFile() const
348 {
349  return locateLocal( "cache", "tdeabc/tderesources/" + identifier() );
350 }
351 
352 TQString ResourceCached::changesCacheFile( const TQString &type ) const
353 {
354  return locateLocal( "cache", "tdeabc/changescache/" + identifier() + "_" + type );
355 }
356 
357 void ResourceCached::saveChangesCache( const TQMap<TQString, TDEABC::Addressee> &map, const TQString &type )
358 {
359  TQFile file( changesCacheFile( type ) );
360 
361  const TDEABC::Addressee::List list = map.values();
362  if ( list.isEmpty() ) {
363  file.remove();
364  } else {
365  if ( !file.open( IO_WriteOnly ) ) {
366  kdError() << "Can't open changes cache file '" << file.name() << "' for saving." << endl;
367  return;
368  }
369 
370  TDEABC::VCardConverter converter;
371 #if defined(KABC_VCARD_ENCODING_FIX)
372  const TQCString vCards = converter.createVCardsRaw( list );
373  file.writeBlock( vCards, vCards.length() );
374 #else
375  const TQString vCards = converter.createVCards( list );
376  TQCString content = vCards.utf8();
377  file.writeBlock( content, content.length() );
378 #endif
379  }
380 }
381 
382 void ResourceCached::saveChangesCache()
383 {
384  saveChangesCache( mAddedAddressees, "added" );
385  saveChangesCache( mDeletedAddressees, "deleted" );
386  saveChangesCache( mChangedAddressees, "changed" );
387 }
388 
389 void ResourceCached::loadChangesCache( TQMap<TQString, TDEABC::Addressee> &map, const TQString &type )
390 {
391  TQFile file( changesCacheFile( type ) );
392  if ( !file.open( IO_ReadOnly ) )
393  return;
394 
395  TDEABC::VCardConverter converter;
396 
397 #if defined(KABC_VCARD_ENCODING_FIX)
398  const TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
399 #else
400  TQTextStream s( &file );
401  s.setEncoding( TQTextStream::UnicodeUTF8 );
402  const TDEABC::Addressee::List list = converter.parseVCards( s.read() );
403 #endif
404  TDEABC::Addressee::List::ConstIterator it;
405  for ( it = list.begin(); it != list.end(); ++it )
406  map.insert( (*it).uid(), *it );
407 
408  file.close();
409 }
410 
411 void ResourceCached::loadChangesCache()
412 {
413  loadChangesCache( mAddedAddressees, "added" );
414  loadChangesCache( mDeletedAddressees, "deleted" );
415  loadChangesCache( mChangedAddressees, "changed" );
416 }
417 
418 void ResourceCached::setIdMapperIdentifier()
419 {
420  mIdMapper.setIdentifier( type() + "_" + identifier() );
421 }
422 
423 #include "tdeabcresourcecached.moc"