Skip to content

Commit

Permalink
Syncer: sync newest songs on user refresh request
Browse files Browse the repository at this point in the history
  • Loading branch information
BLeeEZ committed Oct 7, 2021
1 parent 953bc43 commit 0f40f73
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 3 deletions.
48 changes: 48 additions & 0 deletions Amperfy/Api/Ampache/AmpacheLibrarySyncer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,54 @@ class AmpacheLibrarySyncer: LibrarySyncer {
ampacheXmlServerApi.eventLogger.error(topic: "Internal Error", statusCode: .internalError, message: "GetMusicDirectory API function is not support by Ampache")
}

func syncLatestLibraryElements(library: LibraryStorage) {
guard var syncWave = library.getLatestSyncWave() else { return }
guard let ampacheMetaData = ampacheXmlServerApi.requesetLibraryMetaData() else { return }
guard syncWave.libraryChangeDates.dateOfLastAdd != ampacheMetaData.libraryChangeDates.dateOfLastAdd else {
os_log("No new library elements available", log: log, type: .info)
return
}
let lastStr = "\(syncWave.libraryChangeDates.dateOfLastAdd)"
let newStr = "\(ampacheMetaData.libraryChangeDates.dateOfLastAdd)"
os_log("New library elements available (last: %s, new: %s)", log: log, type: .info, lastStr, newStr)

let addDate = Date(timeInterval: 1, since: syncWave.libraryChangeDates.dateOfLastAdd)
syncWave = library.createSyncWave()
syncWave.setMetaData(fromLibraryChangeDates: ampacheMetaData.libraryChangeDates)
library.saveContext()

var allParsed = false
var syncIndex = 0
repeat {
let artistParser = ArtistParserDelegate(library: library, syncWave: syncWave)
ampacheXmlServerApi.requestArtists(parserDelegate: artistParser, addDate: addDate, startIndex: syncIndex, pollCount: AmpacheXmlServerApi.maxItemCountToPollAtOnce)
syncIndex += artistParser.parsedCount
allParsed = artistParser.parsedCount == 0
} while(!allParsed)
os_log("%i new Artists synced", log: log, type: .info, syncIndex)
library.saveContext()

syncIndex = 0
repeat {
let albumParser = AlbumParserDelegate(library: library, syncWave: syncWave)
ampacheXmlServerApi.requestAlbums(parserDelegate: albumParser, addDate: addDate, startIndex: syncIndex, pollCount: AmpacheXmlServerApi.maxItemCountToPollAtOnce)
syncIndex += albumParser.parsedCount
allParsed = albumParser.parsedCount == 0
} while(!allParsed)
os_log("%i new Albums synced", log: log, type: .info, syncIndex)
library.saveContext()

syncIndex = 0
repeat {
let songParser = SongParserDelegate(library: library, syncWave: syncWave)
ampacheXmlServerApi.requestSongs(parserDelegate: songParser, addDate: addDate, startIndex: syncIndex, pollCount: AmpacheXmlServerApi.maxItemCountToPollAtOnce)
syncIndex += songParser.parsedCount
allParsed = songParser.parsedCount == 0
} while(!allParsed)
os_log("%i new Songs synced", log: log, type: .info, syncIndex)
library.saveContext()
}

func requestRandomSongs(playlist: Playlist, count: Int, library: LibraryStorage) {
guard let syncWave = library.getLatestSyncWave() else { return }
let parser = SongParserDelegate(library: library, syncWave: syncWave, parseNotifier: nil)
Expand Down
1 change: 1 addition & 0 deletions Amperfy/Api/BackendApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ protocol LibrarySyncer {
func sync(currentContext: NSManagedObjectContext, persistentContainer: NSPersistentContainer, statusNotifyier: SyncCallbacks?)
func sync(artist: Artist, library: LibraryStorage)
func sync(album: Album, library: LibraryStorage)
func syncLatestLibraryElements(library: LibraryStorage)
func syncDownPlaylistsWithoutSongs(library: LibraryStorage)
func syncDown(playlist: Playlist, library: LibraryStorage)
func syncUpload(playlistToAddSongs playlist: Playlist, songs: [Song], library: LibraryStorage)
Expand Down
4 changes: 4 additions & 0 deletions Amperfy/Api/Subsonic/SsAlbumParserDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import os.log
class SsAlbumParserDelegate: SsXmlLibWithArtworkParser {

var guessedArtist: Artist?
var parsedAlbums = [Album]()
private var albumBuffer: Album?

override func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
Expand Down Expand Up @@ -68,6 +69,9 @@ class SsAlbumParserDelegate: SsXmlLibWithArtworkParser {
switch(elementName) {
case "album":
parsedCount += 1
if let album = albumBuffer {
parsedAlbums.append(album)
}
albumBuffer = nil
default:
break
Expand Down
15 changes: 15 additions & 0 deletions Amperfy/Api/Subsonic/SubsonicLibrarySyncer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ class SubsonicLibrarySyncer: LibrarySyncer {
library.saveContext()
}

func syncLatestLibraryElements(library: LibraryStorage) {
guard let syncWave = library.getLatestSyncWave() else { return }
os_log("Sync newest albums", log: log, type: .info)
let albumDelegate = SsAlbumParserDelegate(library: library, syncWave: syncWave, subsonicUrlCreator: subsonicServerApi)
subsonicServerApi.requestLatestAlbums(parserDelegate: albumDelegate)
library.saveContext()
os_log("Sync songs of newest albums", log: log, type: .info)
for album in albumDelegate.parsedAlbums {
let songParser = SsSongParserDelegate(library: library, syncWave: syncWave, subsonicUrlCreator: subsonicServerApi)
subsonicServerApi.requestAlbum(parserDelegate: songParser, id: album.id)
}
os_log("%i newest Albums synced", log: log, type: .info, albumDelegate.parsedAlbums.count)
library.saveContext()
}

func syncMusicFolders(library: LibraryStorage) {
guard let syncWave = library.getLatestSyncWave() else { return }
let musicFolderParser = SsMusicFolderParserDelegate(library: library, syncWave: syncWave)
Expand Down
7 changes: 7 additions & 0 deletions Amperfy/Api/Subsonic/SubsonicServerApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,13 @@ class SubsonicServerApi {
request(fromUrlComponent: urlComp, viaXmlParser: parserDelegate)
}

func requestLatestAlbums(parserDelegate: SsXmlParser) {
guard var urlComp = createAuthenticatedApiUrlComponent(forAction: "getAlbumList2") else { return }
urlComp.addQueryItem(name: "type", value: "newest")
urlComp.addQueryItem(name: "size", value: 50)
request(fromUrlComponent: urlComp, viaXmlParser: parserDelegate)
}

func requestRandomSongs(parserDelegate: SsXmlParser, count: Int) {
guard var urlComp = createAuthenticatedApiUrlComponent(forAction: "getRandomSongs") else { return }
urlComp.addQueryItem(name: "size", value: count)
Expand Down
18 changes: 15 additions & 3 deletions Amperfy/Screens/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@
</connections>
</tableView>
<navigationItem key="navigationItem" title="Artists" id="r1Y-hi-fd7"/>
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="OLQ-2i-rN9">
<autoresizingMask key="autoresizingMask"/>
</refreshControl>
<connections>
<segue destination="CbP-zj-PDn" kind="show" identifier="toArtistDetail" id="PtL-O3-n85"/>
</connections>
Expand Down Expand Up @@ -310,6 +313,9 @@
</connections>
</tableView>
<navigationItem key="navigationItem" title="Albums" id="tB5-PS-t7P"/>
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="hYm-lD-F5a">
<autoresizingMask key="autoresizingMask"/>
</refreshControl>
<connections>
<segue destination="CiG-al-lkI" kind="show" identifier="toAlbumDetail" id="sdx-Gn-m0J"/>
</connections>
Expand Down Expand Up @@ -352,6 +358,9 @@
</connections>
</tableView>
<navigationItem key="navigationItem" title="Songs" id="bi8-mc-CgH"/>
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="bF0-OW-Sag">
<autoresizingMask key="autoresizingMask"/>
</refreshControl>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8cX-Lc-IQ2" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
Expand Down Expand Up @@ -2429,6 +2438,9 @@
</connections>
</tableView>
<navigationItem key="navigationItem" title="Genres" id="QuU-c2-iBn"/>
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="g8Q-Jo-DTW">
<autoresizingMask key="autoresizingMask"/>
</refreshControl>
<connections>
<segue destination="noZ-Ok-RcV" kind="show" identifier="toGenreDetail" id="gUH-lh-jqe"/>
</connections>
Expand Down Expand Up @@ -2730,9 +2742,9 @@
</scene>
</scenes>
<inferredMetricsTieBreakers>
<segue reference="kw4-13-m0t"/>
<segue reference="JPy-r0-4uB"/>
<segue reference="whh-XI-a5P"/>
<segue reference="sdx-Gn-m0J"/>
<segue reference="PtL-O3-n85"/>
<segue reference="qYo-eV-9nj"/>
</inferredMetricsTieBreakers>
<resources>
<image name="music_library" width="30" height="30"/>
Expand Down
19 changes: 19 additions & 0 deletions Amperfy/Screens/ViewController/AlbumsVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class AlbumsVC: SingleFetchedResultsTableViewController<AlbumMO> {
configureSearchController(placeholder: "Search in \"Albums\"", scopeButtonTitles: ["All", "Cached"], showSearchBarAtEnter: false)
tableView.register(nibName: AlbumTableCell.typeName)
tableView.rowHeight = AlbumTableCell.rowHeight
self.refreshControl?.addTarget(self, action: #selector(Self.handleRefresh), for: UIControl.Event.valueChanged)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
Expand Down Expand Up @@ -50,5 +51,23 @@ class AlbumsVC: SingleFetchedResultsTableViewController<AlbumMO> {
tableView.reloadData()
}

@objc func handleRefresh(refreshControl: UIRefreshControl) {
appDelegate.persistentStorage.persistentContainer.performBackgroundTask() { (context) in
if self.appDelegate.persistentStorage.settings.isOnlineMode {
let syncLibrary = LibraryStorage(context: context)
let syncer = self.appDelegate.backendApi.createLibrarySyncer()
syncer.syncLatestLibraryElements(library: syncLibrary)
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
} else {
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
}

}
}

}

19 changes: 19 additions & 0 deletions Amperfy/Screens/ViewController/ArtistsVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ArtistsVC: SingleFetchedResultsTableViewController<ArtistMO> {
configureSearchController(placeholder: "Search in \"Artists\"", scopeButtonTitles: ["All", "Cached"], showSearchBarAtEnter: false)
tableView.register(nibName: ArtistTableCell.typeName)
tableView.rowHeight = ArtistTableCell.rowHeight
self.refreshControl?.addTarget(self, action: #selector(Self.handleRefresh), for: UIControl.Event.valueChanged)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
Expand Down Expand Up @@ -49,6 +50,24 @@ class ArtistsVC: SingleFetchedResultsTableViewController<ArtistMO> {
fetchedResultsController.search(searchText: searchText, onlyCached: searchController.searchBar.selectedScopeButtonIndex == 1)
tableView.reloadData()
}

@objc func handleRefresh(refreshControl: UIRefreshControl) {
appDelegate.persistentStorage.persistentContainer.performBackgroundTask() { (context) in
if self.appDelegate.persistentStorage.settings.isOnlineMode {
let syncLibrary = LibraryStorage(context: context)
let syncer = self.appDelegate.backendApi.createLibrarySyncer()
syncer.syncLatestLibraryElements(library: syncLibrary)
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
} else {
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
}

}
}

}

19 changes: 19 additions & 0 deletions Amperfy/Screens/ViewController/GenresVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class GenresVC: SingleFetchedResultsTableViewController<GenreMO> {
configureSearchController(placeholder: "Search in \"Genres\"", scopeButtonTitles: ["All", "Cached"])
tableView.register(nibName: GenreTableCell.typeName)
tableView.rowHeight = GenreTableCell.rowHeight
self.refreshControl?.addTarget(self, action: #selector(Self.handleRefresh), for: UIControl.Event.valueChanged)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
Expand Down Expand Up @@ -42,6 +43,24 @@ class GenresVC: SingleFetchedResultsTableViewController<GenreMO> {
fetchedResultsController.search(searchText: searchText, onlyCached: searchController.searchBar.selectedScopeButtonIndex == 1)
tableView.reloadData()
}

@objc func handleRefresh(refreshControl: UIRefreshControl) {
appDelegate.persistentStorage.persistentContainer.performBackgroundTask() { (context) in
if self.appDelegate.persistentStorage.settings.isOnlineMode {
let syncLibrary = LibraryStorage(context: context)
let syncer = self.appDelegate.backendApi.createLibrarySyncer()
syncer.syncLatestLibraryElements(library: syncLibrary)
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
} else {
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
}

}
}

}

19 changes: 19 additions & 0 deletions Amperfy/Screens/ViewController/SongsVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class SongsVC: SingleFetchedResultsTableViewController<SongMO> {
tableView.rowHeight = SongTableCell.rowHeight

optionsButton = UIBarButtonItem(title: "\(CommonString.threeMiddleDots)", style: .plain, target: self, action: #selector(optionsPressed))
self.refreshControl?.addTarget(self, action: #selector(Self.handleRefresh), for: UIControl.Event.valueChanged)
}

override func viewWillAppear(_ animated: Bool) {
Expand Down Expand Up @@ -78,5 +79,23 @@ class SongsVC: SingleFetchedResultsTableViewController<SongMO> {
present(alert, animated: true, completion: nil)
}

@objc func handleRefresh(refreshControl: UIRefreshControl) {
appDelegate.persistentStorage.persistentContainer.performBackgroundTask() { (context) in
if self.appDelegate.persistentStorage.settings.isOnlineMode {
let syncLibrary = LibraryStorage(context: context)
let syncer = self.appDelegate.backendApi.createLibrarySyncer()
syncer.syncLatestLibraryElements(library: syncLibrary)
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
} else {
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
}

}
}

}

0 comments on commit 0f40f73

Please sign in to comment.