108 lines
3.8 KiB
Plaintext
108 lines
3.8 KiB
Plaintext
|
#!/Users/ashutoshnayak/Learning and Work/linkedIn_auto_jobs_applier_with_AI/JobApply/bin/python3
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import sys
|
||
|
import os.path
|
||
|
import json
|
||
|
import jsonpatch
|
||
|
import tempfile
|
||
|
import argparse
|
||
|
|
||
|
|
||
|
parser = argparse.ArgumentParser(
|
||
|
description='Apply a JSON patch on a JSON file')
|
||
|
parser.add_argument('ORIGINAL', type=argparse.FileType('r'),
|
||
|
help='Original file')
|
||
|
parser.add_argument('PATCH', type=argparse.FileType('r'),
|
||
|
nargs='?', default=sys.stdin,
|
||
|
help='Patch file (read from stdin if omitted)')
|
||
|
parser.add_argument('--indent', type=int, default=None,
|
||
|
help='Indent output by n spaces')
|
||
|
parser.add_argument('-b', '--backup', action='store_true',
|
||
|
help='Back up ORIGINAL if modifying in-place')
|
||
|
parser.add_argument('-i', '--in-place', action='store_true',
|
||
|
help='Modify ORIGINAL in-place instead of to stdout')
|
||
|
parser.add_argument('-v', '--version', action='version',
|
||
|
version='%(prog)s ' + jsonpatch.__version__)
|
||
|
parser.add_argument('-u', '--preserve-unicode', action='store_true',
|
||
|
help='Output Unicode character as-is without using Code Point')
|
||
|
|
||
|
def main():
|
||
|
try:
|
||
|
patch_files()
|
||
|
except KeyboardInterrupt:
|
||
|
sys.exit(1)
|
||
|
|
||
|
|
||
|
def patch_files():
|
||
|
""" Diffs two JSON files and prints a patch """
|
||
|
args = parser.parse_args()
|
||
|
doc = json.load(args.ORIGINAL)
|
||
|
patch = json.load(args.PATCH)
|
||
|
result = jsonpatch.apply_patch(doc, patch)
|
||
|
|
||
|
if args.in_place:
|
||
|
dirname = os.path.abspath(os.path.dirname(args.ORIGINAL.name))
|
||
|
|
||
|
try:
|
||
|
# Attempt to replace the file atomically. We do this by
|
||
|
# creating a temporary file in the same directory as the
|
||
|
# original file so we can atomically move the new file over
|
||
|
# the original later. (This is done in the same directory
|
||
|
# because atomic renames do not work across mount points.)
|
||
|
|
||
|
fd, pathname = tempfile.mkstemp(dir=dirname)
|
||
|
fp = os.fdopen(fd, 'w')
|
||
|
atomic = True
|
||
|
|
||
|
except OSError:
|
||
|
# We failed to create the temporary file for an atomic
|
||
|
# replace, so fall back to non-atomic mode by backing up
|
||
|
# the original (if desired) and writing a new file.
|
||
|
|
||
|
if args.backup:
|
||
|
os.rename(args.ORIGINAL.name, args.ORIGINAL.name + '.orig')
|
||
|
fp = open(args.ORIGINAL.name, 'w')
|
||
|
atomic = False
|
||
|
|
||
|
else:
|
||
|
# Since we're not replacing the original file in-place, write
|
||
|
# the modified JSON to stdout instead.
|
||
|
|
||
|
fp = sys.stdout
|
||
|
|
||
|
# By this point we have some sort of file object we can write the
|
||
|
# modified JSON to.
|
||
|
|
||
|
json.dump(result, fp, indent=args.indent, ensure_ascii=not(args.preserve_unicode))
|
||
|
fp.write('\n')
|
||
|
|
||
|
if args.in_place:
|
||
|
# Close the new file. If we aren't replacing atomically, this
|
||
|
# is our last step, since everything else is already in place.
|
||
|
|
||
|
fp.close()
|
||
|
|
||
|
if atomic:
|
||
|
try:
|
||
|
# Complete the atomic replace by linking the original
|
||
|
# to a backup (if desired), fixing up the permissions
|
||
|
# on the temporary file, and moving it into place.
|
||
|
|
||
|
if args.backup:
|
||
|
os.link(args.ORIGINAL.name, args.ORIGINAL.name + '.orig')
|
||
|
os.chmod(pathname, os.stat(args.ORIGINAL.name).st_mode)
|
||
|
os.rename(pathname, args.ORIGINAL.name)
|
||
|
|
||
|
except OSError:
|
||
|
# In the event we could not actually do the atomic
|
||
|
# replace, unlink the original to move it out of the
|
||
|
# way and finally move the temporary file into place.
|
||
|
|
||
|
os.unlink(args.ORIGINAL.name)
|
||
|
os.rename(pathname, args.ORIGINAL.name)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|