-
Notifications
You must be signed in to change notification settings - Fork 24
/
Song.ts
126 lines (122 loc) · 3.65 KB
/
Song.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import uuid from 'uuid'
import allSongs from '../assets/chordpro/songs.json'
import ChordSheetJS from 'chordsheetjs';
import { Artist } from './Artist';
import realm from '.';
export class Song {
id!: string
title!: string
content!: string
artist!: Artist
updated_at!: Date
static schema: Realm.ObjectSchema = {
name: 'Song',
primaryKey: 'id',
properties: {
id: 'string',
title: 'string',
content: 'string',
artist: { type: 'Artist' },
updated_at: 'date'
}
}
static search(query: string) {
return realm.objects<Song>('Song').filtered('title CONTAINS[c] $0 OR artist.name CONTAINS[c] $0', query)
}
static getById(id: string) {
return realm.objectForPrimaryKey<Song>('Song', id)
}
static getByArtist(artistId: string) {
return realm.objects<Song>('Song').filtered('artist.id = $0', artistId).sorted('title');
}
static shouldUpdateDb() {
let s = this.getAll().find(() => true)
let newSongsDate = new Date(allSongs.updated_at)
if (s == null)
return true
else
return newSongsDate > s.updated_at
}
static populateDb() {
if (this.shouldUpdateDb()) {
for (var i = 0; i < allSongs.data.length; i++) {
let s: string = allSongs.data[i]
const parser = new ChordSheetJS.ChordProParser();
const formatter = new ChordSheetJS.ChordProFormatter();
const parsedSong = parser.parse(s);
let artistName = parsedSong.getMetaData('artist')!
let songTitle = parsedSong.getMetaData('title')!
let songContent = formatter.format(parsedSong)
let artist = Artist.create(artistName)
Song.create(artist, songTitle, songContent)
}
}
}
static getAll() { return realm.objects<Song>('Song').sorted('title') }
static getChordPro(song: Song) {
let headerlessContent = song.content
headerlessContent = headerlessContent.replace(/{artist:[^}]*}\n/g, '')
headerlessContent = headerlessContent.replace(/{title:[^}]*}\n/g, '')
let header =
`{title: ${song.title}}\n` +
`{artist: ${song.artist.name}}\n`
return header + headerlessContent
}
static create(artist: Artist, title: string, content: string) {
if (title == null || title == "") {
throw new Error(`Empty title not allowed`)
}
if (content == null || content == "") {
throw new Error(`Empty content not allowed`)
}
let song: Song | undefined
song = realm
.objects<Song>('Song')
.filtered('title = $0 && artist.name = $1', title, artist.name)
.find(() => true)
if (song == null) {
realm.write(() => {
song = realm.create('Song', {
id: uuid(),
title,
content,
artist,
updated_at: new Date()
})
})
} else {
// TODO: Enable multiple versions of same song
}
return song!
}
static update(id: string, artist: Artist, title: string, content: string) {
if (title == null || title == "") {
throw new Error(`Empty title not allowed`)
}
if (content == null || content == "") {
throw new Error(`Empty content not allowed`)
}
let song = Song.getById(id)
if (song != null) {
realm.write(() => {
song!.title = title
song!.artist = artist
song!.content = content
song!.updated_at = new Date()
})
} else {
throw new Error(`Song not found`)
}
return song!
}
static delete(id: string) {
realm.write(() => {
let song = Song.getById(id)
let artistId = song!.artist.id!
realm.delete(song)
if (Song.getByArtist(artistId).length <= 0) {
realm.delete(Artist.getById(artistId))
}
})
}
}