From eb91a2967ed18aa24166f13a635091e2193aecc0 Mon Sep 17 00:00:00 2001 From: deva Date: Mon, 25 Apr 2011 06:27:08 +0000 Subject: Initial version of praxisd communications class. --- server/src/praxisd.cc | 317 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 server/src/praxisd.cc (limited to 'server/src/praxisd.cc') 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 += "\n"; + xml += " "+entry+"\n"; + xml += "\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 += "\n"; + xml += " \n"; + xml += " "+ + sogetxt+"\n"; + xml += " \n"; + xml += "\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 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*/ -- cgit v1.2.3