better logging, better handling of datadir arguments;
authorKonrad Rosenbaum <konrad@silmor.de>
Sun, 10 Jul 2016 19:43:47 +0000 (21:43 +0200)
committerKonrad Rosenbaum <konrad@silmor.de>
Sun, 10 Jul 2016 19:44:15 +0000 (21:44 +0200)
first draft of client selection

commonlib/mapplication.cpp
commonlib/mapplication.h
commonlib/misc/debug.cpp
sessman/login.cpp
sessman/login.h
sessman/sman.cpp
sessman/sman.h
src/main.cpp

index e82efc5..7a47193 100644 (file)
@@ -28,6 +28,7 @@
 #include <QStringList>
 #include <QTranslator>
 #include <QUrl>
+#include <QtGlobal>
 
 #include <TimeStamp>
 #include <TZFile>
@@ -38,7 +39,6 @@
 #include "hmac.h"
 #include "keygen.h"
 #include "mapplication.h"
-// #include "login.h"
 #include "msinterface.h"
 #include <ELAM/Engine>
 #include "misc.h"
@@ -277,6 +277,9 @@ void MApplication::help(int idx)
        QDesktopServices::openUrl(u);
 }
 
+#define ENV_DATADIR "MAGICSMOKE_DATADIR"
+#define ENV_CONFIGDIR "MAGICSMOKE_CONFIGDIR"
+
 MApplication::MApplication(int&ac,char**av)
 :QApplication(ac,av)
 {
@@ -296,6 +299,12 @@ MApplication::MApplication(int&ac,char**av)
                 return new MProgressWrapperGui(label,button);
         });
         
+        //check environment
+       if(qEnvironmentVariableIsSet(ENV_DATADIR))
+               setDataDir(QString::fromLocal8Bit(qgetenv(ENV_DATADIR)));
+       if(qEnvironmentVariableIsSet(ENV_CONFIGDIR))
+               setConfigDir(QString::fromLocal8Bit(qgetenv(ENV_CONFIGDIR)));
+
         //check parameters
 //         qDebug()<<"arguments"<<arguments();
         for(const QString& param:arguments()){
@@ -305,8 +314,8 @@ MApplication::MApplication(int&ac,char**av)
                         setDataDir(param.mid(9));
                 }
         }
-        
-        //data directory
+
+        //data directory fallback
         if(dataDir().isEmpty())
                 setDataDir("$BASE/.magicSmoke2");
 }
@@ -317,11 +326,14 @@ void MApplication::setConfigDir(QString d)
         const QString cdir=MSInterface::resolveDir(d);
         QSettings::setPath(QSettings::IniFormat,QSettings::UserScope,cdir);
         qDebug()<<"Setting the config directory to"<<cdir<<"from"<<d;
+       qputenv(ENV_CONFIGDIR,d.toLocal8Bit());
 }
 
 void MApplication::setDataDir(QString d)
 {
         MSInterface::setAppDataDir(d);
+       qDebug()<<"Setting Data Directory to"<<d;
+       qputenv(ENV_DATADIR,d.toLocal8Bit());
 }
 
 
@@ -408,10 +420,6 @@ void MApplication::initialize()
         initProfile();
         //init help menu layout
         initHelpUrl();
-        //init updater
-        initUpdater();
-        //init plugins
-        MBarcodeHub::instance()->initialize();
 }
 
 void MApplication::initUpdater()
index eb17647..81ee0f9 100644 (file)
@@ -63,6 +63,10 @@ class MAGICSMOKE_COMMON_EXPORT MApplication:public QApplication
                void versionDlg();
                 ///start a browser with the help page
                void help();
+
+               ///initialize the updater
+                void initUpdater();
+
         private slots:
                 ///jump to a specific help page
                void help(int);
@@ -70,9 +74,6 @@ class MAGICSMOKE_COMMON_EXPORT MApplication:public QApplication
                 ///initialize the help menu from config files
                 void initHelpUrl();
                 
-                ///initialize the updater
-                void initUpdater();
-                
                 ///updater is ready for download
                 void updateReadyDownload(const QString&);
                 ///updater is ready for install
index 986074f..854ee3c 100644 (file)
 
 static QFile*mylogFile=0;
 
+
 static void mymsghandler(QtMsgType,const QMessageLogContext&, const QString&msg)
 {
         if(mylogFile){
-                mylogFile->write(msg.toLatin1());
-                mylogFile->write("\n",1);
+               QByteArray data=
+                       QDateTime::currentDateTime().toString("yyyy-MM-dd hh.mm.ss.zzz").toLatin1() +" "+
+                       msg.toLatin1()+"\n";
+                mylogFile->write(data);
                 mylogFile->flush();
         }
 #ifdef Q_OS_UNIX
@@ -39,8 +42,9 @@ void initDebug(const QString&dataDir)
         qDebug()<<"-nolog argument was given, will not create a log file";
     }
        //create new log file
+       QFileInfo appfi(qApp->applicationFilePath());
        QDir(dataDir).mkpath("debuglog");
-        mylogFile=new QFile(dataDir+"/debuglog/log-"+QDateTime::currentDateTime().toString("yyyy-MM-dd_hh.mm.ss.zzz")+".txt");
+        mylogFile=new QFile(dataDir+"/debuglog/"+appfi.baseName()+"-"+QDateTime::currentDateTime().toString("yyyy-MM-dd_hh.mm.ss.zzz")+".log");
         //...open it
         if(mylogFile->open(QIODevice::WriteOnly|QIODevice::Append|QIODevice::Text)){
                //install as default log
@@ -52,6 +56,7 @@ void initDebug(const QString&dataDir)
                 mylogFile=0;
                 qDebug("Failed to install debuglog.");
         }
+        qDebug()<<"Log file opened by"<<appfi.absoluteFilePath();
         //delete old logs (older than 30 days)
        QStringList fll=QDir(dataDir+"/debuglog").entryList(QDir::Files);
        QDateTime old=QDateTime::currentDateTime().addDays(-30);
index 617c06c..f6d9c59 100644 (file)
@@ -13,6 +13,7 @@
 #include "login.h"
 #include "msinterface.h"
 #include "configdialog.h"
+#include "sman.h"
 
 #include <QApplication>
 #include <QByteArray>
@@ -30,7 +31,7 @@
 #include <QSizeGrip>
 #include <QProgressDialog>
 
-MLogin::MLogin()
+MLogin::MLogin(MSessionManager*sm)
 {
        setWindowTitle(tr("Magic Smoke Login"));
        setWindowFlags(windowFlags()|Qt::Window|Qt::Dialog);
@@ -54,6 +55,9 @@ MLogin::MLogin()
        lab->setAlignment(Qt::AlignRight);
        gl->addWidget(profiles=new QComboBox,lctr,1);
        connect(profiles,SIGNAL(currentIndexChanged(int)),this,SLOT(loadProfile()));
+       gl->addWidget(lab=new QLabel(tr("Client:")),++lctr,0);
+       lab->setAlignment(Qt::AlignRight);
+       gl->addWidget(clients=new QComboBox,lctr,1);
        gl->addWidget(lab=new QLabel(tr("Username:")),++lctr,0);
        lab->setAlignment(Qt::AlignRight);
        gl->addWidget(username=new QLineEdit,lctr,1);
@@ -73,6 +77,7 @@ MLogin::MLogin()
        resizer=new QSizeGrip(this);
        connect(p,SIGNAL(clicked()),this,SLOT(startLogin()));
        initProfiles();
+       initClients(sm);
        loadProfile();
        
        //react to Escape button
@@ -107,6 +112,27 @@ void MLogin::loadProfile()
                 password->setFocus();
 }
 
+#define LASTCLIENTSETTING "SessionManager/LastClient"
+void MLogin::initClients(MSessionManager*sm)
+{
+       QString last=QSettings().value(LASTCLIENTSETTING).toString().trimmed();
+       int pos=-1;
+       for(auto entry:sm->menuItems()){
+               if(!entry.first.startsWith('@'))continue;
+               if(last==entry.first)pos=clients->count();
+               clients->addItem(entry.second.replace("&",""),entry.first);
+       }
+       if(pos>=0)
+               clients->setCurrentIndex(pos);
+       connect(clients,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+               this, [this]{QSettings().setValue(LASTCLIENTSETTING,clients->currentData());} );
+}
+
+QString MLogin::getCurrentClient() const
+{
+       return clients->currentData().toString();
+}
+
 void MLogin::startLogin()
 {
        qDebug()<<"Logging in...";
index 2bb39c4..9aa6b8b 100644 (file)
@@ -19,17 +19,20 @@ class QComboBox;
 class QLineEdit;
 class QSizeGrip;
 
+class MSessionManager;
+
 /**login and profile configuration window*/
 class MLogin:public QWidget
 {
        Q_OBJECT
        public:
-               MLogin();
+               explicit MLogin(MSessionManager*);
                
+               QString getCurrentClient()const;
        private:
                QString sessionid;
                QLineEdit*username,*password;
-               QComboBox*profiles;
+               QComboBox*profiles,*clients;
                QSizeGrip*resizer;
                
        protected:
@@ -39,9 +42,10 @@ class MLogin:public QWidget
                void initProfiles();
                void loadProfile();
                void startLogin();
-               void configwin();
+               void initClients(MSessionManager*);
 
        public slots:
+               void configwin();
                void relogin();
 
        signals:
index 83e37c9..18a6829 100644 (file)
@@ -9,13 +9,17 @@
 //
 
 
+#include <QAction>
 #include <QApplication>
 #include <QDebug>
 #include <QLocalServer>
 #include <QLocalSocket>
+#include <QMenu>
 #include <QMessageBox>
-#include <QSystemTrayIcon>
 #include <QProcess>
+#include <QSignalMapper>
+#include <QSystemTrayIcon>
+#include <QTimer>
 
 #include "sman.h"
 #include "login.h"
 #include "../sesscli/scrand.h"
 
 #include <msinterface.h>
+#include <mapplication.h>
 #include <WTransaction>
 
+static QPointer<MLogin> loginwindow;
+
 MSessionManager::MSessionManager ( QObject* parent ) : QObject ( parent )
 {
        // create socket
@@ -66,6 +73,15 @@ MSessionManager::MSessionManager ( QObject* parent ) : QObject ( parent )
        //create systray icon
        micon=new QSystemTrayIcon(QIcon(":/icon.png"),this);
        micon->setToolTip(tr("MagicSmoke Session Manager, waiting for login..."));
+       QMenu*m=new QMenu;
+       QSignalMapper*sm=new QSignalMapper(m);
+       for(auto entry:menuItems()){
+               QAction*a=m->addAction(entry.second);
+               sm->setMapping(a,entry.first);
+               connect(a,SIGNAL(triggered()),sm,SLOT(map()));
+       }
+       connect(sm,SIGNAL(mapped(QString)),this,SLOT(execCmd(QString)));
+       micon->setContextMenu(m);
        micon->show();
 }
 
@@ -179,7 +195,7 @@ void MSessionManager::readyRead()
                }else if(cmd=="getmenu")
                        sendMenu(s);
                else if(cmd=="exec")
-                       execCmd(par);
+                       execCmd(par.trimmed());
                else
                        qDebug()<<"Warning: unknown client command"<<cmd;
        }
@@ -213,25 +229,70 @@ void MSessionManager::socketLost ( QObject* o)
 void MSessionManager::sendMenu(QLocalSocket*s)
 {
        s->write("newmenu\n");
-       //TODO: send "menu command entry-text" for each entry
+       //send "menu command entry-text" for each entry
+       for(auto entry:menuItems())
+               s->write(QString("menu %1 %2\n").arg(entry.first).arg(entry.second).toUtf8());
        s->write("endmenu\n");
 }
 
-void MSessionManager::execCmd ( QString cmd)
+void MSessionManager::execCmd (const QString &cmd)
 {
-       qDebug()<<"I wish I knew how to execute"<<cmd;
-       QProcess *p=new QProcess;
+       qDebug()<<"Received command"<<cmd;
+       if(cmd=="config"){
+               emit openConfig();
+       }else if(cmd=="quit"){
+               qDebug()<<"Sending QUIT command to all clients and exiting!";
+               for(auto c:mconnections){
+                       c->write("quit\n");
+                       c->flush();
+               }
+               QTimer::singleShot(1000,qApp,SLOT(quit()));
+       }else if(cmd.startsWith("@")){
+               QString bin=(cmd=="@@main")?QString():"-"+cmd.mid(1);
+               startBinary(bin);
+       }else
+               qDebug()<<"I wish I knew how to execute"<<cmd<<"but it does not seem to exist.";
+}
+
+void MSessionManager::startBinary ( QString bin )
+{
+       if(!hasSession()){
+               QMessageBox::warning(nullptr,tr("Warning"),tr("Cannot start a client while not logged in!"));
+               return;
+       }
+       QProcess *p=new QProcess(this);
        p->setProcessChannelMode(QProcess::ForwardedChannels);
-       p->start(qApp->applicationDirPath()+"/magicsmoke",QStringList()<<"-sms:"+mkey);
+       connect(p,SIGNAL(finished(int,QProcess::ExitStatus)), this,SLOT(processLost(int,QProcess::ExitStatus)));
+       QString binname=qApp->applicationDirPath()+"/magicsmoke"+bin;
+       p->start(binname,QStringList()<<"-sms:"+mkey);
+       qDebug()<<"starting MagicSmoke client binary"<<binname;
+       if(!p->waitForStarted(5000)){
+               qDebug()<<"Error: binary does not start!"<<p->errorString();
+               delete p;
+               return;
+       }
+       qDebug()<<"Started"<<binname<<"as PID"<<p->processId();
+}
+
+void MSessionManager::processLost ( int exitCode, QProcess::ExitStatus exitStatus)
+{
+       QProcess *p=qobject_cast<QProcess*>(sender());
+       qDebug()<<"Process exited with status"<<exitCode<<"and status" <<(exitStatus==QProcess::NormalExit?"normal exit":"crash!");
+       if(p){
+               qDebug()<<"   ...process was a"<<p->program();
+               qDebug()<<"   ...Last Error reads"<<p->errorString();
+               p->deleteLater();
+       }
 }
 
+
 void MSessionManager::loginSucceeded()
 {
        micon->setToolTip(tr("MagicSmoke Session Manager, logged in as %1 at %2.").arg(username()).arg(profileName()));
        if(mconnections.count()>0)
                sendNewSessionId();
        else
-               execCmd("msmoke");
+               execCmd(loginwindow->getCurrentClient());
 }
 
 void MSessionManager::sendNewSessionId()
@@ -256,27 +317,37 @@ void MSessionManager::loginLost()
                s->write("closed\n");
 }
 
-
-int main(int ac,char**av)
+QList<QPair< QString, QString >> MSessionManager::menuItems() const
 {
-       QApplication app(ac,av);
-       //locate settings
-        app.setOrganizationName("MagicSmoke");
-        app.setApplicationName("MagicSmoke2");
-
-        //set icon
-        app.setWindowIcon(QIcon(":/icon.png"));
+       static QList<QPair<QString,QString>> items;
+       if(items.isEmpty()){
+               auto _ = [&](QString c,QString t){items.append(QPair<QString,QString>(c,t));};
+               _("config",tr("&Configuration..."));
+               _("@@main",tr("Start &Expert Client"));
+               _("@wizard",tr("Start &Wizard"));
+               _("@statistic",tr("Start &Statistics Client"));
+               _("@print",tr("Start &Print@Home Daemon"));
+               _("quit",tr("&Quit Session"));
+       }
+       return items;
+}
 
-       MSInterface::setAppDataDir("$BASE/.magicSmoke2");
-       WTransaction::setLogPrefix("SM-T");
 
-       MBoxWrapper::setWarning([](QString title,QString text){QMessageBox::warning(nullptr,title,text);});
 
+int main(int ac,char**av)
+{
+       MApplication app(ac,av);
+       WTransaction::setLogPrefix("SM-T");
+       app.initialize();
+        //init updater
+        app.initUpdater();
 
        MSessionManager *sm=new MSessionManager(&app);
-       MLogin lw;
+       MLogin lw(sm);
+       loginwindow=&lw;
        lw.connect(&lw,SIGNAL(loginSucceeded()),sm,SLOT(loginSucceeded()));
        lw.connect(&lw,SIGNAL(lostSession()),sm,SLOT(loginLost()));
+       lw.connect(sm,SIGNAL(openConfig()),&lw,SLOT(configwin()));
        lw.show();
 
        return app.exec();
index a0cafab..3837c54 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <QObject>
 #include <QList>
+#include <QPair>
+#include <QProcess>
 
 class QLocalServer;
 class QLocalSocket;
@@ -35,15 +37,24 @@ public:
        virtual QString profile()const;
        virtual QString profileName()const;
 
+       virtual QList<QPair<QString,QString>> menuItems()const;
+
 private slots:
        void newConnection();
        void readyRead();
        void socketClosed();
        void socketLost(QObject*);
 
+       void execCmd(const QString&);
+
        void loginSucceeded();
        void sendNewSessionId();
        void loginLost();
+       void processLost(int,QProcess::ExitStatus);
+
+signals:
+       void openConfig();
+
 private:
        QLocalServer*mserver=nullptr;
        QList<QLocalSocket*>mconnections;
@@ -51,8 +62,8 @@ private:
        QSystemTrayIcon*micon;
 
        void sendMenu(QLocalSocket*);
-       void execCmd(QString);
        void sendSessionInfo(QLocalSocket*);
+       void startBinary(QString);
 };
 
 
index f99f2da..082ec33 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "main.h"
 #include <WTransaction>
+#include "barcode-plugin.h"
 
 
 int MagicSmokeMain::realmain(int argc,char**argv)
@@ -28,6 +29,10 @@ int MagicSmokeMain::realmain(int argc,char**argv)
        
        //init
        app.initialize();
+        //init plugins
+        MBarcodeHub::instance()->initialize();
+
+       //get session
        MSessionClient sc;
        sc.connect(&sc,SIGNAL(sessionLost()),&app,SLOT(quit()));
        sc.connect(&sc,SIGNAL(managerLost()),&app,SLOT(quit()));