Compare commits
7 Commits
refactor
...
f343e9d87b
| Author | SHA1 | Date | |
|---|---|---|---|
| f343e9d87b | |||
| 50c8bb5d72 | |||
| e4fd116250 | |||
| eabe518b10 | |||
| 15fd7900de | |||
| 127e2294e5 | |||
| f42857eb56 |
24
README.md
24
README.md
@@ -9,26 +9,34 @@ At the moment, an alpha version is undertaken, with these features:
|
|||||||
### Database
|
### Database
|
||||||
|
|
||||||
- The sqlite-database holds a growing number of piano-solo pieces, together with their exact catalogue-numbers and composers.
|
- The sqlite-database holds a growing number of piano-solo pieces, together with their exact catalogue-numbers and composers.
|
||||||
- Prepared in this database is a table for users (pianists), that marks which of the pieces can be played.
|
- Enclosed in this database is a table for users (pianists), in which is marked which of the works and movements can be played.
|
||||||
|
|
||||||
### Application and usage
|
### Application and usage, Roadmap
|
||||||
|
|
||||||
- Create new users (`n username`)
|
- Create new users (`n username`)
|
||||||
- Show users (`su`)
|
- Show users (`su`)
|
||||||
- Set an active user (`a number_of_user`)
|
- Set an active user (`a number_of_user`)
|
||||||
- Show the pieces stored in the database (`s`)
|
- Show the pieces stored in the database (`s`)
|
||||||
- Mark pieces as mastered for the active user (`m number_of_work`)
|
- Mark work as mastered for the active user (`m number_of_work`)
|
||||||
- Show pieces by composer (`c` shows composers, `s number_of_composer` shows pieces)
|
- Show pieces by composer (`c` shows composers, `s number_of_composer` shows pieces)
|
||||||
- Show movements through works (`sw work_number`)
|
- Show movements through works (`sw work_number`)
|
||||||
- Mark movement as mastered for active user (`m number_of_work number_of_movement`)
|
- Mark movement as mastered for active user (`m number_of_work number_of_movement`)
|
||||||
- Show possible commands (`h`)
|
- Show possible commands (`h`)
|
||||||
- Show mastered movements for activated user (`sm`)
|
- Show mastered movements for activated user (`sm`)
|
||||||
- (planned) display, if work or movement is mastered from active user when viewing works and movements
|
- display, if work or movement is mastered from active user when viewing works and movements
|
||||||
- (planned) Save recordings per movement in db
|
- Works are shown sorted by composer and opus/work_directory-number (`s`, `smo`) or by composer and collection (`sm`)
|
||||||
- (planned) Listen to saved recordings
|
- (planned) Remove work or movement from being mastered for active user
|
||||||
- (planned) Works are shown sorted (opus, collection e.g. "Walzer", "Sonaten")
|
- (planned) Remove user
|
||||||
|
- (planned) Fix known bugs
|
||||||
|
|
||||||
## Requirements
|
_(planned) Release piano_repertoire_cli V 0.0.1 alpha (learn about versioning before)_
|
||||||
|
|
||||||
|
_(planned) Port funtionality to a kivy-GUI_
|
||||||
|
|
||||||
|
- (planned) Save recordings per movement in userspace
|
||||||
|
- (planned) Listen to saved recordings
|
||||||
|
|
||||||
|
## Requirements and how to run the application
|
||||||
|
|
||||||
- Python 3.9 or higher
|
- Python 3.9 or higher
|
||||||
- Enough disk space to hold the database
|
- Enough disk space to hold the database
|
||||||
|
|||||||
68
rep_cli.py
68
rep_cli.py
@@ -1,4 +1,5 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
from functools import total_ordering
|
||||||
|
|
||||||
class Session:
|
class Session:
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ class Session:
|
|||||||
'n': (self.create_new_user, 'Creates new user\n Usage: n firstname name'),
|
'n': (self.create_new_user, 'Creates new user\n Usage: n firstname name'),
|
||||||
's': (self.show_works, 'Show the works stored in the database\n Usage: s, s number_of_composer'),
|
's': (self.show_works, 'Show the works stored in the database\n Usage: s, s number_of_composer'),
|
||||||
'sm': (self.show_mastered, 'Show mastered movements for activated user'),
|
'sm': (self.show_mastered, 'Show mastered movements for activated user'),
|
||||||
|
'smo': (self.show_mastered_opus, 'Show mastered movements for activated user, sorted by opus.'),
|
||||||
'sw': (self.show_movements, 'Show movements of a work\n Usage: sw work_number'),
|
'sw': (self.show_movements, 'Show movements of a work\n Usage: sw work_number'),
|
||||||
'su': (self.show_users, 'Show all users'),
|
'su': (self.show_users, 'Show all users'),
|
||||||
'q': (self.quit, 'Quits the program')
|
'q': (self.quit, 'Quits the program')
|
||||||
@@ -46,7 +48,29 @@ class Session:
|
|||||||
|
|
||||||
def result(self):
|
def result(self):
|
||||||
return self.resultstring
|
return self.resultstring
|
||||||
|
|
||||||
|
def movement_is_mastered(self, work_id, mov_id):
|
||||||
|
is_mastered = False
|
||||||
|
if self.user != -1:
|
||||||
|
sql_command = f'''
|
||||||
|
SELECT *
|
||||||
|
FROM is_able_to_play
|
||||||
|
WHERE work_id = {work_id}
|
||||||
|
AND mov_id = {mov_id}
|
||||||
|
AND pianist_id = {self.user}
|
||||||
|
'''
|
||||||
|
if self.db_agent.execute(sql_command).fetchone():
|
||||||
|
is_mastered = True
|
||||||
|
return is_mastered
|
||||||
|
|
||||||
|
def percentage_of_work_is_mastered(self, work): # work, not work_id, as a work-object is created anyway when there's need to check
|
||||||
|
number_of_movements = len(work.values['movements'])
|
||||||
|
count_mastered = 0
|
||||||
|
for key in work.values['movements']:
|
||||||
|
if self.movement_is_mastered(work.id(), key):
|
||||||
|
count_mastered += 1
|
||||||
|
return int(count_mastered / number_of_movements * 100)
|
||||||
|
|
||||||
def create_new_user(self, arguments):
|
def create_new_user(self, arguments):
|
||||||
first_name, name = arguments[0], arguments[1]
|
first_name, name = arguments[0], arguments[1]
|
||||||
sql_command = f'''
|
sql_command = f'''
|
||||||
@@ -81,7 +105,7 @@ class Session:
|
|||||||
fun_resultstring += f'{key}: {value[1]}\n'
|
fun_resultstring += f'{key}: {value[1]}\n'
|
||||||
return fun_resultstring
|
return fun_resultstring
|
||||||
|
|
||||||
def show_mastered(self, _):
|
def show_mastered(self, _, key='standard'):
|
||||||
fun_resultstring = 'Please activate user'
|
fun_resultstring = 'Please activate user'
|
||||||
if not self.user == -1:
|
if not self.user == -1:
|
||||||
sql_command = f'''
|
sql_command = f'''
|
||||||
@@ -95,6 +119,11 @@ class Session:
|
|||||||
for item in list_of_work_ids:
|
for item in list_of_work_ids:
|
||||||
list_of_works.append(work_under_id(item[0], self.db_agent))
|
list_of_works.append(work_under_id(item[0], self.db_agent))
|
||||||
fun_resultstring = 'All mastered movements:\n'
|
fun_resultstring = 'All mastered movements:\n'
|
||||||
|
if key == 'opus':
|
||||||
|
list_of_works.sort(key=lambda work_s: work_s.opus_and_wd_for_comparison())
|
||||||
|
else:
|
||||||
|
list_of_works.sort(key=lambda work_s: work_s.sammlung())
|
||||||
|
list_of_works.sort()
|
||||||
for work in list_of_works:
|
for work in list_of_works:
|
||||||
for mov_number in work.values['movements'].keys():
|
for mov_number in work.values['movements'].keys():
|
||||||
# check if movement is mastered
|
# check if movement is mastered
|
||||||
@@ -110,11 +139,18 @@ class Session:
|
|||||||
fun_resultstring += f'{work.id()} {mov_number}. {work.pretty_mov(mov_number)}\n'
|
fun_resultstring += f'{work.id()} {mov_number}. {work.pretty_mov(mov_number)}\n'
|
||||||
return fun_resultstring
|
return fun_resultstring
|
||||||
|
|
||||||
|
def show_mastered_opus(self, arguments):
|
||||||
|
return self.show_mastered(arguments, key='opus')
|
||||||
|
|
||||||
def show_movements(self, arguments):
|
def show_movements(self, arguments):
|
||||||
work_id = arguments[0]
|
work_id = arguments[0]
|
||||||
work = work_under_id(work_id, self.db_agent)
|
work = work_under_id(work_id, self.db_agent)
|
||||||
fun_resultstring = ''
|
fun_resultstring = ''
|
||||||
for mov_number in work.values['movements'].keys():
|
for mov_number in work.values['movements'].keys():
|
||||||
|
if self.movement_is_mastered(work_id, mov_number):
|
||||||
|
fun_resultstring += '[x] '
|
||||||
|
else:
|
||||||
|
fun_resultstring += '[ ] '
|
||||||
fun_resultstring += f'{mov_number}. {work.pretty_mov(mov_number)}\n'
|
fun_resultstring += f'{mov_number}. {work.pretty_mov(mov_number)}\n'
|
||||||
return fun_resultstring
|
return fun_resultstring
|
||||||
|
|
||||||
@@ -144,7 +180,15 @@ class Session:
|
|||||||
for item in list_of_work_ids:
|
for item in list_of_work_ids:
|
||||||
list_of_works.append(work_under_id(item[0], self.db_agent))
|
list_of_works.append(work_under_id(item[0], self.db_agent))
|
||||||
fun_resultstring = ''
|
fun_resultstring = ''
|
||||||
for work in list_of_works:
|
list_of_works.sort(key=lambda wo: wo.opus_and_wd_for_comparison())
|
||||||
|
for work in sorted(list_of_works):
|
||||||
|
mastered = self.percentage_of_work_is_mastered(work)
|
||||||
|
if mastered == 100:
|
||||||
|
fun_resultstring += '[x] '
|
||||||
|
elif mastered > 0:
|
||||||
|
fun_resultstring += '[/] '
|
||||||
|
else:
|
||||||
|
fun_resultstring += '[ ] '
|
||||||
fun_resultstring += f'{work.id()}: {work.pretty_string()}\n'
|
fun_resultstring += f'{work.id()}: {work.pretty_string()}\n'
|
||||||
return fun_resultstring
|
return fun_resultstring
|
||||||
|
|
||||||
@@ -175,6 +219,7 @@ class Session:
|
|||||||
|
|
||||||
# End session
|
# End session
|
||||||
|
|
||||||
|
@total_ordering
|
||||||
class work_under_id:
|
class work_under_id:
|
||||||
# con = sqlite3.connect('repertoire.db')
|
# con = sqlite3.connect('repertoire.db')
|
||||||
# reader = con.cursor()
|
# reader = con.cursor()
|
||||||
@@ -232,6 +277,22 @@ class work_under_id:
|
|||||||
def id(self):
|
def id(self):
|
||||||
return self.values['id']
|
return self.values['id']
|
||||||
|
|
||||||
|
def just_num(self, st):
|
||||||
|
num_str = ''
|
||||||
|
for c in st:
|
||||||
|
if c.isdigit():
|
||||||
|
num_str += c
|
||||||
|
return int(num_str)
|
||||||
|
|
||||||
|
def opus_and_wd_for_comparison(self):
|
||||||
|
op = 9999 # no composer has that many!
|
||||||
|
if not self.values['opus'] is None:
|
||||||
|
op = self.just_num(self.values['opus'])
|
||||||
|
wd = 0 # no directory starts with 0
|
||||||
|
if not self.values['wd_number'] is None:
|
||||||
|
wd = self.just_num(self.values['wd_number'])
|
||||||
|
return (op, wd)
|
||||||
|
|
||||||
def pretty_string(self):
|
def pretty_string(self):
|
||||||
ret_str = ''
|
ret_str = ''
|
||||||
for key in ['first_name', 'name',
|
for key in ['first_name', 'name',
|
||||||
@@ -281,6 +342,9 @@ class work_under_id:
|
|||||||
ret_str += f'{key}: {value}\n'
|
ret_str += f'{key}: {value}\n'
|
||||||
return ret_str
|
return ret_str
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return (self.values['name'] < other.values['name'])
|
||||||
|
|
||||||
# End work_under_id
|
# End work_under_id
|
||||||
|
|
||||||
def parse_user_input(user_in, session):
|
def parse_user_input(user_in, session):
|
||||||
|
|||||||
Reference in New Issue
Block a user