mirror of
https://github.com/memen45/SubMusic.git
synced 2026-02-18 00:57:39 +01:00
fixed some rare crashes on receiving invalid response added setting to enable debug logging removed default debug output (speed improvement)
443 lines
8.3 KiB
MonkeyC
443 lines
8.3 KiB
MonkeyC
using Toybox.System;
|
|
using Toybox.Application;
|
|
|
|
class Playlist {
|
|
|
|
// required external playlist properties
|
|
hidden var d_id;
|
|
hidden var d_name = "default";
|
|
hidden var d_songCount = 0;
|
|
|
|
// optional external playlist properties
|
|
hidden var d_songs = []; // array of song ids
|
|
|
|
// required internal playlist properties
|
|
hidden var d_time = 0; // total playing time of the playlist in seconds
|
|
|
|
hidden var d_remote = false; // true if metadata remotely available (according to last check)
|
|
hidden var d_synced = false; // true if no songs failed during sync -> or track by date last synced?
|
|
|
|
hidden var d_linked = false; // true if all songs are referenced in their refCount
|
|
hidden var d_local = false; // true if should be locally available, false if should not
|
|
|
|
hidden var d_podcast = false; // true if playback position is stored,
|
|
|
|
|
|
function initialize(storage) {
|
|
// if ($.debug) {
|
|
// System.println("Playlist::initialize( storage = " + storage + " )");
|
|
// }
|
|
if ($.debug) {
|
|
System.println("Playlist::initialize( storage : " + storage + " )");
|
|
}
|
|
|
|
d_id = storage["id"];
|
|
fromStorage(storage);
|
|
}
|
|
|
|
function fromStorage(storage) {
|
|
if (storage["name"] != null) {
|
|
d_name = storage["name"];
|
|
}
|
|
if (storage["songCount"] != null) {
|
|
d_songCount = storage["songCount"];
|
|
}
|
|
if (storage["songs"] != null) {
|
|
d_songs = storage["songs"];
|
|
}
|
|
if (storage["time"] != null) {
|
|
d_time = storage["time"];
|
|
}
|
|
if (storage["remote"] != null) {
|
|
d_remote = storage["remote"];
|
|
}
|
|
if (storage["synced"] != null) {
|
|
d_synced = storage["synced"];
|
|
}
|
|
if (storage["local"] != null) {
|
|
d_local = storage["local"];
|
|
}
|
|
if (storage["linked"] != null) {
|
|
d_linked = storage["linked"];
|
|
}
|
|
if (storage["podcast"] != null) {
|
|
d_podcast = storage["podcast"];
|
|
}
|
|
}
|
|
|
|
function toStorage() {
|
|
return {
|
|
"id" => d_id,
|
|
"name" => d_name,
|
|
"songCount" => d_songCount,
|
|
|
|
"songs" => d_songs,
|
|
"time" => d_time,
|
|
|
|
"linked" => d_linked,
|
|
"remote" => d_remote,
|
|
"synced" => d_synced,
|
|
"local" => d_local,
|
|
|
|
"podcast" => d_podcast,
|
|
};
|
|
}
|
|
|
|
// getters
|
|
function id() {
|
|
return d_id;
|
|
}
|
|
|
|
function name() {
|
|
return d_name;
|
|
}
|
|
|
|
function count() {
|
|
return d_songCount;
|
|
}
|
|
|
|
function songs() {
|
|
return d_songs;
|
|
}
|
|
|
|
function remote() {
|
|
return d_remote;
|
|
}
|
|
|
|
function local() {
|
|
return d_local;
|
|
}
|
|
|
|
function synced() {
|
|
return d_synced;
|
|
}
|
|
|
|
function linked() {
|
|
return d_linked;
|
|
}
|
|
|
|
function time() {
|
|
return d_time;
|
|
}
|
|
|
|
function podcast() {
|
|
return d_podcast;
|
|
}
|
|
|
|
}
|
|
|
|
// playlist connection to store
|
|
class IPlaylist extends Playlist {
|
|
|
|
// storage access
|
|
private var d_stored = false; // true if playlist metadata is in storage
|
|
|
|
function initialize(id) {
|
|
if ($.debug) {
|
|
System.println("IPlaylist::initialize( id : " + id + " )");
|
|
}
|
|
var storage = PlaylistStore.get(id);
|
|
if (storage != null) {
|
|
d_stored = true;
|
|
} else {
|
|
storage = {"id" => id}; // nothing known yet except for id
|
|
}
|
|
|
|
Playlist.initialize(storage);
|
|
}
|
|
|
|
function stored() {
|
|
return d_stored;
|
|
}
|
|
|
|
// setters
|
|
function addSong(id) {
|
|
if ($.debug) {
|
|
System.println("IPlaylist::addSong(id: " + id + " )");
|
|
}
|
|
|
|
// add it to the array
|
|
d_songs.add(id);
|
|
}
|
|
|
|
function removeSong(id) {
|
|
return d_songs.remove(id);
|
|
}
|
|
|
|
function setTime(time) {
|
|
// nothing to do if not changed
|
|
if (d_time == time) {
|
|
return false;
|
|
}
|
|
d_time = time;
|
|
|
|
// nothing to do if not stored
|
|
if (d_stored) {
|
|
save();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function setLinked(linked) {
|
|
// nothing to do if not changed
|
|
if (d_linked == linked) {
|
|
return false;
|
|
}
|
|
d_linked = linked;
|
|
|
|
// nothing to do if not stored
|
|
if (d_stored) {
|
|
save();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function setLocal(local) {
|
|
// nothing to do if not changed
|
|
if (d_local == local) {
|
|
return false;
|
|
}
|
|
d_local = local;
|
|
|
|
return save(); // forced save, as local
|
|
}
|
|
|
|
function setRemote(remote) {
|
|
// nothing to do if not changed
|
|
if (d_remote == remote) {
|
|
return false;
|
|
}
|
|
d_remote = remote;
|
|
|
|
// nothing to do if not stored
|
|
if (d_stored) {
|
|
save();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function setSynced(synced) {
|
|
// nothing to do if not changed
|
|
if (d_synced == synced) {
|
|
return false;
|
|
}
|
|
d_synced = synced;
|
|
|
|
// nothing to do if not stored
|
|
if (d_stored) {
|
|
save();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function setName(name) {
|
|
|
|
if (name == null) {
|
|
return false;
|
|
}
|
|
|
|
// nothing to do if not changed
|
|
if (d_name.equals(name)) {
|
|
return false;
|
|
}
|
|
d_name = name;
|
|
|
|
// nothing to do if not stored
|
|
if (d_stored) {
|
|
save();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function setPodcast(podcast) {
|
|
// nothing to do if not changed
|
|
if (d_podcast == podcast) {
|
|
return false;
|
|
}
|
|
d_podcast = podcast;
|
|
|
|
// nothing to do if not stored
|
|
if (d_stored) {
|
|
save();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function setCount(count) {
|
|
if ($.debug) {
|
|
System.println("IPlaylist.setCount( count : " + count + " )");
|
|
}
|
|
// nothing to do if not changed
|
|
if (d_songCount == count) {
|
|
return false;
|
|
}
|
|
d_songCount = count;
|
|
// nothing to do if not stored
|
|
if (d_stored) {
|
|
save();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// unlinks all related songs
|
|
function unlink() {
|
|
if ($.debug) {
|
|
System.println("IPlaylist::unlink()");
|
|
}
|
|
// nothing to do if not linked
|
|
if (!linked()) {
|
|
return;
|
|
}
|
|
|
|
// unlink each of the songs
|
|
for (var idx = 0; idx < d_songs.size(); ++idx) {
|
|
var song = new ISong(d_songs[idx]);
|
|
song.decRefCount();
|
|
}
|
|
setLinked(false);
|
|
save();
|
|
}
|
|
|
|
// links all related songs
|
|
function link() {
|
|
if ($.debug) {
|
|
System.println("IPlaylist::link()");
|
|
}
|
|
|
|
// nothing to do if already linked
|
|
if (linked()) {
|
|
return;
|
|
}
|
|
|
|
// link each of the songs
|
|
for (var idx = 0; idx < d_songs.size(); ++idx) {
|
|
var isong = new ISong(d_songs[idx]);
|
|
isong.incRefCount();
|
|
}
|
|
setLinked(true);
|
|
save();
|
|
}
|
|
|
|
function updateMeta(playlist) {
|
|
if ($.debug) {
|
|
System.println("IPlaylist::updateMeta( playlist: " + playlist.toStorage() + " )");
|
|
}
|
|
|
|
// only single save is needed, so mark as not stored temporarily
|
|
d_stored = false;
|
|
|
|
// update the variables
|
|
var changed = setName(playlist.name());
|
|
changed |= setCount(playlist.count());
|
|
changed |= setRemote(playlist.remote());
|
|
if (changed) {
|
|
save();
|
|
}
|
|
d_stored = true;
|
|
}
|
|
|
|
// updates song list, returns array of song ids that are not yet locally available
|
|
function update(songs) {
|
|
if ($.debug) {
|
|
System.println("IPlaylist::update() STARTING id:" + id() + " )");
|
|
}
|
|
|
|
// keep track of current songs
|
|
var songs_now = new [d_songs.size()];
|
|
for (var idx = 0; idx < songs_now.size(); ++idx) {
|
|
songs_now[idx] = d_songs[idx];
|
|
}
|
|
|
|
// keep track of newly added songs
|
|
var songs_new = [];
|
|
|
|
// keep track of order of remote playlist
|
|
var songs_ord = [];
|
|
|
|
// calculate time of the new playlist
|
|
var time = 0;
|
|
|
|
// find remote additions
|
|
for (var idx = 0; idx < songs.size(); ++idx) {
|
|
|
|
var id = songs[idx].id();
|
|
if (id == null) {
|
|
continue;
|
|
}
|
|
|
|
// add it to the new song ids (order preserved)
|
|
songs_ord.add(id);
|
|
|
|
// update information of the song
|
|
var isong = new ISong(id);
|
|
isong.updateMeta(songs[idx]); // update and save song details
|
|
|
|
// add to the time total
|
|
time += isong.time();
|
|
|
|
// add to tosync list if linked, but not downloaded
|
|
if (linked() && (isong.refId() == null)) {
|
|
songs_new.add(id);
|
|
}
|
|
|
|
// if remove returns true, it was already on the old list, so nothing to do
|
|
if (songs_now.remove(id)) {
|
|
continue;
|
|
}
|
|
|
|
// add it to the playlist
|
|
addSong(id);
|
|
|
|
// if linked, increment reference count of the song
|
|
if (linked()) {
|
|
isong.incRefCount();
|
|
}
|
|
|
|
}
|
|
setTime(time);
|
|
|
|
// find extra's on playlist
|
|
for (var idx = 0; idx < songs_now.size(); ++idx) {
|
|
var id = songs_now[idx];
|
|
var isong = new ISong(id);
|
|
|
|
// if linked, decrement reference count of the song
|
|
if (linked()) {
|
|
isong.decRefCount();
|
|
}
|
|
|
|
// remove from playlist
|
|
removeSong(id);
|
|
}
|
|
|
|
// order of songs should be copied from server
|
|
d_songs = songs_ord;
|
|
|
|
save();
|
|
return songs_new;
|
|
}
|
|
|
|
// saves the playlist
|
|
function save() {
|
|
d_stored = PlaylistStore.save(self);
|
|
return d_stored;
|
|
}
|
|
|
|
// safely removes the playlist from Store,
|
|
function remove() {
|
|
// if still linked, unlink
|
|
if (linked()) {
|
|
unlink();
|
|
}
|
|
|
|
// if not stored, do not remove
|
|
if (!d_stored) {
|
|
return false;
|
|
}
|
|
|
|
// remove
|
|
d_stored = !PlaylistStore.remove(self);
|
|
return true;
|
|
}
|
|
}
|
|
|