e71c7ca681f3e908276ca6e6fca074af93c30469
[sfa.git] / sfa / rspecs / version_manager.py
1 from __future__ import print_function
2
3 import os
4 from sfa.util.faults import InvalidRSpec, UnsupportedRSpecVersion
5 from sfa.rspecs.version import RSpecVersion
6 from sfa.util.sfalogging import logger
7 from sfa.util.py23 import StringType
8
9
10 class VersionManager:
11
12     def __init__(self):
13         self.versions = []
14         self.load_versions()
15
16     def __repr__(self):
17         return "<VersionManager with {} flavours: [{}]>"\
18             .format(len(self.versions),
19                     ", ".join([str(x) for x in self.versions]))
20
21     def load_versions(self):
22         path = os.path.dirname(os.path.abspath(__file__))
23         versions_path = path + os.sep + 'versions'
24         versions_module_path = 'sfa.rspecs.versions'
25         valid_module = lambda x: os.path.isfile(os.sep.join([versions_path, x])) \
26             and x.endswith('.py') and x != '__init__.py'
27         files = [f for f in os.listdir(versions_path) if valid_module(f)]
28         for filename in files:
29             basename = filename.split('.')[0]
30             module_path = versions_module_path + '.' + basename
31             module = __import__(module_path, fromlist=module_path)
32             for attr_name in dir(module):
33                 attr = getattr(module, attr_name)
34                 if hasattr(attr, 'version') and hasattr(attr, 'enabled') and attr.enabled == True:
35                     self.versions.append(attr())
36
37     def _get_version(self, type, version_num=None, content_type=None):
38         retval = None
39         for version in self.versions:
40             if type is None or type.lower() == version.type.lower():
41                 if version_num is None or str(float(version_num)) == str(float(version.version)):
42                     if content_type is None or content_type.lower() == version.content_type.lower() \
43                             or version.content_type == '*':
44                         retval = version
45                         # sounds like we should be glad with the first match,
46                         # not the last one
47                         break
48         if not retval:
49             raise UnsupportedRSpecVersion(
50                 "[%s %s %s] is not suported here" % (type, version_num, content_type))
51         return retval
52
53     def get_version(self, version=None):
54         retval = None
55         if isinstance(version, dict):
56             retval = self._get_version(version.get('type'), version.get(
57                 'version'), version.get('content_type'))
58         elif isinstance(version, StringType):
59             version_parts = version.split(' ')
60             num_parts = len(version_parts)
61             type = version_parts[0]
62             version_num = None
63             content_type = None
64             if num_parts > 1:
65                 version_num = version_parts[1]
66             if num_parts > 2:
67                 content_type = version_parts[2]
68             retval = self._get_version(type, version_num, content_type)
69         elif isinstance(version, RSpecVersion):
70             retval = version
71         elif not version:
72             retval = self.versions[0]
73         else:
74             raise UnsupportedRSpecVersion(
75                 "No such version: %s " % str(version))
76
77         return retval
78
79     def get_version_by_schema(self, schema):
80         retval = None
81         for version in self.versions:
82             if schema == version.schema:
83                 retval = version
84         if not retval:
85             raise InvalidRSpec("Unkwnown RSpec schema: %s" % schema)
86         return retval
87
88     def show_by_string(self, string):
89         try:
90             print(self.get_version(string))
91         except Exception as e:
92             print(e)
93
94     def show_by_schema(self, string):
95         try:
96             print(self.get_version_by_schema(string))
97         except Exception as e:
98             print(e)
99
100 if __name__ == '__main__':
101     manager = VersionManager()
102     print(manager)
103     manager.show_by_string('sfa 1')
104     manager.show_by_string('protogeni 2')
105     manager.show_by_string('protogeni 2 advertisement')
106     manager.show_by_schema('http://www.protogeni.net/resources/rspec/2/ad.xsd')
107     manager.show_by_schema('http://sorch.netmode.ntua.gr/ws/RSpec/ad.xsd')