~ubuntu-branches/ubuntu/lucid/python-cups/lucid

« back to all changes in this revision

Viewing changes to cupsconnection.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2008-07-31 12:47:13 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20080731124713-t3nfxx1y5f2itg36
Tags: 1.9.41-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
{
41
41
  PyObject_HEAD
42
42
  http_t *http;
 
43
  char *host; /* for repr */
43
44
} Connection;
44
45
 
45
46
typedef struct
139
140
{
140
141
  Connection *self;
141
142
  self = (Connection *) type->tp_alloc (type, 0);
142
 
  if (self != NULL)
 
143
  if (self != NULL) {
143
144
    self->http = NULL;
 
145
    self->host = NULL;
 
146
  }
144
147
 
145
148
  return (PyObject *) self;
146
149
}
148
151
static int
149
152
Connection_init (Connection *self, PyObject *args, PyObject *kwds)
150
153
{
151
 
  static char *kwlist[] = { NULL };
152
 
 
153
 
  if (!PyArg_ParseTupleAndKeywords (args, kwds, "", kwlist))
154
 
    return -1;
155
 
 
156
 
  debugprintf ("-> Connection_init()\n");
 
154
  const char *host = cupsServer ();
 
155
  int port = ippPort ();
 
156
  int encryption = (http_encryption_t) cupsEncryption ();
 
157
  static char *kwlist[] = { "host", "port", "encryption", NULL };
 
158
 
 
159
  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|sii", kwlist,
 
160
                                    &host, &port, &encryption))
 
161
    return -1;
 
162
 
 
163
  debugprintf ("-> Connection_init(host=%s)\n", host);
 
164
  self->host = strdup (host);
 
165
  if (!self->host) {
 
166
    debugprintf ("<- Connection_init() = -1\n");
 
167
    return -1;
 
168
  }
157
169
 
158
170
  Py_BEGIN_ALLOW_THREADS;
159
171
  debugprintf ("httpConnectEncrypt(...)\n");
160
 
  self->http = httpConnectEncrypt (cupsServer (),
161
 
                                   ippPort (),
162
 
                                   cupsEncryption ());
 
172
  self->http = httpConnectEncrypt (host, port, (http_encryption_t) encryption);
163
173
  Py_END_ALLOW_THREADS;
164
174
 
165
175
  if (!self->http) {
178
188
  if (self->http) {  
179
189
    debugprintf ("httpClose()\n");
180
190
    httpClose (self->http);
 
191
    free (self->host);
181
192
  }
182
193
 
183
194
  self->ob_type->tp_free ((PyObject *) self);
184
195
}
185
196
 
 
197
static PyObject *
 
198
Connection_repr (Connection *self)
 
199
{
 
200
  return PyString_FromFormat ("<cups.Connection object for %s at %p>",
 
201
                              self->host, self);
 
202
}
 
203
 
186
204
////////////////
187
205
// Connection // METHODS
188
206
////////////////
1354
1372
}
1355
1373
 
1356
1374
static PyObject *
1357
 
Connection_putFile (Connection *self, PyObject *args)
 
1375
Connection_putFile (Connection *self, PyObject *args, PyObject *kwds)
1358
1376
{
1359
 
  const char *resource, *filename;
 
1377
  static char *kwlist[] = { "resource", "filename", "fd", "file", NULL };
 
1378
  const char *resource, *filename = NULL;
 
1379
  int fd = -1;
 
1380
  PyObject *fileobj = NULL;
1360
1381
  http_status_t status;
1361
1382
 
1362
 
  if (!PyArg_ParseTuple (args, "ss", &resource, &filename))
1363
 
    return NULL;
1364
 
 
1365
 
  debugprintf ("-> Connection_putFile(%s, %s)\n", resource, filename);
1366
 
  debugprintf ("cupsPutFile()\n");
1367
 
  status = cupsPutFile (self->http, resource, filename);
 
1383
  if (!PyArg_ParseTupleAndKeywords (args, kwds, "s|siO", kwlist,
 
1384
                                    &resource, &filename, &fd, &fileobj))
 
1385
    return NULL;
 
1386
 
 
1387
  if ((fd > -1 && (filename || fileobj)) ||
 
1388
      (filename && fileobj)) {
 
1389
    PyErr_SetString (PyExc_RuntimeError,
 
1390
                     "Only one destination type may be specified");
 
1391
    return NULL;
 
1392
  }
 
1393
 
 
1394
  if (fileobj) {
 
1395
    FILE *f = PyFile_AsFile (fileobj);
 
1396
    fd = fileno (f);
 
1397
  }
 
1398
 
 
1399
  if (filename) {
 
1400
    debugprintf ("-> Connection_putFile(%s, %s)\n", resource, filename);
 
1401
    debugprintf ("cupsPutFile()\n");
 
1402
    status = cupsPutFile (self->http, resource, filename);
 
1403
  } else {
 
1404
    debugprintf ("-> Connection_putFile(%s, %d)\n", resource, fd);
 
1405
    debugprintf ("cupsPutFd()\n");
 
1406
    status = cupsPutFd (self->http, resource, fd);
 
1407
  }
 
1408
 
1368
1409
  if (status != HTTP_OK && status != HTTP_CREATED) {
1369
1410
    set_http_error (status);
1370
1411
    debugprintf ("<- Connection_putFile() (error)\n");
2220
2261
  char *name;
2221
2262
  PyObject *uriobj = NULL;
2222
2263
  char *uri;
 
2264
  PyObject *requested_attrs = NULL;
 
2265
  char **attrs = NULL; /* initialised to calm compiler */
 
2266
  size_t n_attrs = 0; /* initialised to calm compiler */
2223
2267
  ipp_t *request, *answer;
2224
2268
  ipp_attribute_t *attr;
2225
2269
  char consuri[HTTP_MAX_URI];
2226
2270
  int i;
2227
 
  static char *kwlist[] = { "name", "uri", NULL };
 
2271
  static char *kwlist[] = { "name", "uri", "requested_attributes", NULL };
2228
2272
 
2229
 
  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|OO", kwlist,
2230
 
                                    &nameobj, &uriobj))
 
2273
  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|OOO", kwlist,
 
2274
                                    &nameobj, &uriobj, &requested_attrs))
2231
2275
    return NULL;
2232
2276
 
2233
2277
  if (nameobj && uriobj) {
2248
2292
    return NULL;
2249
2293
  }
2250
2294
 
 
2295
  if (requested_attrs) {
 
2296
    int i;
 
2297
 
 
2298
    if (!PyList_Check (requested_attrs)) {
 
2299
      PyErr_SetString (PyExc_TypeError, "List required");
 
2300
      return NULL;
 
2301
    }
 
2302
 
 
2303
    n_attrs = PyList_Size (requested_attrs);
 
2304
    attrs = malloc ((n_attrs + 1) * sizeof (char *));
 
2305
    for (i = 0; i < n_attrs; i++) {
 
2306
      PyObject *val = PyList_GetItem (requested_attrs, i); // borrowed ref
 
2307
      if (!PyString_Check (val)) {
 
2308
        PyErr_SetString (PyExc_TypeError, "String required");
 
2309
        while (--i >= 0)
 
2310
          free (attrs[i]);
 
2311
        free (attrs);
 
2312
        if (nameobj)
 
2313
          free (name);
 
2314
        else if (uriobj)
 
2315
          free (uri);
 
2316
        return NULL;
 
2317
      }
 
2318
 
 
2319
      attrs[i] = strdup (PyString_AsString (val));
 
2320
    }
 
2321
    attrs[n_attrs] = NULL;
 
2322
  }
 
2323
 
2251
2324
  debugprintf ("-> Connection_getPrinterAttributes(%s)\n",
2252
2325
               nameobj ? name : uri);
 
2326
 
 
2327
  if (requested_attrs) {
 
2328
    int i;
 
2329
    debugprintf ("Requested attributes:\n");
 
2330
    for (i = 0; attrs[i] != NULL; i++)
 
2331
      debugprintf ("  %s\n", attrs[i]);
 
2332
  }
 
2333
 
2253
2334
  if (nameobj) {
2254
2335
    snprintf (consuri, sizeof (consuri), "ipp://localhost/printers/%s", name);
2255
2336
    uri = consuri;
2259
2340
    request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES);
2260
2341
    ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
2261
2342
                  "printer-uri", NULL, uri);
 
2343
    if (requested_attrs)
 
2344
      ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
 
2345
                     "requested-attributes", n_attrs, NULL,
 
2346
                     (const char **) attrs);
2262
2347
    debugprintf ("trying request with uri %s\n", uri);
2263
2348
    answer = cupsDoRequest (self->http, request, "/");
2264
2349
    if (answer && answer->request.status.status_code == IPP_NOT_POSSIBLE) {
2277
2362
  if (uriobj)
2278
2363
    free (uri);
2279
2364
 
 
2365
  if (requested_attrs) {
 
2366
    int i;
 
2367
    for (i = 0; attrs[i] != NULL; i++)
 
2368
      free (attrs[i]);
 
2369
    free (attrs);
 
2370
  }
 
2371
 
2280
2372
  if (!answer || answer->request.status.status_code > IPP_OK_CONFLICT) {
2281
2373
    set_ipp_error (answer ?
2282
2374
                   answer->request.status.status_code :
2335
2427
            "notify-events-default",
2336
2428
            "requesting-user-name-allowed",
2337
2429
            "requesting-user-name-denied",
2338
 
            "finishings-supported",
2339
2430
            "printer-state-reasons",
2340
2431
            NULL
2341
2432
          };
2348
2439
        case IPP_TAG_CHARSET:
2349
2440
        case IPP_TAG_MIMETYPE:
2350
2441
        case IPP_TAG_LANGUAGE:
 
2442
        case IPP_TAG_ENUM:
2351
2443
          is_list = !strcmp (attr->name + namelen - 10, "-supported");
2352
2444
 
2353
2445
          if (!is_list) {
3611
3703
      "getJobAttributes(jobid) -> None\n\n"
3612
3704
      "Fetch job attributes.\n"
3613
3705
      "@type jobid: integer\n"
3614
 
      "@param jobid_jobs: job ID\n"
 
3706
      "@param jobid: job ID\n"
3615
3707
      "@return: a dict representing job attributes.\n"
3616
3708
      "@raise IPPError: IPP problem" },
3617
3709
 
3679
3771
      "@raise HTTPError: HTTP problem" },
3680
3772
 
3681
3773
    { "putFile",
3682
 
      (PyCFunction) Connection_putFile, METH_VARARGS,
3683
 
      "putFile(resource, filename) -> None\n\n"
 
3774
      (PyCFunction) Connection_putFile, METH_VARARGS | METH_KEYWORDS,
 
3775
      "putFile(resource, filename=None, fd=-1, file=None) -> None\n\n"
3684
3776
      "This is for uploading new configuration files for the CUPS \n"
3685
3777
      "server.  Note: L{adminSetServerSettings} is a way of \n"
3686
3778
      "adjusting server settings without needing to parse the \n"
3689
3781
      "@param resource: resource name\n"
3690
3782
      "@type filename: string\n"
3691
3783
      "@param filename: name of local file to upload\n"
 
3784
      "@type fd: int\n"
 
3785
      "@param fd: file descriptor of local file\n"
 
3786
      "@type file: file\n"
 
3787
      "@param file: Python file object for local file\n"
3692
3788
      "@raise HTTPError: HTTP problem"},
3693
3789
 
3694
3790
    { "addPrinter",
3850
3946
    { "getPrinterAttributes",
3851
3947
      (PyCFunction) Connection_getPrinterAttributes,
3852
3948
      METH_VARARGS | METH_KEYWORDS,
3853
 
      "getPrinterAttributes() -> dict\n"
 
3949
      "getPrinterAttributes(name=None, uri=None, requested_attributes=None) -> dict\n"
3854
3950
      "Fetch the attributes for a printer, specified either by name or by \n"
3855
3951
      "uri but not both.\n\n"
3856
3952
      "@type name: string\n"
3857
3953
      "@param name: queue name\n"
3858
3954
      "@type uri: string\n"
3859
3955
      "@param uri: queue URI\n"
 
3956
      "@type requested_attributes: string list\n"
 
3957
      "@param requested_attributes: list of requested attribute names\n"
3860
3958
      "@return: a dict, indexed by attribute, of printer attributes\n"
3861
3959
      "for the specified printer.\n\n"
3862
3960
      "Attributes:\n"
4054
4152
 
4055
4153
    { "renewSubscription",
4056
4154
      (PyCFunction) Connection_renewSubscription, METH_VARARGS | METH_KEYWORDS,
4057
 
      "renewSubscription(id) -> None\n\n"
 
4155
      "renewSubscription(id, lease_duration=-1) -> None\n\n"
4058
4156
      "Renew a subscription.\n\n"
4059
4157
      "@type id: integer\n"
4060
4158
      "@param id: subscription ID\n"
4107
4205
    0,                         /*tp_getattr*/
4108
4206
    0,                         /*tp_setattr*/
4109
4207
    0,                         /*tp_compare*/
4110
 
    0,                         /*tp_repr*/
 
4208
    (reprfunc)Connection_repr, /*tp_repr*/
4111
4209
    0,                         /*tp_as_number*/
4112
4210
    0,                         /*tp_as_sequence*/
4113
4211
    0,                         /*tp_as_mapping*/
4124
4222
    "  A connection to the CUPS server.  Before it is created the \n"
4125
4223
    "  connection server and username should be set using \n"
4126
4224
    "  L{cups.setServer} and L{cups.setUser}; otherwise the defaults will \n"
4127
 
    "  be used.  When a Connection object is instantiated it results in a "
4128
 
    "  call to the libcups function httpConnectEncrypt()."
 
4225
    "  be used.  When a Connection object is instantiated it results in a \n"
 
4226
    "  call to the libcups function httpConnectEncrypt().\n\n"
 
4227
    "  The constructor takes optional arguments host, port, and encryption, \n"
 
4228
    "  which default to the values of L{cups.getServer}(), \n"
 
4229
    "  L{cups.getPort}(), and L{cups.getEncryption}().\n"
4129
4230
    "",         /* tp_doc */
4130
4231
    0,                         /* tp_traverse */
4131
4232
    0,                         /* tp_clear */
4185
4286
  self->ob_type->tp_free ((PyObject *) self);
4186
4287
}
4187
4288
 
 
4289
static PyObject *
 
4290
Dest_repr (Dest *self)
 
4291
{
 
4292
  return PyString_FromFormat ("<cups.Dest %s%s%s%s>",
 
4293
                              self->destname,
 
4294
                              self->instance ? "/" : "",
 
4295
                              self->instance ? self->instance : "",
 
4296
                              self->is_default ? " (default)" : "");
 
4297
}
 
4298
 
4188
4299
//////////
4189
4300
// Dest // ATTRIBUTES
4190
4301
//////////
4258
4369
    0,                         /*tp_getattr*/
4259
4370
    0,                         /*tp_setattr*/
4260
4371
    0,                         /*tp_compare*/
4261
 
    0,                         /*tp_repr*/
 
4372
    (reprfunc)Dest_repr,       /*tp_repr*/
4262
4373
    0,                         /*tp_as_number*/
4263
4374
    0,                         /*tp_as_sequence*/
4264
4375
    0,                         /*tp_as_mapping*/