Finished Version 1.0. Guide for installation will be available soon

This commit is contained in:
janis
2022-02-27 13:48:51 +01:00
commit 523c11281c
8 changed files with 378 additions and 0 deletions

122
backend/csv_parsers.py Normal file
View File

@@ -0,0 +1,122 @@
"""@package docstring
This is a simplification of the csv module"""
import csv
class CsvRead:
"""This is a class that reads csv files and depending on the module selected does do different things with it"""
def __init__(self):
self.__imp = ""
self.__raw = ""
self.__raw_list = ""
def importing(self, path):
"""Returns a list of the imported csv-file, requires path, either direct system path or relative path"""
self.__imp = open(path)
self.__raw = csv.reader(self.__imp, delimiter=',')
self.__raw_list = list(self.__raw)
self.__imp.close()
return self.__raw_list
class CsvWrite:
"""This is a class that modifies csv files"""
def __init__(self):
self.__impl = []
self.__strpop = []
self.__removed = []
self.__removing = 0
self.__change = 0
self.__appending = 0
self.__imp = []
self.__raw = []
def rem_str(self, path, row):
"""Opens the csv-file in write mode which is specified as an argument either as direct or relative path"""
self.__imp = open(path)
self.__raw = csv.reader(self.__imp, delimiter=',')
self.__impl = list(self.__raw)
self.__removed = self.__impl.pop(row + 1)
with open(path, "w") as removedata:
self.__removing = csv.writer(removedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__removing.writerow(self.__impl.pop(0))
while len(self.__impl) > 0:
with open(path, "a") as removedata:
self.__removing = csv.writer(removedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__removing.writerow(self.__impl.pop(0))
self.__imp.close()
removedata.close()
def chg_str(self, path, row, pos, new_value):
"""Opens the csv-file in write mode to change a value, e.g. if a recipes is changed."""
self.__imp = open(path)
self.__raw = csv.reader(self.__imp, delimiter=',')
self.__impl = list(self.__raw)
self.__strpop = self.__impl.pop(row)
self.__strpop.pop(pos)
self.__strpop.insert(pos, new_value)
self.__impl.insert(row, self.__strpop)
with open(path, "w") as changedata:
self.__change = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__change.writerow(self.__impl.pop(0))
while len(self.__impl) > 0:
with open(path, "a") as changedata:
self.__removing = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__removing.writerow(self.__impl.pop(0))
self.__imp.close()
changedata.close()
def chg_str_rem(self, path, row, pos):
"""Opens the csv-file in write mode to change a value, e.g. if a recipes is changed."""
self.__imp = open(path)
self.__raw = csv.reader(self.__imp, delimiter=',')
self.__impl = list(self.__raw)
self.__strpop = self.__impl.pop(row)
self.__strpop.pop(pos)
self.__strpop.pop(pos)
self.__impl.insert(row, self.__strpop)
with open(path, "w") as changedata:
self.__change = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__change.writerow(self.__impl.pop(0))
while len(self.__impl) > 0:
with open(path, "a") as changedata:
self.__removing = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__removing.writerow(self.__impl.pop(0))
self.__imp.close()
changedata.close()
def chg_str_add(self, path, row, new_value1, new_value2):
"""Opens the csv-file in write mode to change a value, e.g. if a recipes is changed."""
self.__imp = open(path)
self.__raw = csv.reader(self.__imp, delimiter=',')
self.__impl = list(self.__raw)
self.__strpop = self.__impl.pop(row)
self.__strpop.append(new_value1)
self.__strpop.append(new_value2)
self.__impl.insert(row, self.__strpop)
with open(path, "w") as changedata:
self.__change = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__change.writerow(self.__impl.pop(0))
while len(self.__impl) > 0:
with open(path, "a") as changedata:
self.__removing = csv.writer(changedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__removing.writerow(self.__impl.pop(0))
self.__imp.close()
changedata.close()
def app_str(self, path, value):
"""Opens the csv-file in append mode and writes given input. CsvWrite.app_str(path, value).
Path can be specified both as direct or relative. value is a list. Will return an error if type of value is
not a list."""
with open(path, "a") as appenddata:
self.__appending = csv.writer(appenddata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__appending.writerow(value)
appenddata.close()
def write_str(self, path, value):
with open(path, "w") as writedata:
self.__change = csv.writer(writedata, delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.__change.writerow(value)
writedata.close()

View File

@@ -0,0 +1,77 @@
from mido import MidiFile
import pyperclip as pc
class MidiManagement:
def __init__(self):
pass
def addToClipboard(self, text):
pc.copy(text)
def analyse_track(self, path, trackname):
self.midi_imp = MidiFile(path, clip=True)
self.tracks = []
for self.track in self.midi_imp.tracks:
self.tracks.append(str(self.track))
self.tracks.pop(0)
self.track_ext = self.tracks.pop(0)
self.trackn = 0
while self.track_ext != trackname:
self.track_ext = self.tracks.pop(0)
self.trackn += 1
self.extracted_track = self.track_ext
self.__output_list = []
for self.msg in self.midi_imp.tracks[self.trackn]:
self.ext = str(self.msg)
self.note = self.ext[23:25]
try:
self.note_height = int(self.note)
self.note_decod_oct = self.note_height // 12
self.note_decode_tone = self.note_height % 12
if self.note_decode_tone == 1:
self.note_ext = "C"
elif self.note_decode_tone == 2:
self.note_ext = "C#"
elif self.note_decode_tone == 3:
self.note_ext = "D"
elif self.note_decode_tone == 4:
self.note_ext = "D#"
elif self.note_decode_tone == 5:
self.note_ext = "E"
elif self.note_decode_tone == 6:
self.note_ext = "F"
elif self.note_decode_tone == 7:
self.note_ext = "F#"
elif self.note_decode_tone == 8:
self.note_ext = "G"
elif self.note_decode_tone == 9:
self.note_ext = "G#"
elif self.note_decode_tone == 10:
self.note_ext = "A"
elif self.note_decode_tone == 11:
self.note_ext = "A#"
elif self.note_decode_tone == 12:
self.note_ext = "H"
self.ext_shortened = self.ext[40:]
self.pos = 0
for buchstabe in self.ext_shortened:
if buchstabe == "=":
self.pos += 1
break
else:
self.pos += 1
self.timing_exp = self.ext_shortened[self.pos:]
self.__output = self.note_ext
self.__output += f":{self.timing_exp}"
self.__output_list.append(str(self.__output))
except:
pass
self.addToClipboard(str(self.__output_list))

1
backend/temp.csv Normal file
View File

@@ -0,0 +1 @@
/home/janis/Desktop/Victory.mid
1 /home/janis/Desktop/Victory.mid

32
dev/hr.py Normal file
View File

@@ -0,0 +1,32 @@
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
#:import KivyLexer kivy.extras.highlight.KivyLexer
#:import HotReloadViewer kivymd.utils.hot_reload_viewer.HotReloadViewer
BoxLayout:
HotReloadViewer:
size_hint_x: .3
path: app.path_to_kv_file
errors: True
errors_text_color: 1, 1, 0, 1
errors_background_color: app.theme_cls.bg_dark
'''
class Example(MDApp):
path_to_kv_file = "../gui/loading_screen.kv"
def build(self):
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
def update_kv_file(self, text):
with open(self.path_to_kv_file, "w") as kv_file:
kv_file.write(text)
Example().run()

22
gui/filechooser.kv Normal file
View File

@@ -0,0 +1,22 @@
FileChooserScreen:
name: "ChooseFile"
md_bg_color: (0, 0, 0, 1)
BoxLayout:
size: root.size
pos: root.pos
orientation: "vertical"
FileChooserListView:
id: filechooser
BoxLayout:
size_hint_y: None
height: 30
Button:
text: "Cancel"
on_release:
app.root.current = "Home"
root.manager.transition.direction = "right"
Button:
text: "Load"
on_release: root.load(filechooser.path, filechooser.selection)

20
gui/gui.kv Normal file
View File

@@ -0,0 +1,20 @@
HomeScreen:
name: "Home"
md_bg_color: app.theme_cls.accent_color
GridLayout:
cols:1
Label:
text: "MIDI to Micro:bit Sound converter"
font_size: 30
bold: True
italic: True
color: (50, 50, 255, 1)
Label:
id: infobox
text: "Output will be automatically added to your clipboard once you have selected a file"
Button:
text: "choose file to start"
background_color: app.theme_cls.primary_color
on_release:
app.root.current = "ChooseFile"
root.manager.transition.direction = "left"

24
gui/loading_screen.kv Normal file
View File

@@ -0,0 +1,24 @@
TrackChooseScreen:
name: "Track"
md_bg_color: app.theme_cls.accent_color
GridLayout:
cols:1
Label:
text: "Track selection"
font_size: 30
bold: True
italic: True
color: (50, 50, 255, 1)
FloatLayout:
Spinner:
id: track_spinner
size_hint: 0.7, 0.2
pos_hint: {"x": 0.15, "y":0.5}
background_color: (0, 0, 0, 1)
text: "Select a track"
values: ["Test"]
Button:
text: "confirm"
background_color: app.theme_cls.primary_color
on_release:
root.extract()

80
midi_converter.py Normal file
View File

@@ -0,0 +1,80 @@
from kivy.uix.screenmanager import ScreenManager
from kivymd.uix.screen import MDScreen
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.label import Label
from kivymd.app import MDApp
from mido import MidiFile
import os
import backend.midi_management
import backend.csv_parsers
import time
class HomeScreen(MDScreen):
pass
class FileChooserScreen(MDScreen):
loadfile = ObjectProperty(None)
def load(self, path, filename):
try:
self.path = os.path.join(path, filename[0])
try:
self.mid = MidiFile(self.path, clip=True)
backend.csv_parsers.CsvWrite().write_str("./backend/temp.csv", [self.path])
self.tracks = []
for self.track in self.mid.tracks:
self.tracks.append(str(self.track))
self.tracks.pop(0)
if len(self.tracks) > 1:
screen_manager.get_screen("Track").ids.track_spinner.values = self.tracks
screen_manager.current = "Track"
screen_manager.transition.direction = "up"
else:
screen_manager.current = "Home"
screen_manager.transition.direction = "right"
except:
self.popup_fe = Popup(title="FileError", content=Label(text="Please select a MIDI-File!"),
size_hint=(0.4, 0.4), auto_dismiss=True)
self.popup_fe.open()
except:
self.popup_foldererror = Popup(title="FileError", content=Label(text="Only MIDI-Files allowed, not folder"),
size_hint=(0.4, 0.4), auto_dismiss=True)
self.popup_foldererror.open()
class TrackChooseScreen(MDScreen):
def extract(self):
self.chosen_track = self.ids.track_spinner.text
if self.chosen_track == "Select a track":
self.popup_ns = Popup(title="NoSelectionError", content=Label(text="Please select a Track!"),
size_hint=(0.4, 0.4), auto_dismiss=True)
self.popup_ns.open()
else:
self.path = backend.csv_parsers.CsvRead().importing("./backend/temp.csv").pop(0)
self.path_transmit = self.path.pop(0)
backend.midi_management.MidiManagement().analyse_track(str(self.path_transmit), self.chosen_track)
screen_manager.get_screen("Home").ids.infobox.text = "The command has been copied to the clipboard"
screen_manager.current = "Home"
screen_manager.transition.direction = "right"
class MidiConverter(MDApp):
global screen_manager
screen_manager = ScreenManager()
def build(self):
self.title = "Midi-Microbit-Converter"
self.theme_cls.primary_palette = "Blue"
self.theme_cls.accent_palette = "BlueGray"
screen_manager.add_widget(Builder.load_file("./gui/gui.kv"))
screen_manager.add_widget(Builder.load_file("./gui/filechooser.kv"))
screen_manager.add_widget(Builder.load_file("./gui/loading_screen.kv"))
return screen_manager
MidiConverter().run()