Source code for pypath.internals.license

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
#  This file is part of the `pypath` python module
#
#  Copyright 2014-2023
#  EMBL, EMBL-EBI, Uniklinik RWTH Aachen, Heidelberg University
#
#  Authors: see the file `README.rst`
#  Contact: Dénes Türei (turei.denes@gmail.com)
#
#  Distributed under the GPLv3 License.
#  See accompanying file LICENSE.txt or copy at
#      https://www.gnu.org/licenses/gpl-3.0.html
#
#  Website: https://pypath.omnipathdb.org/
#

from future.utils import iteritems

import os
import json
import warnings

import pypath.share.common as common


# these are all ordinal scales from the smallest to the greatest freedom
_purpose_levels = {
    'composite': 25,
    'free': 20,
    'commercial': 15,
    'for_profit': 15,
    'forprofit': 15,
    'nonprofit': 10,
    'non_profit': 10,
    'academic': 5,
    'ignore': 0,
}

_sharing_levels = {
    'composite': 20,
    'free': 25,
    'share': 20,
    'deriv': 20,
    'alike': 15,
    'noderiv': 10,
    'noshare': 5,
    'ignore': 0,
}

_attrib_levels = {
    'composite': 20,
    'free': 10,
    'noattrib': 10,
    'attrib': 5,
    'ignore': 0,
}

_int_purpose_levels = common.swap_dict(_purpose_levels)
_int_sharing_levels = common.swap_dict(_sharing_levels)
_int_attrib_levels = common.swap_dict(_attrib_levels)


[docs] class LicenseFeature(object): levels = {} name = 'feature' int_levels = common.swap_dict(levels)
[docs] def __init__(self, level): self.level = level _ = self.check_level(level)
[docs] @classmethod def level_to_int(cls, level): """ Return the value for the key ``level`` as an integer on the ordinal scale of the levels. """ if cls.check_level(level): return cls.levels[level] return 99
[docs] @classmethod def int_to_level(cls, i): """ Returns a set of labels corresponding to the level nearest to the integer ``i`` on the ordinal scale of levels. """ if i > max(cls.int_levels.keyd()): i = max(cls.int_levels.keys()) elif i not in cls.int_levels: for _i in sorted(cls.int_levels.keys()): if _i > i: i = _i break return cls.int_levels[i]
def __str__(self): return self.level def __repr__(self): return '<License %s: %s>' % (self.name, self.level)
[docs] @classmethod def check_level(cls, level): """ Checks of ``level`` is a valid key for the """ if level not in cls.levels: cls.unknown_warning(level) return False return True
[docs] def to_int(self): """ Returns the value of the current level of this license feature as an integer on the ordinal scale of levels. """ return self.level_to_int(self.level)
def __int__(self): return self.to_int() @classmethod def ensure_int(cls, other): if isinstance(other, int): return other elif isinstance(other, str): return cls.level_to_int(other) else: try: return int(other) except (TypeError, ValueError): cls.unknown_warning(other) return 99 def __eq__(self, other): i_level = self.ensure_int(other) return int(self) == i_level def __gt__(self, other): i_level = self.ensure_int(other) return int(self) > i_level def __ge__(self, other): i_level = self.ensure_int(other) return int(self) >= i_level def __lt__(self, other): i_level = self.ensure_int(other) return int(self) < i_level def __le__(self, other): i_level = self.ensure_int(other) return int(self) <= i_level def enables(self, other): return self >= other @classmethod def unknown_warning(cls, value): warnings.warn( 'Unknown `%s` level for licenses: `%s`. ' 'This will always disable the resource.' % ( cls.name, str(value), ) )
[docs] class LicensePurpose(LicenseFeature): levels = _purpose_levels name = 'purpose' int_levels = _int_purpose_levels
[docs] def __init__(self, level): LicenseFeature.__init__(self, level)
[docs] class LicenseSharing(LicenseFeature): levels = _sharing_levels name = 'sharing' int_levels = _int_sharing_levels
[docs] def __init__(self, level): LicenseFeature.__init__(self, level)
[docs] class LicenseAttrib(LicenseFeature): levels = _attrib_levels name = 'attrib' int_levels = _int_attrib_levels
[docs] def __init__(self, level): LicenseFeature.__init__(self, level)
[docs] class License(object):
[docs] def __init__( self, name, full_name = None, purpose = None, sharing = None, attrib = 'attrib', url = None, **kwargs ): self.name = name self.full_name = full_name or name self.purpose = LicensePurpose(purpose) self.sharing = LicenseSharing(sharing) self.attrib = LicenseAttrib(attrib) self.url = url for k, v in iteritems(kwargs): setattr(self, k, v)
def __repr__(self): return '<License %s>' % self.name def __str__(self): return self.name
[docs] def enables(self, purpose, sharing = None, attrib = None): """ Checks if the license enables a particular use, according to purpose, sharing and attribution. For example, to check if the license enables academic use with redistribution under a compatible license, call ``License.enables(purpose = 'academic', sharing = 'alike')``. """ return ( ( not attrib or self.attrib.enables(attrib) ) and ( not sharing or self.sharing.enables(sharing) ) and ( self.purpose.enables(purpose) ) )
@property def features(self): return dict( ( aspect, getattr(self, aspect).level ) for aspect in ('purpose', 'sharing', 'attrib') ) @property def features_str(self): return common.dict_str(self.features) @classmethod def from_json(cls, path, **kwargs): with open(path, 'r') as fp: json_data = json.load(fp) json_data.update(kwargs) return cls(**json_data) # some shortcut methods @classmethod def _generate_enables_methods(cls): def get_enables_method(aspect, level): @property def enables_method(self): return getattr(self, aspect).enables(level) return enables_method for aspect in ('attrib', 'sharing', 'purpose'): for level in globals()['_%s_levels' % aspect]: if level in ('composite', 'ignore', 'free', 'attrib'): continue method = get_enables_method(aspect, level) method_name = level setattr(cls, level, method)
License._generate_enables_methods()