From aca349dc01eaa1cff7984a9d0ba9313ba1e6a85f Mon Sep 17 00:00:00 2001 From: Michael Holroyd Date: Wed, 10 Feb 2021 15:13:18 -0500 Subject: [PATCH 1/5] .show support for flat.io --- music21/converter/subConverters.py | 55 ++++++++++++++++++++++++++++++ music21/environment.py | 3 ++ setup.py | 2 ++ 3 files changed, 60 insertions(+) diff --git a/music21/converter/subConverters.py b/music21/converter/subConverters.py index ecc445d388..57ae38f0f0 100644 --- a/music21/converter/subConverters.py +++ b/music21/converter/subConverters.py @@ -1015,6 +1015,61 @@ def show(self, obj, fmt, app=None, subformats=None, **keywords): # pragma: no c self.launch(returnedFilePath, fmt=fmt, app=app) +# ------------------------------------------------------------------------------ +class ConverterFlatio(SubConverter): + ''' + Converter for Flatio. Roughly the same as XMLconverter but sends XML to http://flat.io + ''' + registerFormats = ('flat',) + registerOutputExtensions = ('flat',) + + def parseData(self, strData, number=None): + ''' + Not implemented + ''' + # Pull MusicXML from a url? + + def write(self, obj, fmt, fp=None, subformats=None, + compress=False, **keywords): # pragma: no cover + ''' + Write to a .xml file. + Set `compress=True` to immediately compress the output to a .mxl file. + ''' + import requests + from music21.musicxml import m21ToXml + + if not environLocal['flatioAuthToken']: + raise SubConverterException("Trying to use flat.io subconverter, but no flatioAuthToken is set. See https://flat.io/developers/docs/api/authentication.html#personal-access-tokens to get a token.") + + generalExporter = m21ToXml.GeneralObjectExporter(obj) + dataBytes: bytes = generalExporter.parse() + + body = { + 'title': defaults.title, + 'privacy': 'private', + 'data': dataBytes.decode("utf-8") + } + + headers = { + 'Authorization': 'Bearer ' + environLocal['flatioAuthToken'], + 'Content-Type': 'application/json' + } + r = requests.post("https://api.flat.io/v2/scores", json=body, headers=headers) + print(r.status_code, r.reason) + + return r + + def show(self, obj, fmt, app=None, subformats=None, **keywords): # pragma: no cover + ''' + Override to do something with png... + ''' + import webbrowser + r = self.write(obj, fmt, subformats=subformats, **keywords) + json = r.json() + print(r.json()) + print(json['htmlUrl']) + webbrowser.open(json['htmlUrl'], new=2) + # ------------------------------------------------------------------------------ class ConverterMidi(SubConverter): ''' diff --git a/music21/environment.py b/music21/environment.py index 99398d7034..a2669fef21 100644 --- a/music21/environment.py +++ b/music21/environment.py @@ -377,6 +377,9 @@ def _loadDefaults(self, forcePlatform=None): self._ref['autoDownload'] = 'ask' self._ref['debug'] = 0 + # authentication token for http://flat.io + self._ref['flatioAuthToken'] = None + # printing of missing import warnings # default/non-zero is on self._ref['warnings'] = 1 diff --git a/setup.py b/setup.py index 185507f19e..1472445f89 100644 --- a/setup.py +++ b/setup.py @@ -36,6 +36,8 @@ "joblib", "more-itertools", "webcolors", + "requests", + "webbrowser" ] From 8d12471481a662a301dcb7e2a3d627fe16a1862f Mon Sep 17 00:00:00 2001 From: Michael Holroyd Date: Wed, 10 Feb 2021 15:16:59 -0500 Subject: [PATCH 2/5] better error messages --- music21/converter/subConverters.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/music21/converter/subConverters.py b/music21/converter/subConverters.py index 57ae38f0f0..98457f33ab 100644 --- a/music21/converter/subConverters.py +++ b/music21/converter/subConverters.py @@ -1055,20 +1055,19 @@ def write(self, obj, fmt, fp=None, subformats=None, 'Content-Type': 'application/json' } r = requests.post("https://api.flat.io/v2/scores", json=body, headers=headers) - print(r.status_code, r.reason) + if r.status_code != 200: + print("Could not upload XML to flat.io") + print(r.status_code, r.reason) - return r + return r.json()['htmlUrl'] def show(self, obj, fmt, app=None, subformats=None, **keywords): # pragma: no cover ''' Override to do something with png... ''' import webbrowser - r = self.write(obj, fmt, subformats=subformats, **keywords) - json = r.json() - print(r.json()) - print(json['htmlUrl']) - webbrowser.open(json['htmlUrl'], new=2) + url = self.write(obj, fmt, subformats=subformats, **keywords) + webbrowser.open(url, new=2) # ------------------------------------------------------------------------------ class ConverterMidi(SubConverter): From d6afb5e086f986d16833aa949d95cedc8fe74af6 Mon Sep 17 00:00:00 2001 From: Michael Holroyd Date: Wed, 10 Feb 2021 15:24:13 -0500 Subject: [PATCH 3/5] better documentation --- music21/converter/subConverters.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/music21/converter/subConverters.py b/music21/converter/subConverters.py index 98457f33ab..af7c9f544f 100644 --- a/music21/converter/subConverters.py +++ b/music21/converter/subConverters.py @@ -1018,22 +1018,26 @@ def show(self, obj, fmt, app=None, subformats=None, **keywords): # pragma: no c # ------------------------------------------------------------------------------ class ConverterFlatio(SubConverter): ''' - Converter for Flatio. Roughly the same as XMLconverter but sends XML to http://flat.io + Converter for Flatio. Sends XML to http://flat.io and then opens it in a browser tab. You must have a flat.io authentication token, and set it like + + >>> us = environment.UserSettings() + >>> us['flatioAuthToken'] = '[MY FLAT.IO AUTH TOKEN]' + + See https://flat.io/developers/docs/api/authentication.html#personal-access-tokens ''' registerFormats = ('flat',) registerOutputExtensions = ('flat',) def parseData(self, strData, number=None): ''' - Not implemented + Not implemented yet. ''' - # Pull MusicXML from a url? + # Pull MusicXML from a flat.io url? def write(self, obj, fmt, fp=None, subformats=None, compress=False, **keywords): # pragma: no cover ''' - Write to a .xml file. - Set `compress=True` to immediately compress the output to a .mxl file. + Uploads MusicXML to flat.io via their API. ''' import requests from music21.musicxml import m21ToXml @@ -1063,7 +1067,7 @@ def write(self, obj, fmt, fp=None, subformats=None, def show(self, obj, fmt, app=None, subformats=None, **keywords): # pragma: no cover ''' - Override to do something with png... + Uploads MusixXML to flat.io and opens the result in a browser tab. ''' import webbrowser url = self.write(obj, fmt, subformats=subformats, **keywords) From f3fe7bf1d45ff7e6d7e6b152d6868736cb84bd26 Mon Sep 17 00:00:00 2001 From: Michael Holroyd Date: Wed, 10 Feb 2021 15:25:18 -0500 Subject: [PATCH 4/5] better documentation --- music21/converter/subConverters.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/music21/converter/subConverters.py b/music21/converter/subConverters.py index af7c9f544f..badbb1d2c0 100644 --- a/music21/converter/subConverters.py +++ b/music21/converter/subConverters.py @@ -1018,8 +1018,9 @@ def show(self, obj, fmt, app=None, subformats=None, **keywords): # pragma: no c # ------------------------------------------------------------------------------ class ConverterFlatio(SubConverter): ''' - Converter for Flatio. Sends XML to http://flat.io and then opens it in a browser tab. You must have a flat.io authentication token, and set it like + Converter for Flatio. Sends XML to http://flat.io and then opens it in a browser tab. + You must have a flat.io authentication token, and set it like >>> us = environment.UserSettings() >>> us['flatioAuthToken'] = '[MY FLAT.IO AUTH TOKEN]' From 49390b11b6860c5c228d63a3ff1b768230f215ef Mon Sep 17 00:00:00 2001 From: Myke Cuthbert Date: Tue, 11 Jan 2022 13:05:11 -1000 Subject: [PATCH 5/5] add requests to requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index af43bbcf9d..3a4d2b0c86 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ jsonpickle matplotlib more_itertools numpy +requests webcolors>=1.5