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)