1
|
1 import vdb_common
|
|
2 import vdb_retrieval # For message text
|
|
3
|
|
4 class VDBDataStore(object):
|
|
5
|
|
6 """
|
|
7 Provides data store engine super-class with methods to list available versions, and to generate a version (potentially providing a link to cached version). Currently have options for git, folder, and kipper.
|
|
8
|
|
9 get_data_store_gateway() method loads the appropriate data_stores/vdb_.... data store variant.
|
|
10
|
|
11 """
|
|
12
|
|
13 def __init__(self, retrieval_obj, spec_file_id):
|
|
14 """
|
|
15 Note that api is only needed for data store type = folder.
|
|
16
|
|
17 @init self.type
|
|
18 @init self.base_file_name
|
|
19 @init self.library_label_path
|
|
20 @init self.data_store_path
|
|
21 @init self.global_retrieval_date
|
|
22
|
|
23 @sets self.library_version_path
|
|
24 @sets self.version_label
|
|
25 @sets self.version_path
|
|
26 """
|
|
27
|
|
28 self.admin_api = retrieval_obj.admin_api
|
|
29 self.library_id = retrieval_obj.library_id
|
|
30 self.library_label_path = retrieval_obj.get_library_label_path(spec_file_id)
|
|
31 try:
|
|
32 # Issue: Error probably gets trapped but is never reported back to Galaxy from thread via <code file="versioned_data_form.py" /> form's call?
|
|
33 # It appears galaxy user needs more than just "r" permission on this file, oddly?
|
|
34 spec = self.admin_api.libraries.show_folder(self.library_id, spec_file_id)
|
|
35
|
|
36 except IOError as e:
|
|
37 print 'Tried to fetch library folder spec file: %s. Check permissions?"' % spec_file_id
|
|
38 print "I/O error({0}): {1}".format(e.errno, e.strerror)
|
|
39 sys.exit(1)
|
|
40
|
|
41 self.type = retrieval_obj.test_data_store_type(spec['name'])
|
|
42
|
|
43 #Server absolute path to data_store spec file (can be Galaxy .dat file representing Galaxy library too.
|
|
44
|
|
45 self.base_file_name = spec['file_name']
|
|
46
|
|
47 # In all cases a pointer file's content (data_store_path)
|
|
48 # should point to a real server folder (that galaxy has permission to read).
|
|
49 # Exception to this is for pointer.folder, where content can be empty,
|
|
50 # in which case idea is to use library folder contents directly.
|
|
51
|
|
52 with open(self.base_file_name,'r') as path_spec:
|
|
53 self.data_store_path = path_spec.read().strip()
|
|
54 if len(self.data_store_path) > 0:
|
|
55 # Let people forget to put a trailing slash on the folder path.
|
|
56 if not self.data_store_path[-1] == '/':
|
|
57 self.data_store_path += '/'
|
|
58
|
|
59 # Generated on subsequent subclass call
|
|
60 self.library_version_path = None
|
|
61 self.version_label = None
|
|
62 self.version_path = None
|
|
63
|
|
64
|
|
65 def get_version_options(self, global_retrieval_date=0, version_name=None, selection=False):
|
|
66 """
|
|
67 Provides list of available versions of a given archive. List is filtered by
|
|
68 optional global_retrieval_date or version id. For date filter, the version immediately
|
|
69 preceeding given datetime (includes same datetime) is returned.
|
|
70 All comparisons are done by version NAME not id, because underlying db id might change.
|
|
71
|
|
72 If global_retrieval_date datetime preceeds first version, no filtering is done.
|
|
73
|
|
74 @param global_retrieval_date long unix time date to test entry against.
|
|
75 @param version_name string Name of version
|
|
76 @param version_id string Looks like a number, or '' to pull latest id.
|
|
77 """
|
|
78
|
|
79 data = []
|
|
80
|
|
81 date_match = vdb_common.date_matcher(global_retrieval_date)
|
|
82 found=False
|
|
83
|
|
84 for ptr, item in enumerate(self.versions):
|
|
85 created = float(item['created'])
|
|
86 item_name = item['name']
|
|
87
|
|
88 # Note version_id is often "None", so must come last in conjunction.
|
|
89 selected = (found == False) \
|
|
90 and ((item_name == version_name ) or date_match.next(created))
|
|
91
|
|
92 if selected == True:
|
|
93 found = True
|
|
94 if selection==True:
|
|
95 return item_name
|
|
96
|
|
97 # Folder type data stores should already have something resembling created date in name.
|
|
98 if type(self).__name__ in 'VDBFolderDataStore VDBBiomajDataStore':
|
|
99 item_label = item['name']
|
|
100 else:
|
|
101 item_label = vdb_common.lightDate(created) + '_' + item['name']
|
|
102
|
|
103 data.append([item_label, item['name'], selected])
|
|
104
|
|
105 if not found and len(self.versions) > 0:
|
|
106 if global_retrieval_date: # Select oldest date version since no match above.
|
|
107 item_name = data[-1][1]
|
|
108 data[-1][2] = True
|
|
109 else:
|
|
110 item_name = data[0][1]
|
|
111 data[0][2] = True
|
|
112 if selection == True:
|
|
113 return item_name
|
|
114
|
|
115
|
|
116 # For cosmetic display: Natural sort takes care of version keys that have mixed characters/numbers
|
|
117 data = sorted(data, key=lambda el: vdb_common.natural_sort_key(el[0]), reverse=True) #descending
|
|
118
|
|
119 #Always tag the first item as the most current one
|
|
120 if len(data) > 0:
|
|
121 data[0][0] = data[0][0] + ' (current)'
|
|
122 else:
|
|
123 data.append([vdb_retrieval.VDB_DATASET_NOT_AVAILABLE + ' Is pointer file content right? : ' + self.data_store_path,'',False])
|
|
124
|
|
125 """
|
|
126 globalFound = False
|
|
127 for i in range(len(data)):
|
|
128 if data[i][2] == True:
|
|
129 globalFound = True
|
|
130 break
|
|
131
|
|
132 if globalFound == False:
|
|
133 data[0][2] = True # And select it if no other date has been selcted
|
|
134
|
|
135 """
|
|
136
|
|
137 return data
|
|
138
|
|
139
|
|
140 def get_version(self, version_name):
|
|
141 # All subclasses must define this.
|
|
142 pass
|