File indexing completed on 2024-04-14 05:34:15
0001 /* 0002 SPDX-FileCopyrightText: 2011 Vishesh Yadav <vishesh3y@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef HG_SERVE_WRAPPER_H 0008 #define HG_SERVE_WRAPPER_H 0009 0010 #include <QHash> 0011 #include <QProcess> 0012 #include <QTextCodec> 0013 #include <QString> 0014 #include <KLocalizedString> 0015 0016 class ServerProcessType; 0017 0018 /** 0019 * Wrapper to manage web server instances of mercurial repository. More than one 0020 * server can be handled. 0021 * 0022 * This wrapper should be singleton hence only one instance should be created 0023 * and used. Hence, never create an object statically or use 'new' operator. 0024 * Use instance() method to get(create) an instance. 0025 */ 0026 class HgServeWrapper : public QObject 0027 { 0028 Q_OBJECT 0029 0030 public: 0031 explicit HgServeWrapper(QObject *parent=nullptr); 0032 ~HgServeWrapper() override; 0033 0034 /** 0035 * Returns pointer to singleton instance of the wrapper. An instance is 0036 * created if none exists. 0037 * 0038 * @return Pointer to the instance 0039 */ 0040 static HgServeWrapper *instance(); 0041 0042 /** 0043 * Starts a new instance of server. 0044 * 0045 * @param repoLocation Path to repository which is to be hosted on server 0046 * @param portNumber Port to create server on. 0047 * 0048 */ 0049 void startServer(const QString &repoLocation, int portNumber); 0050 0051 /** 0052 * Stops a server. 0053 * 0054 * @param repoLocation Path to repository whose server instance in this 0055 * has to be stopped. 0056 */ 0057 void stopServer(const QString &repoLocation); 0058 0059 /** 0060 * Checks whether a web server for given repository is running under this 0061 * wrapper. 0062 * 0063 * @param repoLocation Path to repository 0064 * @return true if running/started else false 0065 */ 0066 bool running(const QString &repoLocation); 0067 0068 /** 0069 * Cleans all resources in this wrapper used by non-running servers 0070 */ 0071 void cleanUnused(); 0072 0073 /** 0074 * If terminated, get error message of that server instances 0075 */ 0076 QString errorMessage(const QString &repoLocation); 0077 0078 /** 0079 * Check if the just stopped server for given repository was 0080 * exited successfully. 0081 * 0082 * @param repoLocation Path to repository 0083 * @return true if exitCode == 0 and exitStatus == Normal, otherwise false 0084 */ 0085 bool normalExit(const QString &repoLocation); 0086 0087 Q_SIGNALS: 0088 // These signals are emitted for every ServerProcessType in list. Its upto 0089 // the owner of this wrapper to decide which server was updated. If any of 0090 // these signals are emitted cleanUnused() is called and every initiater 0091 // of server should check status and act according. 0092 void finished(); 0093 void error(); 0094 void started(); 0095 void readyReadLine(const QString &repoLocation, const QString &line); 0096 0097 private: 0098 0099 private Q_SLOTS: 0100 void slotFinished(int exitCode, QProcess::ExitStatus status); 0101 0102 private: 0103 QHash<QString, ServerProcessType*> m_serverList; 0104 static HgServeWrapper *m_instance; 0105 }; 0106 0107 //FIXME: Had to change struct to class and make it unnested. 0108 // Hide member variables. 0109 0110 /** 0111 * Represents a Mercurial Server instance. 0112 */ 0113 class ServerProcessType : public QObject { 0114 Q_OBJECT 0115 0116 public: 0117 QProcess process; 0118 int port; 0119 0120 ServerProcessType() 0121 { 0122 connect(&process, &QProcess::readyReadStandardOutput, 0123 this, &ServerProcessType::slotAppendOutput); 0124 connect(&process, &QProcess::readyReadStandardError, 0125 this, &ServerProcessType::slotAppendRemainingOutput); 0126 connect(&process, &QProcess::finished, 0127 this, &ServerProcessType::slotFinished); 0128 } 0129 0130 Q_SIGNALS: 0131 void readyReadLine(const QString &repoLocation, const QString &line); 0132 0133 private Q_SLOTS: 0134 void slotAppendOutput() 0135 { 0136 if (process.canReadLine()) { 0137 Q_EMIT readyReadLine(process.workingDirectory(), 0138 QTextCodec::codecForLocale()->toUnicode(process.readAllStandardOutput()).trimmed()); 0139 } 0140 } 0141 0142 void slotAppendRemainingOutput() 0143 { 0144 Q_EMIT readyReadLine(process.workingDirectory(), 0145 QTextCodec::codecForLocale()->toUnicode(process.readAllStandardError()).trimmed()); 0146 } 0147 0148 void slotFinished() 0149 { 0150 Q_EMIT readyReadLine(process.workingDirectory(), 0151 i18n("## Server Stopped! ##\n")); 0152 } 0153 }; 0154 0155 #endif /* HG_SERVE_WRAPPER_H */ 0156 0157