Commits

Arne Babenhauserheide  committed 720c239

new option: path_from_key.

  • Participants
  • Parent commits 475ed44

Comments (0)

Files changed (2)

 >>> from fdb import get_data_for_key, edit_data_for_key
 >>> get_data_for_key(key,
                      sites_dir="sites",
-                     states_dir="states")
+                     states_dir="states", 
+		     latest_revision=False)
 
 >>> edit_data_for_key(key, site=None, state=None, action="put", 
                      sites_dir="sites",
-                     states_dir="states"):
+                     states_dir="states", 
+		     latest_revision=False, 
+		     path_from_key=True)
 
 Key is USK@.../bla/foo or SSK@.../bla/foo or KSK@...
 
-site and state are dictionaries. They MUST contain a 'path' key: 
+They can contain a 'path' key. If you set path_from_key=False, that path will be used in the entry. Else the the path will be computed from the key: 
 
-* for a KSK@... key just the full key (KSK@...)
-* for a USK or SSK key only the part after the main key. USK@.../bla/foo becomes /bla/foo. You can use fbd_io.key_to_subkey(key) to turn a key into the path component.
+* for a KSK@... the path is just the full key (KSK@...)
+* for a USK or SSK the path is only the part after the main key. USK@.../bla/foo becomes /bla/foo. You can use fbd_io.key_to_subkey(key) to turn a key into the path component. fbd_io.key_to_subkey(key, latest_revision=True) turns it into a key to the latest revision
 
 Copyright: 
 
 
 
 def _put_data_for_key(key, subkey, site=None, state=None, 
-                     sites_dir="sites",
-                     states_dir="states"):
+                      sites_dir="sites",
+                      states_dir="states",
+                      path_from_key=True):
     """Put a site or state or both into the site. This HAS TO be called in the CRITICAL SECTION of edit_data_for_key() to make it multiprocess-safe."""
     sites_new = []
     states_new = []
     if site is not None:
         added = False
         for s in sites:
-            if not added and s.get("path", None) == subkey:
+            if not added and (path_from_key and s.get("path", None) == subkey
+                              or not path_from_key and 'path' in site and s.get("path", None) == site['path']):
                 # update the site
                 sites_new.append(site)
                 added = True
     if state is not None:
         for s in states:
             added = False
-            if not added and s.get("path", None) == subkey:
+            if not added and (path_from_key and s.get("path", None) == subkey
+                              or not path_from_key and 'path' in state and s.get("path", None) == state['path']):
                 # update the site
                 states_new.append(site)
                 added = True
     
 
 def _remove_data_for_key(key, subkey, site=None, state=None, 
-                     sites_dir="sites",
-                     states_dir="states"):
-    """Remove a site or state or both from the site. This HAS TO be called in the CRITICAL SECTION of edit_data_for_key() to make it multiprocess-safe."""
+                         sites_dir="sites",
+                         states_dir="states",
+                         path_from_key=True):
+    """Remove a site or state or both from the site. This HAS TO be called in the CRITICAL SECTION of edit_data_for_key() to make it multiprocess-safe.
+
+    Set site or state to anything but None to remove the data."""
     sites_new = []
     states_new = []
     sites, states = io.get_dataset_for_key(key, sites_dir, states_dir)
     if site is not None:
         for s in sites:
-            if not s.get("path", None) == subkey:
+            if path_from_key and not s.get("path", None) == subkey or not path_from_key and 'path' in site and not s.get("path", None) == site['path']:
                 sites_new.append(s)
         sites = sites_new
         
     if state is not None:
         for s in states:
-            if not s.get("path", None) == subkey:
+            if path_from_key and not s.get("path", None) == subkey or not path_from_key and 'path' in state and not s.get("path", None) == state['path']:
                 states_new.append(s)
         states = states_new
 
 def edit_data_for_key(key, site=None, state=None, action="put", 
                       sites_dir="sites",
                       states_dir="states",
-                      latest_revision=False):
+                      latest_revision=False,
+                      path_from_key=True):
     """Put a site or state or both into the site.
 
+    @param path_from_key: Should the path be computed from the key or taken from the site/state dictionary?
+
     TODO: Refactor: the site doesn’t need to contain the path. The path should come from the key alone.
     
     >>> io._test_clean_dirs()
     Warning: the path in the site and the key don’t match. Adjusting the path.
     >>> get_data_for_key(usk + inf_subkey, sites_dir="test_sites", states_dir="test_states")
     ({'path': '/Infinite_Hands/-1/', 'description': 'singing a part of the history of free software.', 'randomint': 5}, {})
+    
     >>> sites, states = io.get_dataset_for_key(usk, sites_dir="test_sites", states_dir="test_states")
-
     >>> list(sites)
     [{'path': '/Infinite_Hands/2/', 'description': 'singing a part of the history of free software.', 'randomint': 5}, {'path': '/Infinite_Hands/-1/', 'description': 'singing a part of the history of free software.', 'randomint': 5}]
     >>> edit_data_for_key("USK@N7dmVKbxm5Q9YIzg74T1gUJd96eyAa2VLoMlPp0CQQs,AfZRxhqkvql5E~hDcW1s0mtHTAKrkhWpfcRm2kqkUjE,AQACAAE" + inf_subkey, site=infinite_hands, action="remove", sites_dir="test_sites", states_dir="test_states")
     Warning: the path in the site and the key don’t match. Adjusting the path.
     >>> get_data_for_key("USK@N7dmVKbxm5Q9YIzg74T1gUJd96eyAa2VLoMlPp0CQQs,AfZRxhqkvql5E~hDcW1s0mtHTAKrkhWpfcRm2kqkUjE,AQACAAE" + inf_subkey, sites_dir="test_sites", states_dir="test_states")
     ({}, {})
-    
+    >>> edit_data_for_key("USK@N7dmVKbxm5Q9YIzg74T1gUJd96eyAa2VLoMlPp0CQQs,AfZRxhqkvql5E~hDcW1s0mtHTAKrkhWpfcRm2kqkUjE,AQACAAE" + infinite_hands['path'], site={'description': 'singing a part of the history of free software.'}, sites_dir="test_sites", states_dir="test_states", latest_revision=True)
+    Warning: the path in the site and the key don’t match. Adjusting the path.
+    >>> get_data_for_key("USK@N7dmVKbxm5Q9YIzg74T1gUJd96eyAa2VLoMlPp0CQQs,AfZRxhqkvql5E~hDcW1s0mtHTAKrkhWpfcRm2kqkUjE,AQACAAE" + inf_subkey, sites_dir="test_sites", states_dir="test_states")
+    ({'path': '/Infinite_Hands/-1/', 'description': 'singing a part of the history of free software.'}, {})
+    >>> edit_data_for_key("USK@N7dmVKbxm5Q9YIzg74T1gUJd96eyAa2VLoMlPp0CQQs,AfZRxhqkvql5E~hDcW1s0mtHTAKrkhWpfcRm2kqkUjE,AQACAAE" + infinite_hands['path'], site={'description': 'singing a part of the history of free software.'}, sites_dir="test_sites", states_dir="test_states", latest_revision=True, path_from_key=False)
+    >>> sites, states = io.get_dataset_for_key(usk, sites_dir="test_sites", states_dir="test_states")
+    >>> list(sites)
+    [{'path': '/Infinite_Hands/2/', 'description': 'singing a part of the history of free software.', 'randomint': 5}, {'path': '/Infinite_Hands/-1/', 'description': 'singing a part of the history of free software.'}, {'description': 'singing a part of the history of free software.'}]
+
+
     """
     # make sure the data folders exist.
     if not isdir(sites_dir):
 
     # prepare local stuff for the critical section.
     subkey = io.key_to_subkey(key, latest_revision=latest_revision)
-    if site is not None and 'path' in site and site['path'] != subkey:
+    if site is not None and path_from_key and (('path' in site and site['path'] != subkey) or not 'path' in site):
         print("Warning: the path in the site and the key don’t match. Adjusting the path.")
         # TODO: use deepcopy
         site = deepcopy(site)
         site['path'] = subkey
-    if state is not None and 'path' in state and state['path'] != subkey:
+    if state is not None and path_from_key and (('path' in state and state['path'] != subkey) or not 'path' in site):
         print("Warning: the path in the state and the key don’t match. Adjusting the path.")
         site = deepcopy(site)
         state['path'] = subkey
     # nothing in this section may break the script, else the lock stays put.
     try:
         if action == "put": 
-            _put_data_for_key(key, subkey, site, state, sites_dir=sites_dir, states_dir=states_dir)
+            _put_data_for_key(key, subkey, site, state, sites_dir=sites_dir, states_dir=states_dir, path_from_key=path_from_key)
         elif action == "remove":
-            _remove_data_for_key(key, subkey, site, state, sites_dir=sites_dir, states_dir=states_dir)
+            _remove_data_for_key(key, subkey, site, state, sites_dir=sites_dir, states_dir=states_dir, path_from_key=path_from_key)
         else: print("Unknown action")
     except IOError:
         print("Couldn’t store the updated data. Dataset discarded.")
-    except:
-        print("Unknown Error. Dataset discarded.")
+    #except:
+    #    print("Unknown Error. Dataset discarded.")
     #### /critical section ####
     rmdir(lockdir)