2a3399827680bd0a5bed1f706e28ecb1f5558a39
[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                 if ( tagName == QString( "serverurl" ) )
159                 {
160                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->serverUrl().toString() );
161                         if ( e.hasChildNodes() )
162                         {
163                                 e.replaceChild( t, e.firstChild() );
164                         }
165                         else
166                         {
167                                 e.appendChild( e.firstChild() );
168                         }
169                 }
170                 else if ( tagName == QString( "username" ) )
171                 {
172                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->username() );
173                         if ( e.hasChildNodes() )
174                         {
175                                 e.replaceChild( t, e.firstChild() );
176                         }
177                         else
178                         {
179                                 e.appendChild( e.firstChild() );
180                         }
181                 }
182                 else if ( tagName == QString( "password" ) )
183                 {
184                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->password() );
185                         if ( e.hasChildNodes() )
186                         {
187                                 e.replaceChild( t, e.firstChild() );
188                         }
189                         else
190                         {
191                                 e.appendChild( e.firstChild() );
192                         }
193                 }
194                 else if ( tagName == QString( "refreshinterval" ) )
195                 {
196                         QString s = QString( "%1" ).arg( iConnectionSettings->refreshInterval() );
197                         QDomText t = node.ownerDocument().createTextNode( s );
198                         e.replaceChild( t, e.firstChild() );
199                 }
200         }
201 }
202
203 void Configuration::saveRooms( const QDomNode &aXML )
204 {
205         //! List of rooms must be cleared and rewritten again
206         QDomDocument doc = aXML.ownerDocument();
207         QDomNode root = aXML; 
208
209         // Remove child nodes...
210         int count = root.childNodes().count();
211         QDomNode node = root.firstChild();
212         QDomNode next;
213         for (int i = 0; i < count; i++)
214         {
215                 qDebug() << "remove " << node.toElement().text();
216                 next = node.nextSibling();
217                 node = root.removeChild(node);
218                 node = next;
219         }
220
221         node = aXML;
222         QList<Room*>::iterator i;
223         for ( i = iRooms.begin(); i != iRooms.end(); ++i )
224         {
225                 QDomElement tag = doc.createElement( "room" );
226                 node.appendChild( tag );
227
228                 // First room in the list is a dafault room
229                 if ( i == iRooms.begin() )
230                 {
231                         tag.setAttribute( "default", "true" );
232                 }
233
234                 QDomElement ename = doc.createElement( "name" );
235                 QDomText tname = node.ownerDocument().createTextNode(( *i )->name() );
236                 ename.appendChild( tname );
237                 tag.appendChild( ename );
238
239                 QDomElement eaddress = doc.createElement( "address" );
240                 QDomText taddress = node.ownerDocument().createTextNode(( *i )->address() );
241                 eaddress.appendChild( taddress );
242                 tag.appendChild( eaddress );
243         }
244 }
245
246 void Configuration::saveLanguageCode( const QDomNode &aXML )
247 {
248         QDomElement e = aXML.toElement();
249         e.setAttribute( "code", languageCode() );
250 }
251
252 void Configuration::saveStartupSettings( const QDomNode &aXML )
253 {
254         QDomElement e = aXML.toElement();
255
256         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
257         {
258                 e = node.toElement();
259                 QString tagName = e.tagName().toLower();
260
261                 if ( tagName == QString( "powersaving" ) )
262                 {
263                         ( iStartupSettings->isPowersavingEnabled() ?
264                           e.setAttribute( "enabled", "true" ) :
265                           e.setAttribute( "enabled", "false" ) );
266
267                         e.setAttribute( "on", iStartupSettings->turnOnAt().toString( "hh:mm" ) );
268                         e.setAttribute( "off", iStartupSettings->turnOffAt().toString( "hh:mm" ) );
269                 }
270         }
271 }
272
273 void Configuration::saveDisplaySettings( const QDomNode &aXML )
274 {
275         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
276         {
277                 QDomElement e = node.toElement();
278                 QString tagName = e.tagName().toLower();
279
280                 if ( tagName == QString( "schedule" ) )
281                 {
282                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
283                         {
284                                 QDomElement scheduleElem = scheduleNode.toElement();
285                                 tagName = scheduleElem.tagName().toLower();
286
287                                 if ( tagName == QString( "week" ) )
288                                 {
289                                         scheduleElem.setAttribute( "days", iDisplaySettings->daysInSchedule() );
290                                 }
291                                 else if ( tagName == QString( "day" ) )
292                                 {
293                                         scheduleElem.setAttribute( "startsat", iDisplaySettings->dayStartsAt().toString( "hh:mm" ) );
294                                         scheduleElem.setAttribute( "endsat", iDisplaySettings->dayEndsAt().toString( "hh:mm" ) );
295                                 }
296                         }       // end of for
297                 }       // end of schedule
298                 else if ( tagName == QString( "dateformat" ) )
299                 {
300                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->dateFormat() );
301                         e.replaceChild( t, e.firstChild() );
302                 }
303                 else if ( tagName == QString( "timeformat" ) )
304                 {
305                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->timeFormat() );
306                         e.replaceChild( t, e.firstChild() );
307                 }
308                 else if ( tagName == QString( "screensaver" ) )
309                 {
310                         QString s = QString( "%1" ).arg( iDisplaySettings->screensaver() );
311                         QDomText t = node.ownerDocument().createTextNode( s );
312                         e.replaceChild( t, e.firstChild() );
313                 }
314         }
315 }
316
317 void Configuration::saveDateTimeSettings( const QDomNode &aXML )
318 {
319         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
320         {
321                 QDomElement e = node.toElement();
322                 QString tagName = e.tagName().toLower();
323
324                 if ( tagName == QString( "dayofweek" ) )
325                 {
326                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->switchDay() );
327                         e.replaceChild( t, e.firstChild() );
328                 }
329                 else if( tagName == QString( "StandardTimeChangeMoment" ) )
330                 {
331                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->STDDateTime().toString("ddMMyyyyhhmmss"));
332                         e.replaceChild( t, e.firstChild() );
333                 }
334                 else if( tagName == QString( "DaylightSaveTimeChangeMoment" ) )
335                 {
336                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->DSTDateTime().toString("ddMMyyyyhhmmss"));
337                         e.replaceChild( t, e.firstChild() );
338                 }
339         }
340 }
341
342 void Configuration::saveAdminPassword( const QDomNode &aXML )
343 {
344         QDomElement e = aXML.toElement();
345         e.setAttribute( "password", QString( adminPassword() ) );
346 }
347
348
349 Configuration* Configuration::readFromXML( const QString &aPath )
350 {
351         QDomDocument doc;
352         QFile file( aPath );
353
354         if ( !file.open( QIODevice::ReadOnly ) )
355         {
356                 return 0;
357         }
358         if ( !doc.setContent( &file ) )
359         {
360                 file.close();
361                 return 0;
362         }
363         file.close();
364
365         QDomElement root = doc.documentElement();
366         // check if the file is the one we need
367         if ( root.tagName().toLower() != QString( "configuration" ) )
368         {
369                 return 0;
370         }
371
372         Configuration* conf = new Configuration();
373
374         conf->iAdminPassword = Configuration::readAdminPassword( root );
375
376         for ( QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling() )
377         {
378                 QDomElement e = node.toElement();
379                 QString tagName = e.tagName().toLower();
380
381                 if ( tagName == QString( "connection" ) )
382                 {
383                         conf->iConnectionSettings = Configuration::readConnectionSettings( node );
384                 }
385                 else if ( tagName == QString( "rooms" ) )
386                 {
387                         conf->iRooms = Configuration::readRooms( node );
388                 }
389                 else if ( tagName == QString( "language" ) )
390                 {
391                         conf->iLanguageCode = Configuration::readLanguageCode( node );
392                 }
393                 else if ( tagName == QString( "startup" ) )
394                 {
395                         conf->iStartupSettings = Configuration::readStartupSettings( node );
396                 }
397                 else if ( tagName == QString( "display" ) )
398                 {
399                         conf->iDisplaySettings = Configuration::readDisplaySettings( node );
400                 }
401                 else if ( tagName == QString( "daylight_saving_time" ) )
402                 {
403                         conf->iDateTimeSettings = Configuration::readDateTimeSettings(node);
404                 }
405         }
406
407         return conf;
408 }
409
410 ConnectionSettings* Configuration::readConnectionSettings( const QDomNode &aXML )
411 {
412         QString server, username, password;
413         unsigned int interval = Configuration::sDefaultInterval;
414
415         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
416         {
417                 QDomElement e = node.toElement();
418                 QString tagName = e.tagName().toLower();
419
420                 if ( tagName == QString( "serverurl" ) )
421                 {
422                         server = e.text();
423                 }
424                 else if ( tagName == QString( "username" ) )
425                 {
426                         username = e.text();
427                 }
428                 else if ( tagName == QString( "password" ) )
429                 {
430                         password = e.text();
431                 }
432                 else if ( tagName == QString( "refreshinterval" ) )
433                 {
434                         bool success = false;
435                         unsigned int intervalTMP = e.text().toUInt( &success );
436                         if ( success )
437                         {
438                                 interval = intervalTMP;
439                         }
440                 }
441         }
442
443         return new ConnectionSettings( server, username, password, interval );
444 }
445
446 QList<Room*> Configuration::readRooms( const QDomNode &aXML )
447 {
448         QList<Room*> rooms;
449
450         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
451         {
452                 QDomElement e = node.toElement();
453                 QString tagName = e.tagName().toLower();
454
455                 if ( tagName == QString( "room" ) )
456                 {
457                         QString name, address;
458
459                         for ( QDomNode roomNode = node.firstChild(); !roomNode.isNull(); roomNode = roomNode.nextSibling() )
460                         {
461                                 QDomElement roomElem = roomNode.toElement();
462                                 tagName = roomElem.tagName().toLower();
463                                 if ( tagName == QString( "name" ) )
464                                 {
465                                         name = roomElem.text();
466                                 }
467                                 else if ( tagName == QString( "address" ) )
468                                 {
469                                         address = roomElem.text();
470                                 }
471                         }
472                         Room* room = new Room( name, address );
473                         QString defaultAttr = e.attribute( "default" ).toLower();
474                         if ( defaultAttr == QString( "true" ) )
475                         {
476                                 rooms.insert( 0, room );
477                         }
478                         else
479                         {
480                                 rooms.append( room );
481                         }
482                 }
483         }
484
485         return rooms;
486 }
487
488 QString Configuration::readLanguageCode( const QDomNode &aXML )
489 {
490         QDomElement e = aXML.toElement();
491         QString tagName = e.tagName().toLower();
492
493         if ( e.hasAttribute( "code" ) )
494         {
495                 return e.attribute( "code" );
496         }
497         else
498         {
499                 // default language is English
500                 return "EN";
501         }
502 }
503
504 StartupSettings * Configuration::readStartupSettings( const QDomNode &aXML )
505 {
506         QDomElement e = aXML.toElement();
507
508         bool isPowersavingEnabled = false;
509         QTime turnOnAt, turnOffAt;
510
511         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
512         {
513                 e = node.toElement();
514                 QString tagName = e.tagName().toLower();
515
516                 if ( tagName == QString( "powersaving" ) )
517                 {
518                         if ( e.hasAttribute( "enabled" ) &&
519                                   e.attribute( "enabled" ) == QString( "true" ) )
520                         {
521                                 isPowersavingEnabled = true;
522                         }
523
524                         if ( e.hasAttribute( "on" ) )
525                         {
526                                 QString on = e.attribute( "on" );
527                                 turnOnAt = QTime::fromString( on, "hh:mm" );
528
529                         }
530
531                         if ( e.hasAttribute( "off" ) )
532                         {
533                                 QString off = e.attribute( "off" );
534                                 turnOffAt = QTime::fromString( off, "hh:mm" );
535                         }
536                 }
537         }
538
539         return new StartupSettings( isPowersavingEnabled, turnOnAt, turnOffAt );
540 }
541
542 DisplaySettings * Configuration::readDisplaySettings( const QDomNode &aXML )
543 {
544         DisplaySettings::DaysInSchedule daysInSchedule = DisplaySettings::WeekdaysInSchedule;
545         QTime dayStartsAt, dayEndsAt;
546         DisplaySettings::DateFormat dateformat = DisplaySettings::ShortDateFormat;
547         DisplaySettings::TimeFormat timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
548         int screensaver = 1;    //! Default value for screensaver wait time
549
550         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
551         {
552                 QDomElement e = node.toElement();
553                 QString tagName = e.tagName().toLower();
554
555                 if ( tagName == QString( "schedule" ) )
556                 {
557                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
558                         {
559                                 QDomElement scheduleElem = scheduleNode.toElement();
560                                 tagName = scheduleElem.tagName().toLower();
561
562                                 if ( tagName == QString( "week" ) )
563                                 {
564                                         if ( scheduleElem.hasAttribute( "days" ) )
565                                         {
566                                                 // default value is 5, only other supported possibility is 7
567                                                 bool success = false;
568                                                 unsigned int days = scheduleElem.attribute( "days" ).toUInt( &success );
569                                                 daysInSchedule = ( success && days == 7 ) ? DisplaySettings::WholeWeekInSchedule : DisplaySettings::WeekdaysInSchedule;
570                                         }
571
572                                 }
573                                 else if ( tagName == QString( "day" ) )
574                                 {
575                                         if ( scheduleElem.hasAttribute( "startsat" ) )
576                                         {
577                                                 QString time = scheduleElem.attribute( "startsat" );
578                                                 dayStartsAt = QTime::fromString( time, "hh:mm" );
579                                         }
580                                         if ( scheduleElem.hasAttribute( "endsat" ) )
581                                         {
582                                                 QString time = scheduleElem.attribute( "endsat" );
583                                                 dayEndsAt = QTime::fromString( time, "hh:mm" );
584                                         }
585
586                                 }
587                         }       // end of for
588                 }       // end of schedule
589                 else if ( tagName == QString( "dateformat" ) )
590                 {
591                         //! Not able to display long format anyway at the moment
592                         /*
593                         if ( e.text() == QObject::tr( "dddd d MMMM yyyy" ) )
594                                 dateformat = DisplaySettings::LongDateFormat;
595                         else
596                                 dateformat = DisplaySettings::ShortDateFormat;
597                         */
598                         dateformat = DisplaySettings::ShortDateFormat;
599                 }
600                 else if ( tagName == QString( "timeformat" ) )
601                 {
602                         //! Not able to display "TwelveHoursTimeFormat" anyway at the moment
603                         /*
604                         if ( e.text() == QObject::tr( "hh:mm ap" ) )
605                                 timeformat = DisplaySettings::TwelveHoursTimeFormat;
606                         else
607                                 timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
608                         */
609                         timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
610                 }
611                 else if ( tagName == QString( "screensaver" ) )
612                 {
613                         bool success = false;
614                         unsigned int screensaverTMP = e.text().toUInt( &success );
615                         if ( success )
616                         {
617                                 screensaver = screensaverTMP;
618                         }
619                 }
620         }
621
622         return new DisplaySettings( dateformat, timeformat, daysInSchedule, dayStartsAt, dayEndsAt, screensaver );
623 }
624
625 DateTimeSettings * Configuration::readDateTimeSettings( const QDomNode &aXML )
626 {
627         // Set defaults..
628         QDateTime standardTimeChangeMoment = QDateTime::fromString("05.10.2009 04:00:00", "dd'.'MM'.'yyyy' 'hh:mm:ss");
629         QDateTime daylightSaveTimeChangeMoment = QDateTime::fromString("01.04.2010 03:00:00", "dd'.'MM'.'yyyy' 'hh:mm:ss");
630         DateTimeSettings::weekDay dayOfWeek = DateTimeSettings::Sunday;
631         
632         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
633         {
634                 QDomElement e = node.toElement();
635                 QString tagName = e.tagName().toLower();
636
637                 if ( tagName == QString( "dayofweek" ) )
638                 {
639                         qDebug() << "Configuration::readDateTimeSettings: " +e.text();
640                         
641                         bool success = false;
642                         unsigned int weekDayTmp = e.text().toUInt( &success );
643                         if( success && weekDayTmp < 7 )
644                         {
645                                 dayOfWeek = (DateTimeSettings::weekDay)weekDayTmp;
646                         }
647                 }
648                 else if( tagName == QString( "standardtimechangemoment" ) )
649                 {
650                         standardTimeChangeMoment = QDateTime::fromString(e.text(), "dd'.'MM'.'yyyy' 'hh:mm:ss");
651                         qDebug() << "Configuration::readDateTimeSettings: " +standardTimeChangeMoment.toString("dd.MM.yyyy hh:mm:ss");
652                 }
653                 else if( tagName == QString( "daylightsavetimechangemoment" ) )
654                 {
655                         daylightSaveTimeChangeMoment = QDateTime::fromString(e.text(), "dd'.'MM'.'yyyy' 'hh:mm:ss");
656                         qDebug() << "Configuration::readDateTimeSettings: " +daylightSaveTimeChangeMoment.toString("dd.MM.yyyy hh:mm:ss");
657                 }
658         }
659         
660         return new DateTimeSettings(standardTimeChangeMoment, daylightSaveTimeChangeMoment, dayOfWeek);
661 }
662
663 QByteArray Configuration::readAdminPassword( const QDomNode &aXML )
664 {
665         QDomElement e = aXML.toElement();
666         QString tagName = e.tagName().toLower();
667         if ( e.hasAttribute( "password" ) )
668         {
669                 QString pw = e.attribute( "password" );
670                 // Check if the password is default uncrypted "admin"
671                 if ( pw == QString( "admin" ) )
672                 {
673                         // uncrypted password needs to be encoded
674                         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
675                         hash->addData( pw.toUtf8() );
676                         pw = QString( hash->result() );
677                         delete hash;
678                 }
679                 return ( pw.toAscii() ).toHex();
680                 
681         }
682         else
683         {
684                 return 0;
685         }
686 }
687
688 void Configuration::setRooms( const QList<Room*> aRooms )
689 {
690         iRooms = aRooms;
691 }
692
693 QString Configuration::hashPassword( const QString aPassword )
694 {
695         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
696         hash->addData( aPassword.toUtf8() );
697         QByteArray password = hash->result();
698         delete hash;
699
700         return QString( password );
701 }