summaryrefslogtreecommitdiff
path: root/server/src/praxisd.cc
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/praxisd.cc')
-rw-r--r--server/src/praxisd.cc317
1 files changed, 317 insertions, 0 deletions
diff --git a/server/src/praxisd.cc b/server/src/praxisd.cc
new file mode 100644
index 0000000..b4b0a88
--- /dev/null
+++ b/server/src/praxisd.cc
@@ -0,0 +1,317 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * praxisd.cc
+ *
+ * Tue Apr 19 09:00:29 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Pracro.
+ *
+ * Pracro is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Pracro is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Pracro; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "praxisd.h"
+
+static std::string strtime(bool with_sec = true)
+{
+ std::string ret;
+
+ time_t epoch = time(NULL);
+ struct tm t;
+ localtime_r(&epoch, &t);
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%04d-%02d-%02d",
+ t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
+ ret = buf;
+
+ if(with_sec) {
+ snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
+ t.tm_hour, t.tm_min, t.tm_sec);
+ ret += " ";
+ ret += buf;
+ }
+
+ return ret;
+}
+
+static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
+{
+ std::string *str = (std::string*)userp;
+ str->append((char*)buffer, size * nmemb);
+ return size * nmemb;
+}
+
+Praxisd::Praxisd(std::string h, int port)
+{
+ ch = curl_easy_init();
+ host = h;
+
+ curl_easy_setopt(ch, CURLOPT_PORT, port);
+ curl_easy_setopt(ch, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt(ch, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt(ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt(ch, CURLOPT_CONNECTTIMEOUT, 15L);
+ curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_setopt(ch, CURLOPT_USERAGENT, "libpraxisd");
+ curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, write_data);
+ curl_easy_setopt(ch, CURLOPT_FILETIME, 1L);
+ curl_easy_setopt(ch, CURLOPT_HEADER, 0L);
+}
+
+Praxisd::~Praxisd()
+{
+ curl_easy_cleanup(ch);
+}
+
+// Get Journal By CPR
+std::string Praxisd::journal_get_by_cpr(std::string cpr)
+{
+ std::string journal;
+
+ std::string uri = host + "/praxisd/1.0/journal/get_by_cpr?cpr=" + cpr;
+ curl_easy_setopt(ch, CURLOPT_URL, uri.c_str());
+
+ curl_easy_setopt(ch, CURLOPT_POST, 0L);
+ curl_easy_setopt(ch, CURLOPT_WRITEDATA, &journal);
+
+ CURLcode errornum = curl_easy_perform(ch);
+ if(errornum != CURLE_OK) {
+ printf("Ouch %d\n", errornum);
+ }
+
+ time_t time;
+ errornum = curl_easy_getinfo(ch, CURLINFO_FILETIME, &time);
+
+ return journal;
+}
+
+time_t Praxisd::journal_last_changed(std::string cpr)
+{
+ std::string journal;
+
+ std::string uri = host + "/praxisd/1.0/journal/get_by_cpr?cpr=" + cpr;
+ curl_easy_setopt(ch, CURLOPT_URL, uri.c_str());
+
+ curl_easy_setopt(ch, CURLOPT_POST, 0L);
+ curl_easy_setopt(ch, CURLOPT_WRITEDATA, &journal);
+
+ CURLcode errornum = curl_easy_perform(ch);
+ if(errornum != CURLE_OK) {
+ printf("Ouch %d\n", errornum);
+ }
+
+ time_t time;
+ errornum = curl_easy_getinfo(ch, CURLINFO_FILETIME, &time);
+
+ return time;
+}
+
+
+void Praxisd::journal_add(std::string cpr, std::string entry)
+{
+ std::string xml;
+ xml += "<praxisd version=\"1.0\">\n";
+ xml += " <journal cpr=\""+cpr+"\">"+entry+"</journal>\n";
+ xml += "</praxisd>\n";
+
+ curl_easy_setopt(ch, CURLOPT_POSTFIELDSIZE, (long)xml.length());
+ curl_easy_setopt(ch, CURLOPT_POSTFIELDS, xml.c_str());
+ curl_easy_setopt(ch, CURLOPT_POST, 1L);
+
+ struct curl_slist *slist = NULL;
+ // Unset 'Expect' header, set by CURLOPT_POSTFIELDS
+ slist = curl_slist_append(slist, "Expect:");
+ slist = curl_slist_append(slist, "Content-Type: text/xml");
+ slist = curl_slist_append(slist, "Connection: keep-alive");
+ curl_easy_setopt(ch, CURLOPT_HTTPHEADER, slist);
+
+ std::string uri = host + "/praxisd/1.0/journal/add";
+ curl_easy_setopt(ch, CURLOPT_URL, uri.c_str());
+
+ std::string reply;
+ curl_easy_setopt(ch, CURLOPT_WRITEDATA, &reply);
+
+ CURLcode errornum = curl_easy_perform(ch);
+ if(errornum != CURLE_OK) {
+ printf("Ouch: %d %s\n", errornum, reply.c_str());
+ }
+}
+
+void Praxisd::add_sogeord(std::string cpr, std::string sogeord,
+ std::string sogetxt)
+{
+
+ std::string datestr = strtime(false);
+
+ std::string xml;
+ xml += "<praxisd version=\"1.0\">\n";
+ xml += " <addsogeord cpr=\""+cpr+"\">\n";
+ xml += " <sogeord sogenr=\""+sogeord+"\" date=\""+datestr+"\">"+
+ sogetxt+"</sogeord>\n";
+ xml += " </addsogeord>\n";
+ xml += "</praxisd>\n";
+
+ curl_easy_setopt(ch, CURLOPT_POSTFIELDSIZE, (long)xml.length());
+ curl_easy_setopt(ch, CURLOPT_POSTFIELDS, xml.c_str());
+ curl_easy_setopt(ch, CURLOPT_POST, 1L);
+
+ struct curl_slist *slist = NULL;
+ // Unset 'Expect' header, set by CURLOPT_POSTFIELDS
+ slist = curl_slist_append(slist, "Expect:");
+ slist = curl_slist_append(slist, "Content-Type: text/xml");
+ slist = curl_slist_append(slist, "Connection: keep-alive");
+ curl_easy_setopt(ch, CURLOPT_HTTPHEADER, slist);
+
+ std::string uri = host + "/praxisd/1.0/patient/add_sogeord";
+ curl_easy_setopt(ch, CURLOPT_URL, uri.c_str());
+
+ std::string reply;
+ curl_easy_setopt(ch, CURLOPT_WRITEDATA, &reply);
+
+ CURLcode errornum = curl_easy_perform(ch);
+ if(errornum != CURLE_OK) {
+ printf("Ouch: %d %s\n", errornum, reply.c_str());
+ }
+}
+
+#define DOTAG(x) if(name == #x) str = &p.x;
+#include "saxparser.h"
+class PatientParser : public SAXParser {
+public:
+ PatientParser(Praxisd::patient_t &_p) : p(_p) { str = NULL; }
+
+ void characterData(std::string &data)
+ {
+ if(str) *str += data;
+ }
+
+ void startTag(std::string name, std::map<std::string, std::string> attr)
+ {
+ DOTAG(fornavne);
+ DOTAG(efternavn);
+ DOTAG(stilling);
+ DOTAG(gade);
+ DOTAG(by);
+ DOTAG(telefonnumre);
+ DOTAG(sikringsgr);
+ DOTAG(amtsnr);
+ DOTAG(sygekontor);
+ DOTAG(henvnr);
+ DOTAG(frilinie1);
+ DOTAG(frilinie2);
+ DOTAG(frilinie3);
+ DOTAG(frilinie4);
+ DOTAG(frilinie5);
+ DOTAG(ydernr);
+ DOTAG(created);
+ DOTAG(donottouch);
+ DOTAG(visus);
+ DOTAG(labkort);
+ DOTAG(medkort);
+ DOTAG(jlock);
+ DOTAG(unknown1);
+ DOTAG(henvdato);
+ DOTAG(aarhund);
+ DOTAG(fakturadato);
+ DOTAG(fakturabelob);
+ DOTAG(betaldato);
+ DOTAG(betalbelob);
+ DOTAG(jdato);
+ DOTAG(unknown250);
+ DOTAG(unknown251);
+ DOTAG(jtime);
+ if(name == "sogeords") {} // do nothing
+ if(name == "sogeord") {
+ Praxisd::sogeord_t s;
+ if(attr.find("sogenr") != attr.end()) s.sogenr = attr["sogenr"];
+ if(attr.find("sogedatpo") != attr.end()) s.sogedato = attr["sogedato"];
+ p.sogeord.push_back(s);
+ str = &p.sogeord[p.sogeord.size() - 1].sogetxt;
+ }
+ }
+
+ void endTag(std::string name)
+ {
+ str = NULL;
+ }
+
+private:
+ std::string *str;
+ Praxisd::patient_t &p;
+};
+
+Praxisd::patient_t Praxisd::patient_get_by_cpr(std::string cpr)
+{
+ patient_t p;
+
+ std::string xml;
+
+ std::string uri = host + "/praxisd/1.0/patient/get_by_cpr?cpr=" + cpr;
+ curl_easy_setopt(ch, CURLOPT_URL, uri.c_str());
+
+ curl_easy_setopt(ch, CURLOPT_POST, 0L);
+ curl_easy_setopt(ch, CURLOPT_WRITEDATA, &xml);
+
+ CURLcode errornum = curl_easy_perform(ch);
+ if(errornum != CURLE_OK) {
+ printf("Ouch %d\n", errornum);
+ }
+
+ PatientParser parser(p);
+ parser.parse(xml.data(), xml.length());
+
+ return p;
+}
+
+#ifdef TEST_PRAXISD
+//deps: saxparser.cc debug.cc log.cc
+//cflags: $(CURL_CFLAGS) $(EXPAT_CFLAGS) -I..
+//libs: $(CURL_LIBS) $(EXPAT_LIBS)
+#include "test.h"
+
+#define NL "\r\n"
+#define CPR "1505050505"
+
+TEST_BEGIN;
+
+Praxisd p("http://localhost", 10000);
+
+std::string j = p.journal_get_by_cpr(CPR);
+TEST_NOTEQUAL(j, "", "Did we get a journal?");
+
+std::string more = "less is more... much much more.";
+p.journal_add(CPR, more);
+
+time_t changed = p.journal_last_changed(CPR);
+TEST_EQUAL_INT(changed, time(NULL), "Changed just now?");
+
+Praxisd::patient_t patient = p.patient_get_by_cpr(CPR);
+TEST_EQUAL_STR(patient.fornavne, "Kristian", "Who are you?");
+
+/*
+std::string exp = j + more + NL;
+std::string j2 = p.journal_get_by_cpr(CPR);
+TEST_EQUAL_INT(exp.length(), j2.length(), "Compare lengths");
+TEST_EQUAL_STR(exp, j2, "Did we correctly append to the journal?");
+*/
+
+p.add_sogeord(CPR, "CA0003", "Nolder");
+
+TEST_END;
+
+#endif/*TEST_PRAXISD*/