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  typedef QMap<int, Device*> DeviceMap;
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  void Notify(const QString &mesg, const QStringList &extra) const;
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  void Notify(const QString &mesg, const QStringList &extra) const;
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:
260  // Marked mutable as storagegroup.h does not enforce const-correctness
262 };
263 
264 
268 template <class FS>
269 class META_PUBLIC ImageDb : public FS
270 {
271 public:
272  // Handler support
273  int GetImages(const QString &ids, ImageList &files, ImageList &dirs,
274  const QString &refine = "") const;
275  bool GetDescendants(const QString &ids,
276  ImageList &files, ImageList &dirs) const;
277  int InsertDbImage(ImageItemK &im, bool checkForDuplicate = false) const;
278  bool UpdateDbImage(ImageItemK &im) const;
279  QStringList RemoveFromDB(const ImageList &imList) const;
280 
281  bool SetHidden(bool hide, QString ids) const;
282  bool SetCover(int dir, int id) const;
283  bool SetOrientation(int id, int orientation) const;
284 
285  // Scanner support
286  bool ReadAllImages(ImageHash &files, ImageHash &dirs) const;
287  void ClearDb(int fsId, const QString &action);
288 
289  // ImageReader support
290  int GetChildren(QString ids, ImageList &files, ImageList &dirs,
291  const QString &refine = "") const;
292  bool GetImageTree(int id, ImageList &files, const QString &refine) const;
293  int GetDirectory(int id, ImagePtr &parent, ImageList &files, ImageList &dirs,
294  const QString &refine) const;
295  void GetDescendantCount(int id, bool all, int &dirs, int &pics,
296  int &videos, int &sizeKb) const;
297 
298 protected:
299  explicit ImageDb(const QString &table) : FS(), m_table(table) {}
300 
301  ImageItem *CreateImage(const MSqlQuery &query) const;
302  int ReadImages(ImageList &dirs, ImageList &images,
303  const QString &selector) const;
305  QString m_table;
306 };
307 
308 
310 class META_PUBLIC ImageDbSg : public ImageDb<ImageAdapterSg>
311 {
312 public:
313  ImageDbSg();
314 };
315 
316 
318 class META_PUBLIC ImageDbLocal : public ImageDb<ImageAdapterLocal>
319 {
320 protected:
321  ImageDbLocal();
322  ~ImageDbLocal() { DropTable(); }
323  bool CreateTable();
325 
326 private:
327  void DropTable();
328 };
329 
330 
332 template <class DBFS>
333 class META_PUBLIC ImageHandler : protected DBFS
334 {
335 public:
336  QStringList HandleRename(const QString &, const QString &) const;
337  QStringList HandleDelete(const QString &) const;
338  QStringList HandleDbCreate(QStringList) const;
339  QStringList HandleDbMove(const QString &, const QString &, QString) const;
340  QStringList HandleHide(bool, const QString &ids) const;
341  QStringList HandleTransform(int, const QString &) const;
342  QStringList HandleDirs(const QString &, bool rescan,
343  const QStringList &relPaths) const;
344  QStringList HandleCover(int, int) const;
345  QStringList HandleIgnore(const QString &) const;
346  QStringList HandleScanRequest(const QString &, int devId = DEVICE_INVALID) const;
347  QStringList HandleCreateThumbnails(const QStringList &) const;
348  QStringList HandleGetMetadata(const QString &) const;
349 
350 protected:
351  ImageHandler() : DBFS(),
352  m_thumbGen(new ImageThumb<DBFS>(this)),
353  m_scanner(new ImageScanThread<DBFS>(this, m_thumbGen)) {}
354 
356  {
357  delete m_scanner;
358  delete m_thumbGen;
359  }
360 
361  void RemoveFiles(ImageList &) const;
362 
365 };
366 
367 
373 class META_PUBLIC ImageManagerBe : protected QObject, public ImageHandler<ImageDbSg>
374 {
375 public:
376  static ImageManagerBe* getInstance();
377 
378 protected:
379  ImageManagerBe() :QObject(), ImageHandler()
380  {
381  // Cleanup & terminate child threads before application exits
382  connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(deleteLater()));
383  }
384 
387 };
388 
389 
395 class META_PUBLIC ImageDbReader : protected ImageHandler<ImageDbLocal>
396 {
397 public:
398  ~ImageDbReader() { delete m_remote; }
399 
400  int GetType() { return m_showType; }
401  bool GetVisibility() { return m_showHidden; }
402 
403  void SetType(int showType)
404  { m_showType = showType; SetRefinementClause(); }
405 
406  void SetSortOrder(int order, int dirOrder)
407  { m_dirOrder = dirOrder; m_fileOrder = order; SetRefinementClause(); }
408 
409  void SetVisibility(bool showHidden)
410  { m_showHidden = showHidden; SetRefinementClause(); }
411 
412  int GetImages(ImageIdList ids, ImageList &files, ImageList &dirs) const;
413  int GetChildren(int id, ImageList &files, ImageList &dirs) const;
414  int GetDirectory(int id, ImagePtr &parent,
415  ImageList &files, ImageList &dirs) const;
416  void GetDescendants(const ImageIdList &ids,
417  ImageList &files, ImageList &dirs) const;
418  void GetImageTree(int id, ImageList &files) const;
419  void GetDescendantCount(int id, int &dirs, int &pics, int &videos,
420  int &sizeKb) const;
421 protected:
422  ImageDbReader(int order, int dirOrder, bool showAll, int showType)
423  : ImageHandler(), m_remote(new ImageDbSg()),
424  m_dirOrder(dirOrder), m_fileOrder(order),
425  m_showHidden(showAll), m_showType(showType)
426  { SetRefinementClause(); }
427 
428  void SetRefinementClause();
429 
430  static QString TypeSelector(int type);
431  static QString OrderSelector(int order);
432 
434 
439  QString m_refineClause;
440 };
441 
442 
451 class META_PUBLIC ImageManagerFe : protected QObject, public ImageDbReader
452 {
453  Q_DECLARE_TR_FUNCTIONS(ImageManagerFe);
454 public:
455  static ImageManagerFe &getInstance();
456 
457  // UI actions on all images
458  void CreateThumbnails(const ImageIdList &ids, bool forFolder);
459  QString ScanImagesAction(bool start, bool local = false);
460  QStringList ScanQuery();
461  QString HideFiles(bool hidden, const ImageIdList &ids);
462  QString ChangeOrientation(ImageFileTransform transform, const ImageIdList &ids);
463  QString SetCover(int parent, int cover);
464  void RequestMetaData(int id);
465  QString IgnoreDirs(const QString &excludes);
466  QString MakeDir(int, const QStringList &names, bool rescan = true);
467  QString RenameFile(ImagePtrK im, const QString &name);
468  QString CreateImages(int, const ImageListK &transfers);
469  QString MoveDbImages(ImagePtrK destDir, ImageListK &images, const QString &);
470  QString DeleteFiles(const ImageIdList &);
471  void ClearStorageGroup();
472  void CloseDevices(int devId = DEVICE_INVALID, bool eject = false);
473 
475 
476  // Local Device management
477  bool DetectLocalDevices();
478  void DeviceEvent(MythMediaEvent *event);
479  QString CreateImport();
482 
483  // UI helper functions
484  void SetDateFormat(const QString &format) { m_dateFormat = format; }
485  QString LongDateOf(ImagePtrK) const;
486  QString ShortDateOf(ImagePtrK) const;
487  QString DeviceCaption(ImageItemK &im) const;
488  QString CrumbName(ImageItemK &im, bool getPath = false) const;
489 
491  QString BuildTransferUrl(const QString &path, bool local) const
492  { return local ? ImageDbReader::MakeFileUrl(path)
493  : m_remote->MakeFileUrl(path); }
494 
495 protected:
496  ImageManagerFe(int order, int dirOrder, bool showAll, int showType,
497  QString dateFormat)
498  : ImageDbReader(order, dirOrder, showAll, showType),
499  m_dateFormat(dateFormat)
500  {
501  // Cleanup & terminate child threads before application exits
502  connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(deleteLater()));
503  }
504 
507 
509  QString m_dateFormat;
510 };
511 
512 
513 #endif // IMAGEMANAGER_H
Common filesystem facilities.
Definition: imagemanager.h:120
void SetType(int showType)
Definition: imagemanager.h:403
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:395
void Notify(const QString &mesg, const QStringList &extra) const
Send local message to UI about local ids.
bool RemoveFromDB(Bookmark *site)
QMap< int, Device * > DeviceMap
Definition: imagemanager.h:112
QString GenMythURL(QString host=QString(), QString port=QString(), QString path=QString(), QString storageGroup=QString())
Filesystem adapter for Frontend, managing local devices iaw MediaMonitor.
Definition: imagemanager.h:185
int m_dirOrder
Display ordering of dirs.
Definition: imagemanager.h:435
void SetDateFormat(const QString &format)
Definition: imagemanager.h:484
QHash< QString, ImagePtr > ImageHash
Definition: imagetypes.h:175
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:438
QString m_dateFormat
UI format for thumbnail date captions.
Definition: imagemanager.h:509
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:451
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:269
static int ToDbId(int id)
Converts local image ids (negative) to Db ids (positive)
Definition: imagetypes.h:146
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:433
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:439
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:401
bool m_showHidden
Whether hidden images are displayed.
Definition: imagemanager.h:437
ImageManagerFe(int order, int dirOrder, bool showAll, int showType, QString dateFormat)
Definition: imagemanager.h:496
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:261
QString MakeFileUrl(const QString &path) const
Construct URL of a remote image.
Definition: imagemanager.h:237
QMap< int, QString > StringMap
Definition: imagetypes.h:62
Handles Exif/FFMpeg metadata tags for images.
QString DbIds(const QString &ids) const
Definition: imagemanager.h:214
The image manager to be used by the Backend.
Definition: imagemanager.h:373
QString GetConfDir(void)
Definition: mythdirs.cpp:224
ImageThumb< DBFS > * m_thumbGen
Thumbnail generator.
Definition: imagemanager.h:363
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:436
static ImageManagerFe * m_instance
FE Gallery instance.
Definition: imagemanager.h:506
#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.
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
QString m_table
Db table name.
Definition: imagemanager.h:305
const char * name
Definition: ParseText.cpp:339
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
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:179
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:299
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
ImageScanThread< DBFS > * m_scanner
File scanner.
Definition: imagemanager.h:364
A handler for image operations. Requires a database/filesystem adapter.
Definition: imagemanager.h:333
QString MakeThumbUrl(const QString &devPath, const QString &path="") const
Construct URL of the thumbnail of a remote image.
Definition: imagemanager.h:242
QSharedPointer< ImageItem > ImagePtr
Definition: imagetypes.h:173
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
void Notify(const QString &mesg, const QStringList &extra) const
Send message to all clients about remote ids.
Image Scanner thread requires a database/filesystem adapter.
Definition: imagescanner.h:28
Represents a picture, video or directory.
Definition: imagetypes.h:67
static ImageManagerBe * m_instance
BE Gallery instance.
Definition: imagemanager.h:386
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:491
int DbId(int id) const
Definition: imagemanager.h:253
int DbId(int id) const
Definition: imagemanager.h:213
QList< int > ImageIdList
Definition: imagetypes.h:59
Hide pictures.
Definition: imagemanager.h:76
Unprocessable file type.
Definition: imagetypes.h:34
A Database with device adapter for local images.
Definition: imagemanager.h:318
int DeviceCount() const
Definition: imagemanager.h:96
Manages image sources, ie.
Definition: imagemanager.h:90
ImageNodeType
Type of image node.
Definition: imagetypes.h:33
void SetSortOrder(int order, int dirOrder)
Definition: imagemanager.h:406
QString DbIds(const QString &ids) const
Definition: imagemanager.h:254
QString m_hostport
Definition: imagemanager.h:258
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.
QList< ImagePtrK > ImageListK
Definition: imagetypes.h:180
ImageDbReader(int order, int dirOrder, bool showAll, int showType)
Definition: imagemanager.h:422
ImageDisplayType
Display filter.
Definition: imagemanager.h:73
void SetVisibility(bool showHidden)
Definition: imagemanager.h:409
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:310
StringMap GetDeviceDirs() const
Get all known devices.
QDir GetImageFilters() const
Get filters for detecting recognised images/videos.
Definition: imagemanager.h:158