Commit 6e4abc76 authored by Laura Heimann's avatar Laura Heimann

further work on the library database

parent 9e188be4
<template> <template>
<div id="app" tabindex="-1" v-on:keydown.esc="closeOverlays()"> <div id="app" tabindex="-1" v-on:keydown.esc="closeOverlays()">
<main :class="(['Login'].indexOf($route.name) > -1) ? 'hide-navigation' : ''"> <main :class="(['LibraryUpdate', 'Login'].indexOf($route.name) > -1) ? 'hide-navigation' : ''">
<Navigation v-bind:downloadQueueCount="downloadQueue.length" v-bind:downloadOverlayShown="showDownloadOverlay" /> <Navigation v-bind:downloadQueueCount="downloadQueue.length" v-bind:downloadOverlayShown="showDownloadOverlay" />
<router-view :key="$route.fullPath" /> <router-view :key="$route.fullPath" />
</main> </main>
......
...@@ -8,10 +8,6 @@ import VueTilt from 'vue-tilt.js'; ...@@ -8,10 +8,6 @@ import VueTilt from 'vue-tilt.js';
import { ipcRenderer } from 'electron'; import { ipcRenderer } from 'electron';
import VueObserveVisibility from 'vue-observe-visibility'; import VueObserveVisibility from 'vue-observe-visibility';
import { VTooltip, VPopover, VClosePopover } from 'v-tooltip'; import { VTooltip, VPopover, VClosePopover } from 'v-tooltip';
import ChartLibrary from '@/modules/module.library.js';
let chartLibrary = new ChartLibrary();
chartLibrary.updateLibrary();
Vue.use(VueTilt); Vue.use(VueTilt);
Vue.use(VueObserveVisibility); Vue.use(VueObserveVisibility);
......
...@@ -12,6 +12,9 @@ class ChartLibrary { ...@@ -12,6 +12,9 @@ class ChartLibrary {
const userDataPath = app.getPath('userData'); const userDataPath = app.getPath('userData');
this.path = path.join(userDataPath, 'ChartLibrary.sqlite'); this.path = path.join(userDataPath, 'ChartLibrary.sqlite');
this.db = null; this.db = null;
this.databaseReady = false;
this.databaseUpdating = false;
this.databaseUpdateProgress = 0;
} }
async getLibrary() { async getLibrary() {
...@@ -22,14 +25,16 @@ class ChartLibrary { ...@@ -22,14 +25,16 @@ class ChartLibrary {
this.db.serialize(() => { this.db.serialize(() => {
this.createDatabaseIfNotExists(); this.createDatabaseIfNotExists();
console.log("[ChartLibrary] Check Library Cleanness");
// TODO: Check if Database is up to date and update if not // TODO: Check if Database is up to date and update if not
this.db.get('SELECT * FROM meta', (err, row) => { this.db.all("SELECT * FROM meta", (err, rows) => {
if (err) { if (err) {
console.error("[ChartLibrary] " + err.message); console.error("[ChartLibrary] " + err.message);
} }
console.log(row); console.log(rows);
}); }).run();
// TODO: Get Library // TODO: Get Library
}); });
...@@ -50,47 +55,106 @@ class ChartLibrary { ...@@ -50,47 +55,106 @@ class ChartLibrary {
} */ } */
} }
async updateLibrary() { updateLibrary() {
let userSettings = new UserSettings();
console.log("[ChartLibrary] Library Refresh"); console.log("[ChartLibrary] Library Refresh");
this.connectToDatabase(); this.connectToDatabase(() => {
this.db.serialize(() => {
this.createDatabaseIfNotExists();
this.db.serialize(() => { this.databaseReady = false;
this.createDatabaseIfNotExists();
// TODO: Update Library and Save to DB console.log("[ChartLibrary] Updating Meta");
});
this.closeDatabase(); let folderMD5 = md5(userSettings.get('gameDirectory'));
let clientVersion = app.getVersion();
/* this.db.run(`
let userSettings = new UserSettings(); INSERT OR REPLACE INTO meta (key, value)
let data = { VALUES ('folderMD5', '${folderMD5}'), ('databaseVersion', 1), ('clientVersion', '${clientVersion}');
folderMD5: "", `);
charts: []
};
data.folderMD5 = md5(userSettings.get('gameDirectory'));
// Find all SRTB files
let srtbFiles = glob.sync(path.join(userSettings.get('gameDirectory'), "*.srtb"));
srtbFiles.forEach((file) => {
// Parse SRTB file
try {
data.charts.push(this.parseSRTBFile(file));
} catch(error) {
console.error(error);
}
});
console.log("[ChartLibrary] Library Refresh Done."); // Clear previous entries
/* this.db.run(`
DELETE FROM charts;
VACUUM;
`); */
// Save changes console.log("[ChartLibrary] Reading Charts");
fs.writeFileSync(this.path, JSON.stringify(data));
console.log("[ChartLibrary] Wrote Library to: " + this.path);
return data; this.databaseUpdating = true;
*/
this.db.run("BEGIN TRANSACTION");
// Find all SRTB files
let srtbFiles = glob.sync(path.join(userSettings.get('gameDirectory'), "*.srtb"));
srtbFiles.forEach((file, index) => {
// Parse SRTB file
try {
let chartData = this.parseSRTBFile(file);
this.db.run(`
INSERT INTO charts (
title,
subtitle,
artist,
charter,
hasEasyDifficulty,
hasNormalDifficulty,
hasHardDifficulty,
hasExpertDifficulty,
hasXDDifficulty,
easyDifficulty,
normalDifficulty,
hardDifficulty,
expertDifficulty,
XDDifficulty,
srtbHash,
srtbPath,
oggPath,
coverPath
) VALUES (
'${chartData.title}',
'${chartData.subtitle}',
'${chartData.artist}',
'${chartData.charter}',
'${chartData.hasEasyDifficulty}',
'${chartData.hasNormalDifficulty}',
'${chartData.hasHardDifficulty}',
'${chartData.hasExpertDifficulty}',
'${chartData.hasXDDifficulty}',
'${chartData.easyDifficulty}',
'${chartData.normalDifficulty}',
'${chartData.hardDifficulty}',
'${chartData.expertDifficulty}',
'${chartData.XDDifficulty}',
'${chartData.srtbHash}',
'${chartData.srtbPath}',
'${chartData.oggPath}',
'${chartData.coverPath}',
);
`);
console.log(`[ChartLibrary] Progress: ${index} / ${srtbFiles.length}`);
this.databaseUpdateProgress = srtbFiles.length / index * 100;
} catch(error) {
console.error(error);
}
});
this.db.run("COMMIT");
this.databaseUpdating = false;
this.databaseReady = true;
console.log("[ChartLibrary] Library Refresh Done.");
this.closeDatabase();
});
});
} }
parseSRTBFile(srtbFilePath) { parseSRTBFile(srtbFilePath) {
...@@ -112,18 +176,15 @@ class ChartLibrary { ...@@ -112,18 +176,15 @@ class ChartLibrary {
expertDifficulty: 0, expertDifficulty: 0,
XDDifficulty: 0, XDDifficulty: 0,
srtbHash: "", srtbHash: "",
paths: { srtbPath: "",
srtb: "", oggPath: "",
ogg: "", coverPath: "",
cover: "",
coverBase64: "",
}
} }
let srtbRawData = fs.readFileSync(srtbFilePath, "utf-8"); let srtbRawData = fs.readFileSync(srtbFilePath, "utf-8");
let srtbData = JSON.parse( srtbRawData ); let srtbData = JSON.parse( srtbRawData );
data.paths.srtb = srtbFilePath; data.srtbPath = srtbFilePath;
data.srtbHash = md5( srtbData ); data.srtbHash = md5( srtbData );
srtbData.largeStringValuesContainer.values.forEach(lSV => { srtbData.largeStringValuesContainer.values.forEach(lSV => {
...@@ -137,14 +198,7 @@ class ChartLibrary { ...@@ -137,14 +198,7 @@ class ChartLibrary {
data.artist = lSVData.artistName; data.artist = lSVData.artistName;
data.charter = lSVData.charter; data.charter = lSVData.charter;
data.paths.cover = glob.sync(path.join(userSettings.get('gameDirectory'), "AlbumArt", lSVData.albumArtReference.assetName + '.*'))[0]; data.coverPath = glob.sync(path.join(userSettings.get('gameDirectory'), "AlbumArt", lSVData.albumArtReference.assetName + '.*'))[0];
if(data.paths.cover != undefined) {
try {
data.paths.coverBase64 = "data:image/jpg;base64," + fs.readFileSync(data.paths.cover, { encoding: 'base64' })
} catch(error) {
console.error(error);
}
}
lSVData.difficulties.forEach(difficulty => { lSVData.difficulties.forEach(difficulty => {
if(difficulty._active) { if(difficulty._active) {
...@@ -204,7 +258,7 @@ class ChartLibrary { ...@@ -204,7 +258,7 @@ class ChartLibrary {
// Parse ClipInfo // Parse ClipInfo
if(lSV.key.includes("ClipInfo")) { if(lSV.key.includes("ClipInfo")) {
data.paths.ogg = glob.sync(path.join(userSettings.get('gameDirectory'), "AudioClips", lSVData.clipAssetReference.assetName + '.*'))[0]; data.oggPath = glob.sync(path.join(userSettings.get('gameDirectory'), "AudioClips", lSVData.clipAssetReference.assetName + '.*'))[0];
} }
}); });
...@@ -213,12 +267,14 @@ class ChartLibrary { ...@@ -213,12 +267,14 @@ class ChartLibrary {
return data; return data;
} }
connectToDatabase() { connectToDatabase(callback) {
this.db = new sqlite3.Database(this.path, (err) => { this.db = new sqlite3.Database(this.path, (err) => {
if (err) { if (err) {
console.error("[ChartLibrary] " + err.message); console.error("[ChartLibrary] " + err.message);
} }
console.log('[ChartLibrary] Connected to Database'); console.log('[ChartLibrary] Connected to Database');
callback();
}); });
} }
...@@ -233,9 +289,38 @@ class ChartLibrary { ...@@ -233,9 +289,38 @@ class ChartLibrary {
createDatabaseIfNotExists() { createDatabaseIfNotExists() {
// TODO: Finalize Database Structure // TODO: Finalize Database Structure
this.db.prepare(` this.db.run(`
CREATE TABLE IF NOT EXISTS meta (folderMD5 TEXT, clientVersion TEXT); CREATE TABLE IF NOT EXISTS meta (
`).run().finalize(); key TEXT,
value TEXT
);
`);
this.db.run(`
CREATE TABLE IF NOT EXISTS charts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
subtitle TEXT,
artist TEXT,
charter TEXT,
hasEasyDifficulty INTEGER,
hasNormalDifficulty INTEGER,
hasHardDifficulty INTEGER,
hasExpertDifficulty INTEGER,
hasXDDifficulty INTEGER,
easyDifficulty INTEGER,
normalDifficulty INTEGER,
hardDifficulty INTEGER,
expertDifficulty INTEGER,
XDDifficulty INTEGER,
srtbHash TEXT,
srtbPath TEXT,
oggPath TEXT,
coverPath TEXT
);
`);
console.log("[ChartLibrary] Created Tables");
} }
} }
......
...@@ -11,6 +11,7 @@ import ViewStartupHotThisWeekSongs from '../views/StartupHotThisWeekSongs.vue'; ...@@ -11,6 +11,7 @@ import ViewStartupHotThisWeekSongs from '../views/StartupHotThisWeekSongs.vue';
import ViewStartupHotThisMonthSongs from '../views/StartupHotThisMonthSongs.vue'; import ViewStartupHotThisMonthSongs from '../views/StartupHotThisMonthSongs.vue';
import ViewSearch from '../views/Search.vue'; import ViewSearch from '../views/Search.vue';
import ViewLibrary from '../views/Library.vue'; import ViewLibrary from '../views/Library.vue';
import ViewLibraryUpdate from '../views/LibraryUpdate.vue';
import ViewSongDetail from '../views/SongDetail.vue'; import ViewSongDetail from '../views/SongDetail.vue';
import ViewSongDetailReviews from '../views/SongDetailReviews.vue'; import ViewSongDetailReviews from '../views/SongDetailReviews.vue';
import ViewSongDetailSpinPlays from '../views/SongDetailSpinPlays.vue'; import ViewSongDetailSpinPlays from '../views/SongDetailSpinPlays.vue';
...@@ -29,6 +30,12 @@ Vue.use(VueAxios, axios); ...@@ -29,6 +30,12 @@ Vue.use(VueAxios, axios);
const routes = [{ const routes = [{
path: '/', path: '/',
name: 'Index',
redirect: {
name: 'LibraryUpdate'
},
}, {
path: '/login',
name: 'Login', name: 'Login',
component: ViewLogin component: ViewLogin
}, { }, {
...@@ -74,7 +81,11 @@ const routes = [{ ...@@ -74,7 +81,11 @@ const routes = [{
name: 'Library', name: 'Library',
component: ViewLibrary component: ViewLibrary
}, { }, {
path: '/song/:id', path: '/libraryUpdate',
name: 'LibraryUpdate',
component: ViewLibraryUpdate
}, {
path: '/song/:id?',
name: 'SongDetail', name: 'SongDetail',
component: ViewSongDetail, component: ViewSongDetail,
redirect: { redirect: {
...@@ -94,7 +105,7 @@ const routes = [{ ...@@ -94,7 +105,7 @@ const routes = [{
} }
] ]
}, { }, {
path: '/user/:id', path: '/user/:id?',
name: 'UserDetail', name: 'UserDetail',
component: ViewUserDetail, component: ViewUserDetail,
redirect: { redirect: {
...@@ -127,7 +138,7 @@ const routes = [{ ...@@ -127,7 +138,7 @@ const routes = [{
} }
] ]
}, { }, {
path: '/playlist/:id', path: '/playlist/:id?',
name: 'PlaylistDetail', name: 'PlaylistDetail',
component: ViewPlaylistDetail, component: ViewPlaylistDetail,
}, { }, {
......
<template>
<div class="section-libraryUpdate">
<div class="login-box login-loading">
<Loading />
</div>
</div>
</template>
<script>
import { remote, ipcRenderer } from 'electron';
import ChartLibrary from '@/modules/module.library.js';
import Loading from '@/components/Loading.vue';
export default {
name: 'LibraryUpdate',
components: {
Loading
},
mounted: function() {
setTimeout(function () {
console.log('[LibraryUpdate] Updating Library');
let chartLibrary = new ChartLibrary();
chartLibrary.updateLibrary();
console.log("[LibraryUpdate] Redirect to Login");
}, 1000);
}
}
</script>
<style scoped lang="less">
.section-libraryUpdate {
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
display: flex;
justify-content: center;
align-items: center;
& .loading {
background: black;
}
& .login-box {
width: 500px;
background: #000;
border-radius: 6px;
padding: 40px;
& .logo {
text-align: center;
margin-bottom: 30px;
& img {
height: 50px;
}
}
& .explaination {
line-height: 1.5;
}
& .error {
border: 2px solid #fb1357;
padding: 15px;
background: #fb1357;
border-radius: 4px;
margin-bottom: 15px;
}
& .connectcodeInput {
font-size: 42px;
background: transparent;
border: 0px;
width: 100%;
text-align: center;
color: #fff;
padding: 15px;
margin-top: 30px;
margin-bottom: 15px;
letter-spacing: 0.15em;
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
}
& .actions {
display: flex;
flex-direction: row-reverse;
}
&.login-loading {
padding: 60px;
}
}
}
</style>
\ No newline at end of file
<template> <template>
<section class="section-login"> <section class="section-login">
<div class="login-box login-loading" v-if="chartLibraryLoading">
<Loading /><br />
ChartLibrary Loading
</div>
<div class="login-box login-loading" v-if="apiLoginLoading"> <div class="login-box login-loading" v-if="apiLoginLoading">
<Loading /> <Loading />
</div> </div>
...@@ -46,7 +50,9 @@ ...@@ -46,7 +50,9 @@
let ssapi = new SSAPI(); let ssapi = new SSAPI();
let userSettings = new UserSettings(); let userSettings = new UserSettings();
if(!userSettings.get("connectToken")) { console.log("[Login] Check Login");
/* if(!userSettings.get("connectToken")) {
this.showLoginBox(); this.showLoginBox();
} else { } else {
ssapi.validateConnectToken(userSettings.get("connectToken")).then((data) => { ssapi.validateConnectToken(userSettings.get("connectToken")).then((data) => {
...@@ -58,7 +64,7 @@ ...@@ -58,7 +64,7 @@
}).catch(() => { }).catch(() => {
this.showLoginBox(); this.showLoginBox();
}); });
} } */
}, },
methods: { methods: {
connect: function() { connect: function() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment