3 * Bacula interface to Python for the Storage Daemon
5 * Kern Sibbald, January MMV
11 Copyright (C) 2005-2006 Kern Sibbald
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License
15 version 2 as amended with additional clauses defined in the
16 file LICENSE in the main source directory.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 the file LICENSE for additional details.
30 #undef _POSIX_C_SOURCE
33 extern JCR *get_jcr_from_PyObject(PyObject *self);
34 extern PyObject *find_method(PyObject *eventsObject, PyObject *method,
37 static PyObject *set_job_events(PyObject *self, PyObject *arg);
38 static PyObject *job_write(PyObject *self, PyObject *arg);
40 PyMethodDef JobMethods[] = {
41 {"set_events", set_job_events, METH_VARARGS, "Set Job events"},
42 {"write", job_write, METH_VARARGS, "Write to output"},
43 {NULL, NULL, 0, NULL} /* last item */
52 static struct s_vars getvars[] = {
53 { NT_("Job"), "s"}, /* 0 */
54 { NT_("SDName"), "s"}, /* 1 */
55 { NT_("Level"), "s"}, /* 2 */
56 { NT_("Type"), "s"}, /* 3 */
57 { NT_("JobId"), "i"}, /* 4 */
58 { NT_("Client"), "s"}, /* 5 */
59 { NT_("Pool"), "s"}, /* 6 */
60 { NT_("MediaType"), "s"}, /* 7 */
61 { NT_("JobName"), "s"}, /* 8 */
62 { NT_("JobStatus"), "s"}, /* 9 */
63 { NT_("VolumeName"), "s"}, /* 10 */
64 { NT_("Device"), "s"}, /* 11 */
70 /* Writable variables */
71 static struct s_vars setvars[] = {
72 { NT_("JobReport"), "s"},
78 /* Return Job variables */
79 PyObject *job_getattr(PyObject *self, char *attrname)
87 Dmsg1(100, "In job_getattr=%s\n", attrname);
88 jcr = get_jcr_from_PyObject(self);
90 bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
94 for (i=0; getvars[i].name; i++) {
95 if (strcmp(getvars[i].name, attrname) == 0) {
101 /* Try our methods */
102 return Py_FindMethod(JobMethods, self, attrname);
106 return Py_BuildValue(getvars[i].fmt, jcr->job_name); /* Non-unique name */
107 case 1: /* SD's name */
108 return Py_BuildValue(getvars[i].fmt, my_name);
110 return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
112 return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
114 return Py_BuildValue(getvars[i].fmt, jcr->JobId);
116 return Py_BuildValue(getvars[i].fmt, jcr->client_name);
118 return Py_BuildValue(getvars[i].fmt, jcr->dcr->pool_name);
119 case 7: /* MediaType */
120 return Py_BuildValue(getvars[i].fmt, jcr->dcr->media_type);
121 case 8: /* JobName */
122 return Py_BuildValue(getvars[i].fmt, jcr->Job);
123 case 9: /* JobStatus */
125 buf[0] = jcr->JobStatus;
126 return Py_BuildValue(getvars[i].fmt, buf);
128 return Py_BuildValue(getvars[i].fmt, jcr->dcr->VolumeName);
130 return Py_BuildValue(getvars[i].fmt, jcr->dcr->dev_name);
132 bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
134 PyErr_SetString(PyExc_AttributeError, errmsg);
138 int job_setattr(PyObject *self, char *attrname, PyObject *value)
147 Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
148 if (value == NULL) { /* Cannot delete variables */
149 bsnprintf(buf, sizeof(buf), _("Cannot delete attribute %s"), attrname);
153 jcr = get_jcr_from_PyObject(self);
155 errmsg = _("Job pointer not found.");
159 /* Find attribute name in list */
160 for (i=0; setvars[i].name; i++) {
161 if (strcmp(setvars[i].name, attrname) == 0) {
169 /* Get argument value ***FIXME*** handle other formats */
170 if (setvars[i].fmt != NULL) {
171 if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
172 PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
177 case 0: /* JobReport */
178 Jmsg(jcr, M_INFO, 0, "%s", strval);
182 bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
185 PyErr_SetString(PyExc_AttributeError, errmsg);
190 static PyObject *set_job_events(PyObject *self, PyObject *arg)
195 Dmsg0(100, "In set_job_events.\n");
196 if (!PyArg_ParseTuple(arg, "O:set_events", &eObject)) {
197 Dmsg0(000, _("Error in ParseTuple\n"));
200 jcr = get_jcr_from_PyObject(self);
201 Py_XDECREF((PyObject *)jcr->Python_events);
203 jcr->Python_events = (void *)eObject;
208 static PyObject *job_write(PyObject *self, PyObject *args)
212 if (!PyArg_ParseTuple(args, "s:write", &text)) {
213 Dmsg0(000, _("Parse tuple error in job_write\n"));
217 Jmsg(NULL, M_INFO, 0, "%s", text);
224 int generate_job_event(JCR *jcr, const char *event)
226 PyObject *method = NULL;
227 PyObject *Job = (PyObject *)jcr->Python_job;
228 PyObject *events = (PyObject *)jcr->Python_events;
229 PyObject *result = NULL;
232 if (!Job || !events) {
237 // PyEval_AcquireLock();
239 method = find_method(events, method, event);
244 bstrncpy(jcr->event, event, sizeof(jcr->event));
245 result = PyObject_CallFunction(method, "O", Job);
246 jcr->event[0] = 0; /* no event in progress */
247 if (result == NULL) {
248 if (PyErr_Occurred()) {
250 Dmsg1(000, _("Error in Python method %s\n"), event);
259 // PyEval_ReleaseLock();
266 /* Dummy if Python not configured */
267 int generate_job_event(JCR *jcr, const char *event)
271 #endif /* HAVE_PYTHON */