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