Python: implemented doc_subscript() so that doc["someattr"] actually works (as documented...)
This commit is contained in:
parent
cb4ddc3608
commit
cce32c3e12
@ -428,6 +428,23 @@ Doc_items(recoll_DocObject *self)
|
|||||||
return pdict;
|
return pdict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool docget(recoll_DocObject *self, const string& key, string& value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!key.compare("xdocid")) {
|
||||||
|
char cid[30];
|
||||||
|
sprintf(cid, "%lu", (unsigned long)self->doc->xdocid);
|
||||||
|
value = cid;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (self->doc->getmeta(key, 0)) {
|
||||||
|
value = self->doc->meta[key];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(doc_Doc_get,
|
PyDoc_STRVAR(doc_Doc_get,
|
||||||
"get(key) -> value\n"
|
"get(key) -> value\n"
|
||||||
"Retrieve the named doc attribute\n"
|
"Retrieve the named doc attribute\n"
|
||||||
@ -436,39 +453,22 @@ static PyObject *
|
|||||||
Doc_get(recoll_DocObject *self, PyObject *args)
|
Doc_get(recoll_DocObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
LOGDEB0("Doc_get\n" );
|
LOGDEB0("Doc_get\n" );
|
||||||
|
if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "doc??");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
char *sutf8 = 0; // needs freeing
|
char *sutf8 = 0; // needs freeing
|
||||||
if (!PyArg_ParseTuple(args, "es:Doc_get",
|
if (!PyArg_ParseTuple(args, "es:Doc_get", "utf-8", &sutf8)) {
|
||||||
"utf-8", &sutf8)) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
string key(sutf8);
|
string key(sutf8);
|
||||||
PyMem_Free(sutf8);
|
PyMem_Free(sutf8);
|
||||||
|
|
||||||
if (self->doc == 0 ||
|
|
||||||
the_docs.find(self->doc) == the_docs.end()) {
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "doc??");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
string value;
|
string value;
|
||||||
bool found = false;
|
bool found = docget(self, key, value);
|
||||||
|
|
||||||
//
|
|
||||||
if (!key.compare("xdocid")) {
|
|
||||||
char cid[30];
|
|
||||||
sprintf(cid, "%lu", (unsigned long)self->doc->xdocid);
|
|
||||||
value = cid;
|
|
||||||
found = true;
|
|
||||||
} else {
|
|
||||||
if (self->doc->getmeta(key, 0)) {
|
|
||||||
value = self->doc->meta[key];
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
return PyUnicode_Decode(value.c_str(),
|
return PyUnicode_Decode(value.c_str(), value.size(), "UTF-8", "replace");
|
||||||
value.size(),
|
|
||||||
"UTF-8", "replace");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@ -480,6 +480,7 @@ static PyMethodDef Doc_methods[] = {
|
|||||||
{"keys", (PyCFunction)Doc_keys, METH_NOARGS, doc_Doc_keys},
|
{"keys", (PyCFunction)Doc_keys, METH_NOARGS, doc_Doc_keys},
|
||||||
{"items", (PyCFunction)Doc_items, METH_NOARGS, doc_Doc_items},
|
{"items", (PyCFunction)Doc_items, METH_NOARGS, doc_Doc_items},
|
||||||
{"get", (PyCFunction)Doc_get, METH_VARARGS, doc_Doc_get},
|
{"get", (PyCFunction)Doc_get, METH_VARARGS, doc_Doc_get},
|
||||||
|
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -489,7 +490,6 @@ static PyMethodDef Doc_methods[] = {
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
Doc_getattro(recoll_DocObject *self, PyObject *nameobj)
|
Doc_getattro(recoll_DocObject *self, PyObject *nameobj)
|
||||||
{
|
{
|
||||||
LOGDEB0("Doc_getattro\n" );
|
|
||||||
if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
|
if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "doc");
|
PyErr_SetString(PyExc_AttributeError, "doc");
|
||||||
return 0;
|
return 0;
|
||||||
@ -518,6 +518,7 @@ Doc_getattro(recoll_DocObject *self, PyObject *nameobj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
key = rclconfig->fieldQCanon(string(name));
|
key = rclconfig->fieldQCanon(string(name));
|
||||||
|
LOGDEB1("Doc_getattro: key: " << key << endl);
|
||||||
|
|
||||||
switch (key.at(0)) {
|
switch (key.at(0)) {
|
||||||
case 'u':
|
case 'u':
|
||||||
@ -596,7 +597,7 @@ Doc_getattro(recoll_DocObject *self, PyObject *nameobj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
LOGDEB1("Doc_getattro: [" << (key) << "] -> [" << (value) << "]\n" );
|
LOGDEB1("Doc_getattro: [" << key << "] -> [" << value << "]\n");
|
||||||
// Return a python unicode object
|
// Return a python unicode object
|
||||||
return PyUnicode_Decode(value.c_str(), value.size(), "utf-8",
|
return PyUnicode_Decode(value.c_str(), value.size(), "utf-8",
|
||||||
"replace");
|
"replace");
|
||||||
@ -642,7 +643,8 @@ Doc_setattr(recoll_DocObject *self, char *name, PyObject *value)
|
|||||||
char* uvalue = PyBytes_AsString(putf8);
|
char* uvalue = PyBytes_AsString(putf8);
|
||||||
string key = rclconfig->fieldQCanon(string(name));
|
string key = rclconfig->fieldQCanon(string(name));
|
||||||
|
|
||||||
LOGDEB0("Doc_setattr: doc " << (self->doc) << " [" << (key) << "] (" << (name) << ") -> [" << (uvalue) << "]\n" );
|
LOGDEB0("Doc_setattr: doc " << self->doc << " [" << key << "] (" << name <<
|
||||||
|
") -> [" << uvalue << "]\n");
|
||||||
|
|
||||||
// We set the value in the meta array in all cases. Good idea ? or do it
|
// We set the value in the meta array in all cases. Good idea ? or do it
|
||||||
// only for fields without a dedicated Doc:: entry?
|
// only for fields without a dedicated Doc:: entry?
|
||||||
@ -701,6 +703,57 @@ Doc_setattr(recoll_DocObject *self, char *name, PyObject *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Py_ssize_t
|
||||||
|
Doc_length(recoll_DocObject *self)
|
||||||
|
{
|
||||||
|
if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "doc??");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return self->doc->meta.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Doc_subscript(recoll_DocObject *self, PyObject *key)
|
||||||
|
{
|
||||||
|
if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "doc??");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char *name = 0;
|
||||||
|
if (PyUnicode_Check(key)) {
|
||||||
|
PyObject* utf8o = PyUnicode_AsUTF8String(key);
|
||||||
|
if (utf8o == 0) {
|
||||||
|
LOGERR("Doc_getitemo: encoding name to utf8 failed\n" );
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "name??");
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
name = PyBytes_AsString(utf8o);
|
||||||
|
Py_DECREF(utf8o);
|
||||||
|
} else if (PyBytes_Check(key)) {
|
||||||
|
name = PyBytes_AsString(key);
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "key not unicode nor string??");
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
string skey = rclconfig->fieldQCanon(string(name));
|
||||||
|
string value;
|
||||||
|
bool found = docget(self, skey, value);
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
return PyUnicode_Decode(value.c_str(), value.size(), "UTF-8", "replace");
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMappingMethods doc_as_mapping = {
|
||||||
|
(lenfunc)Doc_length, /*mp_length*/
|
||||||
|
(binaryfunc)Doc_subscript, /*mp_subscript*/
|
||||||
|
(objobjargproc)0, /*mp_ass_subscript*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(doc_DocObject,
|
PyDoc_STRVAR(doc_DocObject,
|
||||||
"Doc()\n"
|
"Doc()\n"
|
||||||
@ -745,20 +798,20 @@ static PyTypeObject recoll_DocType = {
|
|||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
(destructor)Doc_dealloc, /*tp_dealloc*/
|
(destructor)Doc_dealloc, /*tp_dealloc*/
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
0, /*tp_getattr*/
|
0, /*tp_getattr*/
|
||||||
(setattrfunc)Doc_setattr, /*tp_setattr*/
|
(setattrfunc)Doc_setattr, /*tp_setattr*/
|
||||||
0, /*tp_compare*/
|
0, /*tp_compare*/
|
||||||
0, /*tp_repr*/
|
0, /*tp_repr*/
|
||||||
0, /*tp_as_number*/
|
0, /*tp_as_number*/
|
||||||
0, /*tp_as_sequence*/
|
0, /*tp_as_sequence*/
|
||||||
0, /*tp_as_mapping*/
|
&doc_as_mapping, /*tp_as_mapping */
|
||||||
0, /*tp_hash */
|
0, /*tp_hash */
|
||||||
0, /*tp_call*/
|
0, /*tp_call*/
|
||||||
0, /*tp_str*/
|
0, /*tp_str*/
|
||||||
(getattrofunc)Doc_getattro,/*tp_getattro*/
|
(getattrofunc)Doc_getattro,/*tp_getattro*/
|
||||||
0, /*tp_setattro*/
|
0, /*tp_setattro*/
|
||||||
0, /*tp_as_buffer*/
|
0, /*tp_as_buffer*/
|
||||||
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||||
doc_DocObject, /* tp_doc */
|
doc_DocObject, /* tp_doc */
|
||||||
0, /* tp_traverse */
|
0, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user