2 """Quick, dirty script that will convert a csv file to yaml, spawn an editor
3 for you to fiddle with it, then convert back to csv and replace the original
6 Run me as: $0 some_file.csv
8 The editor used is $EDITOR, of course.
10 This script is not guaranteed to be even remotely reliable, so consider only
11 using it on files in source control.
24 sys.stderr.write("Please install PyYAML.\n")
27 infilename, = sys.argv[1:]
30 with open(infilename) as infile:
31 reader = csv.reader(infile, lineterminator='\n')
32 column_names = [unicode(column) for column in next(reader)]
37 for col, value in zip(column_names, row):
38 datum[col] = value.decode('utf-8')
43 # Monkeypatch yaml to use > syntax for multiline text; easier to edit
44 from yaml.emitter import Emitter
45 orig_choose_scalar_style = Emitter.choose_scalar_style
46 def new_choose_scalar_style(self):
47 if self.analysis is None:
48 self.analysis = self.analyze_scalar(self.event.value)
49 if self.analysis.multiline:
51 return orig_choose_scalar_style(self)
52 Emitter.choose_scalar_style = new_choose_scalar_style
55 with tempfile.NamedTemporaryFile(suffix='.yml') as tmp:
56 yaml.safe_dump(data, tmp,
57 default_flow_style=False,
61 del data # reclaim rams!
63 error_line = '' # used on errors
65 args = [os.environ['EDITOR'], tmp.name]
66 if 'vim' in os.environ['EDITOR']:
67 # vim has an arg for jumping to a line:
68 args.append("+{0}".format(error_line))
70 # Run the user's editor and wait for it to close
71 subprocess.Popen(args).wait()
75 new_data = yaml.safe_load(tmp)
77 except yaml.YAMLError as e:
78 if hasattr(e, 'problem_mark'):
79 error_line = e.problem_mark.line + 1
84 print "Oh my god what have you done:"
88 print "Press Enter to try again, or I guess ctrl-c to bail."
91 with open(infilename, 'wb') as outfile:
92 writer = csv.writer(outfile, lineterminator='\n')
93 writer.writerow([ column.encode('utf8') for column in column_names ])
95 for datum in new_data:
97 datum[column].encode('utf8') for column in column_names