Reputation: 7841
I have the following simple script
#!/usr/bin/env python
import yaml
returns = {'file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed': {'comment': 'File /usr/bin/gen-motd.py updated', 'pchanges': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, 'name': '/usr/bin/gen-motd.py', 'start_time': '16:18:54.060168', 'result': True, 'duration': 99.663, '__run_num__': 1, 'changes': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, '__id__': '/usr/bin/gen-motd.py'}}
returns = yaml.dump(returns, default_flow_style=False)
print returns
Its outputting
file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed:
__id__: /usr/bin/gen-motd.py
__run_num__: 1
changes:
diff: "--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import\
\ urllib2\n import socket\n import json\n import time\n"
comment: File /usr/bin/gen-motd.py updated
duration: 99.663
name: /usr/bin/gen-motd.py
pchanges:
diff: "--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import\
\ urllib2\n import socket\n import json\n import time\n"
result: true
start_time: '16:18:54.060168'
The diff part is badly formatted.. I want it to return something like
file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed:
__id__: /usr/bin/gen-motd.py
__run_num__: 1
changes:
diff: |
---
+++
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+import sys
+import urllib2
import socket
import json
import time
comment: "File /usr/bin/gen-motd.py updated"
duration: 99.663
name: /usr/bin/gen-motd.py
pchanges:
diff: |
---
+++
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+import sys
+import urllib2
import socket
import json
import time
result: true
start_time: "16:18:54.060168"
Upvotes: 1
Views: 249
Reputation: 76632
There are two problems to overcome to get this as you want:
Using ruamel.yaml
is the far more easy way, just convert strings that are 3 levels deep and contain a newline:
import sys
import ruamel.yaml
from ruamel.yaml.scalarstring import LiteralScalarString
returns = {'file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed': {'comment': 'File /usr/bin/gen-motd.py updated', 'pchanges': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, 'name': '/usr/bin/gen-motd.py', 'start_time': '16:18:54.060168', 'result': True, 'duration': 99.663, '__run_num__': 1, 'changes': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, '__id__': '/usr/bin/gen-motd.py'}}
for k in returns:
for k1 in returns[k]:
if not isinstance(returns[k][k1], dict):
continue
for k2 in returns[k][k1]:
v = returns[k][k1][k2]
try:
if '\n' in v:
while ' \n' in v:
v = v.replace(' \n', '\n') # remove EOL spaces
returns[k][k1][k2] = LiteralScalarString(v)
except TypeError:
continue
yaml = ruamel.yaml.YAML()
yaml.dump(returns, sys.stdout)
You can of course remove the whole for
construction and use
returns = {'file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed': {'comment': 'File /usr/bin/gen-motd.py updated', 'pchanges': {'diff': PreservedScalarString('---\n+++\n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n\n+import sys\n+import urllib2\n import socket\n import json\n import time\n')}, 'name': '/usr/bin/gen-motd.py', 'start_time': '16:18:54.060168', 'result': True, 'duration': 99.663, '__run_num__': 1, 'changes': {'diff': PreservedScalarString('---\n+++\n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n\n+import sys\n+import urllib2\n import socket\n import json\n import time\n')}, '__id__': '/usr/bin/gen-motd.py'}}
Either way this gives you:
file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed:
start_time: '16:18:54.060168'
comment: File /usr/bin/gen-motd.py updated
duration: 99.663
__id__: /usr/bin/gen-motd.py
changes:
diff: |
---
+++
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+import sys
+import urllib2
import socket
import json
import time
__run_num__: 1
pchanges:
diff: |
---
+++
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+import sys
+import urllib2
import socket
import json
import time
name: /usr/bin/gen-motd.py
result: true
Because you are using dict
the order of the keys in the YAML file is undetermined. You can construct returns
directly with CommentedMap
instances (from ruamel.yaml.comments
) and PreservedScalarString
and have control over the key orderings in your YAML mappings as well.
Upvotes: 2