MythTV  master
imagemanager.h
Go to the documentation of this file.
1 
9 /* Myth uses two Gallery instances;
10  *
11  * One runs on the BE to manage the 'Photographs' Storage Group. The (permanent)
12  * database table is synchronised to SG files, thumbnails are generated and stored
13  * in the Temp SG, and BE messages for these images are handled.
14  *
15  * A separate instance runs on each FE to manage local/removeable media. This uses
16  * a temporary, memory Db table that is synchronised to images on USB/CDs etc,
17  * as they are mounted. Thumbnails are generated/stored on the FE and operations on
18  * these images are handled locally. The Db table and all thumbnails are removed
19  * when the FE exits.
20  *
21  * The UI integrates images/functions from both instances seamlessly.
22  *
23  * Commonality is provided by using an adapter layer for database and filesystem access.
24  * Functionality is segregated into local classes, which are layered on an
25  * adapter to assemble singletons for a BE manager & FE manager - the only
26  * elements intended for external use.
27  *
28  * Device manager
29  * |
30  * Common Adapter
31  * / \
32  * BE adapter FE adapter
33  * | Common Db API |
34  * | / \ |
35  * BE Db functions FE Db functions
36  * | Common Handler |
37  * | / \ |
38  * BE manager UI Db API
39  * |
40  * FE manager
41  *
42  * Implemented using templates rather than polymorphism for speed/efficiency.
43  */
44 
45 #ifndef IMAGEMANAGER_H
46 #define IMAGEMANAGER_H
47 
48 #include "mythcorecontext.h"
49 #include "storagegroup.h"
50 #include "mythdirs.h"
51 
52 #include "imagescanner.h"
53 #include "imagemetadata.h"
54 
55 
56 // Builtin storage groups as per storagegroup.cpp
57 #define IMAGE_STORAGE_GROUP "Photographs"
58 #define THUMBNAIL_STORAGE_GROUP "Temp"
59 
60 // Filesystem dir within config dir used by TEMP SG
61 #define TEMP_SUBDIR "tmp"
62 // Filesystem dir within tmp config dir where thumbnails reside
63 #define THUMBNAIL_SUBDIR "Images"
64 
65 #define DEVICE_INVALID -1
66 
67 #include <QTemporaryDir>
68 
69 class MythMediaDevice;
70 class MythMediaEvent;
71 
75  kPicOnly = 1,
77 };
78 
79 class Device;
80 
91 {
92 public:
93  QStringList CloseDevices(int devId, const QString &action);
94  QString DeviceMount(int devId) const;
95  QString DeviceName(int devId) const;
96  int DeviceCount() const { return m_devices.size(); }
97  QString ThumbDir(int fs) const;
98 
99 protected:
100  int OpenDevice(const QString &name, const QString &mount,
101  MythMediaDevice *media = nullptr,
102  QTemporaryDir *dir = nullptr);
103 
104  int LocateMount(const QString &mount) const;
105  StringMap GetDeviceDirs() const;
106  QList<int> GetAbsentees();
107 
108  DeviceManager() : m_devices() {}
109  ~DeviceManager();
110 
111 private:
112  using DeviceMap = QMap<int, Device*>;
113 
116 };
117 
118 
121 {
122 public:
123  static QStringList SupportedImages();
124 
125  static QStringList SupportedVideos();
126 
128  static QString ConstructPath(const QString &path, const QString &name)
129  { return path.isEmpty() ? name : path + "/" + name; }
130 
132  static QString BaseNameOf(const QString &path)
133  { QString result = path.section('/', -1); return result.isNull() ? "" : result; }
134 
136  static QString PathOf(const QString &path)
137  { QString result = path.section('/', 0, -2); return result.isNull() ? "" : result; }
138 
139  static QString FormatSize(int sizeKib)
140  { return (sizeKib < 10000) ? QString("%L1 KiB").arg(sizeKib)
141  : QString("%L1 MiB").arg(sizeKib / 1024.0, 0, 'f', 1); }
142 
144  static QString GetAbsThumbPath(const QString &devPath, const QString &path)
145  { return QString("%1/" TEMP_SUBDIR "/%2/%3").arg(GetConfDir(), devPath, path); }
146 
148  static QString ThumbPath(const ImageItem &im)
149  { return im.m_type != kVideoFile ? im.m_filePath : im.m_filePath + ".jpg"; }
150 
158  QDir GetImageFilters() const { return m_dirFilter; }
159 
161  ImageNodeType GetImageType(const QString &ext) const
162  { return m_imageFileExt.contains(ext)
163  ? kImageFile
164  : m_videoFileExt.contains(ext) ? kVideoFile : kUnknown; }
165 protected:
167  virtual ~ImageAdapterBase() = default;
168 
169 private:
173  QStringList m_imageFileExt;
175  QStringList m_videoFileExt;
176 };
177 
178 
186 {
187 public:
189 
190  ImageItem *CreateItem(const QFileInfo &fi, int parentId, int devId,
191  const QString &base) const;
192 
194  StringMap GetScanDirs() const { return GetDeviceDirs(); }
195 
197  QString GetAbsFilePath(const ImagePtrK &im) const
198  { return im->m_filePath; }
199 
201  QString MakeFileUrl(const QString &path) const { return path; }
202 
204  QString MakeThumbUrl(const QString &devPath, const QString &path = "") const
205  { return GetAbsThumbPath(devPath, path); }
206 
207  static void Notify(const QString &mesg, const QStringList &extra) ;
208 
209 protected:
210  // Adapter functions used by Database for local images. Negate ids in & out
211  int ImageId(int id) const { return ImageItem::ToLocalId(id); }
212  QString ImageId(const QString &id) const { return ImageItem::ToLocalId(id); }
213  int DbId(int id) const { return ImageItem::ToDbId(id); }
214  QString DbIds(const QString &ids) const { return ImageItem::ToDbId(ids); }
215 };
216 
217 
224 {
225 public:
227  m_hostname(gCoreContext->GetMasterHostName()),
228  m_hostport(gCoreContext->GetMasterServerPort()),
230 
231  ImageItem *CreateItem(const QFileInfo &fi, int parentId, int devId,
232  const QString &base) const;
233  StringMap GetScanDirs() const;
234  QString GetAbsFilePath(const ImagePtrK &im) const;
235 
237  QString MakeFileUrl(const QString &path) const
238  { return gCoreContext->GenMythURL(m_hostname, m_hostport, path,
240 
242  QString MakeThumbUrl(const QString &devPath, const QString &path = "") const
244  devPath + "/" + path,
246 
247  static void Notify(const QString &mesg, const QStringList &extra) ;
248 
249 protected:
250  // Adapter functions used by Database for remote images. Do nothing
251  int ImageId(int id) const { return id; }
252  QString ImageId(const QString &id) const { return id; }
253  int DbId(int id) const { return id; }
254  QString DbIds(const QString &ids) const { return ids; }
255 
256 private:
258  QString m_hostname;
261  // Marked mutable as storagegroup.h does not enforce const-correctness
263 };
264 
265 
269 template <class FS>
270 class META_PUBLIC ImageDb : public FS
271 {
272 public:
273  // Handler support
274  int GetImages(const QString &ids, ImageList &files, ImageList &dirs,
275  const QString &refine = "") const;
276  bool GetDescendants(const QString &ids,
277  ImageList &files, ImageList &dirs) const;
278  int InsertDbImage(ImageItemK &im, bool checkForDuplicate = false) const;
279  bool UpdateDbImage(ImageItemK &im) const;
280  QStringList RemoveFromDB(const ImageList &imList) const;
281 
282  bool SetHidden(bool hide, QString ids) const;
283  bool SetCover(int dir, int id) const;
284  bool SetOrientation(int id, int orientation) const;
285 
286  // Scanner support
287  bool ReadAllImages(ImageHash &files, ImageHash &dirs) const;
288  void ClearDb(int devId, const QString &action);
289 
290  // ImageReader support
291  int GetChildren(QString ids, ImageList &files, ImageList &dirs,
292  const QString &refine = "") const;
293  bool GetImageTree(int id, ImageList &files, const QString &refine) const;
294  int GetDirectory(int id, ImagePtr &parent, ImageList &files, ImageList &dirs,
295  const QString &refine) const;
296  void GetDescendantCount(int id, bool all, int &dirs, int &pics,
297  int &videos, int &sizeKb) const;
298 
299 protected:
300  explicit ImageDb(const QString &table) : FS(), m_table(table) {}
301 
302  ImageItem *CreateImage(const MSqlQuery &query) const;
303  int ReadImages(ImageList &dirs, ImageList &files,
304  const QString &selector) const;
306  QString m_table;
307 };
308 
309 
311 class META_PUBLIC ImageDbSg : public ImageDb<ImageAdapterSg>
312 {
313 public:
314  ImageDbSg();
315 };
316 
317 
319 class META_PUBLIC ImageDbLocal : public ImageDb<ImageAdapterLocal>
320 {
321 protected:
322  ImageDbLocal();
323  ~ImageDbLocal() { DropTable(); }
324  bool CreateTable();
326 
327 private:
328  void DropTable();
329 };
330 
331 
333 template <class DBFS>
334 class META_PUBLIC ImageHandler : protected DBFS
335 {
336 public:
337  QStringList HandleRename(const QString &, const QString &) const;
338  QStringList HandleDelete(const QString &) const;
339  QStringList HandleDbCreate(QStringList) const;
340  QStringList HandleDbMove(const QString &, const QString &, QString) const;
341  QStringList HandleHide(bool, const QString &ids) const;
342  QStringList HandleTransform(int, const QString &) const;
343  QStringList HandleDirs(const QString &, bool rescan,
344  const QStringList &relPaths) const;
345  QStringList HandleCover(int, int) const;
346  QStringList HandleIgnore(const QString &) const;
347  QStringList HandleScanRequest(const QString &, int devId = DEVICE_INVALID) const;
348  QStringList HandleCreateThumbnails(const QStringList &) const;
349  QStringList HandleGetMetadata(const QString &) const;
350 
351 protected:
352  ImageHandler() : DBFS(),
353  m_thumbGen(new ImageThumb<DBFS>(this)),
354  m_scanner(new ImageScanThread<DBFS>(this, m_thumbGen)) {}
355 
357  {
358  delete m_scanner;
359  delete m_thumbGen;
360  }
361 
362  void RemoveFiles(ImageList &) const;
363 
364  ImageThumb<DBFS> *m_thumbGen {nullptr};
365  ImageScanThread<DBFS> *m_scanner {nullptr};
366 };
367 
368 
374 class META_PUBLIC ImageManagerBe : protected QObject, public ImageHandler<ImageDbSg>
375 {
376 public:
377  static ImageManagerBe* getInstance();
378 
379 protected:
380  ImageManagerBe() :QObject(), ImageHandler()
381  {
382  // Cleanup & terminate child threads before application exits
383  connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(deleteLater()));
384  }
385 
388 };
389 
390 
396 class META_PUBLIC ImageDbReader : protected ImageHandler<ImageDbLocal>
397 {
398 public:
399  ~ImageDbReader() { delete m_remote; }
400 
401  int GetType() { return m_showType; }
402  bool GetVisibility() { return m_showHidden; }
403 
404  void SetType(int showType)
405  { m_showType = showType; SetRefinementClause(); }
406 
407  void SetSortOrder(int order, int dirOrder)
408  { m_dirOrder = dirOrder; m_fileOrder = order; SetRefinementClause(); }
409 
410  void SetVisibility(bool showHidden)
411  { m_showHidden = showHidden; SetRefinementClause(); }
412 
413  int GetImages(const ImageIdList& ids, ImageList &files, ImageList &dirs) const;
414  int GetChildren(int id, ImageList &files, ImageList &dirs) const;
415  int GetDirectory(int id, ImagePtr &parent,
416  ImageList &files, ImageList &dirs) const;
417  void GetDescendants(const ImageIdList &ids,
418  ImageList &files, ImageList &dirs) const;
419  void GetImageTree(int id, ImageList &files) const;
420  void GetDescendantCount(int id, int &dirs, int &pics, int &videos,
421  int &sizeKb) const;
422 protected:
423  ImageDbReader(int order, int dirOrder, bool showAll, int showType)
424  : ImageHandler(), m_remote(new ImageDbSg()),
425  m_dirOrder(dirOrder), m_fileOrder(order),
426  m_showHidden(showAll), m_showType(showType)
427  { SetRefinementClause(); }
428 
429  void SetRefinementClause();
430 
431  static QString TypeSelector(int type);
432  static QString OrderSelector(int order);
433 
435 
440  QString m_refineClause;
441 };
442 
443 
452 class META_PUBLIC ImageManagerFe : protected QObject, public ImageDbReader
453 {
454  Q_DECLARE_TR_FUNCTIONS(ImageManagerFe);
455 public:
456  static ImageManagerFe &getInstance();
457 
458  // UI actions on all images
459  void CreateThumbnails(const ImageIdList &ids, bool forFolder);
460  QString ScanImagesAction(bool start, bool local = false);
461  static QStringList ScanQuery();
462  QString HideFiles(bool hidden, const ImageIdList &ids);
463  QString ChangeOrientation(ImageFileTransform transform, const ImageIdList &ids);
464  QString SetCover(int parent, int cover);
465  void RequestMetaData(int id);
466  static QString IgnoreDirs(const QString &excludes);
467  QString MakeDir(int, const QStringList &names, bool rescan = true);
468  QString RenameFile(const ImagePtrK& im, const QString &name);
469  QString CreateImages(int, const ImageListK &images);
470  QString MoveDbImages(const ImagePtrK& destDir, ImageListK &images, const QString &);
471  QString DeleteFiles(const ImageIdList &);
472  static void ClearStorageGroup();
473  void CloseDevices(int devId = DEVICE_INVALID, bool eject = false);
474 
476 
477  // Local Device management
478  bool DetectLocalDevices();
479  void DeviceEvent(MythMediaEvent *event);
480  QString CreateImport();
483 
484  // UI helper functions
485  void SetDateFormat(const QString &format) { m_dateFormat = format; }
486  static QString LongDateOf(const ImagePtrK&) ;
487  QString ShortDateOf(const ImagePtrK&) const;
488  QString DeviceCaption(ImageItemK &im) const;
489  QString CrumbName(ImageItemK &im, bool getPath = false) const;
490 
492  QString BuildTransferUrl(const QString &path, bool local) const
493  { return local ? ImageDbReader::MakeFileUrl(path)
494  : m_remote->MakeFileUrl(path); }
495 
496 protected:
497  ImageManagerFe(int order, int dirOrder, bool showAll, int showType,
498  QString dateFormat)
499  : ImageDbReader(order, dirOrder, showAll, showType),
500  m_dateFormat(dateFormat)
501  {
502  // Cleanup & terminate child threads before application exits
503  connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(deleteLater()));
504  }
505 
508 
510  QString m_dateFormat;
511 };
512 
513 
514 #endif // IMAGEMANAGER_H
Common filesystem facilities.
Definition: imagemanager.h:120
void SetType(int showType)
Definition: imagemanager.h:404
A video.
Definition: imagetypes.h:39
static QString FormatSize(int sizeKib)
Definition: imagemanager.h:139
Provides read access to local & remote images.
Definition: imagemanager.h:396
QSharedPointer< ImageItem > ImagePtr
Definition: imagetypes.h:173
bool RemoveFromDB(Bookmark *site)
Filesystem adapter for Frontend, managing local devices iaw MediaMonitor.
Definition: imagemanager.h:185
int m_dirOrder
Display ordering of dirs.
Definition: imagemanager.h:436
void SetDateFormat(const QString &format)
Definition: imagemanager.h:485
static int ToLocalId(int id)
Converts a DB id (positive) to an id of a local image (negative)
Definition: imagetypes.h:142
int m_showType
Type of images to display - pic only/video only/both.
Definition: imagemanager.h:439
QString m_dateFormat
UI format for thumbnail date captions.
Definition: imagemanager.h:510
static QString GetAbsThumbPath(const QString &devPath, const QString &path)
Get absolute filepath for thumbnail of an image.
Definition: imagemanager.h:144
The image manager for use by Frontends.
Definition: imagemanager.h:452
QString m_filePath
Absolute for local images. Usually SG-relative for remotes.
Definition: imagetypes.h:100
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
Database API.
Definition: imagemanager.h:270
static int ToDbId(int id)
Converts local image ids (negative) to Db ids (positive)
Definition: imagetypes.h:146
QMap< int, Device * > DeviceMap
Definition: imagemanager.h:112
QString m_hostname
Host of SG.
Definition: imagemanager.h:258
int ImageId(int id) const
Definition: imagemanager.h:211
static QString ThumbPath(const ImageItem &im)
Thumbnails of videos are a JPEG snapshot with jpg suffix appended.
Definition: imagemanager.h:148
QDir m_dirFilter
A pre-configured dir for reading image/video files.
Definition: imagemanager.h:171
ImageDbSg * m_remote
Remote database access.
Definition: imagemanager.h:434
QString ImageId(const QString &id) const
Definition: imagemanager.h:252
Show Pictures & Videos.
Definition: imagemanager.h:74
QString m_refineClause
SQL clause for image filtering/ordering.
Definition: imagemanager.h:440
QString GetAbsFilePath(const ImagePtrK &im) const
Get absolute filepath for a remote image.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
bool GetVisibility()
Definition: imagemanager.h:402
bool m_showHidden
Whether hidden images are displayed.
Definition: imagemanager.h:438
ImageManagerFe(int order, int dirOrder, bool showAll, int showType, QString dateFormat)
Definition: imagemanager.h:497
static void Notify(const QString &mesg, const QStringList &extra)
Send message to all clients about remote ids.
int OpenDevice(const QString &name, const QString &mount, MythMediaDevice *media=nullptr, QTemporaryDir *dir=nullptr)
Define a new device and assign it a unique id. If the device is already known, its existing id is ret...
QStringList CloseDevices(int devId, const QString &action)
Remove a device (or all devices)
StorageGroup m_sg
Images storage group.
Definition: imagemanager.h:262
QString MakeFileUrl(const QString &path) const
Construct URL of a remote image.
Definition: imagemanager.h:237
Handles Exif/FFMpeg metadata tags for images.
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:179
QString DbIds(const QString &ids) const
Definition: imagemanager.h:214
The image manager to be used by the Backend.
Definition: imagemanager.h:374
QString GetConfDir(void)
Definition: mythdirs.cpp:224
QString ImageId(const QString &id) const
Definition: imagemanager.h:212
Hide videos.
Definition: imagemanager.h:75
A device containing images (ie. USB stick, CD, storage group etc)
#define THUMBNAIL_STORAGE_GROUP
Definition: imagemanager.h:58
ImageFileTransform
Image transformations.
Definition: imagemetadata.h:42
QStringList m_imageFileExt
List of file extensions recognised as pictures.
Definition: imagemanager.h:173
int m_fileOrder
Display ordering of pics/videos.
Definition: imagemanager.h:437
static ImageManagerBe * s_instance
BE Gallery instance.
Definition: imagemanager.h:387
#define TEMP_SUBDIR
Definition: imagemanager.h:61
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
#define META_PUBLIC
Definition: mythmetaexp.h:9
ImageNodeType GetImageType(const QString &ext) const
Determine file type from its extension.
Definition: imagemanager.h:161
bool SetCover(int dir, int id) const
Set the thumbnail(s) to be used for a dir.
QMap< int, QString > StringMap
Definition: imagetypes.h:62
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
ImageItem * CreateItem(const QFileInfo &fi, int parentId, int devId, const QString &base) const
Construct a local image from a file.
StringMap GetScanDirs() const
Returns SG dirs.
static QString BaseNameOf(const QString &path)
Extracts file name (incl extension) from a filepath.
Definition: imagemanager.h:132
StringMap GetScanDirs() const
Returns local device dirs to scan.
Definition: imagemanager.h:194
static ImageManagerFe * s_instance
FE Gallery instance.
Definition: imagemanager.h:507
QString m_table
Db table name.
Definition: imagemanager.h:306
static QString ConstructPath(const QString &path, const QString &name)
Assembles a canonical file path without corrupting its absolute/relative nature.
Definition: imagemanager.h:128
DeviceMap m_devices
Device store.
Definition: imagemanager.h:115
QList< ImagePtr > ImageList
Definition: imagetypes.h:174
Synchronises image database to filesystem.
A picture.
Definition: imagetypes.h:38
ImageDb(const QString &table)
Definition: imagemanager.h:300
QString GetAbsFilePath(const ImagePtrK &im) const
Get absolute filepath for a local image.
Definition: imagemanager.h:197
int ImageId(int id) const
Definition: imagemanager.h:251
QList< int > ImageIdList
Definition: imagetypes.h:59
A handler for image operations. Requires a database/filesystem adapter.
Definition: imagemanager.h:334
QString MakeThumbUrl(const QString &devPath, const QString &path="") const
Construct URL of the thumbnail of a remote image.
Definition: imagemanager.h:242
QStringList m_videoFileExt
List of file extensions recognised as videos.
Definition: imagemanager.h:175
QString MakeFileUrl(const QString &path) const
Construct URL of a local image, which is an absolute path.
Definition: imagemanager.h:201
Image Scanner thread requires a database/filesystem adapter.
Definition: imagescanner.h:28
Represents a picture, video or directory.
Definition: imagetypes.h:67
int m_type
Type of node: dir, video etc.
Definition: imagetypes.h:104
QString BuildTransferUrl(const QString &path, bool local) const
Generate Myth URL for a local or remote path.
Definition: imagemanager.h:492
int DbId(int id) const
Definition: imagemanager.h:253
int DbId(int id) const
Definition: imagemanager.h:213
Hide pictures.
Definition: imagemanager.h:76
Unprocessable file type.
Definition: imagetypes.h:34
A Database with device adapter for local images.
Definition: imagemanager.h:319
int DeviceCount() const
Definition: imagemanager.h:96
static void Notify(const QString &mesg, const QStringList &extra)
Send local message to UI about local ids.
Manages image sources, ie.
Definition: imagemanager.h:90
ImageNodeType
Type of image node.
Definition: imagetypes.h:33
QHash< QString, ImagePtr > ImageHash
Definition: imagetypes.h:175
void SetSortOrder(int order, int dirOrder)
Definition: imagemanager.h:407
QString DbIds(const QString &ids) const
Definition: imagemanager.h:254
Filesystem adapter for Backend, managing Photographs storage group.
Definition: imagemanager.h:223
QString MakeThumbUrl(const QString &devPath, const QString &path="") const
Construct URL of the thumbnail of a local image (An absolute path)
Definition: imagemanager.h:204
ImageItem * CreateItem(const QFileInfo &fi, int parentId, int devId, const QString &base) const
Construct a remote image from a file.
ImageDbReader(int order, int dirOrder, bool showAll, int showType)
Definition: imagemanager.h:423
ImageDisplayType
Display filter.
Definition: imagemanager.h:73
void SetVisibility(bool showHidden)
Definition: imagemanager.h:410
static QString PathOf(const QString &path)
Extracts path from a filepath.
Definition: imagemanager.h:136
#define DEVICE_INVALID
Definition: imagemanager.h:65
#define IMAGE_STORAGE_GROUP
Definition: imagemanager.h:57
A Database API with SG adapter for remote images.
Definition: imagemanager.h:311
StringMap GetDeviceDirs() const
Get all known devices.
QList< ImagePtrK > ImageListK
Definition: imagetypes.h:180
QDir GetImageFilters() const
Get filters for detecting recognised images/videos.
Definition: imagemanager.h:158