1 #ifndef AFTL_MTP_METADATA_LIBRARY_H 2 #define AFTL_MTP_METADATA_LIBRARY_H 3 4 #include <mtp/ptp/ObjectId.h> 5 #include <mtp/ptp/ObjectFormat.h> 6 #include <mtp/types.h> 7 #include <functional> 8 #include <memory> 9 #include <string> 10 #include <unordered_map> 11 #include <unordered_set> 12 13 namespace mtp 14 { 15 class Session; 16 DECLARE_PTR(Session); 17 18 class Library 19 { 20 SessionPtr _session; 21 StorageId _storage; 22 23 public: 24 enum struct State { 25 Initialising, 26 QueryingArtists, 27 LoadingArtists, 28 QueryingAlbums, 29 LoadingAlbums, 30 Loaded 31 }; 32 using ProgressReporter = std::function<void (State, u64, u64)>; 33 34 struct Artist 35 { 36 ObjectId Id; 37 ObjectId MusicFolderId; 38 std::string Name; 39 }; 40 DECLARE_PTR(Artist); 41 42 struct Album 43 { 44 ObjectId Id; 45 ObjectId MusicFolderId; 46 ArtistPtr Artist; 47 std::string Name; 48 time_t Year = 0; 49 bool RefsLoaded = false; 50 51 void LoadRefs(); 52 53 std::unordered_set<ObjectId> Refs; 54 std::unordered_multimap<std::string, int> Tracks; 55 }; 56 DECLARE_PTR(Album); 57 58 struct NewTrackInfo 59 { 60 ObjectId Id; 61 std::string Name; 62 int Index; 63 }; 64 65 private: 66 ObjectId _artistsFolder; 67 ObjectId _albumsFolder; 68 ObjectId _musicFolder; 69 bool _artistSupported; 70 bool _albumDateAuthoredSupported; 71 72 using ArtistMap = std::unordered_map<std::string, ArtistPtr>; 73 ArtistMap _artists; 74 75 using AlbumKey = std::pair<ArtistPtr, std::string>; 76 struct AlbumKeyHash operatorAlbumKeyHash77 { size_t operator() (const AlbumKey & key) const { 78 return std::hash<ArtistPtr>()(key.first) + std::hash<std::string>()(key.second); 79 }}; 80 81 using AlbumMap = std::unordered_map<AlbumKey, AlbumPtr, AlbumKeyHash>; 82 AlbumMap _albums; 83 84 using NameToObjectIdMap = std::unordered_map<std::string, ObjectId>; 85 NameToObjectIdMap ListAssociations(ObjectId parentId); 86 87 ObjectId GetOrCreate(ObjectId parentId, const std::string &name); 88 void LoadRefs(AlbumPtr album); 89 90 public: 91 Library(const mtp::SessionPtr & session, ProgressReporter && reporter = ProgressReporter()); 92 ~Library(); 93 94 static bool Supported(const mtp::SessionPtr & session); 95 96 //search by Metadata? 97 ArtistPtr GetArtist(std::string name); 98 ArtistPtr CreateArtist(std::string name); 99 100 AlbumPtr GetAlbum(const ArtistPtr & artist, std::string name); 101 AlbumPtr CreateAlbum(const ArtistPtr & artist, std::string name, int year); 102 bool HasTrack(const AlbumPtr & album, const std::string &name, int trackIndex); 103 NewTrackInfo CreateTrack(const ArtistPtr & artist, const AlbumPtr & album, ObjectFormat type, std::string name, const std::string & genre, int trackIndex, const std::string &filename, size_t size); 104 void AddTrack(AlbumPtr album, const NewTrackInfo &ti); 105 }; 106 DECLARE_PTR(Library); 107 } 108 109 #endif 110