shell: add edit_{record,binary}_decoded shell commands

This allows the user to edit the file/record contents in its
JSON representation inside the standard system text editor.

Change-Id: Icf6a6e8529e7664c5645519fb4bdd55b35f34664
diff --git a/pySim/filesystem.py b/pySim/filesystem.py
index d2b8443..e771f3c 100644
--- a/pySim/filesystem.py
+++ b/pySim/filesystem.py
@@ -25,6 +25,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import code
+import tempfile
 import json
 
 import cmd2
@@ -433,6 +434,26 @@
             if data:
                 self._cmd.poutput_json(data)
 
+        def do_edit_binary_decoded(self, opts):
+            """Edit the JSON representation of the EF contents in an editor."""
+            (orig_json, sw) = self._cmd.rs.read_binary_dec()
+            with tempfile.TemporaryDirectory(prefix='pysim_') as dirname:
+                filename = '%s/file' % dirname
+                # write existing data as JSON to file
+                with open(filename, 'w') as text_file:
+                    json.dump(orig_json, text_file, indent=4)
+                # run a text editor
+                self._cmd._run_editor(filename)
+                with open(filename, 'r') as text_file:
+                    edited_json = json.load(text_file)
+                if edited_json == orig_json:
+                    self._cmd.poutput("Data not modified, skipping write")
+                else:
+                    (data, sw) = self._cmd.rs.update_binary_dec(edited_json)
+                    if data:
+                        self._cmd.poutput_json(data)
+
+
     def __init__(self, fid:str, sfid:str=None, name:str=None, desc:str=None, parent:CardDF=None,
                  size={1,None}):
         """
@@ -622,6 +643,32 @@
             if data:
                 self._cmd.poutput(data)
 
+        edit_rec_dec_parser = argparse.ArgumentParser()
+        edit_rec_dec_parser.add_argument('record_nr', type=int, help='Number of record to be edited')
+        @cmd2.with_argparser(edit_rec_dec_parser)
+        def do_edit_record_decoded(self, opts):
+            """Edit the JSON representation of one record in an editor."""
+            (orig_json, sw) = self._cmd.rs.read_record_dec(opts.record_nr)
+            dirname = tempfile.mkdtemp(prefix='pysim_')
+            try:
+                filename = '%s/file' % dirname
+                # write existing data as JSON to file
+                with open(filename, 'w') as text_file:
+                    json.dump(orig_json, text_file, indent=4)
+                # run a text editor
+                self._cmd._run_editor(filename)
+                with open(filename, 'r') as text_file:
+                    edited_json = json.load(text_file)
+                if edited_json == orig_json:
+                    self._cmd.poutput("Data not modified, skipping write")
+                else:
+                    (data, sw) = self._cmd.rs.update_record_dec(opts.record_nr, edited_json)
+                    if data:
+                        self._cmd.poutput_json(data)
+            finally:
+                shutil.rmtree(dirname)
+
+
     def __init__(self, fid:str, sfid:str=None, name:str=None, desc:str=None,
                  parent:Optional[CardDF]=None, rec_len={1,None}):
         """