Compare commits
2 Commits
a30d678c08
...
b6309cf16c
Author | SHA1 | Date | |
---|---|---|---|
b6309cf16c | |||
27fdf3cf24 |
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,7 +1,10 @@
|
|||||||
|
**/__pycache__
|
||||||
|
.vscode
|
||||||
|
.venv
|
||||||
|
|
||||||
|
recordings/
|
||||||
*.mkv
|
*.mkv
|
||||||
|
*.png
|
||||||
out/
|
out/
|
||||||
|
|
||||||
.venv
|
scores
|
||||||
mscz/
|
|
||||||
recordings/
|
|
||||||
**/__pycache__
|
|
@ -1,86 +1,25 @@
|
|||||||
from xml.etree import ElementTree
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import zipfile
|
|
||||||
import shutil
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps
|
||||||
from modules import logger
|
from modules import logger, mscz
|
||||||
|
|
||||||
RATIO = 16/9 # 16:9
|
RATIO = 16/9 # 16:9
|
||||||
|
|
||||||
|
|
||||||
def get_elements(root, attribute):
|
|
||||||
return [i for i in root if i.tag == attribute]
|
|
||||||
|
|
||||||
def get_element(root, attribute):
|
|
||||||
elems = get_elements(root, attribute)
|
|
||||||
|
|
||||||
if len(elems) > 1:
|
|
||||||
print(f"More than one '{attribute}' found", file=sys.stderr)
|
|
||||||
if len(elems) == 0:
|
|
||||||
raise IndexError(f"No '{attribute}' found !")
|
|
||||||
|
|
||||||
return elems[0]
|
|
||||||
|
|
||||||
def create_pagebreaks(data):
|
|
||||||
"""
|
|
||||||
Replaces all manual linebreaks by pagebreaks in a .mscx file (xml)
|
|
||||||
"""
|
|
||||||
root = ElementTree.fromstring(data)
|
|
||||||
|
|
||||||
score = get_element(root, "Score")
|
|
||||||
parts = get_elements(score, "Part")
|
|
||||||
staffs = get_elements(score, "Staff")
|
|
||||||
for part in parts:
|
|
||||||
staffs += get_elements(part, "Staff")
|
|
||||||
|
|
||||||
changes = 0
|
|
||||||
for staff in staffs:
|
|
||||||
measures = get_elements(staff, "Measure")
|
|
||||||
for measure in measures:
|
|
||||||
layoutbreaks = get_elements(measure, "LayoutBreak")
|
|
||||||
for layoutbreak in layoutbreaks:
|
|
||||||
subtype = get_element(layoutbreak, "subtype")
|
|
||||||
if subtype.text == "line":
|
|
||||||
subtype.text = "page"
|
|
||||||
changes += 1
|
|
||||||
|
|
||||||
|
|
||||||
return ElementTree.tostring(root), changes
|
|
||||||
|
|
||||||
def remove_footer(data):
|
|
||||||
"""
|
|
||||||
Disable page footer in .mss (xml)
|
|
||||||
"""
|
|
||||||
root = ElementTree.fromstring(data)
|
|
||||||
|
|
||||||
style = get_element(root, "Style")
|
|
||||||
show_footer = get_element(style, "showFooter")
|
|
||||||
show_footer.text = 0
|
|
||||||
|
|
||||||
return ElementTree.tostring(root)
|
|
||||||
|
|
||||||
def prepare_mscz(source, dest):
|
|
||||||
shutil.copy(source, dest)
|
|
||||||
with zipfile.ZipFile(source) as inzip, zipfile.ZipFile(dest, "w") as outzip:
|
|
||||||
for inzipinfo in inzip.infolist():
|
|
||||||
with inzip.open(inzipinfo) as infile:
|
|
||||||
if inzipinfo.filename.endswith(".mscx"):
|
|
||||||
new_data, changes = create_pagebreaks(infile.read())
|
|
||||||
outzip.writestr(inzipinfo.filename, new_data)
|
|
||||||
elif inzipinfo.filename.endswith(".mss"):
|
|
||||||
new_data = remove_footer(infile.read())
|
|
||||||
outzip.writestr(inzipinfo.filename, new_data)
|
|
||||||
else:
|
|
||||||
outzip.writestr(inzipinfo.filename, infile.read())
|
|
||||||
|
|
||||||
def generate_images(mscz_file, base_dest):
|
def generate_images(mscz_file, base_dest):
|
||||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
tmp_mscz = os.path.join(tmpdirname, "score.mscz")
|
tmp_mscz = os.path.join(tmpdirname, "score.mscz")
|
||||||
prepare_mscz(mscz_file, tmp_mscz)
|
mscz.apply(
|
||||||
|
mscz_file,
|
||||||
|
tmp_mscz,
|
||||||
|
[
|
||||||
|
mscz.patches.create_pagebreaks,
|
||||||
|
mscz.patches.remove_footer
|
||||||
|
]
|
||||||
|
)
|
||||||
logger.log(".mscz file patched")
|
logger.log(".mscz file patched")
|
||||||
|
|
||||||
subprocess.call(["mscore", tmp_mscz, "-o", base_dest+".png"])
|
subprocess.call(["mscore", tmp_mscz, "-o", base_dest+".png"])
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
IN=$1
|
|
||||||
[[ $IN ]]|| IN="concat.txt"
|
|
||||||
FILES=$(cat $IN | grep file | awk '{print $2}' | uniq)
|
|
||||||
|
|
||||||
echo $FILES
|
|
||||||
|
|
||||||
# Get the larger width and height of all the images
|
|
||||||
WIDTH=$(identify -format "%w\n" $FILES | sort -nr | head -1)
|
|
||||||
HEIGHT=$(identify -format "%h\n" $FILES | sort -nr | head -1)
|
|
||||||
|
|
||||||
echo $WIDTH x $HEIGHT
|
|
||||||
|
|
||||||
# Center all the images and pad them to the larger width and height
|
|
||||||
# Set the border color to the dominant color of the image
|
|
||||||
for f in $FILES; do
|
|
||||||
BORDER_COLOR=$(magick $f -format "%[pixel:p{0,0}]" info:)
|
|
||||||
#BORDER_COLOR="srgb(255,255,255)"
|
|
||||||
echo "Border color: $BORDER_COLOR"
|
|
||||||
magick $f -gravity center -background none -extent ${WIDTH}x${HEIGHT} -bordercolor $BORDER_COLOR -border 0x0 $f
|
|
||||||
done
|
|
111
src/modules/mscz.py
Normal file
111
src/modules/mscz.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
from xml.etree import ElementTree
|
||||||
|
import functools
|
||||||
|
import zipfile
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Patches
|
||||||
|
"""
|
||||||
|
class Patches:
|
||||||
|
def __init__(self):
|
||||||
|
self._data = {}
|
||||||
|
def __getattr__(self, key):
|
||||||
|
return self._data[key]
|
||||||
|
|
||||||
|
|
||||||
|
patches = Patches()
|
||||||
|
|
||||||
|
def register_patch(file_ext):
|
||||||
|
def inner_wrapper(view):
|
||||||
|
patches._data[view.__name__] = (view, file_ext)
|
||||||
|
|
||||||
|
@functools.wraps(view)
|
||||||
|
def wrapped_view(**kwargs):
|
||||||
|
return view(**kwargs)
|
||||||
|
|
||||||
|
return wrapped_view
|
||||||
|
return inner_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@register_patch("mscx")
|
||||||
|
def create_pagebreaks(data):
|
||||||
|
"""
|
||||||
|
Replaces all manual linebreaks by pagebreaks in a .mscx file (xml)
|
||||||
|
"""
|
||||||
|
root = ElementTree.fromstring(data)
|
||||||
|
|
||||||
|
score = get_element(root, "Score")
|
||||||
|
parts = get_elements(score, "Part")
|
||||||
|
staffs = get_elements(score, "Staff")
|
||||||
|
for part in parts:
|
||||||
|
staffs += get_elements(part, "Staff")
|
||||||
|
|
||||||
|
for staff in staffs:
|
||||||
|
measures = get_elements(staff, "Measure")
|
||||||
|
for measure in measures:
|
||||||
|
layoutbreaks = get_elements(measure, "LayoutBreak")
|
||||||
|
for layoutbreak in layoutbreaks:
|
||||||
|
subtype = get_element(layoutbreak, "subtype")
|
||||||
|
if subtype.text == "line":
|
||||||
|
subtype.text = "page"
|
||||||
|
|
||||||
|
|
||||||
|
return ElementTree.tostring(root)
|
||||||
|
|
||||||
|
@register_patch("mss")
|
||||||
|
def remove_footer(data):
|
||||||
|
"""
|
||||||
|
Disable page footer in .mss (xml)
|
||||||
|
"""
|
||||||
|
root = ElementTree.fromstring(data)
|
||||||
|
|
||||||
|
style = get_element(root, "Style")
|
||||||
|
show_footer = get_element(style, "showFooter")
|
||||||
|
show_footer.text = 0
|
||||||
|
|
||||||
|
return ElementTree.tostring(root)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
The "main" apply function
|
||||||
|
"""
|
||||||
|
def get_elements(root, attribute):
|
||||||
|
return [i for i in root if i.tag == attribute]
|
||||||
|
|
||||||
|
def get_element(root, attribute):
|
||||||
|
elems = get_elements(root, attribute)
|
||||||
|
|
||||||
|
if len(elems) > 1:
|
||||||
|
print(f"More than one '{attribute}' found", file=sys.stderr)
|
||||||
|
if len(elems) == 0:
|
||||||
|
raise IndexError(f"No '{attribute}' found !")
|
||||||
|
|
||||||
|
return elems[0]
|
||||||
|
|
||||||
|
def apply(source, dest, patches):
|
||||||
|
"""
|
||||||
|
Apply functions to patch files inside a mscz
|
||||||
|
- source : source file
|
||||||
|
- dest : destination file, must differ
|
||||||
|
- patches : list of (function, file extension)
|
||||||
|
"""
|
||||||
|
patches_by_ext = {}
|
||||||
|
for func, ext in patches:
|
||||||
|
if ext not in patches_by_ext:
|
||||||
|
patches_by_ext[ext] = []
|
||||||
|
|
||||||
|
patches_by_ext[ext].append(func)
|
||||||
|
|
||||||
|
shutil.copy(source, dest)
|
||||||
|
with zipfile.ZipFile(source) as inzip, zipfile.ZipFile(dest, "w") as outzip:
|
||||||
|
for inzipinfo in inzip.infolist():
|
||||||
|
with inzip.open(inzipinfo) as infile:
|
||||||
|
ext = inzipinfo.filename.split(".")[-1]
|
||||||
|
if ext in patches_by_ext:
|
||||||
|
data = infile.read()
|
||||||
|
for func in patches_by_ext[ext]:
|
||||||
|
data = func(data)
|
||||||
|
outzip.writestr(inzipinfo.filename, data)
|
||||||
|
else:
|
||||||
|
outzip.writestr(inzipinfo.filename, infile.read())
|
Loading…
Reference in New Issue
Block a user