Switch to unified view

a/src/python/recoll/pyrecoll.cpp b/src/python/recoll/pyrecoll.cpp
...
...
426
                    "UTF-8", "replace"));
426
                    "UTF-8", "replace"));
427
    }
427
    }
428
    return pdict;
428
    return pdict;
429
}
429
}
430
430
431
PyDoc_STRVAR(doc_Doc_get,
431
static bool docget(recoll_DocObject *self, const string& key, string& value)
432
"get(key) -> value\n"
433
"Retrieve the named doc attribute\n"
434
);
435
static PyObject *
436
Doc_get(recoll_DocObject *self, PyObject *args)
437
{
432
{
438
    LOGDEB0("Doc_get\n" );
439
    char *sutf8 = 0; // needs freeing
440
    if (!PyArg_ParseTuple(args, "es:Doc_get",
441
            "utf-8", &sutf8)) {
442
  return 0;
443
    }
444
    string key(sutf8);
445
    PyMem_Free(sutf8);
446
447
    if (self->doc == 0 || 
448
  the_docs.find(self->doc) == the_docs.end()) {
449
        PyErr_SetString(PyExc_AttributeError, "doc??");
450
  return 0;
451
    }
452
    string value;
453
    bool found = false;
454
455
    // 
433
    // 
456
    if (!key.compare("xdocid")) {
434
    if (!key.compare("xdocid")) {
457
        char cid[30];
435
        char cid[30];
458
        sprintf(cid, "%lu", (unsigned long)self->doc->xdocid);
436
        sprintf(cid, "%lu", (unsigned long)self->doc->xdocid);
459
        value = cid;
437
        value = cid;
460
        found = true;
438
        return true;
461
    } else {
439
    } else {
462
        if (self->doc->getmeta(key, 0)) {
440
        if (self->doc->getmeta(key, 0)) {
463
            value = self->doc->meta[key];
441
            value = self->doc->meta[key];
464
            found = true;
442
            return true;
465
        }
443
        }
466
    }
444
    }
445
    return false;
446
}
447
448
PyDoc_STRVAR(doc_Doc_get,
449
"get(key) -> value\n"
450
"Retrieve the named doc attribute\n"
451
);
452
static PyObject *
453
Doc_get(recoll_DocObject *self, PyObject *args)
454
{
455
    LOGDEB0("Doc_get\n" );
456
    if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
457
        PyErr_SetString(PyExc_AttributeError, "doc??");
458
  return 0;
459
    }
460
    char *sutf8 = 0; // needs freeing
461
    if (!PyArg_ParseTuple(args, "es:Doc_get", "utf-8", &sutf8)) {
462
  return 0;
463
    }
464
    string key(sutf8);
465
    PyMem_Free(sutf8);
466
467
    string value;
468
    bool found = docget(self, key, value);
467
469
468
    if (found) {
470
    if (found) {
469
  return PyUnicode_Decode(value.c_str(), 
471
  return PyUnicode_Decode(value.c_str(), value.size(), "UTF-8", "replace");
470
              value.size(), 
471
              "UTF-8", "replace");
472
    }
472
    }
473
473
474
    Py_RETURN_NONE;
474
    Py_RETURN_NONE;
475
}
475
}
476
476
...
...
478
    {"getbinurl", (PyCFunction)Doc_getbinurl, METH_NOARGS, doc_Doc_getbinurl},
478
    {"getbinurl", (PyCFunction)Doc_getbinurl, METH_NOARGS, doc_Doc_getbinurl},
479
    {"setbinurl", (PyCFunction)Doc_setbinurl, METH_O, doc_Doc_setbinurl},
479
    {"setbinurl", (PyCFunction)Doc_setbinurl, METH_O, doc_Doc_setbinurl},
480
    {"keys", (PyCFunction)Doc_keys, METH_NOARGS, doc_Doc_keys},
480
    {"keys", (PyCFunction)Doc_keys, METH_NOARGS, doc_Doc_keys},
481
    {"items", (PyCFunction)Doc_items, METH_NOARGS, doc_Doc_items},
481
    {"items", (PyCFunction)Doc_items, METH_NOARGS, doc_Doc_items},
482
    {"get", (PyCFunction)Doc_get, METH_VARARGS, doc_Doc_get},
482
    {"get", (PyCFunction)Doc_get, METH_VARARGS, doc_Doc_get},
483
        
483
    {NULL}  /* Sentinel */
484
    {NULL}  /* Sentinel */
484
};
485
};
485
486
486
// Note that this returns None if the attribute is not found instead of raising
487
// Note that this returns None if the attribute is not found instead of raising
487
// an exception as would be standard. We don't change it to keep existing code
488
// an exception as would be standard. We don't change it to keep existing code
488
// working.
489
// working.
489
static PyObject *
490
static PyObject *
490
Doc_getattro(recoll_DocObject *self, PyObject *nameobj)
491
Doc_getattro(recoll_DocObject *self, PyObject *nameobj)
491
{
492
{
492
    LOGDEB0("Doc_getattro\n" );
493
    if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
493
    if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
494
        PyErr_SetString(PyExc_AttributeError, "doc");
494
        PyErr_SetString(PyExc_AttributeError, "doc");
495
    return 0;
495
    return 0;
496
    }
496
    }
497
497
...
...
516
    PyErr_SetString(PyExc_AttributeError, "name not unicode nor string??");
516
    PyErr_SetString(PyExc_AttributeError, "name not unicode nor string??");
517
    Py_RETURN_NONE;
517
    Py_RETURN_NONE;
518
    }
518
    }
519
519
520
    key = rclconfig->fieldQCanon(string(name));
520
    key = rclconfig->fieldQCanon(string(name));
521
    LOGDEB1("Doc_getattro: key: " << key << endl);
521
522
522
    switch (key.at(0)) {
523
    switch (key.at(0)) {
523
    case 'u':
524
    case 'u':
524
    if (!key.compare(Rcl::Doc::keyurl)) {
525
    if (!key.compare(Rcl::Doc::keyurl)) {
525
        value = self->doc->url; found = true;
526
        value = self->doc->url; found = true;
...
...
594
        found = true;
595
        found = true;
595
    }
596
    }
596
    }
597
    }
597
598
598
    if (found) {
599
    if (found) {
599
    LOGDEB1("Doc_getattro: ["  << (key) << "] -> ["  << (value) << "]\n" );
600
    LOGDEB1("Doc_getattro: ["  << key << "] -> ["  << value << "]\n");
600
    // Return a python unicode object
601
    // Return a python unicode object
601
    return PyUnicode_Decode(value.c_str(), value.size(), "utf-8",
602
    return PyUnicode_Decode(value.c_str(), value.size(), "utf-8",
602
                "replace");
603
                "replace");
603
    }
604
    }
604
    
605
    
...
...
640
    return -1;
641
    return -1;
641
    }
642
    }
642
    char* uvalue = PyBytes_AsString(putf8);
643
    char* uvalue = PyBytes_AsString(putf8);
643
    string key = rclconfig->fieldQCanon(string(name));
644
    string key = rclconfig->fieldQCanon(string(name));
644
645
645
    LOGDEB0("Doc_setattr: doc "  << (self->doc) << " ["  << (key) << "] ("  << (name) << ") -> ["  << (uvalue) << "]\n" );
646
    LOGDEB0("Doc_setattr: doc " << self->doc << " [" << key << "] (" << name <<
647
            ") -> [" << uvalue << "]\n");
646
648
647
    // We set the value in the meta array in all cases. Good idea ? or do it
649
    // We set the value in the meta array in all cases. Good idea ? or do it
648
    // only for fields without a dedicated Doc:: entry?
650
    // only for fields without a dedicated Doc:: entry?
649
    self->doc->meta[key] = uvalue;
651
    self->doc->meta[key] = uvalue;
650
    switch (key.at(0)) {
652
    switch (key.at(0)) {
...
...
698
    break;
700
    break;
699
    }
701
    }
700
    Py_DECREF(putf8);
702
    Py_DECREF(putf8);
701
    return 0;
703
    return 0;
702
}
704
}
705
706
static Py_ssize_t
707
Doc_length(recoll_DocObject *self)
708
{
709
    if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
710
        PyErr_SetString(PyExc_AttributeError, "doc??");
711
  return -1;
712
    }
713
    return self->doc->meta.size();
714
}
715
716
static PyObject *
717
Doc_subscript(recoll_DocObject *self, PyObject *key)
718
{
719
    if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
720
        PyErr_SetString(PyExc_AttributeError, "doc??");
721
  return NULL;
722
    }
723
    char *name = 0;
724
    if (PyUnicode_Check(key)) {
725
        PyObject* utf8o = PyUnicode_AsUTF8String(key);
726
  if (utf8o == 0) {
727
      LOGERR("Doc_getitemo: encoding name to utf8 failed\n" );
728
      PyErr_SetString(PyExc_AttributeError, "name??");
729
      Py_RETURN_NONE;
730
  }
731
  name = PyBytes_AsString(utf8o);
732
  Py_DECREF(utf8o);
733
    }  else if (PyBytes_Check(key)) {
734
  name = PyBytes_AsString(key);
735
    } else {
736
  PyErr_SetString(PyExc_AttributeError, "key not unicode nor string??");
737
  Py_RETURN_NONE;
738
    }
739
740
    string skey = rclconfig->fieldQCanon(string(name));
741
    string value;
742
    bool found = docget(self, skey, value);
743
744
    if (found) {
745
  return PyUnicode_Decode(value.c_str(), value.size(), "UTF-8", "replace");
746
    }
747
748
    Py_RETURN_NONE;
749
}
750
751
static PyMappingMethods doc_as_mapping = {
752
    (lenfunc)Doc_length, /*mp_length*/
753
    (binaryfunc)Doc_subscript, /*mp_subscript*/
754
    (objobjargproc)0, /*mp_ass_subscript*/
755
};
703
756
704
757
705
PyDoc_STRVAR(doc_DocObject,
758
PyDoc_STRVAR(doc_DocObject,
706
"Doc()\n"
759
"Doc()\n"
707
"\n"
760
"\n"
...
...
743
    "recoll.Doc",             /*tp_name*/
796
    "recoll.Doc",             /*tp_name*/
744
    sizeof(recoll_DocObject), /*tp_basicsize*/
797
    sizeof(recoll_DocObject), /*tp_basicsize*/
745
    0,                         /*tp_itemsize*/
798
    0,                         /*tp_itemsize*/
746
    (destructor)Doc_dealloc,    /*tp_dealloc*/
799
    (destructor)Doc_dealloc,    /*tp_dealloc*/
747
    0,                         /*tp_print*/
800
    0,                         /*tp_print*/
748
    0,  /*tp_getattr*/
801
    0,                         /*tp_getattr*/
749
    (setattrfunc)Doc_setattr, /*tp_setattr*/
802
    (setattrfunc)Doc_setattr,  /*tp_setattr*/
750
    0,                         /*tp_compare*/
803
    0,                         /*tp_compare*/
751
    0,                         /*tp_repr*/
804
    0,                         /*tp_repr*/
752
    0,                         /*tp_as_number*/
805
    0,                         /*tp_as_number*/
753
    0,                         /*tp_as_sequence*/
806
    0,                         /*tp_as_sequence*/
754
    0,                         /*tp_as_mapping*/
807
    &doc_as_mapping,          /*tp_as_mapping */
755
    0,                         /*tp_hash */
808
    0,                         /*tp_hash */
756
    0,                         /*tp_call*/
809
    0,                         /*tp_call*/
757
    0,                         /*tp_str*/
810
    0,                         /*tp_str*/
758
    (getattrofunc)Doc_getattro,/*tp_getattro*/
811
    (getattrofunc)Doc_getattro,/*tp_getattro*/
759
    0,                         /*tp_setattro*/
812
    0,                         /*tp_setattro*/
760
    0,                         /*tp_as_buffer*/
813
    0,                         /*tp_as_buffer*/
761
    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,        /*tp_flags*/
814
    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
762
    doc_DocObject,             /* tp_doc */
815
    doc_DocObject,             /* tp_doc */
763
    0,                     /* tp_traverse */
816
    0,                     /* tp_traverse */
764
    0,                     /* tp_clear */
817
    0,                     /* tp_clear */
765
    0,                     /* tp_richcompare */
818
    0,                     /* tp_richcompare */
766
    0,                     /* tp_weaklistoffset */
819
    0,                     /* tp_weaklistoffset */