0076e232702db8857725af968e2c4f730ba3fc02
[qtmeetings] / src / Domain / Configuration / Configuration.cpp
1 #include "Configuration.h"
2 #include "ConnectionSettings.h"
3 #include "StartupSettings.h"
4 #include "DisplaySettings.h"
5 #include "DateTimeSettings.h"
6 #include "Room.h"
7 #include <QDomDocument>
8 #include <QDomElement>
9 #include <QDomNode>
10 #include <QFile>
11 #include <QCryptographicHash>
12
13 #include <QtDebug>
14
15 Configuration * Configuration::sInstance = 0;
16 QString Configuration::sConfigurationPath = "/etc/QtMeetings.conf";
17
18 Configuration::Configuration() :
19                 iConnectionSettings( 0 ),
20                 iStartupSettings( 0 ),
21                 iDisplaySettings( 0 ),
22                 iDateTimeSettings( 0 )
23 {
24 }
25
26 Configuration::~Configuration()
27 {
28         delete iConnectionSettings;
29         delete iStartupSettings;
30         delete iDisplaySettings;
31         delete iDateTimeSettings;
32         while ( !iRooms.isEmpty() )
33         {
34                 delete iRooms.takeFirst();
35         }
36 }
37
38 Configuration* Configuration::instance()
39 {
40         if ( sInstance == 0 )
41         {
42                 sInstance = readFromXML( sConfigurationPath );
43         if( !sInstance )
44         {
45             qDebug() << "FATAL: Configuration cannot be read from:" << Configuration::sConfigurationPath;
46         }
47     }
48         return sInstance;
49 }
50
51 ConnectionSettings* Configuration::connectionSettings()
52 {
53         return iConnectionSettings;
54 }
55
56 StartupSettings * Configuration::startupSettings()
57 {
58         return iStartupSettings;
59 }
60
61 DisplaySettings * Configuration::displaySettings()
62 {
63         return iDisplaySettings;
64 }
65
66 DateTimeSettings * Configuration::dateTimeSettings()
67 {
68         return iDateTimeSettings;
69 }
70
71 Room* Configuration::defaultRoom()
72 {
73         // default room is stored as the first element of the list
74         return ( iRooms.count() == 0 ) ? 0 : iRooms.at( 0 );
75 }
76
77 QString Configuration::languageCode()
78 {
79         return iLanguageCode;
80 }
81
82 QList<Room*> Configuration::rooms()
83 {
84         return iRooms;
85 }
86
87 QByteArray Configuration::adminPassword()
88 {
89         return iAdminPassword;
90 }
91
92 void Configuration::save()
93 {
94         QDomDocument doc;
95         QFile file( sConfigurationPath );
96
97         if ( !file.open( QIODevice::ReadWrite ) )
98         {
99                 return;
100         }
101
102         if ( !doc.setContent( &file ) )
103         {
104                 file.close();
105                 return;
106         }
107
108         QDomElement root = doc.documentElement();
109         // Save all attributes to document
110
111         saveAdminPassword( root );
112
113         for ( QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling() )
114         {
115                 QDomElement e = node.toElement();
116                 QString tagName = e.tagName().toLower();
117
118                 if ( tagName == QString( "connection" ) )
119                 {
120                         saveConnectionSettings( node );
121                 }
122                 else if ( tagName == QString( "rooms" ) )
123                 {
124                         saveRooms( node );
125                 }
126                 else if ( tagName == QString( "language" ) )
127                 {
128                         saveLanguageCode( node );
129                 }
130                 else if ( tagName == QString( "startup" ) )
131                 {
132                         saveStartupSettings( node );
133                 }
134                 else if ( tagName == QString( "display" ) )
135                 {
136                         saveDisplaySettings( node );
137                 }
138                 else if (tagName == QString( "daylight_saving_time" ) )
139                 {
140                         saveDateTimeSettings( node );
141                 }
142         }
143
144         //! Empty the file from previous content and write again with new one
145         file.resize( 0 );
146         file.write( doc.toByteArray( 4 ) );     //! 4 as intent
147
148         file.close();
149
150 }
151
152 void Configuration::saveConnectionSettings( const QDomNode &aXML )
153 {
154         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
155         {
156                 QDomElement e = node.toElement();
157                 QString tagName = e.tagName().toLower();
158
159                 if ( tagName == QString( "serverurl" ) )
160                 {
161                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->serverUrl().toString() );
162                         e.replaceChild( t, e.firstChild() );
163                 }
164                 else if ( tagName == QString( "username" ) )
165                 {
166                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->username() );
167                         e.replaceChild( t, e.firstChild() );
168                 }
169                 else if ( tagName == QString( "password" ) )
170                 {
171                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->password() );
172                         e.replaceChild( t, e.firstChild() );
173                 }
174                 else if ( tagName == QString( "refreshinterval" ) )
175                 {
176                         QString s = QString( "%1" ).arg( iConnectionSettings->refreshInterval() );
177                         QDomText t = node.ownerDocument().createTextNode( s );
178                         e.replaceChild( t, e.firstChild() );
179                 }
180         }
181 }
182
183 void Configuration::saveRooms( const QDomNode &aXML )
184 {
185         //! List of rooms must be cleared and rewritten again
186         QDomDocument doc = aXML.ownerDocument();
187         QDomNode root = aXML; 
188
189         // Remove child nodes...
190         int count = root.childNodes().count();
191         QDomNode node = root.firstChild();
192         QDomNode next;
193         for (int i=0; i<count; i++)
194         {
195                 qDebug() << "remove " << node.toElement().text();
196                 next = node.nextSibling();
197                 node = root.removeChild(node);
198                 node = next;
199         }
200
201         QList<Room*>::iterator i;
202         for ( i = iRooms.begin(); i != iRooms.end(); ++i )
203         {
204                 QDomElement tag = doc.createElement( "room" );
205                 node.appendChild( tag );
206
207                 // First room in the list is a dafault room
208                 if ( i == iRooms.begin() )
209                 {
210                         tag.setAttribute( "default", "true" );
211                 }
212
213                 QDomElement ename = doc.createElement( "name" );
214                 QDomText tname = node.ownerDocument().createTextNode(( *i )->name() );
215                 ename.appendChild( tname );
216                 tag.appendChild( ename );
217
218                 QDomElement eaddress = doc.createElement( "address" );
219                 QDomText taddress = node.ownerDocument().createTextNode(( *i )->address() );
220                 eaddress.appendChild( taddress );
221                 tag.appendChild( eaddress );
222         }
223 }
224
225 void Configuration::saveLanguageCode( const QDomNode &aXML )
226 {
227         QDomElement e = aXML.toElement();
228         e.setAttribute( "code", languageCode() );
229 }
230
231 void Configuration::saveStartupSettings( const QDomNode &aXML )
232 {
233         QDomElement e = aXML.toElement();
234
235         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
236         {
237                 e = node.toElement();
238                 QString tagName = e.tagName().toLower();
239
240                 if ( tagName == QString( "powersaving" ) )
241                 {
242                         ( iStartupSettings->isPowersavingEnabled() ?
243                           e.setAttribute( "enabled", "true" ) :
244                           e.setAttribute( "enabled", "false" ) );
245
246                         e.setAttribute( "on", iStartupSettings->turnOnAt().toString( "hh:mm" ) );
247                         e.setAttribute( "off", iStartupSettings->turnOffAt().toString( "hh:mm" ) );
248                 }
249         }
250 }
251
252 void Configuration::saveDisplaySettings( const QDomNode &aXML )
253 {
254         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
255         {
256                 QDomElement e = node.toElement();
257                 QString tagName = e.tagName().toLower();
258
259                 if ( tagName == QString( "schedule" ) )
260                 {
261                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
262                         {
263                                 QDomElement scheduleElem = scheduleNode.toElement();
264                                 tagName = scheduleElem.tagName().toLower();
265
266                                 if ( tagName == QString( "week" ) )
267                                 {
268                                         scheduleElem.setAttribute( "days", iDisplaySettings->daysInSchedule() );
269                                 }
270                                 else if ( tagName == QString( "day" ) )
271                                 {
272                                         scheduleElem.setAttribute( "startsat", iDisplaySettings->dayStartsAt().toString( "hh:mm" ) );
273                                         scheduleElem.setAttribute( "endsat", iDisplaySettings->dayEndsAt().toString( "hh:mm" ) );
274                                 }
275                         }       // end of for
276                 }       // end of schedule
277                 else if ( tagName == QString( "dateformat" ) )
278                 {
279                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->dateFormat() );
280                         e.replaceChild( t, e.firstChild() );
281                 }
282                 else if ( tagName == QString( "timeformat" ) )
283                 {
284                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->timeFormat() );
285                         e.replaceChild( t, e.firstChild() );
286                 }
287                 else if ( tagName == QString( "screensaver" ) )
288                 {
289                         QString s = QString( "%1" ).arg( iDisplaySettings->screensaver() );
290                         QDomText t = node.ownerDocument().createTextNode( s );
291                         e.replaceChild( t, e.firstChild() );
292                 }
293         }
294 }
295
296 void Configuration::saveDateTimeSettings( const QDomNode &aXML )
297 {
298         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
299         {
300                 QDomElement e = node.toElement();
301                 QString tagName = e.tagName().toLower();
302
303                 if ( tagName == QString( "dayofweek" ) )
304                 {
305                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->switchDay() );
306                         e.replaceChild( t, e.firstChild() );
307                 }
308                 else if( tagName == QString( "StandardTimeChangeMoment" ) )
309                 {
310                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->STDDateTime().toString("ddMMyyyyhhmmss"));
311                         e.replaceChild( t, e.firstChild() );
312                 }
313                 else if( tagName == QString( "DaylightSaveTimeChangeMoment" ) )
314                 {
315                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->DSTDateTime().toString("ddMMyyyyhhmmss"));
316                         e.replaceChild( t, e.firstChild() );
317                 }
318         }
319 }
320
321 void Configuration::saveAdminPassword( const QDomNode &aXML )
322 {
323         QDomElement e = aXML.toElement();
324         e.setAttribute( "password", QString( adminPassword() ) );
325 }
326
327
328 Configuration* Configuration::readFromXML( const QString &aPath )
329 {
330         QDomDocument doc;
331         QFile file( aPath );
332
333         if ( !file.open( QIODevice::ReadOnly ) )
334         {
335                 return 0;
336         }
337         if ( !doc.setContent( &file ) )
338         {
339                 file.close();
340                 return 0;
341         }
342         file.close();
343
344         QDomElement root = doc.documentElement();
345         // check if the file is the one we need
346         if ( root.tagName().toLower() != QString( "configuration" ) )
347         {
348                 return 0;
349         }
350
351         Configuration* conf = new Configuration();
352
353         conf->iAdminPassword = Configuration::readAdminPassword( root );
354
355         for ( QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling() )
356         {
357                 QDomElement e = node.toElement();
358                 QString tagName = e.tagName().toLower();
359
360                 if ( tagName == QString( "connection" ) )
361                 {
362                         conf->iConnectionSettings = Configuration::readConnectionSettings( node );
363                 }
364                 else if ( tagName == QString( "rooms" ) )
365                 {
366                         conf->iRooms = Configuration::readRooms( node );
367                 }
368                 else if ( tagName == QString( "language" ) )
369                 {
370                         conf->iLanguageCode = Configuration::readLanguageCode( node );
371                 }
372                 else if ( tagName == QString( "startup" ) )
373                 {
374                         conf->iStartupSettings = Configuration::readStartupSettings( node );
375                 }
376                 else if ( tagName == QString( "display" ) )
377                 {
378                         conf->iDisplaySettings = Configuration::readDisplaySettings( node );
379                 }
380                 else if ( tagName == QString( "daylight_saving_time" ) )
381                 {
382                         conf->iDateTimeSettings = Configuration::readDateTimeSettings(node);
383                 }
384         }
385
386         return conf;
387 }
388
389 ConnectionSettings* Configuration::readConnectionSettings( const QDomNode &aXML )
390 {
391         QString server, username, password;
392         unsigned int interval = Configuration::sDefaultInterval;
393
394         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
395         {
396                 QDomElement e = node.toElement();
397                 QString tagName = e.tagName().toLower();
398
399                 if ( tagName == QString( "serverurl" ) )
400                 {
401                         server = e.text();
402                 }
403                 else if ( tagName == QString( "username" ) )
404                 {
405                         username = e.text();
406                 }
407                 else if ( tagName == QString( "password" ) )
408                 {
409                         password = e.text();
410                 }
411                 else if ( tagName == QString( "refreshinterval" ) )
412                 {
413                         bool success = false;
414                         unsigned int intervalTMP = e.text().toUInt( &success );
415                         if ( success )
416                         {
417                                 interval = intervalTMP;
418                         }
419                 }
420         }
421
422         return new ConnectionSettings( server, username, password, interval );
423 }
424
425 QList<Room*> Configuration::readRooms( const QDomNode &aXML )
426 {
427         QList<Room*> rooms;
428
429         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
430         {
431                 QDomElement e = node.toElement();
432                 QString tagName = e.tagName().toLower();
433
434                 if ( tagName == QString( "room" ) )
435                 {
436                         QString name, address;
437
438                         for ( QDomNode roomNode = node.firstChild(); !roomNode.isNull(); roomNode = roomNode.nextSibling() )
439                         {
440                                 QDomElement roomElem = roomNode.toElement();
441                                 tagName = roomElem.tagName().toLower();
442                                 if ( tagName == QString( "name" ) )
443                                 {
444                                         name = roomElem.text();
445                                 }
446                                 else if ( tagName == QString( "address" ) )
447                                 {
448                                         address = roomElem.text();
449                                 }
450                         }
451                         Room* room = new Room( name, address );
452                         QString defaultAttr = e.attribute( "default" ).toLower();
453                         if ( defaultAttr == QString( "true" ) )
454                         {
455                                 rooms.insert( 0, room );
456                         }
457                         else
458                         {
459                                 rooms.append( room );
460                         }
461                 }
462         }
463
464         return rooms;
465 }
466
467 QString Configuration::readLanguageCode( const QDomNode &aXML )
468 {
469         QDomElement e = aXML.toElement();
470         QString tagName = e.tagName().toLower();
471
472         if ( e.hasAttribute( "code" ) )
473         {
474                 return e.attribute( "code" );
475         }
476         else
477         {
478                 // default language is English
479                 return "EN";
480         }
481 }
482
483 StartupSettings * Configuration::readStartupSettings( const QDomNode &aXML )
484 {
485         QDomElement e = aXML.toElement();
486
487         bool isPowersavingEnabled = false;
488         QTime turnOnAt, turnOffAt;
489
490         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
491         {
492                 e = node.toElement();
493                 QString tagName = e.tagName().toLower();
494
495                 if ( tagName == QString( "powersaving" ) )
496                 {
497                         if ( e.hasAttribute( "enabled" ) &&
498                                   e.attribute( "enabled" ) == QString( "true" ) )
499                         {
500                                 isPowersavingEnabled = true;
501                         }
502
503                         if ( e.hasAttribute( "on" ) )
504                         {
505                                 QString on = e.attribute( "on" );
506                                 turnOnAt = QTime::fromString( on, "hh:mm" );
507
508                         }
509
510                         if ( e.hasAttribute( "off" ) )
511                         {
512                                 QString off = e.attribute( "off" );
513                                 turnOffAt = QTime::fromString( off, "hh:mm" );
514                         }
515                 }
516         }
517
518         return new StartupSettings( isPowersavingEnabled, turnOnAt, turnOffAt );
519 }
520
521 DisplaySettings * Configuration::readDisplaySettings( const QDomNode &aXML )
522 {
523         DisplaySettings::DaysInSchedule daysInSchedule = DisplaySettings::WeekdaysInSchedule;
524         QTime dayStartsAt, dayEndsAt;
525         DisplaySettings::DateFormat dateformat = DisplaySettings::ShortDateFormat;
526         DisplaySettings::TimeFormat timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
527         int screensaver = 1;    //! Default value for screensaver wait time
528
529         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
530         {
531                 QDomElement e = node.toElement();
532                 QString tagName = e.tagName().toLower();
533
534                 if ( tagName == QString( "schedule" ) )
535                 {
536                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
537                         {
538                                 QDomElement scheduleElem = scheduleNode.toElement();
539                                 tagName = scheduleElem.tagName().toLower();
540
541                                 if ( tagName == QString( "week" ) )
542                                 {
543                                         if ( scheduleElem.hasAttribute( "days" ) )
544                                         {
545                                                 // default value is 5, only other supported possibility is 7
546                                                 bool success = false;
547                                                 unsigned int days = scheduleElem.attribute( "days" ).toUInt( &success );
548                                                 daysInSchedule = ( success && days == 7 ) ? DisplaySettings::WholeWeekInSchedule : DisplaySettings::WeekdaysInSchedule;
549                                         }
550
551                                 }
552                                 else if ( tagName == QString( "day" ) )
553                                 {
554                                         if ( scheduleElem.hasAttribute( "startsat" ) )
555                                         {
556                                                 QString time = scheduleElem.attribute( "startsat" );
557                                                 dayStartsAt = QTime::fromString( time, "hh:mm" );
558                                         }
559                                         if ( scheduleElem.hasAttribute( "endsat" ) )
560                                         {
561                                                 QString time = scheduleElem.attribute( "endsat" );
562                                                 dayEndsAt = QTime::fromString( time, "hh:mm" );
563                                         }
564
565                                 }
566                         }       // end of for
567                 }       // end of schedule
568                 else if ( tagName == QString( "dateformat" ) )
569                 {
570                         //! Not able to display long format anyway at the moment
571                         /*
572                         if ( e.text() == QObject::tr( "dddd d MMMM yyyy" ) )
573                                 dateformat = DisplaySettings::LongDateFormat;
574                         else
575                                 dateformat = DisplaySettings::ShortDateFormat;
576                         */
577                         dateformat = DisplaySettings::ShortDateFormat;
578                 }
579                 else if ( tagName == QString( "timeformat" ) )
580                 {
581                         //! Not able to display "TwelveHoursTimeFormat" anyway at the moment
582                         /*
583                         if ( e.text() == QObject::tr( "hh:mm ap" ) )
584                                 timeformat = DisplaySettings::TwelveHoursTimeFormat;
585                         else
586                                 timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
587                         */
588                         timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
589                 }
590                 else if ( tagName == QString( "screensaver" ) )
591                 {
592                         bool success = false;
593                         unsigned int screensaverTMP = e.text().toUInt( &success );
594                         if ( success )
595                         {
596                                 screensaver = screensaverTMP;
597                         }
598                 }
599         }
600
601         return new DisplaySettings( dateformat, timeformat, daysInSchedule, dayStartsAt, dayEndsAt, screensaver );
602 }
603
604 DateTimeSettings * Configuration::readDateTimeSettings( const QDomNode &aXML )
605 {
606         // Set defaults..
607         QDateTime standardTimeChangeMoment = QDateTime::fromString("05.10.2009 04:00:00", "dd'.'MM'.'yyyy' 'hh:mm:ss");
608         QDateTime daylightSaveTimeChangeMoment = QDateTime::fromString("01.04.2010 03:00:00", "dd'.'MM'.'yyyy' 'hh:mm:ss");
609         DateTimeSettings::weekDay dayOfWeek = DateTimeSettings::Sunday;
610         
611         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
612         {
613                 QDomElement e = node.toElement();
614                 QString tagName = e.tagName().toLower();
615
616                 if ( tagName == QString( "dayofweek" ) )
617                 {
618                         qDebug() << "Configuration::readDateTimeSettings: " +e.text();
619                         
620                         bool success = false;
621                         unsigned int weekDayTmp = e.text().toUInt( &success );
622                         if( success && weekDayTmp >= 0 && weekDayTmp < 7)
623                         {
624                                 dayOfWeek = (DateTimeSettings::weekDay)weekDayTmp;
625                         }
626                 }
627                 else if( tagName == QString( "standardtimechangemoment" ) )
628                 {
629                         standardTimeChangeMoment = QDateTime::fromString(e.text(), "dd'.'MM'.'yyyy' 'hh:mm:ss");
630                         qDebug() << "Configuration::readDateTimeSettings: " +standardTimeChangeMoment.toString("dd.MM.yyyy hh:mm:ss");
631                 }
632                 else if( tagName == QString( "daylightsavetimechangemoment" ) )
633                 {
634                         daylightSaveTimeChangeMoment = QDateTime::fromString(e.text(), "dd'.'MM'.'yyyy' 'hh:mm:ss");
635                         qDebug() << "Configuration::readDateTimeSettings: " +daylightSaveTimeChangeMoment.toString("dd.MM.yyyy hh:mm:ss");
636                 }
637         }
638         
639         return new DateTimeSettings(standardTimeChangeMoment, daylightSaveTimeChangeMoment, dayOfWeek);
640 }
641
642 QByteArray Configuration::readAdminPassword( const QDomNode &aXML )
643 {
644         QDomElement e = aXML.toElement();
645         QString tagName = e.tagName().toLower();
646         if ( e.hasAttribute( "password" ) )
647         {
648                 QString pw = e.attribute( "password" );
649                 // Check if the password is default uncrypted "admin"
650                 if ( pw == QString( "admin" ) )
651                 {
652                         // uncrypted password needs to be encoded
653                         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
654                         hash->addData( pw.toUtf8() );
655                         pw = QString( hash->result() );
656                         delete hash;
657                 }
658                 return ( pw.toAscii() ).toHex();
659                 
660         }
661         else
662         {
663                 return 0;
664         }
665 }
666
667 void Configuration::setRooms( const QList<Room*> aRooms )
668 {
669         iRooms = aRooms;
670 }
671
672 QString Configuration::hashPassword( const QString aPassword )
673 {
674         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
675         hash->addData( aPassword.toUtf8() );
676         QByteArray password = hash->result();
677         delete hash;
678
679         return QString( password );
680 }