00001 #ifndef MAINSERVER_H_
00002 #define MAINSERVER_H_
00003
00004 #include <QReadWriteLock>
00005 #include <QStringList>
00006 #include <QRunnable>
00007 #include <QEvent>
00008 #include <QMutex>
00009 #include <QHash>
00010 #include <QMap>
00011
00012 #include <vector>
00013 using namespace std;
00014
00015 #include "tv.h"
00016 #include "playbacksock.h"
00017 #include "mthreadpool.h"
00018 #include "encoderlink.h"
00019 #include "filetransfer.h"
00020 #include "scheduler.h"
00021 #include "livetvchain.h"
00022 #include "autoexpire.h"
00023 #include "mythsocket.h"
00024 #include "mythdeque.h"
00025 #include "mythdownloadmanager.h"
00026
00027 #ifdef DeleteFile
00028 #undef DeleteFile
00029 #endif
00030
00031 class QUrl;
00032 class MythServer;
00033 class QTimer;
00034 class FileSystemInfo;
00035 class MetadataFactory;
00036 class FreeSpaceUpdater;
00037
00038 class DeleteStruct
00039 {
00040 friend class MainServer;
00041 public:
00042 DeleteStruct(MainServer *ms, QString filename, QString title,
00043 uint chanid, QDateTime recstartts, QDateTime recendts,
00044 bool forceMetadataDelete) :
00045 m_ms(ms), m_filename(filename), m_title(title),
00046 m_chanid(chanid), m_recstartts(recstartts),
00047 m_recendts(recendts),
00048 m_forceMetadataDelete(forceMetadataDelete), m_fd(-1), m_size(0)
00049 {
00050 }
00051
00052 DeleteStruct(MainServer *ms, QString filename, int fd, off_t size) :
00053 m_ms(ms), m_filename(filename), m_chanid(0),
00054 m_forceMetadataDelete(false), m_fd(fd), m_size(size)
00055 {
00056 }
00057
00058 protected:
00059 MainServer *m_ms;
00060 QString m_filename;
00061 QString m_title;
00062 uint m_chanid;
00063 QDateTime m_recstartts;
00064 QDateTime m_recendts;
00065 bool m_forceMetadataDelete;
00066 int m_fd;
00067 off_t m_size;
00068 };
00069
00070 class DeleteThread : public QRunnable, public DeleteStruct
00071 {
00072 public:
00073 DeleteThread(MainServer *ms, QString filename, QString title, uint chanid,
00074 QDateTime recstartts, QDateTime recendts,
00075 bool forceMetadataDelete) :
00076 DeleteStruct(ms, filename, title, chanid, recstartts,
00077 recendts, forceMetadataDelete) {}
00078 void start(void)
00079 { MThreadPool::globalInstance()->startReserved(this, "DeleteThread"); }
00080 void run(void);
00081 };
00082
00083 class TruncateThread : public QRunnable, public DeleteStruct
00084 {
00085 public:
00086 TruncateThread(MainServer *ms, QString filename, int fd, off_t size) :
00087 DeleteStruct(ms, filename, fd, size) {}
00088 void start(void)
00089 { MThreadPool::globalInstance()->start(this, "Truncate"); }
00090 void run(void);
00091 };
00092
00093 class MainServer : public QObject, public MythSocketCBs
00094 {
00095 Q_OBJECT
00096
00097 friend class DeleteThread;
00098 friend class TruncateThread;
00099 friend class FreeSpaceUpdater;
00100 public:
00101 MainServer(bool master, int port,
00102 QMap<int, EncoderLink *> *tvList,
00103 Scheduler *sched, AutoExpire *expirer);
00104
00105 ~MainServer();
00106
00107 void Stop(void);
00108
00109 void customEvent(QEvent *e);
00110
00111 bool isClientConnected();
00112 void ShutSlaveBackendsDown(QString &haltcmd);
00113
00114 void ProcessRequest(MythSocket *sock);
00115
00116 void readyRead(MythSocket *socket);
00117 void connectionClosed(MythSocket *socket);
00118 void connectionFailed(MythSocket *socket) { (void)socket; }
00119 void connected(MythSocket *socket) { (void)socket; }
00120
00121 void DeletePBS(PlaybackSock *pbs);
00122
00123 size_t GetCurrentMaxBitrate(void);
00124 void BackendQueryDiskSpace(QStringList &strlist, bool consolidated,
00125 bool allHosts);
00126 void GetFilesystemInfos(QList<FileSystemInfo> &fsInfos);
00127
00128 int GetExitCode() const { return m_exitCode; }
00129
00130 protected slots:
00131 void reconnectTimeout(void);
00132 void deferredDeleteSlot(void);
00133 void autoexpireUpdate(void);
00134
00135 private slots:
00136 void newConnection(MythSocket *);
00137
00138 private:
00139
00140 void ProcessRequestWork(MythSocket *sock);
00141 void HandleAnnounce(QStringList &slist, QStringList commands,
00142 MythSocket *socket);
00143 void HandleDone(MythSocket *socket);
00144
00145 void GetActiveBackends(QStringList &hosts);
00146 void HandleActiveBackendsQuery(PlaybackSock *pbs);
00147 void HandleIsActiveBackendQuery(QStringList &slist, PlaybackSock *pbs);
00148 bool HandleDeleteFile(QStringList &slist, PlaybackSock *pbs);
00149 bool HandleDeleteFile(QString filename, QString storagegroup,
00150 PlaybackSock *pbs = NULL);
00151 void HandleQueryRecordings(QString type, PlaybackSock *pbs);
00152 void HandleQueryRecording(QStringList &slist, PlaybackSock *pbs);
00153 void HandleStopRecording(QStringList &slist, PlaybackSock *pbs);
00154 void DoHandleStopRecording(RecordingInfo &recinfo, PlaybackSock *pbs);
00155 void HandleDeleteRecording(QString &chanid, QString &starttime,
00156 PlaybackSock *pbs, bool forceMetadataDelete,
00157 bool forgetHistory);
00158 void HandleDeleteRecording(QStringList &slist, PlaybackSock *pbs,
00159 bool forceMetadataDelete);
00160 void DoHandleDeleteRecording(RecordingInfo &recinfo, PlaybackSock *pbs,
00161 bool forceMetadataDelete, bool expirer=false,
00162 bool forgetHistory=false);
00163 void HandleUndeleteRecording(QStringList &slist, PlaybackSock *pbs);
00164 void DoHandleUndeleteRecording(RecordingInfo &recinfo, PlaybackSock *pbs);
00165 void HandleForgetRecording(QStringList &slist, PlaybackSock *pbs);
00166 void HandleRescheduleRecordings(const QStringList &request,
00167 PlaybackSock *pbs);
00168 void HandleGoToSleep(PlaybackSock *pbs);
00169 void HandleQueryFreeSpace(PlaybackSock *pbs, bool allBackends);
00170 void HandleQueryFreeSpaceSummary(PlaybackSock *pbs);
00171 void HandleQueryCheckFile(QStringList &slist, PlaybackSock *pbs);
00172 void HandleQueryFileExists(QStringList &slist, PlaybackSock *pbs);
00173 void HandleQueryFileHash(QStringList &slist, PlaybackSock *pbs);
00174 void HandleQueryGuideDataThrough(PlaybackSock *pbs);
00175 void HandleGetPendingRecordings(PlaybackSock *pbs, QString table = "", int recordid=-1);
00176 void HandleGetScheduledRecordings(PlaybackSock *pbs);
00177 void HandleGetConflictingRecordings(QStringList &slist, PlaybackSock *pbs);
00178 void HandleGetExpiringRecordings(PlaybackSock *pbs);
00179 void HandleSGGetFileList(QStringList &sList, PlaybackSock *pbs);
00180 void HandleSGFileQuery(QStringList &sList, PlaybackSock *pbs);
00181 void HandleGetNextFreeRecorder(QStringList &slist, PlaybackSock *pbs);
00182 void HandleGetFreeRecorder(PlaybackSock *pbs);
00183 void HandleGetFreeRecorderCount(PlaybackSock *pbs);
00184 void HandleGetFreeRecorderList(PlaybackSock *pbs);
00185 void HandleGetConnectedRecorderList(PlaybackSock *pbs);
00186 void HandleRecorderQuery(QStringList &slist, QStringList &commands,
00187 PlaybackSock *pbs);
00188 void HandleSetNextLiveTVDir(QStringList &commands, PlaybackSock *pbs);
00189 void HandleFileTransferQuery(QStringList &slist, QStringList &commands,
00190 PlaybackSock *pbs);
00191 void HandleGetRecorderNum(QStringList &slist, PlaybackSock *pbs);
00192 void HandleGetRecorderFromNum(QStringList &slist, PlaybackSock *pbs);
00193 void HandleMessage(QStringList &slist, PlaybackSock *pbs);
00194 void HandleSetVerbose(QStringList &slist, PlaybackSock *pbs);
00195 void HandleSetLogLevel(QStringList &slist, PlaybackSock *pbs);
00196 void HandleGenPreviewPixmap(QStringList &slist, PlaybackSock *pbs);
00197 void HandlePixmapLastModified(QStringList &slist, PlaybackSock *pbs);
00198 void HandlePixmapGetIfModified(const QStringList &slist, PlaybackSock *pbs);
00199 void HandleIsRecording(QStringList &slist, PlaybackSock *pbs);
00200 void HandleCheckRecordingActive(QStringList &slist, PlaybackSock *pbs);
00201 void HandleFillProgramInfo(QStringList &slist, PlaybackSock *pbs);
00202 void HandleSetChannelInfo(QStringList &slist, PlaybackSock *pbs);
00203 void HandleRemoteEncoder(QStringList &slist, QStringList &commands,
00204 PlaybackSock *pbs);
00205 void HandleLockTuner(PlaybackSock *pbs, int cardid = -1);
00206 void HandleFreeTuner(int cardid, PlaybackSock *pbs);
00207 void HandleCutMapQuery(const QString &chanid, const QString &starttime,
00208 PlaybackSock *pbs, bool commbreak);
00209 void HandleCommBreakQuery(const QString &chanid, const QString &starttime,
00210 PlaybackSock *pbs);
00211 void HandleCutlistQuery(const QString &chanid, const QString &starttime,
00212 PlaybackSock *pbs);
00213 void HandleBookmarkQuery(const QString &chanid, const QString &starttime,
00214 PlaybackSock *pbs);
00215 void HandleSetBookmark(QStringList &tokens, PlaybackSock *pbs);
00216 void HandleSettingQuery(QStringList &tokens, PlaybackSock *pbs);
00217 void HandleSetSetting(QStringList &tokens, PlaybackSock *pbs);
00218 void HandleScanVideos(PlaybackSock *pbs);
00219 void HandleVersion(MythSocket *socket, const QStringList &slist);
00220 void HandleBackendRefresh(MythSocket *socket);
00221 void HandleQueryLoad(PlaybackSock *pbs);
00222 void HandleQueryUptime(PlaybackSock *pbs);
00223 void HandleQueryHostname(PlaybackSock *pbs);
00224 void HandleQueryMemStats(PlaybackSock *pbs);
00225 void HandleQueryTimeZone(PlaybackSock *pbs);
00226 void HandleBlockShutdown(bool blockShutdown, PlaybackSock *pbs);
00227 void HandleDownloadFile(const QStringList &command, PlaybackSock *pbs);
00228 void HandleSlaveDisconnectedEvent(const MythEvent &event);
00229
00230 void SendResponse(MythSocket *pbs, QStringList &commands);
00231 void SendSlaveDisconnectedEvent(const QList<uint> &offlineEncoderIDs,
00232 bool needsReschedule);
00233
00234 void getGuideDataThrough(QDateTime &GuideDataThrough);
00235
00236 PlaybackSock *GetSlaveByHostname(const QString &hostname);
00237 PlaybackSock *GetMediaServerByHostname(const QString &hostname);
00238 PlaybackSock *GetPlaybackBySock(MythSocket *socket);
00239 FileTransfer *GetFileTransferByID(int id);
00240 FileTransfer *GetFileTransferBySock(MythSocket *socket);
00241
00242 QString LocalFilePath(const QUrl &url, const QString &wantgroup);
00243
00244 int GetfsID(QList<FileSystemInfo>::iterator fsInfo);
00245
00246 void DoTruncateThread(DeleteStruct *ds);
00247 void DoDeleteThread(DeleteStruct *ds);
00248 void DeleteRecordedFiles(DeleteStruct *ds);
00249 void DoDeleteInDB(DeleteStruct *ds);
00250
00251 LiveTVChain *GetExistingChain(const QString &id);
00252 LiveTVChain *GetExistingChain(const MythSocket *sock);
00253 LiveTVChain *GetChainWithRecording(const ProgramInfo &pginfo);
00254 void AddToChains(LiveTVChain *chain);
00255 void DeleteChain(LiveTVChain *chain);
00256
00257 void SetExitCode(int exitCode, bool closeApplication);
00258
00259 static int DeleteFile(const QString &filename, bool followLinks,
00260 bool deleteBrokenSymlinks = false);
00261 static int OpenAndUnlink(const QString &filename);
00262 static bool TruncateAndClose(ProgramInfo *pginfo,
00263 int fd, const QString &filename,
00264 off_t fsize);
00265
00266 vector<LiveTVChain*> liveTVChains;
00267 QMutex liveTVChainsLock;
00268
00269 QMap<int, EncoderLink *> *encoderList;
00270
00271 MythServer *mythserver;
00272 MetadataFactory *metadatafactory;
00273
00274 QReadWriteLock sockListLock;
00275 vector<PlaybackSock *> playbackList;
00276 vector<FileTransfer *> fileTransferList;
00277
00278 QMutex masterFreeSpaceListLock;
00279 FreeSpaceUpdater * volatile masterFreeSpaceListUpdater;
00280 QWaitCondition masterFreeSpaceListWait;
00281 QStringList masterFreeSpaceList;
00282
00283 QTimer *masterServerReconnect;
00284 PlaybackSock *masterServer;
00285
00286 bool ismaster;
00287
00288 QMutex deletelock;
00289 MThreadPool threadPool;
00290
00291 bool masterBackendOverride;
00292
00293 Scheduler *m_sched;
00294 AutoExpire *m_expirer;
00295
00296 struct DeferredDeleteStruct
00297 {
00298 PlaybackSock *sock;
00299 QDateTime ts;
00300 };
00301
00302 QMutex deferredDeleteLock;
00303 QTimer *deferredDeleteTimer;
00304 MythDeque<DeferredDeleteStruct> deferredDeleteList;
00305
00306 QTimer *autoexpireUpdateTimer;
00307 static QMutex truncate_and_close_lock;
00308
00309 QMap<QString, int> fsIDcache;
00310 QMutex fsIDcacheLock;
00311
00312 QMutex m_downloadURLsLock;
00313 QMap<QString, QString> m_downloadURLs;
00314
00315 int m_exitCode;
00316
00317 typedef QHash<QString,QString> RequestedBy;
00318 RequestedBy m_previewRequestedBy;
00319
00320 bool m_stopped;
00321
00322 static const uint kMasterServerReconnectTimeout;
00323 };
00324
00325 #endif
00326
00327