YesPlayMusic/src/utils/db.js
2021-06-08 00:09:30 +08:00

179 lines
4.3 KiB
JavaScript

import axios from 'axios';
import Dexie from 'dexie';
import store from '@/store';
// import pkg from "../../package.json";
const db = new Dexie('yesplaymusic');
db.version(4).stores({
trackDetail: '&id, updateTime',
lyric: '&id, updateTime',
album: '&id, updateTime',
});
db.version(3)
.stores({
trackSources: '&id, createTime',
})
.upgrade(tx =>
tx
.table('trackSources')
.toCollection()
.modify(
track => !track.createTime && (track.createTime = new Date().getTime())
)
);
db.version(1).stores({
trackSources: '&id',
});
let tracksCacheBytes = 0;
async function deleteExcessCache() {
if (
store.state.settings.cacheLimit === false ||
tracksCacheBytes < store.state.settings.cacheLimit * Math.pow(1024, 2)
) {
return;
}
try {
const delCache = await db.trackSources.orderBy('createTime').first();
await db.trackSources.delete(delCache.id);
tracksCacheBytes -= delCache.source.byteLength;
console.debug(
`[debug][db.js] deleteExcessCacheSucces, track: ${delCache.name}, size: ${delCache.source.byteLength}, cacheSize:${tracksCacheBytes}`
);
deleteExcessCache();
} catch (error) {
console.debug('[debug][db.js] deleteExcessCacheFailed', error);
}
}
export function cacheTrackSource(trackInfo, url, bitRate, from = 'netease') {
const name = trackInfo.name;
const artist = trackInfo.ar[0]?.name || trackInfo.artists[0]?.name;
let cover = trackInfo.al.picUrl;
if (cover.slice(0, 5) !== 'https') {
cover = 'https' + cover.slice(4);
}
axios.get(`${cover}?param=512y512`);
axios.get(`${cover}?param=224y224`);
axios.get(`${cover}?param=1024y1024`);
return axios
.get(url, {
responseType: 'arraybuffer',
})
.then(response => {
db.trackSources.put({
id: trackInfo.id,
source: response.data,
bitRate,
from,
name,
artist,
createTime: new Date().getTime(),
});
console.debug(`[debug][db.js] cached track 👉 ${name} by ${artist}`);
tracksCacheBytes += response.data.byteLength;
deleteExcessCache();
return { trackID: trackInfo.id, source: response.data, bitRate };
});
}
export function getTrackSource(id) {
return db.trackSources.get(Number(id)).then(track => {
if (!track) return null;
console.debug(
`[debug][db.js] get track from cache 👉 ${track.name} by ${track.artist}`
);
return track;
});
}
export function cacheTrackDetail(track, privileges) {
db.trackDetail.put({
id: track.id,
detail: track,
privileges: privileges,
updateTime: new Date().getTime(),
});
}
export function getTrackDetailFromCache(ids) {
return db.trackDetail
.filter(track => {
return ids.includes(String(track.id));
})
.toArray()
.then(tracks => {
const result = { songs: [], privileges: [] };
ids.map(id => {
const one = tracks.find(t => String(t.id) === id);
result.songs.push(one?.detail);
result.privileges.push(one?.privileges);
});
if (result.songs.includes(undefined)) {
return undefined;
}
return result;
});
}
export function cacheLyric(id, lyrics) {
db.lyric.put({
id,
lyrics,
updateTime: new Date().getTime(),
});
}
export function getLyricFromCache(id) {
return db.lyric.get(Number(id)).then(result => {
if (!result) return undefined;
return result.lyrics;
});
}
export function cacheAlbum(id, album) {
db.album.put({
id,
album,
updateTime: new Date().getTime(),
});
}
export function getAlbumFromCache(id) {
return db.album.get(Number(id)).then(result => {
if (!result) return undefined;
return result.album;
});
}
export function countDBSize() {
const trackSizes = [];
return db.trackSources
.each(track => {
trackSizes.push(track.source.byteLength);
})
.then(() => {
const res = {
bytes: trackSizes.reduce((s1, s2) => s1 + s2, 0),
length: trackSizes.length,
};
tracksCacheBytes = res.bytes;
console.debug(
`[debug][db.js] load tracksCacheBytes: ${tracksCacheBytes}`
);
return res;
});
}
export function clearDB() {
return new Promise(resolve => {
db.tables.forEach(function (table) {
table.clear();
});
resolve();
});
}