From 1808070b3540e4da31689499b3d7ff94e2b21f97 Mon Sep 17 00:00:00 2001 From: gd Date: Mon, 8 Mar 2021 07:11:45 +0300 Subject: [PATCH] init --- .gitignore | 7 ++++ LICENSE | 24 +++++++++++ README.md | 23 ++++++++++ jwrap.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 24 +++++++++++ 5 files changed, 199 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 jwrap.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4cf7cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +__pycache__/ +*.egg-info/ +build/ +dist/ +*.pyc +*.swp +*~ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..00d2e13 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d396f76 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# jwrap + +**jwrap** — is a single-file micro-library that implements JSON wrapper. Its mission is to make interacting with JSON a little bit easier without writing extra code. + +More information is available in docstrings: + +``` +>>> import jwrap +>>> help(jwrap) +``` + +## Quickstart + +For example, you can write some data to json file by this: + +```python +from jwrap import Jwrap + +j = Jwrap('myfile.json') +j.json['mykey'] = 'my value' +# or: j.ins('mykey', 'my value') +j.commit() # write data to file +``` \ No newline at end of file diff --git a/jwrap.py b/jwrap.py new file mode 100644 index 0000000..6131811 --- /dev/null +++ b/jwrap.py @@ -0,0 +1,121 @@ +"""jwrap -- is a single-file micro-library that implements +JSON wrapper. Its mission is to make interacting with JSON +a little bit easier without writing extra code. + +License: Unlicense (See LICENSE for details). +""" + +__version__ = '0.3' + +import os +import json + + +def read_file(path_to_file: str): + """Return the file data from `path_to_file`.""" + with open(path_to_file, 'r') as json_file: + return json_file.read() + +def write_to_file(path_to_file: str, data): + """Write `data` to file from `path_to_file`.""" + with open(path_to_file, 'w') as json_file: + return json_file.write(data) + +def load_json_from_file(path_to_file: str): + """Load JSON data from file from `path_to_file` by `json.load()`. + Previously call `read_file()`. + """ + return json.loads(read_file(path_to_file)) + +def dump_json_to_file(path_to_file: str, data): + """Dump JSON data and write it to file from `path_to_file`. + `ensure_ascii` option is disabled, indentation is enabled. + """ + write_to_file( + path_to_file, + json.dumps(data, ensure_ascii=False, indent=4) + ) + +class Jwrap(object): + """The Jwrap object provides a JSON file connection and implements + a number of methods for manipulating data. + Some of them duplicate the standard functionality of Python dicts + and they can be easily replaced with equivalents. For example:: + + obj.ins('key', 'value') + # is equivalent to: + obj.json()['key'] = 'value' + """ + + def __init__(self, path_to_file): + """Check `path_to_file`, create directory if not exist + and create file if not exist. If file is empty write empty + dict into it. Load JSON from file. + + Varisbles: + `__file` -- contains path to json file (`path_to_file`). + `__json_data` -- contains loaded JSON data from `__file`. + """ + dirname = os.path.dirname(path_to_file) + if dirname == '' or dirname == '.': + self.__file = path_to_file + else: + try: + os.makedirs(dirname, exist_ok=True) + self.__file = path_to_file + except OSError: + return 'Error: Cannot create path: {}'.format(dirname) + if self.__file: + if not os.path.exists(self.__file) \ + or os.path.getsize(self.__file) == 0: + write_to_file(self.__file, '{}') + self.__json_data = load_json_from_file(self.__file) + + def get_file(self) -> str: + """Return abspath to `__file`.""" + return os.path.abspath(self.__file) + + def json(self) -> dict: + """Return `__json_data`.""" + return self.__json_data + + def reload(self): + """Reload JSON data from file.""" + self.__json_data = load_json_from_file(self.__file) + + def commit(self): + """Write JSON data to file.""" + dump_json_to_file(self.__file, self.__json_data) + + def keys(self) -> list: + """Return root level key list.""" + return list(self.__json_data.keys()) + + def subkeys(self, key: str) -> list: + """Return list of `key` subkeys.""" + return list(self.__json_data[key].keys()) + + def keys_by_value(self, value) -> list: + """Return list of keys by value `value`""" + return [key for key, val in self.__json_data.items() if val == value] + + def ins(self, key: str, value): + """Insert `key` with value `value`.""" + self.__json_data[key] = value + + def inssub(self, key: str, subkey: str, value): + """Similar to `ins`, but for subset.""" + self.__json_data[key][subkey] = value + + def rem(self, key: str): + """Remove value from JSON by `key`.""" + del self.__json_data[key] + + def remsub(self, key: str, subkey: str): + """Similar to `rem`, but for subset. + Remove value by `subkey` of `key`. + """ + del self.__json_data[key][subkey] + +if __name__ == '__main__': + pass diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..0ef0061 --- /dev/null +++ b/setup.py @@ -0,0 +1,24 @@ +import setuptools + + +with open("README.md", "r") as lg: + long_description = lg.read() + +setuptools.setup( + name="jwrap", + py_modules=['jwrap'], + version="0.3", + author="gd", + author_email="gechandev@gmail.com", + description="Wrapper for easy interacting with JSON files.", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://gitea.gch.icu/gd/jwrap/", + packages=setuptools.find_packages(), + classifiers=[ + "Programming Language :: Python :: 3.9", + "License :: OSI Approved :: The Unlicense (Unlicense)", + "Operating System :: OS Independent", + ], + python_requires='>=3.6', +)