diff --git a/casimport/__init__.py b/casimport/__init__.py index f0448b8..8759ccf 100644 --- a/casimport/__init__.py +++ b/casimport/__init__.py @@ -22,6 +22,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. +import configparser import contextlib import filecmp import functools @@ -75,11 +76,19 @@ def tempset(obj, key, value): ''' try: - oldvalue = obj[key] + dodelitem = False + if key in obj: + oldvalue = obj[key] + else: + dodelitem = True + obj[key] = value yield finally: - obj[key] = oldvalue + if not dodelitem: + obj[key] = oldvalue + else: + del obj[key] @contextlib.contextmanager def tempattrset(obj, key, value): @@ -119,6 +128,10 @@ def urlfetch(url): return req.read() class HTTPSCAS(object): + @classmethod + def fromconfig(cls, conf): + return cls() + def fetch_data(self, url): if url.scheme != 'https': raise ValueError('cannot handle scheme %s' % @@ -131,6 +144,10 @@ class IPFSCAS(object): gwhost = 'gateway.ipfs.io' gwhost = 'cloudflare-ipfs.com' + @classmethod + def fromconfig(cls, conf): + return cls() + def make_url(self, url): return urllib.parse.urlunparse(('https', self.gwhost, '/ipfs/' + url.netloc) + ('', ) * 3) @@ -152,6 +169,10 @@ class FileDirCAS(object): self._path.mkdir(exist_ok=True) self._hashes = {} + @classmethod + def fromconfig(cls, conf): + return cls(os.path.expanduser(conf['path'])) + def refresh_dir(self): '''Internal method to refresh the internal cache of hashes.''' @@ -353,17 +374,33 @@ class CASFinder(MetaPathFinder, Loader): exec(data, module.__dict__) +_supportedmodules = { + 'https': HTTPSCAS.fromconfig, + 'ipfs': IPFSCAS.fromconfig, + 'cache': FileDirCAS.fromconfig, +} + def defaultinit(casf): basedir = pathlib.Path.home() / '.casimport' basedir.mkdir(exist_ok=True) - conffile = basedir / 'casimport.conf' + conffile = pathlib.Path(os.environ.get('CASIMPORT_CONF', basedir / 'casimport.conf')) if not conffile.exists(): import casimport with importlib.resources.path(casimport, 'default.conf') as defconf: shutil.copy(defconf, conffile) + cp = configparser.ConfigParser() + cp.read(conffile) + + modorder = [ x.strip() for x in + cp['casimport']['module_prio'].split(',') ] + + for i in modorder: + modfun = _supportedmodules[cp[i]['type']] + casf.register(modfun(cp[i])) + cachedir = basedir / 'cache' cachedir.mkdir(parents=True, exist_ok=True) @@ -484,6 +521,21 @@ class Test(unittest.TestCase): # and when disconnected as second time, nothing happens f.disconnect() + def test_conforder(self): + conf = self.fixtures / 'ordertest.conf' + + # that w/ a custom config + with tempset(os.environ, 'CASIMPORT_CONF', str(conf)), \ + CASFinder() as f: + # that is gets loaded + defaultinit(f) + + # and that the first loader is the HTTPSCAS + self.assertIsInstance(f._loaders[0], HTTPSCAS) + + # and that the second loader is the IPFSCAS + self.assertIsInstance(f._loaders[1], IPFSCAS) + def test_defaultinit(self): temphome = self.tempdir / 'home' temphome.mkdir() diff --git a/casimport/default.conf b/casimport/default.conf index 4b25866..08c3f8b 100644 --- a/casimport/default.conf +++ b/casimport/default.conf @@ -11,7 +11,7 @@ module_prio = homecache, ipfsgw, https # Default cache is in the user's home directory. type = cache -dir = ~/.casimport/cache +path = ~/.casimport/cache #size = 10MB diff --git a/fixtures/ordertest.conf b/fixtures/ordertest.conf new file mode 100644 index 0000000..3b29e6b --- /dev/null +++ b/fixtures/ordertest.conf @@ -0,0 +1,9 @@ +[casimport] +module_prio = https, ipfsgw + +[ipfsgw] +type = ipfs +gateway = https://gateway.ipfs.io/ipfs/ + +[https] +type = https