MythTV master
imagemanager.h
Go to the documentation of this file.
1
8
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 <utility>
49
50// Qt headers
51#include <QTemporaryDir>
52
53// MythTV headers
57
58#include "imagescanner.h"
59#include "imagemetadata.h"
60
61
62// Builtin storage groups as per storagegroup.cpp
63static constexpr const char* IMAGE_STORAGE_GROUP { "Photographs" };
64static constexpr const char* THUMBNAIL_STORAGE_GROUP { "Temp" };
65
66// Filesystem dir within config dir used by TEMP SG
67static constexpr const char* TEMP_SUBDIR { "tmp" };
68// Filesystem dir within tmp config dir where thumbnails reside
69static constexpr const char* THUMBNAIL_SUBDIR { "Images" };
70
71static constexpr int DEVICE_INVALID { -1 };
72
73class MythMediaDevice;
74class MythMediaEvent;
75
77enum ImageDisplayType : std::uint8_t {
80 kVideoOnly = 2
81};
82
83class Device;
84
95{
96public:
97 QStringList CloseDevices(int devId, const QString &action);
98 QString DeviceMount(int devId) const;
99 QString DeviceName(int devId) const;
100 int DeviceCount() const { return m_devices.size(); }
101 QString ThumbDir(int fs) const;
102
103protected:
104 int OpenDevice(const QString &name, const QString &mount,
105 MythMediaDevice *media = nullptr,
106 QTemporaryDir *dir = nullptr);
107
108 int LocateMount(const QString &mount) const;
109 StringMap GetDeviceDirs() const;
110 QList<int> GetAbsentees();
111
112 DeviceManager() = default;
114
115private:
116 using DeviceMap = QMap<int, Device*>;
117
120};
121
122
125{
126public:
127 static QStringList SupportedImages();
128
129 static QStringList SupportedVideos();
130
132 static QString ConstructPath(const QString &path, const QString &name)
133 { return path.isEmpty() ? name : path + "/" + name; }
134
136 static QString BaseNameOf(const QString &path)
137 { QString result = path.section('/', -1); return result.isNull() ? "" : result; }
138
140 static QString PathOf(const QString &path)
141 { QString result = path.section('/', 0, -2); return result.isNull() ? "" : result; }
142
143 static QString FormatSize(int sizeKib)
144 { return (sizeKib < 10000) ? QString("%L1 KiB").arg(sizeKib)
145 : QString("%L1 MiB").arg(sizeKib / 1024.0, 0, 'f', 1); }
146
148 static QString GetAbsThumbPath(const QString &devPath, const QString &path)
149 {
150 QString dirFmt = QString("%1/") % TEMP_SUBDIR % "/%2/%3";
151 return dirFmt.arg(GetConfDir(), devPath, path);
152 }
153
155 static QString ThumbPath(const ImageItem &im)
156 { return im.m_type != kVideoFile ? im.m_filePath : im.m_filePath + ".jpg"; }
157
165 QDir GetImageFilters() const { return m_dirFilter; }
166
168 ImageNodeType GetImageType(const QString &ext) const
169 {
170 if (m_imageFileExt.contains(ext))
171 return kImageFile;
172 if (m_videoFileExt.contains(ext))
173 return kVideoFile;
174 return kUnknown;
175 }
176protected:
178 virtual ~ImageAdapterBase() = default;
179
180private:
184 QStringList m_imageFileExt;
186 QStringList m_videoFileExt;
187};
188
189
197{
198public:
199 ImageAdapterLocal() = default;
200
201 ImageItem *CreateItem(const QFileInfo &fi, int parentId, int devId,
202 const QString &base) const;
203
205 StringMap GetScanDirs() const { return GetDeviceDirs(); }
206
208 static QString GetAbsFilePath(const ImagePtrK &im)
209 { return im->m_filePath; }
210
212 static QString MakeFileUrl(const QString &path) { return path; }
213
215 static QString MakeThumbUrl(const QString &devPath, const QString &path = "")
216 { return GetAbsThumbPath(devPath, path); }
217
218 static void Notify(const QString &mesg, const QStringList &extra) ;
219
220protected:
221 // Adapter functions used by Database for local images. Negate ids in & out
222 static int ImageId(int id) { return ImageItem::ToLocalId(id); }
223 static QString ImageId(const QString &id) { return ImageItem::ToLocalId(id); }
224 static int DbId(int id) { return ImageItem::ToDbId(id); }
225 static QString DbIds(const QString &ids) { return ImageItem::ToDbId(ids); }
226};
227
228
235{
236public:
238
239 ImageItem *CreateItem(const QFileInfo &fi, int parentId, int devId,
240 const QString &base) const;
241 StringMap GetScanDirs() const;
242 QString GetAbsFilePath(const ImagePtrK &im) const;
243
245 QString MakeFileUrl(const QString &path) const;
246
248 QString MakeThumbUrl(const QString &devPath, const QString &path = "") const;
249
250 static void Notify(const QString &mesg, const QStringList &extra) ;
251
252protected:
253 // Adapter functions used by Database for remote images. Do nothing
254 static int ImageId(int id) { return id; }
255 static QString ImageId(const QString &id) { return id; }
256 static int DbId(int id) { return id; }
257 static QString DbIds(const QString &ids) { return ids; }
258
259private:
261 QString m_hostname;
264 // Marked mutable as storagegroup.h does not enforce const-correctness
266};
267
268
272template <class FS>
273class META_PUBLIC ImageDb : public FS
274{
275public:
276 // Handler support
277 int GetImages(const QString &ids, ImageList &files, ImageList &dirs,
278 const QString &refine = "") const;
279 bool GetDescendants(const QString &ids,
280 ImageList &files, ImageList &dirs) const;
281 int InsertDbImage(ImageItemK &im, bool checkForDuplicate = false) const;
282 bool UpdateDbImage(ImageItemK &im) const;
283 QStringList RemoveFromDB(const ImageList &imList) const;
284
285 bool SetHidden(bool hide, const QString &ids) const;
286 bool SetCover(int dir, int id) const;
287 bool SetOrientation(int id, int orientation) const;
288
289 // Scanner support
290 bool ReadAllImages(ImageHash &files, ImageHash &dirs) const;
291 void ClearDb(int devId, const QString &action);
292
293 // ImageReader support
294 int GetChildren(const QString &ids, ImageList &files, ImageList &dirs,
295 const QString &refine = "") const;
296 bool GetImageTree(int id, ImageList &files, const QString &refine) const;
297 int GetDirectory(int id, ImagePtr &parent, ImageList &files, ImageList &dirs,
298 const QString &refine) const;
299 void GetDescendantCount(int id, bool all, int &dirs, int &pics,
300 int &videos, int &sizeKb) const;
301
302protected:
303 explicit ImageDb(QString table) : FS(), m_table(std::move(table)) {}
304
305 ImageItem *CreateImage(const MSqlQuery &query) const;
306 int ReadImages(ImageList &dirs, ImageList &files,
307 const QString &selector) const;
309 QString m_table;
310};
311
312
314class META_PUBLIC ImageDbSg : public ImageDb<ImageAdapterSg>
315{
316public:
317 ImageDbSg();
318};
319
320
322class META_PUBLIC ImageDbLocal : public ImageDb<ImageAdapterLocal>
323{
324protected:
325 ImageDbLocal();
326 ~ImageDbLocal() override { DropTable(); }
327 bool CreateTable();
328 bool m_dbExists { false };
329
330private:
331 void DropTable();
332};
333
334
336template <class DBFS>
337class META_PUBLIC ImageHandler : protected DBFS
338{
339public:
340 QStringList HandleRename(const QString &id, const QString &newBase) const;
341 QStringList HandleDelete(const QString &ids) const;
342 QStringList HandleDbCreate(QStringList defs) const;
343 QStringList HandleDbMove(const QString &ids, const QString &srcPath, QString destPath) const;
344 QStringList HandleHide(bool hide, const QString &ids) const;
345 QStringList HandleTransform(int transform, const QString &ids) const;
346 QStringList HandleDirs(const QString &destId, bool rescan,
347 const QStringList &relPaths) const;
348 QStringList HandleCover(int dir, int cover) const;
349 QStringList HandleIgnore(const QString &exclusions) const;
350 QStringList HandleScanRequest(const QString &command, int devId = DEVICE_INVALID) const;
351 QStringList HandleCreateThumbnails(const QStringList &message) const;
352 QStringList HandleGetMetadata(const QString &id) const;
353
354protected:
355 ImageHandler() : DBFS(),
356 m_thumbGen(new ImageThumb<DBFS>(this)),
357 m_scanner(new ImageScanThread<DBFS>(this, m_thumbGen)) {}
358
359 ~ImageHandler() override
360 {
361 delete m_scanner;
362 delete m_thumbGen;
363 }
364
365 void RemoveFiles(ImageList &images) const;
366
367 ImageThumb<DBFS> *m_thumbGen {nullptr};
368 ImageScanThread<DBFS> *m_scanner {nullptr};
369};
370
371
377class META_PUBLIC ImageManagerBe : protected QObject, public ImageHandler<ImageDbSg>
378{
379public:
380 static ImageManagerBe* getInstance();
381
382protected:
384 {
385 // Cleanup & terminate child threads before application exits
386 connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
387 }
388
391};
392
393
399class META_PUBLIC ImageDbReader : protected ImageHandler<ImageDbLocal>
400{
401public:
402 ~ImageDbReader() override { delete m_remote; }
403
404 int GetType() const { return m_showType; }
405 bool GetVisibility() const { return m_showHidden; }
406
407 void SetType(int showType)
408 { m_showType = showType; SetRefinementClause(); }
409
410 void SetSortOrder(int order, int dirOrder)
411 { m_dirOrder = dirOrder; m_fileOrder = order; SetRefinementClause(); }
412
413 void SetVisibility(bool showHidden)
414 { m_showHidden = showHidden; SetRefinementClause(); }
415
416 int GetImages(const ImageIdList& ids, ImageList &files, ImageList &dirs) const;
417 int GetChildren(int id, ImageList &files, ImageList &dirs) const;
418 int GetDirectory(int id, ImagePtr &parent,
419 ImageList &files, ImageList &dirs) const;
420 void GetDescendants(const ImageIdList &ids,
421 ImageList &files, ImageList &dirs) const;
422 void GetImageTree(int id, ImageList &files) const;
423 void GetDescendantCount(int id, int &dirs, int &pics, int &videos,
424 int &sizeKb) const;
425protected:
426 ImageDbReader(int order, int dirOrder, bool showAll, int showType)
427 : m_remote(new ImageDbSg()),
428 m_dirOrder(dirOrder), m_fileOrder(order),
429 m_showHidden(showAll), m_showType(showType)
430 { SetRefinementClause(); }
431
432 void SetRefinementClause();
433
434 static QString TypeSelector(int type);
435 static QString OrderSelector(int order);
436
438
444};
445
446
455class META_PUBLIC ImageManagerFe : protected QObject, public ImageDbReader
456{
458public:
459 static ImageManagerFe &getInstance();
460
461 // UI actions on all images
462 void CreateThumbnails(const ImageIdList &ids, bool forFolder);
463 QString ScanImagesAction(bool start, bool local = false);
464 static QStringList ScanQuery();
465 QString HideFiles(bool hidden, const ImageIdList &ids);
466 QString ChangeOrientation(ImageFileTransform transform, const ImageIdList &ids);
467 QString SetCover(int parent, int cover);
468 void RequestMetaData(int id);
469 static QString IgnoreDirs(const QString &excludes);
470 QString MakeDir(int parent, const QStringList &names, bool rescan = true);
471 QString RenameFile(const ImagePtrK& im, const QString &name);
472 QString CreateImages(int destId, const ImageListK &images);
473 QString MoveDbImages(const ImagePtrK& destDir, ImageListK &images, const QString &srcPath);
474 QString DeleteFiles(const ImageIdList &ids);
475 static void ClearStorageGroup();
476 void CloseDevices(int devId = DEVICE_INVALID, bool eject = false);
477
479
480 // Local Device management
481 bool DetectLocalDevices();
482 void DeviceEvent(MythMediaEvent *event);
483 QString CreateImport();
486
487 // UI helper functions
488 void SetDateFormat(const QString &format) { m_dateFormat = format; }
489 static QString LongDateOf(const ImagePtrK &im) ;
490 QString ShortDateOf(const ImagePtrK &im) const;
491 QString DeviceCaption(ImageItemK &im) const;
492 QString CrumbName(ImageItemK &im, bool getPath = false) const;
493
495 QString BuildTransferUrl(const QString &path, bool local) const
496 { return local ? ImageDbReader::MakeFileUrl(path)
497 : m_remote->MakeFileUrl(path); }
498
499protected:
500 ImageManagerFe(int order, int dirOrder, bool showAll, int showType,
501 QString dateFormat)
502 : ImageDbReader(order, dirOrder, showAll, showType),
503 m_dateFormat(std::move(dateFormat))
504 {
505 // Cleanup & terminate child threads before application exits
506 connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
507 }
508
511
514};
515
516
517#endif // IMAGEMANAGER_H
bool RemoveFromDB(Bookmark *site)
Manages image sources, ie.
Definition: imagemanager.h:95
DeviceManager()=default
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...
DeviceMap m_devices
Device store.
Definition: imagemanager.h:119
StringMap GetDeviceDirs() const
Get all known devices.
int DeviceCount() const
Definition: imagemanager.h:100
QMap< int, Device * > DeviceMap
Definition: imagemanager.h:116
A device containing images (ie. USB stick, CD, storage group etc)
Common filesystem facilities.
Definition: imagemanager.h:125
QDir GetImageFilters() const
Get filters for detecting recognised images/videos.
Definition: imagemanager.h:165
static QString ThumbPath(const ImageItem &im)
Thumbnails of videos are a JPEG snapshot with jpg suffix appended.
Definition: imagemanager.h:155
static QString ConstructPath(const QString &path, const QString &name)
Assembles a canonical file path without corrupting its absolute/relative nature.
Definition: imagemanager.h:132
static QString PathOf(const QString &path)
Extracts path from a filepath.
Definition: imagemanager.h:140
ImageNodeType GetImageType(const QString &ext) const
Determine file type from its extension.
Definition: imagemanager.h:168
static QString FormatSize(int sizeKib)
Definition: imagemanager.h:143
virtual ~ImageAdapterBase()=default
QStringList m_imageFileExt
List of file extensions recognised as pictures.
Definition: imagemanager.h:184
QDir m_dirFilter
A pre-configured dir for reading image/video files.
Definition: imagemanager.h:182
static QString BaseNameOf(const QString &path)
Extracts file name (incl extension) from a filepath.
Definition: imagemanager.h:136
static QString GetAbsThumbPath(const QString &devPath, const QString &path)
Get absolute filepath for thumbnail of an image.
Definition: imagemanager.h:148
QStringList m_videoFileExt
List of file extensions recognised as videos.
Definition: imagemanager.h:186
Filesystem adapter for Frontend, managing local devices iaw MediaMonitor.
Definition: imagemanager.h:197
static int ImageId(int id)
Definition: imagemanager.h:222
static QString GetAbsFilePath(const ImagePtrK &im)
Get absolute filepath for a local image.
Definition: imagemanager.h:208
static void Notify(const QString &mesg, const QStringList &extra)
Send local message to UI about local ids.
static int DbId(int id)
Definition: imagemanager.h:224
static QString MakeFileUrl(const QString &path)
Construct URL of a local image, which is an absolute path.
Definition: imagemanager.h:212
static QString ImageId(const QString &id)
Definition: imagemanager.h:223
static QString DbIds(const QString &ids)
Definition: imagemanager.h:225
StringMap GetScanDirs() const
Returns local device dirs to scan.
Definition: imagemanager.h:205
ImageAdapterLocal()=default
static QString MakeThumbUrl(const QString &devPath, const QString &path="")
Construct URL of the thumbnail of a local image (An absolute path)
Definition: imagemanager.h:215
ImageItem * CreateItem(const QFileInfo &fi, int parentId, int devId, const QString &base) const
Construct a local image from a file.
Filesystem adapter for Backend, managing Photographs storage group.
Definition: imagemanager.h:235
StorageGroup m_sg
Images storage group.
Definition: imagemanager.h:265
QString m_hostname
Host of SG.
Definition: imagemanager.h:261
static QString ImageId(const QString &id)
Definition: imagemanager.h:255
static int DbId(int id)
Definition: imagemanager.h:256
static int ImageId(int id)
Definition: imagemanager.h:254
static QString DbIds(const QString &ids)
Definition: imagemanager.h:257
A Database with device adapter for local images.
Definition: imagemanager.h:323
~ImageDbLocal() override
Definition: imagemanager.h:326
Provides read access to local & remote images.
Definition: imagemanager.h:400
int GetType() const
Definition: imagemanager.h:404
bool GetVisibility() const
Definition: imagemanager.h:405
QString m_refineClause
SQL clause for image filtering/ordering.
Definition: imagemanager.h:443
void SetType(int showType)
Definition: imagemanager.h:407
int m_fileOrder
Display ordering of pics/videos.
Definition: imagemanager.h:440
void SetVisibility(bool showHidden)
Definition: imagemanager.h:413
void SetSortOrder(int order, int dirOrder)
Definition: imagemanager.h:410
ImageDbSg * m_remote
Remote database access.
Definition: imagemanager.h:437
bool m_showHidden
Whether hidden images are displayed.
Definition: imagemanager.h:441
ImageDbReader(int order, int dirOrder, bool showAll, int showType)
Definition: imagemanager.h:426
int m_showType
Type of images to display - pic only/video only/both.
Definition: imagemanager.h:442
~ImageDbReader() override
Definition: imagemanager.h:402
int m_dirOrder
Display ordering of dirs.
Definition: imagemanager.h:439
A Database API with SG adapter for remote images.
Definition: imagemanager.h:315
Database API.
Definition: imagemanager.h:274
QString m_table
Db table name.
Definition: imagemanager.h:309
ImageDb(QString table)
Definition: imagemanager.h:303
A handler for image operations. Requires a database/filesystem adapter.
Definition: imagemanager.h:338
~ImageHandler() override
Definition: imagemanager.h:359
Represents a picture, video or directory.
Definition: imagetypes.h:69
static int ToDbId(int id)
Converts local image ids (negative) to Db ids (positive)
Definition: imagetypes.h:131
QString m_filePath
Absolute for local images. Usually SG-relative for remotes.
Definition: imagetypes.h:93
static int ToLocalId(int id)
Converts a DB id (positive) to an id of a local image (negative)
Definition: imagetypes.h:127
int m_type
Type of node: dir, video etc.
Definition: imagetypes.h:97
The image manager to be used by the Backend.
Definition: imagemanager.h:378
static ImageManagerBe * s_instance
BE Gallery instance.
Definition: imagemanager.h:390
The image manager for use by Frontends.
Definition: imagemanager.h:456
ImageManagerFe(int order, int dirOrder, bool showAll, int showType, QString dateFormat)
Definition: imagemanager.h:500
Q_DECLARE_TR_FUNCTIONS(ImageManagerFe)
static ImageManagerFe * s_instance
FE Gallery instance.
Definition: imagemanager.h:510
void SetDateFormat(const QString &format)
Definition: imagemanager.h:488
QString m_dateFormat
UI format for thumbnail date captions.
Definition: imagemanager.h:513
QString BuildTransferUrl(const QString &path, bool local) const
Generate Myth URL for a local or remote path.
Definition: imagemanager.h:495
Image Scanner thread requires a database/filesystem adapter.
Definition: imagescanner.h:26
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
static constexpr const char * IMAGE_STORAGE_GROUP
Definition: imagemanager.h:63
static constexpr int DEVICE_INVALID
Definition: imagemanager.h:71
static constexpr const char * TEMP_SUBDIR
Definition: imagemanager.h:67
ImageDisplayType
Display filter.
Definition: imagemanager.h:77
@ kVideoOnly
Hide pictures.
Definition: imagemanager.h:80
@ kPicAndVideo
Show Pictures & Videos.
Definition: imagemanager.h:78
@ kPicOnly
Hide videos.
Definition: imagemanager.h:79
static constexpr const char * THUMBNAIL_SUBDIR
Definition: imagemanager.h:69
static constexpr const char * THUMBNAIL_STORAGE_GROUP
Definition: imagemanager.h:64
Handles Exif/FFMpeg metadata tags for images.
ImageFileTransform
Image transformations.
Definition: imagemetadata.h:46
Synchronises image database to filesystem.
QHash< QString, ImagePtr > ImageHash
Definition: imagetypes.h:161
QVector< ImagePtr > ImageList
Definition: imagetypes.h:160
QList< ImagePtrK > ImageListK
Definition: imagetypes.h:166
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:165
QMap< int, QString > StringMap
Definition: imagetypes.h:63
ImageNodeType
Type of image node.
Definition: imagetypes.h:34
@ kImageFile
A picture.
Definition: imagetypes.h:39
@ kUnknown
Unprocessable file type.
Definition: imagetypes.h:35
@ kVideoFile
A video.
Definition: imagetypes.h:40
QSharedPointer< ImageItem > ImagePtr
Definition: imagetypes.h:159
QList< int > ImageIdList
Definition: imagetypes.h:60
QString GetConfDir(void)
Definition: mythdirs.cpp:263
#define META_PUBLIC
Definition: mythmetaexp.h:9
STL namespace.