/* teamtrack-module.cpp -- Python extension interfacing to TeamTrack Gareth Rees, Ravenbrook Limited, 2000-08-02 $Id: //info.ravenbrook.com/project/p4dti/branch/2000-09-05/interface-debugging/python-teamtrack-interface/teamtrack-module.cpp#1 $ */ #include "teamtrack-module.h" #include "teamtrack-server.h" #include "TSServer.h" #include "da.h" /* Debugging allocator -- GDR 2000-09-01 */ /* Objects representing Python exceptions. They are assigned in initteamtrack(). */ /* teamtrack_error represents errors that represents errors generated by this interface module. In Python it's called teamtrack.error. */ PyObject *teamtrack_error; /* teamtrack_tsapi_error represents errors generated by the TeamShare API. In Python it's called teamtrack.tsapi_error. */ static PyObject *teamtrack_tsapi_error; /* teamtrack_set_error(server) sets the current Python error to the most recent TeamTrack error for the given TeamShare server. */ void teamtrack_set_error(TSServer *server) { char *error_name; switch(TSGetLastError()) { case TS_ERROR: error_name = "ERROR"; break; case TS_INVALID_DATA_TYPE: error_name = "INVALID_DATA_TYPE"; break; case TS_NO_PERMISSION: error_name = "NO_PERMISSION"; break; case TS_NO_SUCH_FIELD: error_name = "NO_SUCH_FIELD"; break; case TS_MEMORY_ERROR: error_name = "MEMORY_ERROR"; break; case TS_SOCKET_READ_ERROR: error_name = "SOCKET_READ_ERROR"; break; case TS_SOCKET_WRITE_ERROR: error_name = "SOCKET_WRITE_ERROR"; break; case TS_SOCKET_CONNECT_FAILED: error_name = "SOCKET_CONNECT_FAILED"; break; case TS_SOCKET_CREATE_FAILED: error_name = "SOCKET_CREATE_FAILED"; break; case TS_INVALID_DATATYPE: error_name = "INVALID_DATATYPE"; break; case TS_INVALID_USER: error_name = "INVALID_USER"; break; case TS_NO_RESULTS: error_name = "NO_RESULTS"; break; case TS_SERVER_ERROR: error_name = "SERVER_ERROR"; break; case TS_INVALID_VERSION: error_name = "INVALID_VERSION"; break; default: error_name = "(unknown)"; break; } PyObject *separator = PyString_FromString(": "); const char *ts_message = server->GetLastErrorMessage(); PyObject *error_message; if (ts_message) { error_message = PyString_FromString(ts_message); } else { error_message = PyString_FromString("(no message from the TeamShare API)"); } PyObject *message = PyString_FromString(error_name); PyString_ConcatAndDel(&message, separator); PyString_ConcatAndDel(&message, error_message); PyErr_SetObject(teamtrack_tsapi_error, message); Py_XDECREF(message); /* Owned by Python's exception handler. */ } /* teamtrack.connect(user,password,hostname) connects to a TeamShare server on hostname with the given user and password and returns an object representing that server. */ static PyObject * teamtrack_connect(PyObject *self, PyObject *args) { char *user; char *password; char *hostname; if (!PyArg_ParseTuple(args, "sss", &user, &password, &hostname)) return 0; TSServer *s = new TSServer; if (!s) return 0; if (s->Connect(user, password, hostname) != TS_OK) { teamtrack_set_error(s); delete s; return 0; } return teamtrack_server_new(s, 1); } static PyMethodDef teamtrack_methods[] = { { "connect", teamtrack_connect, METH_VARARGS }, { NULL, NULL } /* End of methods. */ }; /* teamtrack_tables[] is used to initialize the teamtrack.tables dictionary that maps table name to table id. The table identifiers appear in TSDef.h. */ static struct { char *name; int id; } teamtrack_tables[] = { { "CASES", TS_TBLID_CASES }, { "CHANGES", TS_TBLID_CHANGES }, { "FIELDS", TS_TBLID_FIELDS }, { "GROUPS", TS_TBLID_GROUPS }, { "LICENSES", TS_TBLID_LICENSES }, { "MEMBERS", TS_TBLID_MEMBERS }, { "PRIVILEGES", TS_TBLID_PRIVILEGES }, { "PROJECTS", TS_TBLID_PROJECTS }, { "PROJECTSELECTIONS", TS_TBLID_PROJECTSELECTIONS }, { "PROPERTIES", TS_TBLID_PROPERTIES }, { "REPORTS", TS_TBLID_REPORTS }, { "SELECTIONS", TS_TBLID_SELECTIONS }, { "STATES", TS_TBLID_STATES }, { "TRANSISSUETYPES", TS_TBLID_TRANSISSUETYPES }, { "SYSTEMINFO", TS_TBLID_SYSTEMINFO }, { "TRANSITIONS", TS_TBLID_TRANSITIONS }, { "USERS", TS_TBLID_USERS }, { "TABLES", TS_TBLID_TABLES }, { "ATTACHMENTS", TS_TBLID_ATTACHMENTS }, { "FOLDERS", TS_TBLID_FOLDERS }, { "FOLDERITEMS", TS_TBLID_FOLDERITEMS }, { "FOLDERCOLUMNS", TS_TBLID_FOLDERCOLUMNS }, { "VCACTIONS", TS_TBLID_VCACTIONS }, { "PROJECTTRANSITIONS", TS_TBLID_PROJECTTRANSITIONS }, { "NOTIFICATIONS", TS_TBLID_NOTIFICATIONS }, { "NOTIFICATIONRULES", TS_TBLID_NOTIFICATIONRULES }, { "NOTIFICATIONCONDITIONS", TS_TBLID_NOTIFICATIONCONDITIONS }, { "NOTIFICATIONEVENTS", TS_TBLID_NOTIFICATIONEVENTS }, { "NOTIFICATIONFIELDS", TS_TBLID_NOTIFICATIONFIELDS }, { "NOTIFICATIONMESSAGES", TS_TBLID_NOTIFICATIONMESSAGES }, { "NOTIFICATIONPERMISSIONS", TS_TBLID_NOTIFICATIONPERMISSIONS }, { "NOTIFICATIONSUBSCRIPTIONS", TS_TBLID_NOTIFICATIONSUBSCRIPTIONS }, { "MACROS", TS_TBLID_MACROS }, { "WORKFLOWS", TS_TBLID_WORKFLOWS }, { "FIELDORDERINGS", TS_TBLID_FIELDORDERINGS }, { "INCIDENTS", TS_TBLID_INCIDENTS }, { "COMPANIES", TS_TBLID_COMPANIES }, { "CONTACTS", TS_TBLID_CONTACTS }, { "MERCHANDISE", TS_TBLID_MERCHANDISE }, { "SERVICEAGREEMENTS", TS_TBLID_SERVICEAGREEMENTS }, { "PROBLEMS", TS_TBLID_PROBLEMS }, { "RESOLUTIONS", TS_TBLID_RESOLUTIONS }, { "PRODUCTS", TS_TBLID_PRODUCTS }, { "KEYWORDS", TS_TBLID_KEYWORDS }, { "PRODUCTUSAGES", TS_TBLID_PRODUCTUSAGES }, { "KEYWORDUSAGES", TS_TBLID_KEYWORDUSAGES }, { "TRANSTRIGGERS", TS_TBLID_TRANSTRIGGERS }, { "TRANSTRIGGERSTATES", TS_TBLID_TRANSTRIGGERSTATES }, { "TRANSTRIGGERTRANSITIONS", TS_TBLID_TRANSTRIGGERTRANSITIONS }, }; extern "C" void TEAMTRACK_EXPORTED initteamtrack() { /* Create the "teamtrack" module. */ PyObject *m = Py_InitModule("teamtrack", teamtrack_methods); PyObject *d = PyModule_GetDict(m); /* Create an object to represent TeamTrack errors (a string with the value "TeamShare API error") and give it the Python name "teamtrack.error". */ teamtrack_error = PyString_FromString("TeamTrack interface error"); PyDict_SetItemString(d, "error", teamtrack_error); /* Don't decref teamtrack_error since we continue to own it through a global variable. */ /* Create an object to represent TeamTrack errors (a string with the value "TeamTrack error") and give it the Python name "teamtrack.error". */ teamtrack_tsapi_error = PyString_FromString("TeamShare API error"); PyDict_SetItemString(d, "tsapi_error", teamtrack_tsapi_error); /* Don't decref teamtrack_tsapi_error since we continue to own it through a global variable. */ /* Create the dictionary teamtrack.tables which maps table name to table id. */ PyObject *tables = PyDict_New(); PyDict_SetItemString(d, "tables", tables); for (int i = 0; i < sizeof(teamtrack_tables)/sizeof(teamtrack_tables[0]); ++i) { PyObject *id = PyInt_FromLong((long)teamtrack_tables[i].id); PyDict_SetItemString(tables, teamtrack_tables[i].name, id); Py_XDECREF(id); /* Owned by teamtrack.tables. */ } Py_XDECREF(tables); /* Owned by the teamtrack module. */ /* Check for errors that occurred during module initialization. */ if (PyErr_Occurred()) { Py_FatalError("Can't initialise teamtrack module."); } #if defined(WIN32) if (TSInitializeWinsock() != TS_OK) { Py_FatalError("Can't initialise Winsock."); } #endif /* defined(WIN32) */ }