|
a/src/python/recoll/pyrecoll.cpp |
|
b/src/python/recoll/pyrecoll.cpp |
|
... |
|
... |
45 |
static set<Rcl::Query *> the_queries;
|
45 |
static set<Rcl::Query *> the_queries;
|
46 |
static set<Rcl::Doc *> the_docs;
|
46 |
static set<Rcl::Doc *> the_docs;
|
47 |
|
47 |
|
48 |
static RclConfig *rclconfig;
|
48 |
static RclConfig *rclconfig;
|
49 |
|
49 |
|
|
|
50 |
#if PY_MAJOR_VERSION >=3
|
|
|
51 |
# define Py_TPFLAGS_HAVE_ITER 0
|
|
|
52 |
#endif
|
|
|
53 |
|
50 |
//////////////////////////////////////////////////////////////////////
|
54 |
//////////////////////////////////////////////////////////////////////
|
51 |
/// SEARCHDATA SearchData code
|
55 |
/// SEARCHDATA SearchData code
|
52 |
typedef struct {
|
56 |
typedef struct {
|
53 |
PyObject_HEAD
|
57 |
PyObject_HEAD
|
54 |
/* Type-specific fields go here. */
|
58 |
/* Type-specific fields go here. */
|
|
... |
|
... |
57 |
|
61 |
|
58 |
static void
|
62 |
static void
|
59 |
SearchData_dealloc(recoll_SearchDataObject *self)
|
63 |
SearchData_dealloc(recoll_SearchDataObject *self)
|
60 |
{
|
64 |
{
|
61 |
LOGDEB(("SearchData_dealloc\n"));
|
65 |
LOGDEB(("SearchData_dealloc\n"));
|
62 |
self->ob_type->tp_free((PyObject*)self);
|
66 |
Py_TYPE(self)->tp_free((PyObject*)self);
|
63 |
}
|
67 |
}
|
64 |
|
68 |
|
65 |
static PyObject *
|
69 |
static PyObject *
|
66 |
SearchData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
70 |
SearchData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
67 |
{
|
71 |
{
|
|
... |
|
... |
128 |
doc_addclause},
|
132 |
doc_addclause},
|
129 |
{NULL} /* Sentinel */
|
133 |
{NULL} /* Sentinel */
|
130 |
};
|
134 |
};
|
131 |
|
135 |
|
132 |
static PyTypeObject recoll_SearchDataType = {
|
136 |
static PyTypeObject recoll_SearchDataType = {
|
133 |
PyObject_HEAD_INIT(NULL)
|
137 |
PyVarObject_HEAD_INIT(NULL, 0)
|
134 |
0, /*ob_size*/
|
|
|
135 |
"recoll.SearchData", /*tp_name*/
|
138 |
"recoll.SearchData", /*tp_name*/
|
136 |
sizeof(recoll_SearchDataObject), /*tp_basicsize*/
|
139 |
sizeof(recoll_SearchDataObject), /*tp_basicsize*/
|
137 |
0, /*tp_itemsize*/
|
140 |
0, /*tp_itemsize*/
|
138 |
(destructor)SearchData_dealloc, /*tp_dealloc*/
|
141 |
(destructor)SearchData_dealloc, /*tp_dealloc*/
|
139 |
0, /*tp_print*/
|
142 |
0, /*tp_print*/
|
|
... |
|
... |
291 |
{
|
294 |
{
|
292 |
LOGDEB(("Doc_dealloc\n"));
|
295 |
LOGDEB(("Doc_dealloc\n"));
|
293 |
if (self->doc)
|
296 |
if (self->doc)
|
294 |
the_docs.erase(self->doc);
|
297 |
the_docs.erase(self->doc);
|
295 |
deleteZ(self->doc);
|
298 |
deleteZ(self->doc);
|
296 |
self->ob_type->tp_free((PyObject*)self);
|
299 |
Py_TYPE(self)->tp_free((PyObject*)self);
|
297 |
}
|
300 |
}
|
298 |
|
301 |
|
299 |
static PyObject *
|
302 |
static PyObject *
|
300 |
Doc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
303 |
Doc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
301 |
{
|
304 |
{
|
|
... |
|
... |
461 |
{"items", (PyCFunction)Doc_items, METH_NOARGS, doc_Doc_items},
|
464 |
{"items", (PyCFunction)Doc_items, METH_NOARGS, doc_Doc_items},
|
462 |
{"get", (PyCFunction)Doc_get, METH_VARARGS, doc_Doc_get},
|
465 |
{"get", (PyCFunction)Doc_get, METH_VARARGS, doc_Doc_get},
|
463 |
{NULL} /* Sentinel */
|
466 |
{NULL} /* Sentinel */
|
464 |
};
|
467 |
};
|
465 |
|
468 |
|
|
|
469 |
// Note that this returns None if the attribute is not found instead of raising
|
|
|
470 |
// an exception as would be standard. We don't change it to keep existing code
|
|
|
471 |
// working.
|
466 |
static PyObject *
|
472 |
static PyObject *
|
467 |
Doc_getattr(recoll_DocObject *self, char *name)
|
473 |
Doc_getattro(recoll_DocObject *self, PyObject *nameobj)
|
468 |
{
|
474 |
{
|
469 |
LOGDEB1(("Doc_getattr: name [%s]\n", name));
|
|
|
470 |
if (self->doc == 0 ||
|
|
|
471 |
the_docs.find(self->doc) == the_docs.end()) {
|
475 |
if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
|
472 |
PyErr_SetString(PyExc_AttributeError, "doc");
|
476 |
PyErr_SetString(PyExc_AttributeError, "doc");
|
473 |
return 0;
|
477 |
return 0;
|
474 |
}
|
478 |
}
|
475 |
string key = rclconfig->fieldCanon(string(name));
|
|
|
476 |
|
479 |
|
477 |
// Handle special cases, then check this is not a method then
|
480 |
bool found = false;
|
478 |
// try retrieving key value from the meta array
|
|
|
479 |
|
|
|
480 |
string value;
|
481 |
string value;
|
481 |
bool found = false;
|
482 |
string key;
|
|
|
483 |
char *name = 0;
|
|
|
484 |
PyObject* utf8o = 0;
|
|
|
485 |
|
|
|
486 |
if (PyUnicode_Check(nameobj)) {
|
|
|
487 |
utf8o = PyUnicode_AsUTF8String(nameobj);
|
|
|
488 |
if (utf8o == 0) {
|
|
|
489 |
LOGERR(("Doc_getattro: encoding name to utf8 failed\n"));
|
|
|
490 |
PyErr_SetString(PyExc_AttributeError, "name??");
|
|
|
491 |
Py_RETURN_NONE;
|
|
|
492 |
}
|
|
|
493 |
name = PyBytes_AsString(utf8o);
|
|
|
494 |
Py_DECREF(utf8o);
|
|
|
495 |
} else if (PyBytes_Check(nameobj)) {
|
|
|
496 |
name = PyBytes_AsString(nameobj);
|
|
|
497 |
} else {
|
|
|
498 |
PyErr_SetString(PyExc_AttributeError, "name not unicode nor string??");
|
|
|
499 |
Py_RETURN_NONE;
|
|
|
500 |
}
|
|
|
501 |
|
|
|
502 |
key = rclconfig->fieldCanon(string(name));
|
|
|
503 |
|
482 |
switch (key.at(0)) {
|
504 |
switch (key.at(0)) {
|
483 |
case 'u':
|
505 |
case 'u':
|
484 |
if (!key.compare(Rcl::Doc::keyurl)) {
|
506 |
if (!key.compare(Rcl::Doc::keyurl)) {
|
485 |
value = self->doc->url; found = true;
|
507 |
value = self->doc->url; found = true;
|
486 |
}
|
508 |
}
|
|
... |
|
... |
531 |
}
|
553 |
}
|
532 |
break;
|
554 |
break;
|
533 |
}
|
555 |
}
|
534 |
|
556 |
|
535 |
if (!found) {
|
557 |
if (!found) {
|
536 |
PyObject *meth = Py_FindMethod(Doc_methods, (PyObject*)self,
|
558 |
// This will look up a method name (we have no other standard
|
537 |
key.c_str());
|
559 |
// attributes)
|
|
|
560 |
PyObject *meth = PyObject_GenericGetAttr((PyObject*)self, nameobj);
|
538 |
if (meth) {
|
561 |
if (meth) {
|
539 |
return meth;
|
562 |
return meth;
|
540 |
} else {
|
563 |
}
|
541 |
PyErr_Clear();
|
564 |
PyErr_Clear();
|
542 |
}
|
565 |
// Else look for another attribute
|
543 |
|
|
|
544 |
if (self->doc->getmeta(key, 0)) {
|
566 |
if (self->doc->getmeta(key, 0)) {
|
545 |
value = self->doc->meta[key];
|
567 |
value = self->doc->meta[key];
|
546 |
found = true;
|
568 |
found = true;
|
547 |
}
|
569 |
}
|
548 |
}
|
570 |
}
|
549 |
|
571 |
|
550 |
if (!found) {
|
572 |
if (found) {
|
551 |
LOGDEB(("Doc_getattr: name [%s] key [%s] Not found\n",
|
573 |
LOGDEB1(("Doc_getattro: [%s] -> [%s]\n", key.c_str(), value.c_str()));
|
552 |
name, key.c_str()));
|
|
|
553 |
Py_RETURN_NONE;
|
|
|
554 |
}
|
|
|
555 |
|
|
|
556 |
LOGDEB1(("Doc_getattr: [%s] (%s) -> [%s]\n",
|
|
|
557 |
name, key.c_str(), value.c_str()));
|
|
|
558 |
// Return a python unicode object
|
574 |
// Return a python unicode object
|
559 |
PyObject* res = PyUnicode_Decode(value.c_str(), value.size(), "utf-8",
|
575 |
return PyUnicode_Decode(value.c_str(), value.size(), "utf-8",
|
560 |
"replace");
|
576 |
"replace");
|
561 |
return res;
|
577 |
}
|
|
|
578 |
|
|
|
579 |
Py_RETURN_NONE;
|
562 |
}
|
580 |
}
|
563 |
|
581 |
|
564 |
static int
|
582 |
static int
|
565 |
Doc_setattr(recoll_DocObject *self, char *name, PyObject *value)
|
583 |
Doc_setattr(recoll_DocObject *self, char *name, PyObject *value)
|
566 |
{
|
584 |
{
|
567 |
if (self->doc == 0 ||
|
|
|
568 |
the_docs.find(self->doc) == the_docs.end()) {
|
585 |
if (self->doc == 0 || the_docs.find(self->doc) == the_docs.end()) {
|
569 |
PyErr_SetString(PyExc_AttributeError, "doc??");
|
586 |
PyErr_SetString(PyExc_AttributeError, "doc??");
|
570 |
return -1;
|
587 |
return -1;
|
571 |
}
|
588 |
}
|
572 |
LOGDEB1(("Doc_setmeta: doc %p\n", self->doc));
|
589 |
LOGDEB1(("Doc_setmeta: doc %p\n", self->doc));
|
|
|
590 |
|
|
|
591 |
#if PY_MAJOR_VERSION < 3
|
573 |
if (PyString_Check(value)) {
|
592 |
if (PyString_Check(value)) {
|
574 |
value = PyUnicode_FromObject(value);
|
593 |
value = PyUnicode_FromObject(value);
|
575 |
if (value == 0)
|
594 |
if (value == 0)
|
576 |
return -1;
|
595 |
return -1;
|
577 |
}
|
596 |
}
|
|
|
597 |
#endif
|
578 |
|
598 |
|
579 |
if (!PyUnicode_Check(value)) {
|
599 |
if (!PyUnicode_Check(value)) {
|
580 |
PyErr_SetString(PyExc_AttributeError, "value not str/unicode??");
|
600 |
PyErr_SetString(PyExc_AttributeError, "value not str/unicode??");
|
581 |
return -1;
|
601 |
return -1;
|
582 |
}
|
602 |
}
|
|
... |
|
... |
589 |
if (putf8 == 0) {
|
609 |
if (putf8 == 0) {
|
590 |
LOGERR(("Doc_setmeta: encoding to utf8 failed\n"));
|
610 |
LOGERR(("Doc_setmeta: encoding to utf8 failed\n"));
|
591 |
PyErr_SetString(PyExc_AttributeError, "value??");
|
611 |
PyErr_SetString(PyExc_AttributeError, "value??");
|
592 |
return -1;
|
612 |
return -1;
|
593 |
}
|
613 |
}
|
594 |
|
|
|
595 |
char* uvalue = PyString_AsString(putf8);
|
614 |
char* uvalue = PyBytes_AsString(putf8);
|
|
|
615 |
Py_DECREF(putf8);
|
596 |
string key = rclconfig->fieldCanon(string(name));
|
616 |
string key = rclconfig->fieldCanon(string(name));
|
597 |
|
617 |
|
598 |
LOGDEB0(("Doc_setattr: [%s] (%s) -> [%s]\n", key.c_str(), name, uvalue));
|
618 |
LOGDEB0(("Doc_setattr: [%s] (%s) -> [%s]\n", key.c_str(), name, uvalue));
|
599 |
// We set the value in the meta array in all cases. Good idea ? or do it
|
619 |
// We set the value in the meta array in all cases. Good idea ? or do it
|
600 |
// only for fields without a dedicated Doc:: entry?
|
620 |
// only for fields without a dedicated Doc:: entry?
|
|
... |
|
... |
688 |
" author (both)\n"
|
708 |
" author (both)\n"
|
689 |
" title (both)\n"
|
709 |
" title (both)\n"
|
690 |
" keywords (both)\n"
|
710 |
" keywords (both)\n"
|
691 |
);
|
711 |
);
|
692 |
static PyTypeObject recoll_DocType = {
|
712 |
static PyTypeObject recoll_DocType = {
|
693 |
PyObject_HEAD_INIT(NULL)
|
713 |
PyVarObject_HEAD_INIT(NULL, 0)
|
694 |
0, /*ob_size*/
|
|
|
695 |
"recoll.Doc", /*tp_name*/
|
714 |
"recoll.Doc", /*tp_name*/
|
696 |
sizeof(recoll_DocObject), /*tp_basicsize*/
|
715 |
sizeof(recoll_DocObject), /*tp_basicsize*/
|
697 |
0, /*tp_itemsize*/
|
716 |
0, /*tp_itemsize*/
|
698 |
(destructor)Doc_dealloc, /*tp_dealloc*/
|
717 |
(destructor)Doc_dealloc, /*tp_dealloc*/
|
699 |
0, /*tp_print*/
|
718 |
0, /*tp_print*/
|
700 |
(getattrfunc)Doc_getattr, /*tp_getattr*/
|
719 |
0, /*tp_getattr*/
|
701 |
(setattrfunc)Doc_setattr, /*tp_setattr*/
|
720 |
(setattrfunc)Doc_setattr, /*tp_setattr*/
|
702 |
0, /*tp_compare*/
|
721 |
0, /*tp_compare*/
|
703 |
0, /*tp_repr*/
|
722 |
0, /*tp_repr*/
|
704 |
0, /*tp_as_number*/
|
723 |
0, /*tp_as_number*/
|
705 |
0, /*tp_as_sequence*/
|
724 |
0, /*tp_as_sequence*/
|
706 |
0, /*tp_as_mapping*/
|
725 |
0, /*tp_as_mapping*/
|
707 |
0, /*tp_hash */
|
726 |
0, /*tp_hash */
|
708 |
0, /*tp_call*/
|
727 |
0, /*tp_call*/
|
709 |
0, /*tp_str*/
|
728 |
0, /*tp_str*/
|
710 |
0, /*tp_getattro*/
|
729 |
(getattrofunc)Doc_getattro,/*tp_getattro*/
|
711 |
0, /*tp_setattro*/
|
730 |
0, /*tp_setattro*/
|
712 |
0, /*tp_as_buffer*/
|
731 |
0, /*tp_as_buffer*/
|
713 |
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
732 |
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
714 |
doc_DocObject, /* tp_doc */
|
733 |
doc_DocObject, /* tp_doc */
|
715 |
0, /* tp_traverse */
|
734 |
0, /* tp_traverse */
|
|
... |
|
... |
766 |
static void
|
785 |
static void
|
767 |
Query_dealloc(recoll_QueryObject *self)
|
786 |
Query_dealloc(recoll_QueryObject *self)
|
768 |
{
|
787 |
{
|
769 |
LOGDEB(("Query_dealloc\n"));
|
788 |
LOGDEB(("Query_dealloc\n"));
|
770 |
Query_close(self);
|
789 |
Query_close(self);
|
771 |
self->ob_type->tp_free((PyObject*)self);
|
790 |
Py_TYPE(self)->tp_free((PyObject*)self);
|
772 |
}
|
791 |
}
|
773 |
|
792 |
|
774 |
static PyObject *
|
793 |
static PyObject *
|
775 |
Query_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
794 |
Query_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
776 |
{
|
795 |
{
|
|
... |
|
... |
1116 |
if (res == 0)
|
1135 |
if (res == 0)
|
1117 |
return "<span class=\"rclmatch\">";
|
1136 |
return "<span class=\"rclmatch\">";
|
1118 |
PyObject *res1 = res;
|
1137 |
PyObject *res1 = res;
|
1119 |
if (PyUnicode_Check(res))
|
1138 |
if (PyUnicode_Check(res))
|
1120 |
res1 = PyUnicode_AsUTF8String(res);
|
1139 |
res1 = PyUnicode_AsUTF8String(res);
|
1121 |
return PyString_AsString(res1);
|
1140 |
return PyBytes_AsString(res1);
|
1122 |
}
|
1141 |
}
|
1123 |
|
1142 |
|
1124 |
virtual string endMatch()
|
1143 |
virtual string endMatch()
|
1125 |
{
|
1144 |
{
|
1126 |
PyObject *res = 0;
|
1145 |
PyObject *res = 0;
|
|
... |
|
... |
1129 |
if (res == 0)
|
1148 |
if (res == 0)
|
1130 |
return "</span>";
|
1149 |
return "</span>";
|
1131 |
PyObject *res1 = res;
|
1150 |
PyObject *res1 = res;
|
1132 |
if (PyUnicode_Check(res))
|
1151 |
if (PyUnicode_Check(res))
|
1133 |
res1 = PyUnicode_AsUTF8String(res);
|
1152 |
res1 = PyUnicode_AsUTF8String(res);
|
1134 |
return PyString_AsString(res1);
|
1153 |
return PyBytes_AsString(res1);
|
1135 |
}
|
1154 |
}
|
1136 |
|
1155 |
|
1137 |
PyObject *m_methods;
|
1156 |
PyObject *m_methods;
|
1138 |
};
|
1157 |
};
|
1139 |
|
1158 |
|
|
... |
|
... |
1391 |
PyDoc_STRVAR(doc_QueryObject,
|
1410 |
PyDoc_STRVAR(doc_QueryObject,
|
1392 |
"Recoll Query objects are used to execute index searches. \n"
|
1411 |
"Recoll Query objects are used to execute index searches. \n"
|
1393 |
"They must be created by the Db.query() method.\n"
|
1412 |
"They must be created by the Db.query() method.\n"
|
1394 |
);
|
1413 |
);
|
1395 |
static PyTypeObject recoll_QueryType = {
|
1414 |
static PyTypeObject recoll_QueryType = {
|
1396 |
PyObject_HEAD_INIT(NULL)
|
1415 |
PyVarObject_HEAD_INIT(NULL, 0)
|
1397 |
0, /*ob_size*/
|
|
|
1398 |
"recoll.Query", /*tp_name*/
|
1416 |
"recoll.Query", /*tp_name*/
|
1399 |
sizeof(recoll_QueryObject), /*tp_basicsize*/
|
1417 |
sizeof(recoll_QueryObject), /*tp_basicsize*/
|
1400 |
0, /*tp_itemsize*/
|
1418 |
0, /*tp_itemsize*/
|
1401 |
(destructor)Query_dealloc, /*tp_dealloc*/
|
1419 |
(destructor)Query_dealloc, /*tp_dealloc*/
|
1402 |
0, /*tp_print*/
|
1420 |
0, /*tp_print*/
|
|
... |
|
... |
1456 |
static void
|
1474 |
static void
|
1457 |
Db_dealloc(recoll_DbObject *self)
|
1475 |
Db_dealloc(recoll_DbObject *self)
|
1458 |
{
|
1476 |
{
|
1459 |
LOGDEB(("Db_dealloc\n"));
|
1477 |
LOGDEB(("Db_dealloc\n"));
|
1460 |
Db_close(self);
|
1478 |
Db_close(self);
|
1461 |
self->ob_type->tp_free((PyObject*)self);
|
1479 |
Py_TYPE(self)->tp_free((PyObject*)self);
|
1462 |
}
|
1480 |
}
|
1463 |
|
1481 |
|
1464 |
static PyObject *
|
1482 |
static PyObject *
|
1465 |
Db_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
1483 |
Db_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
1466 |
{
|
1484 |
{
|
|
... |
|
... |
1528 |
deleteZ(self->db);
|
1546 |
deleteZ(self->db);
|
1529 |
return -1;
|
1547 |
return -1;
|
1530 |
}
|
1548 |
}
|
1531 |
for (int i = 0; i < dbcnt; i++) {
|
1549 |
for (int i = 0; i < dbcnt; i++) {
|
1532 |
PyObject *item = PySequence_GetItem(extradbs, i);
|
1550 |
PyObject *item = PySequence_GetItem(extradbs, i);
|
1533 |
char *s = PyString_AsString(item);
|
1551 |
char *s = PyBytes_AsString(item);
|
1534 |
Py_DECREF(item);
|
1552 |
Py_DECREF(item);
|
1535 |
if (!s) {
|
1553 |
if (!s) {
|
1536 |
PyErr_SetString(PyExc_TypeError,
|
1554 |
PyErr_SetString(PyExc_TypeError,
|
1537 |
"extra_dbs must contain strings");
|
1555 |
"extra_dbs must contain strings");
|
1538 |
deleteZ(self->db);
|
1556 |
deleteZ(self->db);
|
|
... |
|
... |
1855 |
" $RECOLL_CONFDIR or ~/.recoll).\n"
|
1873 |
" $RECOLL_CONFDIR or ~/.recoll).\n"
|
1856 |
"extra_dbs is a list of external databases (xapian directories)\n"
|
1874 |
"extra_dbs is a list of external databases (xapian directories)\n"
|
1857 |
"writable decides if we can index new data through this connection\n"
|
1875 |
"writable decides if we can index new data through this connection\n"
|
1858 |
);
|
1876 |
);
|
1859 |
static PyTypeObject recoll_DbType = {
|
1877 |
static PyTypeObject recoll_DbType = {
|
1860 |
PyObject_HEAD_INIT(NULL)
|
1878 |
PyVarObject_HEAD_INIT(NULL, 0)
|
1861 |
0, /*ob_size*/
|
|
|
1862 |
"recoll.Db", /*tp_name*/
|
1879 |
"recoll.Db", /*tp_name*/
|
1863 |
sizeof(recoll_DbObject), /*tp_basicsize*/
|
1880 |
sizeof(recoll_DbObject), /*tp_basicsize*/
|
1864 |
0, /*tp_itemsize*/
|
1881 |
0, /*tp_itemsize*/
|
1865 |
(destructor)Db_dealloc, /*tp_dealloc*/
|
1882 |
(destructor)Db_dealloc, /*tp_dealloc*/
|
1866 |
0, /*tp_print*/
|
1883 |
0, /*tp_print*/
|
|
... |
|
... |
1918 |
"(the default is built like for any Recoll program).\n"
|
1935 |
"(the default is built like for any Recoll program).\n"
|
1919 |
"extra_dbs is a list of external databases (xapian directories)\n"
|
1936 |
"extra_dbs is a list of external databases (xapian directories)\n"
|
1920 |
"writable decides if we can index new data through this connection\n"
|
1937 |
"writable decides if we can index new data through this connection\n"
|
1921 |
);
|
1938 |
);
|
1922 |
|
1939 |
|
1923 |
static PyMethodDef recollMethods[] = {
|
1940 |
static PyMethodDef recoll_methods[] = {
|
1924 |
{"connect", (PyCFunction)recoll_connect, METH_VARARGS|METH_KEYWORDS,
|
1941 |
{"connect", (PyCFunction)recoll_connect, METH_VARARGS|METH_KEYWORDS,
|
1925 |
doc_connect},
|
1942 |
doc_connect},
|
1926 |
|
1943 |
|
1927 |
{NULL, NULL, 0, NULL} /* Sentinel */
|
1944 |
{NULL, NULL, 0, NULL} /* Sentinel */
|
1928 |
};
|
1945 |
};
|
1929 |
|
1946 |
|
1930 |
|
1947 |
|
1931 |
PyDoc_STRVAR(pyrecoll_doc_string,
|
1948 |
PyDoc_STRVAR(pyrecoll_doc_string,
|
1932 |
"This is an interface to the Recoll full text indexer.");
|
1949 |
"This is an interface to the Recoll full text indexer.");
|
1933 |
|
1950 |
|
1934 |
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
|
1951 |
struct module_state {
|
1935 |
#define PyMODINIT_FUNC void
|
1952 |
PyObject *error;
|
|
|
1953 |
};
|
|
|
1954 |
|
|
|
1955 |
#if PY_MAJOR_VERSION >= 3
|
|
|
1956 |
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
|
|
|
1957 |
#else
|
|
|
1958 |
#define GETSTATE(m) (&_state)
|
|
|
1959 |
static struct module_state _state;
|
1936 |
#endif
|
1960 |
#endif
|
|
|
1961 |
|
|
|
1962 |
#if PY_MAJOR_VERSION >= 3
|
|
|
1963 |
static int recoll_traverse(PyObject *m, visitproc visit, void *arg) {
|
|
|
1964 |
Py_VISIT(GETSTATE(m)->error);
|
|
|
1965 |
return 0;
|
|
|
1966 |
}
|
|
|
1967 |
|
|
|
1968 |
static int recoll_clear(PyObject *m) {
|
|
|
1969 |
Py_CLEAR(GETSTATE(m)->error);
|
|
|
1970 |
return 0;
|
|
|
1971 |
}
|
|
|
1972 |
|
|
|
1973 |
static struct PyModuleDef moduledef = {
|
|
|
1974 |
PyModuleDef_HEAD_INIT,
|
|
|
1975 |
"recoll",
|
|
|
1976 |
NULL,
|
|
|
1977 |
sizeof(struct module_state),
|
|
|
1978 |
recoll_methods,
|
|
|
1979 |
NULL,
|
|
|
1980 |
recoll_traverse,
|
|
|
1981 |
recoll_clear,
|
|
|
1982 |
NULL
|
|
|
1983 |
};
|
|
|
1984 |
|
|
|
1985 |
#define INITERROR return NULL
|
|
|
1986 |
|
|
|
1987 |
extern "C" PyObject *
|
|
|
1988 |
PyInit_recoll(void)
|
|
|
1989 |
|
|
|
1990 |
#else
|
|
|
1991 |
#define INITERROR return
|
|
|
1992 |
|
1937 |
PyMODINIT_FUNC
|
1993 |
PyMODINIT_FUNC
|
1938 |
initrecoll(void)
|
1994 |
initrecoll(void)
|
|
|
1995 |
#endif
|
1939 |
{
|
1996 |
{
|
1940 |
// Note: we can't call recollinit here, because the confdir is only really
|
1997 |
// Note: we can't call recollinit here, because the confdir is only really
|
1941 |
// known when the first db object is created (it is an optional parameter).
|
1998 |
// known when the first db object is created (it is an optional parameter).
|
1942 |
// Using a default here may end up with variables such as stripchars being
|
1999 |
// Using a default here may end up with variables such as stripchars being
|
1943 |
// wrong
|
2000 |
// wrong
|
1944 |
|
2001 |
|
1945 |
PyObject* m;
|
2002 |
#if PY_MAJOR_VERSION >= 3
|
1946 |
m = Py_InitModule3("recoll", recollMethods, "Recoll extension module.");
|
2003 |
PyObject *module = PyModule_Create(&moduledef);
|
|
|
2004 |
#else
|
|
|
2005 |
PyObject *module = Py_InitModule("recoll", recoll_methods);
|
|
|
2006 |
#endif
|
|
|
2007 |
if (module == NULL)
|
|
|
2008 |
INITERROR;
|
|
|
2009 |
|
|
|
2010 |
struct module_state *st = GETSTATE(module);
|
|
|
2011 |
// The first parameter is a char *. Hopefully we don't initialize
|
|
|
2012 |
// modules too often...
|
|
|
2013 |
st->error = PyErr_NewException(strdup("recoll.Error"), NULL, NULL);
|
|
|
2014 |
if (st->error == NULL) {
|
|
|
2015 |
Py_DECREF(module);
|
|
|
2016 |
INITERROR;
|
|
|
2017 |
}
|
1947 |
|
2018 |
|
1948 |
if (PyType_Ready(&recoll_DbType) < 0)
|
2019 |
if (PyType_Ready(&recoll_DbType) < 0)
|
1949 |
return;
|
2020 |
INITERROR;
|
1950 |
Py_INCREF((PyObject*)&recoll_DbType);
|
2021 |
Py_INCREF((PyObject*)&recoll_DbType);
|
1951 |
PyModule_AddObject(m, "Db", (PyObject *)&recoll_DbType);
|
2022 |
PyModule_AddObject(module, "Db", (PyObject *)&recoll_DbType);
|
1952 |
|
2023 |
|
1953 |
if (PyType_Ready(&recoll_QueryType) < 0)
|
2024 |
if (PyType_Ready(&recoll_QueryType) < 0)
|
1954 |
return;
|
2025 |
INITERROR;
|
1955 |
Py_INCREF((PyObject*)&recoll_QueryType);
|
2026 |
Py_INCREF((PyObject*)&recoll_QueryType);
|
1956 |
PyModule_AddObject(m, "Query", (PyObject *)&recoll_QueryType);
|
2027 |
PyModule_AddObject(module, "Query", (PyObject *)&recoll_QueryType);
|
1957 |
|
2028 |
|
1958 |
if (PyType_Ready(&recoll_DocType) < 0)
|
2029 |
if (PyType_Ready(&recoll_DocType) < 0)
|
1959 |
return;
|
2030 |
INITERROR;
|
1960 |
Py_INCREF((PyObject*)&recoll_DocType);
|
2031 |
Py_INCREF((PyObject*)&recoll_DocType);
|
1961 |
PyModule_AddObject(m, "Doc", (PyObject *)&recoll_DocType);
|
2032 |
PyModule_AddObject(module, "Doc", (PyObject *)&recoll_DocType);
|
1962 |
|
2033 |
|
1963 |
if (PyType_Ready(&recoll_SearchDataType) < 0)
|
2034 |
if (PyType_Ready(&recoll_SearchDataType) < 0)
|
1964 |
return;
|
2035 |
INITERROR;
|
1965 |
Py_INCREF((PyObject*)&recoll_SearchDataType);
|
2036 |
Py_INCREF((PyObject*)&recoll_SearchDataType);
|
1966 |
PyModule_AddObject(m, "SearchData", (PyObject *)&recoll_SearchDataType);
|
2037 |
PyModule_AddObject(module, "SearchData",
|
|
|
2038 |
(PyObject *)&recoll_SearchDataType);
|
1967 |
PyModule_AddStringConstant(m, "__doc__",
|
2039 |
PyModule_AddStringConstant(module, "__doc__",
|
1968 |
pyrecoll_doc_string);
|
2040 |
pyrecoll_doc_string);
|
1969 |
|
2041 |
|
1970 |
PyObject *doctypecobject;
|
2042 |
PyObject *doctypecobject;
|
1971 |
|
2043 |
|
1972 |
#if PY_MAJOR_VERSION >= 2 && PY_MINOR_VERSION >= 7
|
2044 |
#if PY_MAJOR_VERSION >= 3 || (PY_MAJOR_VERSION >= 2 && PY_MINOR_VERSION >= 7)
|
1973 |
// Export a few pointers for the benefit of other recoll python modules
|
2045 |
// Export a few pointers for the benefit of other recoll python modules
|
1974 |
doctypecobject=
|
2046 |
doctypecobject=
|
1975 |
PyCapsule_New(&recoll_DocType, PYRECOLL_PACKAGE "recoll.doctypeptr", 0);
|
2047 |
PyCapsule_New(&recoll_DocType, PYRECOLL_PACKAGE "recoll.doctypeptr", 0);
|
1976 |
#else
|
2048 |
#else
|
1977 |
doctypecobject = PyCObject_FromVoidPtr(&recoll_DocType, NULL);
|
2049 |
doctypecobject = PyCObject_FromVoidPtr(&recoll_DocType, NULL);
|
1978 |
#endif
|
2050 |
#endif
|
|
|
2051 |
|
1979 |
PyModule_AddObject(m, "doctypeptr", doctypecobject);
|
2052 |
PyModule_AddObject(module, "doctypeptr", doctypecobject);
|
|
|
2053 |
|
|
|
2054 |
#if PY_MAJOR_VERSION >= 3
|
|
|
2055 |
return module;
|
|
|
2056 |
#endif
|
1980 |
}
|
2057 |
}
|