Mercurial > libervia-web
comparison libervia/server/tasks.py @ 1216:b2d067339de3
python 3 port:
/!\ Python 3.6+ is now needed to use libervia
/!\ instability may occur and features may not be working anymore, this will improve with time
/!\ TxJSONRPC dependency has been removed
The same procedure as in backend has been applied (check backend commit ab2696e34d29 logs
for details). Removed now deprecated code (Pyjamas compiled browser part, legacy blog,
JSON RPC related code).
Adapted code to work without `html` and `themes` dirs.
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 13 Aug 2019 19:12:31 +0200 |
parents | 170802865156 |
children | 987595a254b0 |
comparison
equal
deleted
inserted
replaced
1215:f14ab8a25e8b | 1216:b2d067339de3 |
---|---|
30 log = getLogger(__name__) | 30 log = getLogger(__name__) |
31 | 31 |
32 | 32 |
33 class TasksManager(object): | 33 class TasksManager(object): |
34 """Handle tasks of a Libervia site""" | 34 """Handle tasks of a Libervia site""" |
35 FILE_EXTS = {u'py'} | 35 FILE_EXTS = {'py'} |
36 | 36 |
37 def __init__(self, host, site_resource): | 37 def __init__(self, host, site_resource): |
38 """ | 38 """ |
39 @param site_resource(LiberviaRootResource): root resource of the site to manage | 39 @param site_resource(LiberviaRootResource): root resource of the site to manage |
40 """ | 40 """ |
65 def site_name(self): | 65 def site_name(self): |
66 return self.resource.site_name | 66 return self.resource.site_name |
67 | 67 |
68 @property | 68 @property |
69 def task_data(self): | 69 def task_data(self): |
70 return self.tasks[self._current_task][u'data'] | 70 return self.tasks[self._current_task]['data'] |
71 | 71 |
72 def validateData(self, data): | 72 def validateData(self, data): |
73 """Check values in data""" | 73 """Check values in data""" |
74 | 74 |
75 for var, default, allowed in ((u"ON_ERROR", u"stop", (u"continue", u"stop")), | 75 for var, default, allowed in (("ON_ERROR", "stop", ("continue", "stop")), |
76 (u"LOG_OUTPUT", True, bool), | 76 ("LOG_OUTPUT", True, bool), |
77 (u"WATCH_DIRS", [], list)): | 77 ("WATCH_DIRS", [], list)): |
78 value = data.setdefault(var, default) | 78 value = data.setdefault(var, default) |
79 if isinstance(allowed, type): | 79 if isinstance(allowed, type): |
80 if not isinstance(value, allowed): | 80 if not isinstance(value, allowed): |
81 raise ValueError( | 81 raise ValueError( |
82 _(u"Unexpected value for {var}, {allowed} is expected.") | 82 _("Unexpected value for {var}, {allowed} is expected.") |
83 .format(var = var, allowed = allowed)) | 83 .format(var = var, allowed = allowed)) |
84 else: | 84 else: |
85 if not value in allowed: | 85 if not value in allowed: |
86 raise ValueError(_(u"Unexpected value for {var}: {value}").format( | 86 raise ValueError(_("Unexpected value for {var}: {value}").format( |
87 var = var, value = value)) | 87 var = var, value = value)) |
88 | 88 |
89 for var, default, allowed in [[u"ON_ERROR", u"stop", (u"continue", u"stop")]]: | 89 for var, default, allowed in [["ON_ERROR", "stop", ("continue", "stop")]]: |
90 value = data.setdefault(var, default) | 90 value = data.setdefault(var, default) |
91 if not value in allowed: | 91 if not value in allowed: |
92 raise ValueError(_(u"Unexpected value for {var}: {value}").format( | 92 raise ValueError(_("Unexpected value for {var}: {value}").format( |
93 var = var, value = value)) | 93 var = var, value = value)) |
94 | 94 |
95 def parseTasks(self): | 95 def parseTasks(self): |
96 if not os.path.isdir(self.tasks_dir): | 96 if not os.path.isdir(self.tasks_dir): |
97 log.debug(_(u"{name} has no task to launch.").format( | 97 log.debug(_("{name} has no task to launch.").format( |
98 name = self.resource.site_name or u"default site")) | 98 name = self.resource.site_name or "default site")) |
99 return | 99 return |
100 filenames = os.listdir(self.tasks_dir) | 100 filenames = os.listdir(self.tasks_dir) |
101 filenames.sort() | 101 filenames.sort() |
102 for filename in filenames: | 102 for filename in filenames: |
103 filepath = os.path.join(self.tasks_dir, filename) | 103 filepath = os.path.join(self.tasks_dir, filename) |
104 if not filename.startswith(u'task_') or not os.path.isfile(filepath): | 104 if not filename.startswith('task_') or not os.path.isfile(filepath): |
105 continue | 105 continue |
106 task_name, ext = os.path.splitext(filename) | 106 task_name, ext = os.path.splitext(filename) |
107 task_name = task_name[5:].lower().strip() | 107 task_name = task_name[5:].lower().strip() |
108 if not task_name: | 108 if not task_name: |
109 continue | 109 continue |
110 if ext[1:] not in self.FILE_EXTS: | 110 if ext[1:] not in self.FILE_EXTS: |
111 continue | 111 continue |
112 if task_name in self.tasks: | 112 if task_name in self.tasks: |
113 raise exceptions.ConflictError( | 113 raise exceptions.ConflictError( |
114 u"A task with the name [{name}] already exists".format( | 114 "A task with the name [{name}] already exists".format( |
115 name=task_name)) | 115 name=task_name)) |
116 task_data = {u"__name__": "{site_name}.task.{name}".format( | 116 task_data = {"__name__": "{site_name}.task.{name}".format( |
117 site_name=self.site_name, name=task_name)} | 117 site_name=self.site_name, name=task_name)} |
118 self.tasks[task_name] = { | 118 self.tasks[task_name] = { |
119 u'path': filepath, | 119 'path': filepath, |
120 u'data': task_data, | 120 'data': task_data, |
121 } | 121 } |
122 execfile(filepath, task_data) | 122 exec(compile(open(filepath, "rb").read(), filepath, 'exec'), task_data) |
123 # we launch prepare, which is a method used to prepare | 123 # we launch prepare, which is a method used to prepare |
124 # data at runtime (e.g. set WATCH_DIRS using config) | 124 # data at runtime (e.g. set WATCH_DIRS using config) |
125 try: | 125 try: |
126 prepare = task_data['prepare'] | 126 prepare = task_data['prepare'] |
127 except KeyError: | 127 except KeyError: |
148 | 148 |
149 @param task_name(unicode): name of the task to run | 149 @param task_name(unicode): name of the task to run |
150 """ | 150 """ |
151 task_value = self.tasks[task_name] | 151 task_value = self.tasks[task_name] |
152 self._current_task = task_name | 152 self._current_task = task_name |
153 log.info(_(u'== running task "{task_name}" for {site_name} =='.format( | 153 log.info(_('== running task "{task_name}" for {site_name} =='.format( |
154 task_name=task_name, site_name=self.site_name))) | 154 task_name=task_name, site_name=self.site_name))) |
155 data = task_value[u'data'] | 155 data = task_value['data'] |
156 os.chdir(self.site_path) | 156 os.chdir(self.site_path) |
157 try: | 157 try: |
158 yield data['start'](self) | 158 yield data['start'](self) |
159 except Exception as e: | 159 except Exception as e: |
160 on_error = data[u'ON_ERROR'] | 160 on_error = data['ON_ERROR'] |
161 if on_error == u'stop': | 161 if on_error == 'stop': |
162 raise e | 162 raise e |
163 elif on_error == u'continue': | 163 elif on_error == 'continue': |
164 log.warning(_(u'Task "{task_name}" failed for {site_name}: {reason}') | 164 log.warning(_('Task "{task_name}" failed for {site_name}: {reason}') |
165 .format(task_name=task_name, site_name=self.site_name, reason=e)) | 165 .format(task_name=task_name, site_name=self.site_name, reason=e)) |
166 else: | 166 else: |
167 raise exceptions.InternalError(u"we should never reach this point") | 167 raise exceptions.InternalError("we should never reach this point") |
168 self._current_task = None | 168 self._current_task = None |
169 | 169 |
170 @defer.inlineCallbacks | 170 @defer.inlineCallbacks |
171 def runTasks(self): | 171 def runTasks(self): |
172 """Run all the tasks found""" | 172 """Run all the tasks found""" |
173 old_path = os.getcwd() | 173 old_path = os.getcwd() |
174 for task_name, task_value in self.tasks.iteritems(): | 174 for task_name, task_value in self.tasks.items(): |
175 yield self.runTask(task_name) | 175 yield self.runTask(task_name) |
176 os.chdir(old_path) | 176 os.chdir(old_path) |
177 | 177 |
178 def findCommand(self, name, *args): | 178 def findCommand(self, name, *args): |
179 """Find full path of a shell command | 179 """Find full path of a shell command |
184 @raise exceptions.NotFound: can't find this command | 184 @raise exceptions.NotFound: can't find this command |
185 """ | 185 """ |
186 names = (name,) + args | 186 names = (name,) + args |
187 for n in names: | 187 for n in names: |
188 try: | 188 try: |
189 cmd_path = which(n)[0].encode('utf-8') | 189 cmd_path = which(n)[0] |
190 except IndexError: | 190 except IndexError: |
191 pass | 191 pass |
192 else: | 192 else: |
193 return cmd_path | 193 return cmd_path |
194 raise exceptions.NotFound(_( | 194 raise exceptions.NotFound(_( |
195 u"Can't find {name} command, did you install it?").format(name=name)) | 195 "Can't find {name} command, did you install it?").format(name=name)) |
196 | 196 |
197 def runCommand(self, command, *args, **kwargs): | 197 def runCommand(self, command, *args, **kwargs): |
198 kwargs['verbose'] = self.task_data[u"LOG_OUTPUT"] | 198 kwargs['verbose'] = self.task_data["LOG_OUTPUT"] |
199 return async_process.CommandProtocol.run(command, *args, **kwargs) | 199 return async_process.CommandProtocol.run(command, *args, **kwargs) |