Skip to content

Instantly share code, notes, and snippets.

@bwbg
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bwbg/037580e586eec6d43fc5 to your computer and use it in GitHub Desktop.
Save bwbg/037580e586eec6d43fc5 to your computer and use it in GitHub Desktop.
Get and put dictionaries (documents) from and to the filesystem.
#!/usr/bin/env python3
# -----------------------------------------------------------------------------
# Copyright (c) 2015, Heiko Möllerke
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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 OR COPYRIGHT HOLDERS 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.
# -----------------------------------------------------------------------------
"""
=================================================
document.py
Store and retrieve dictionaries to and from files
=================================================
"""
import collections
import functools
import glob
import json
import os
import uuid
def get(base, identifier): # -> dict
with open(_path(base, identifier), 'r', encoding='UTF-8') as fp:
xm = json.load(fp)
xm.update({_IDENTIFIER: identifier})
return xm
def put(base, xm):
if _IDENTIFIER not in xm: xm[_IDENTIFIER] = uuid.uuid4().hex
with open(_path(base, xm[_IDENTIFIER]), 'w', encoding='UTF-8') as fp:
# Ensure that no 'special' root-keys will be stored in the JSON-file:
nonmeta = dict((k, v) for \
k, v in xm.items() \
if not k.startswith(_META_PREFIX))
json.dump(nonmeta, fp, **_JSON_CONFIG)
def delete(base, xm):
os.remove(_path(base, xm[_IDENTIFIER]))
def select(base, trait=lambda xm: True):
filenames = glob.glob(os.path.join(base, '*{}'.format(_FILESUFFIX)))
identifiers = [os.path.splitext(os.path.basename(e))[0] for e in filenames]
return list(filter(trait, [get(base, e_) for e_ in identifiers]))
def functions(base):
return collections.namedtuple('Storage', 'get put delete select')(
*(functools.partial(f, base) for f in (get, put, delete, select))
)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Module specific (non API) constants and utility-functions
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_JSON_CONFIG = {'indent': 2, 'ensure_ascii': False, 'sort_keys': True}
_META_PREFIX = '__'
_IDENTIFIER = _META_PREFIX + 'id'
_FILESUFFIX = '.txt'
def _path(base, identifier):
"""Returns the path aggregated from base and the given identifier."""
return os.path.join(base, '{}{}'.format(identifier, _FILESUFFIX))
#!/usr/bin/env python3
import os
from pprint import pprint
import document
def main():
# Some preparations:
get, put, delete, select = document.functions(os.getcwd())
# Create some example data:
person = {'name': 'John', 'surname': 'Doe'}
other = {'name': 'Johanna', 'surname': 'Doelyn'}
rectangle = {'x': 10, 'y': 12, 'width': 42, 'height': 77}
mistake = {'oops': 'FOO'}
# Save them:
put(person)
put(other)
put(rectangle)
put(mistake)
print('\n ---> Show them all:')
pprint(select(), width=1)
print('\n ---> Show persons only:')
trait = lambda xm: 'name' in xm and 'surname' in xm
pprint(select(trait=trait), width=1)
print('\n ---> Give me only the ids from persons:')
ids = select(trait=trait, map_=lambda xm: xm['__id'])
pprint(ids, width=1)
print('\n ---> Now get the persons:')
persons = [get(e) for e in ids]
pprint(persons, width=1)
print('\n ---> Get rid of the mistake:')
delete(mistake)
print('\n ---> Show them all, again:')
pprint(select(), width=1)
print('\n ---> Get rid of them all')
for e in select():
delete(e)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment