diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..25998f4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "fstools"] + path = fstools + url = https://git.mount-mockery.de/pylib/fstools.git +[submodule "report"] + path = report + url = https://git.mount-mockery.de/pylib/report.git +[submodule "task"] + path = task + url = https://git.mount-mockery.de/pylib/task.git +[submodule "media"] + path = media + url = https://git.mount-mockery.de/pylib/media.git diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..8d48992 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Verwendet IntelliSense zum Ermitteln möglicher Attribute. + // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen. + // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Main File execution", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/pyrip.py", + "console": "integratedTerminal", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ee25f90 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "python.defaultInterpreterPath": "./venv/bin/python", + "autopep8.args": ["--max-line-length=150"], + "[python]": { + "python.formatting.provider": "none", + "editor.defaultFormatter": "ms-python.autopep8", + "editor.formatOnSave": true + }, + "editor.fontSize": 14, + "emmet.includeLanguages": { "django-html": "html" }, + "python.testing.pytestArgs": ["-v", "--cov", "--cov-report=xml", "__test__"], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} diff --git a/config.py b/config.py new file mode 100644 index 0000000..05e5497 --- /dev/null +++ b/config.py @@ -0,0 +1 @@ +APP_NAME = 'pyrip' diff --git a/fstools b/fstools new file mode 160000 index 0000000..c10e879 --- /dev/null +++ b/fstools @@ -0,0 +1 @@ +Subproject commit c10e8792abb05671dab6de51cdadda3bf8ead50f diff --git a/icon.xpm b/icon.xpm new file mode 100644 index 0000000..0d26223 --- /dev/null +++ b/icon.xpm @@ -0,0 +1,295 @@ +/* XPM */ +static char *sound-juicer[] = { +/* columns rows colors chars-per-pixel */ +"32 32 257 2", +" c #79604B", +". c #7E6754", +"X c #7F756A", +"o c #7D7D7B", +"O c #974503", +"+ c #9B4701", +"@ c #9E4803", +"# c #9A4B0D", +"$ c #9C571D", +"% c #875937", +"& c #925B2E", +"* c #9F683C", +"= c #A34B02", +"- c #AA4D02", +"; c #A6520B", +": c #A4591D", +"> c #AF5D1A", +", c #BA5300", +"< c #BC5807", +"1 c #BC5B0C", +"2 c #B35912", +"3 c #B55F1B", +"4 c #BC5D10", +"5 c #AC5F21", +"6 c #BF6311", +"7 c #B9621C", +"8 c #A4622B", +"9 c #AB6025", +"0 c #AA652C", +"q c #AD682E", +"w c #A36635", +"e c #A0673A", +"r c #A1693D", +"t c #A86733", +"y c #AE6A33", +"u c #A96D3C", +"i c #B36222", +"p c #B46628", +"a c #B2692D", +"s c #BA6A2A", +"d c #B16C33", +"f c #B5733C", +"g c #9C6A43", +"h c #917B69", +"j c #9B7E67", +"k c #A87144", +"l c #AC7950", +"z c #B37544", +"x c #BE7C49", +"c c #C35700", +"v c #C55800", +"b c #C85E01", +"n c #C06012", +"m c #C36619", +"M c #C46A1F", +"N c #D46905", +"B c #D66D0D", +"V c #DE6F06", +"C c #D77114", +"Z c #D8761B", +"A c #C67026", +"S c #C7732D", +"D c #C87228", +"F c #C0773B", +"G c #CB7931", +"H c #D77928", +"J c #DA7A22", +"K c #DB7E29", +"L c #E46D02", +"P c #E67104", +"I c #EF7500", +"U c #EE7F16", +"Y c #F47800", +"T c #F47D0A", +"R c #C17B43", +"E c #AC815E", +"W c #B3835C", +"Q c #BB885E", +"! c #AB8F78", +"~ c #AE917B", +"^ c #B1957E", +"/ c #BD9A7D", +"( c #CF833E", +") c #D0823C", +"_ c #DC8433", +"` c #DE8B3E", +"' c #F48214", +"] c #F18319", +"[ c #F5881F", +"{ c #EA8E3B", +"} c #F58A22", +"| c #F99A25", +" . c #F99C29", +".. c #FAA12E", +"X. c #FAA432", +"o. c #FBA739", +"O. c #FAA835", +"+. c #FBAC3B", +"@. c #C6834E", +"#. c #C28856", +"$. c #CA8D57", +"%. c #D58C4A", +"&. c #DF8F45", +"*. c #DD944D", +"=. c #D69459", +"-. c #C39673", +";. c #C79E7C", +":. c #CF9C73", +">. c #DB9F69", +",. c #DFA36A", +"<. c #D4A074", +"1. c #E1944D", +"2. c #E29753", +"3. c #E39B5A", +"4. c #F79C44", +"5. c #E19B63", +"6. c #E5A45D", +"7. c #FBAE42", +"8. c #FBAE4B", +"9. c #F5A353", +"0. c #FBB144", +"q. c #FBB44C", +"w. c #FFBF40", +"e. c #F6B153", +"r. c #F4B75C", +"t. c #FBB452", +"y. c #FCB854", +"u. c #FCBA5B", +"i. c #E5A362", +"p. c #E5AA6D", +"a. c #E8A566", +"s. c #E3AC7A", +"d. c #E5B17F", +"f. c #E3B87C", +"g. c #E8B677", +"h. c #E8B07D", +"j. c #EEBF7B", +"k. c #F5AB64", +"l. c #F0AD6F", +"z. c #F4B06F", +"x. c #F0B969", +"c. c #F9B069", +"v. c #FABC63", +"b. c #FBBF68", +"n. c #F0BB72", +"m. c #F1BA78", +"M. c yellow", +"N. c #EFC17D", +"B. c #FBC06D", +"V. c #F4C07C", +"C. c #FCC372", +"Z. c #FCC57B", +"A. c #808080", +"S. c #8A8B87", +"D. c #8C8D8A", +"F. c #929292", +"G. c #9B9793", +"H. c #9A9A9A", +"J. c #9EA19D", +"K. c #AE9886", +"L. c #A99D94", +"P. c #B59982", +"I. c #B99C86", +"U. c #BC9F89", +"Y. c #BDA28B", +"T. c #BAA492", +"R. c #BDAA9B", +"E. c #A3A3A3", +"W. c #A6ABA6", +"Q. c #AAACA7", +"!. c #ACACAB", +"~. c #B6B6AD", +"^. c #BEB5AE", +"/. c #B3B3B3", +"(. c #BBBBBB", +"). c #D9AB85", +"_. c #D9B98B", +"`. c #D5BC97", +"'. c #D8BD96", +"]. c #C7BBA4", +"[. c #CDBDA0", +"{. c #CCBAAC", +"}. c #C0BBB8", +"|. c #E6B68A", +" X c #E7BA88", +".X c #E9B680", +"XX c #EAB88F", +"oX c #F5BC87", +"OX c #CDC4BA", +"+X c #DAC6AA", +"@X c #F5CB8D", +"#X c #FAC28B", +"$X c #FDCB82", +"%X c #FCCE8C", +"&X c #F5C395", +"*X c #FBCB9C", +"=X c #FDD497", +"-X c #FDD59A", +";X c #E0CDBE", +":X c #EFD0A6", +">X c #EFD4AB", +",X c #E3D1B5", +" YXYXYXYXYXYXYX", +"YXYXYXYXg p G ZXUXSX-XKX6X+.O.+.O.+.C.UXUXIXCXx i 8 YXYXYXYXYXYX", +"YXYXYX8 p %.IXIX%X+.O.q.$XX...O. .+.8.8XMXeXIXUX:.3 2 YXYXYXYXYX", +"YXYXYXd D SXKXu.+.X.+. .-X .X.o. .+.8.wXt.y.v.HXIX@.a YXYXYXYXYX", +"YXYXw 1 9XUXZ.O.O.X... .6Xo.+.0.o.q.7X$Xb.b.b.C.KXPXs t YXYXYXYX", +"YXYX7 6.HXSX+.+.| +...+.v.b.q.t.e.V.NX@X@X@X@X@X4XPXuXl YXYXYXYX", +"YXt M 9XIXIX0.X.0.o.q.8.t.eXv.n.f.cX1X>X5X5X5X:X:XHXDX).h YXYXYX", +"YXa p.UXAX9X9XZ.X.t.t.v.b.ZXg._.+XCX.UXq.+... ...+.t.N.VXPXYXYXYXYXJ.E././.rXU.a.Y T l.f (.A.YXYX", +"5 .XUX+.X...X.+.q.x._.[.iXYXYXw.YXD.S.(./.rXU.5.Y Y } =.T.A.YXYX", +"5 ,.UXr.+.O.O.+.r.f.`.aXW.YXM.YXYXo o /./.}.I.3.n N ] 9.y A.YXYX", +"> ) UX-X+.O.+.q.j.hXjXdXQ.YXYXYX+ . F.!.!.rXI.2.5 I.7 U R & YXYX", +"> A BXUX8XB.4XnXcXOXtXdX!.S.o % # (.Q.!.(.P.1.y dX}.9 P ; O YX", +", 1 %XHXUXNX>X2XsXfXfXdXdX/.h k ).K.W.W./.rXP.&.0 yXiXiX8 @ + @ ", +"YX7 XIXKXqXhXvXFXDXdXdXyX}.u 0X0Xw E.W.(.rXK.&.y yXyXyXF.O O O ", +"YX5 f UXGXmXGXLXFXFXDXdXyX(.u XX5.R L./.(.(.P.K 0 yXyX/.A.YXYXYX", +"YX, 1 VXUXJXPXLXLXFXFXDXdXyXd } I H k (.(.(.P.K 0 tXyXF.YXYXYXYX", +"YXYX9 -.UXUXPXLXLXFXFXDXfXdXy L L c l (./.(.~ K 0 yXE.A.YXYXYXYX", +"YXYXc E uXUXUXPXLXLXFXDXfXfX{.u 5 u (.(.(./.! J 0 /.F.YXYXYXYXYX", +"YXYXYX7 G.FXPXUXLXLXFXFXDXfXfXdXyXyXrXrX(.(.! Z 8 F.A.YXYXYXYXYX", +"YXYXYXYXA.H.dXUXUXLXLXFXDXDXfXfXdXyXyXtXrX(.^ C $ A.YXYXYXYXYXYX", +"YXYXYXYXYXA.H./.LXPXLXFXDXDXDXfXfXdXtXR.R.}.j B = YXYXYXYXYXYXYX", +"YXYXYXYXYXYXYXA.H.rXFXLXFXFXDXfXQ Q <.|.s.$.p V = YXYXYXYXYXYXYX", +"YXYXYXYXYXYXYXYXYXA.H.J./.(.tXW h.*X*X#Xc.4.} ] = YXYXYXYXYXYXYX", +"YXYXYXYXYXYXYXYXYXYXYXYXA.A.A.$ *.oX*X&Xl.{ L b = YXYXYXYXYXYXYX", +"YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXO @ = - , , - = + O YXYXYXYXYXYXYX", +"YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXO O O O YXYXYXYXYXYXYXYXYXYX" +}; diff --git a/media b/media new file mode 160000 index 0000000..402e837 --- /dev/null +++ b/media @@ -0,0 +1 @@ +Subproject commit 402e8375511470c61021956edad72e1080f51c8e diff --git a/pyrip.py b/pyrip.py new file mode 100644 index 0000000..a20cb44 --- /dev/null +++ b/pyrip.py @@ -0,0 +1,105 @@ +import argparse +import config +import logging +import media +import report +import sys +import os +import fstools + +try: + from config import APP_NAME as ROOT_LOGGER_NAME +except ImportError: + ROOT_LOGGER_NAME = 'root' +logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) + + +def progress_callback_rip(p: float): + bar_length = 40 + progress = int(bar_length * p) + out = "\rRipping.... - [ " + out += "*" * progress + out += "-" * (bar_length - progress) + out += " ] %5.1f%%" % (p * 100) + sys.stdout.write(out) + + +def progress_callback_enc(p: float): + bar_length = 40 + progress = int(bar_length * p) + out = "\rEncoding... - [ " + out += "*" * progress + out += "-" * (bar_length - progress) + out += " ] %5.1f%%" % (p * 100) + sys.stdout.write(out) + + +def cddb_user_callback(what: int, info: dict): + if what == media.CALLBACK_CDDB_CHOICE: + keys = tuple(info.keys()) + print("Multiple cddb entries detected:") + print("-------------------------------") + for i in range(0, len(keys)): + print("%2d. %s" % (i + 1, info[keys[i]])) + n = None + while not n: + fb = input("Choose: ") + try: + fb = int(fb) + except ValueError: + n = None + else: + if fb > 0 and fb <= len(keys): + n = fb + if n is None: + print("Use a choice from above!") + print() + return keys[n - 1] + elif what == media.CALLBACK_MAN_INPUT: + print("No cddb entries detected:") + print("-------------------------") + for key in info: + info[key] = input(key[0].upper() + key[1:] + ": ") + return info + + +def main(**kwargs): + disc_data = media.get_media_data(media.get_disc_device(), cddb_user_callback) + + if disc_data is None: + logger.error("Could not reading disc_data") + sys.exit(1) + print("Found Disc:") + print("===========") + print() + print(disc_data[media.common.KEY_ARTIST], "-", disc_data[media.common.KEY_ALBUM]) + print("-" * (len(disc_data[media.common.KEY_ARTIST]) + len(disc_data[media.common.KEY_ALBUM]) + 3)) + for track_info in disc_data["tracks"]: + i = track_info[media.common.KEY_TRACK] + print("%2d. %s" % (i, track_info[media.common.KEY_TITLE])) + wavfile = media.track_to_targetpath(kwargs.get("basepath"), track_info, 'wav') + try: + fstools.mkdir(os.path.dirname(wavfile)) + except PermissionError: + logger.exception("Unable to create ripping target path: %s", os.path.dirname(wavfile)) + sys.exit(1) + rv = media.disc_track_rip(i, wavfile, progress_callback_rip) + if rv == 0: + print() + rv = media.wav_to_mp3(wavfile, kwargs.get("basepath"), track_info, progress_callback_enc) + print() + os.remove(wavfile) + if rv != 0: + logger.error("Error while ripping or encoding...") + + +if __name__ == "__main__": + default_baspath = os.path.join(os.getenv("HOME"), "rip") + parser = argparse.ArgumentParser(description='Description') + parser.add_argument('-v', '--verbose', help='Description for foo argument', action='store_true') + parser.add_argument('-b', '--basepath', help=f'The rip and encode basepath (default is {default_baspath})', default=default_baspath) + args = vars(parser.parse_args()) + + report.stdoutLoggingConfigure(log_name_lvl=((config.APP_NAME, logging.DEBUG if args.get('verbose') else logging.ERROR),)) + + main(**args) diff --git a/pyrip.wxg b/pyrip.wxg new file mode 100644 index 0000000..b60ef78 --- /dev/null +++ b/pyrip.wxg @@ -0,0 +1,384 @@ + + + + + + PyRip + 1033, 761 + + wxVERTICAL + + wxEXPAND + 0 + + + + Rip + Config + + + + + wxVERTICAL + + wxEXPAND + 0 + + + wxHORIZONTAL + + wxEXPAND + 0 + + + + 0 + + + + evt_tracklist + + + + + wxEXPAND + 0 + + + wxVERTICAL + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_artist_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_album_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_year_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_genre_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_title_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_track_no_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_comment_changed + + + + + + + 0 + + + 20 + 20 + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + 1000 + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + 1000 + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + 1000 + + + + + + + + + + 0 + + + wxHORIZONTAL + + 0 + + + 20 + 20 + + + + 0 + + + + + evt_rip + + + + + 0 + + + 20 + 20 + + + + 0 + + + + + evt_new_disc + + + + + 0 + + + 20 + 20 + + + + + + + + + + wxVERTICAL + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_target_path_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_device_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_default_comment_changed + + + + + + + wxEXPAND + 0 + + + wxVERTICAL + + + wxEXPAND + 0 + + + + evt_track_list_string_changed + + + + + + + + + + + + diff --git a/report b/report new file mode 160000 index 0000000..7003c13 --- /dev/null +++ b/report @@ -0,0 +1 @@ +Subproject commit 7003c13ef8c7e7c3a55a545cbbad4039cc024a9f diff --git a/task b/task new file mode 160000 index 0000000..7583bb5 --- /dev/null +++ b/task @@ -0,0 +1 @@ +Subproject commit 7583bb5f3bd2420c901374ba95b678af6ce88433