</table>
If one of the requested events does not exist, it simply does not generate an <tt>Event</tt> block. It is permissible for the server to send an empty <tt>EventData</tt> tag if no data is available for the request.<p>
+
+<h3>Changing/Creating an Event</h3>
+
+The <tt>seteventdata</tt> transaction creates/changes an event. The request data looks like:<p>
+
+<pre>
+<Event id="0" ....>
+ <Title>....
+</Event>
+</pre>
+
+Attributes and tags are the same as for the <tt>geteventdata</tt> response. Except that the <tt>id</tt> attribute may contain the value <tt>"new"</tt> to create a new event, a negative integer is not allowed.<p>
+
+The response contains the ID of the new/changed event if the status is "Ok". In the case of failure the status will be "Error" and an optional reason for the failure may be in the body.
+
+<h2>Room related Transactions</h2>
+
+<h3>Getting Rooms</h3>
+
+The <tt>getroomdata</tt> transaction returns data about rooms in the database. The request data looks like this:<p>
+
+<pre>
+<GetRooms detail="basic">
+ <Room>ID of room</Room>
+ ...
+</GetRooms>
+</pre>
+
+The <tt>detail</tt> attribute may be "basic" or "full". If no <tT><Room></tt> tags are present all rooms are returned.<p>
+
+The response data looks like:<p>
+
+<pre>
+<RoomData>
+ <Room capacity="24">
+ <ID>Room ID</ID>
+ <Description>some encoded HTML text that describes the room</Description>
+ </Room>
+ ...
+</RoomData>
+</pre>
+
+The <tt>capacity</tt> attribute tells how many persons fit into the room. The <tt>ID</tt> tag contains the ID or Name of the room, the optional <tt>Description</tt> tag contains a description of the room - it is only present if full detail has been requested.
+
+<h3>Setting Rooms</h3>
+
+The <tt>setroomdata</tt> transaction is used to create/change one or more rooms, the request data looks like:<p>
+
+<pre>
+<RoomData>
+ <Room capacity="24">
+ <ID>Room ID</ID>
+ <Description>some encoded HTML text that describes the room</Description>
+ </Room>
+ ...
+</RoomData>
+</pre>
+
+The response simply contains the status "Ok" or "Error".
{
req=r;
eventid=id;
+ refresh();
+}
+
+MEvent::MEvent(MWebRequest*r,QDomElement&el)
+{
+ req=r;
m_starttime=QDateTime::currentDateTime().toTime_t();
m_endtime=m_starttime+3600;
m_capacity=10;
m_defaultprice=100;
+ m_valid=false;
+ m_roomid=m_title=m_artist=m_description=m_cancelreason="";
m_valid=true;
- if(id>=0){
+ m_complete=false;
+ bool b;
+ eventid=el.attribute("id","x").toInt(&b);
+ if(!b)eventid=-1;
+ else initFromElement(el);
+}
+
+void MEvent::refresh()
+{
+ m_starttime=QDateTime::currentDateTime().toTime_t();
+ m_endtime=m_starttime+3600;
+ m_capacity=10;
+ m_defaultprice=100;
+ m_valid=false;
+ m_roomid=m_title=m_artist=m_description=m_cancelreason="";
+ m_valid=true;
+ m_complete=false;
+ if(eventid>=0){
//get data from server
- if(!req->request("geteventdata",QString::number(id).toAscii())){
+ if(!req->request("geteventdata",QString::number(eventid).toAscii())){
m_valid=false;
return;
}
bool b;
int eid=el.attribute("id","x").toInt(&b);
if(eid!=eventid || !b)continue;
- //get attribute data
- m_starttime=el.attribute("start","0").toInt();
- m_endtime=el.attribute("end","0").toInt();
- m_capacity=el.attribute("capacity","0").toInt();
- m_defaultprice=el.attribute("defaultprice","0").toInt();
- bool iscancel=el.attribute("cancelled","false")=="true";
- //get title
- QDomNodeList nl2=el.elementsByTagName("Title");
- if(nl2.size()>0){
- QDomElement el2=nl2.at(0).toElement();
- if(!el2.isNull())
- m_title=el2.text();
- }
- //get artist
- nl2=el.elementsByTagName("Artist");
- if(nl2.size()>0){
- QDomElement el2=nl2.at(0).toElement();
- if(!el2.isNull())
- m_artist=el2.text();
- }
- //get description
- nl2=el.elementsByTagName("Description");
- if(nl2.size()>0){
- QDomElement el2=nl2.at(0).toElement();
- if(!el2.isNull())
- m_description=el2.text();
- }
- //get room
- nl2=el.elementsByTagName("Room");
- if(nl2.size()>0){
- QDomElement el2=nl2.at(0).toElement();
- if(!el2.isNull())
- m_roomid=el2.text().trimmed();
- }
- //get cancel reason
- nl2=el.elementsByTagName("CancelReason");
- if(nl2.size()>0){
- QDomElement el2=nl2.at(0).toElement();
- if(!el2.isNull())
- m_cancelreason=el2.text().trimmed();
- }
- if(iscancel){
- if(m_cancelreason=="")m_cancelreason=" ";
- }else{
- m_cancelreason="";
- }
+ initFromElement(el);
}
}
}
+void MEvent::initFromElement(QDomElement&el)
+{
+ //get attribute data
+ m_starttime=el.attribute("start","0").toInt();
+ m_endtime=el.attribute("end","0").toInt();
+ m_capacity=el.attribute("capacity","0").toInt();
+ m_defaultprice=el.attribute("defaultprice","0").toInt();
+ bool iscancel=el.attribute("cancelled","false")=="true";
+ //get title (if element exists this is a complete list, otherwise only preview)
+ QDomNodeList nl2=el.elementsByTagName("Title");
+ if(nl2.size()>0){
+ m_complete=true;
+ QDomElement el2=nl2.at(0).toElement();
+ if(!el2.isNull())
+ m_title=el2.text();
+ }else{
+ //incomplete event, break here
+ m_complete=false;
+ m_title=el.text().trimmed();
+ return;
+ }
+ //get artist
+ nl2=el.elementsByTagName("Artist");
+ if(nl2.size()>0){
+ QDomElement el2=nl2.at(0).toElement();
+ if(!el2.isNull())
+ m_artist=el2.text();
+ }
+ //get description
+ nl2=el.elementsByTagName("Description");
+ if(nl2.size()>0){
+ QDomElement el2=nl2.at(0).toElement();
+ if(!el2.isNull())
+ m_description=el2.text();
+ }
+ //get room
+ nl2=el.elementsByTagName("Room");
+ if(nl2.size()>0){
+ QDomElement el2=nl2.at(0).toElement();
+ if(!el2.isNull())
+ m_roomid=el2.text().trimmed();
+ }
+ //get cancel reason
+ nl2=el.elementsByTagName("CancelReason");
+ if(nl2.size()>0){
+ QDomElement el2=nl2.at(0).toElement();
+ if(!el2.isNull())
+ m_cancelreason=el2.text().trimmed();
+ }
+ if(iscancel){
+ if(m_cancelreason=="")m_cancelreason=" ";
+ }else{
+ m_cancelreason="";
+ }
+}
+
MEvent::~MEvent()
{}
-void MEvent::save()
+QString MEvent::save()
{
+ //do not attempt to save invalid or incomplete data
+ if(!m_valid || !m_complete)return QCoreApplication::translate("MEvent","Event is not complete, cannot save.");
+ //create XML
+ QDomDocument doc;
+ QDomElement root=doc.createElement("Event");
+ if(eventid>=0)root.setAttribute("id",eventid);
+ else root.setAttribute("id","new");
+ root.setAttribute("start",m_starttime);
+ root.setAttribute("end",m_endtime);
+ root.setAttribute("capacity",m_capacity);
+ root.setAttribute("defaultprice",m_defaultprice);
+ root.setAttribute("cancelled",isCancelled()?"true":"false");
+ QDomElement el=doc.createElement("Title");
+ el.appendChild(doc.createTextNode(m_title));
+ root.appendChild(el);
+ el=doc.createElement("Artist");
+ el.appendChild(doc.createTextNode(m_artist));
+ root.appendChild(el);
+ el=doc.createElement("Description");
+ el.appendChild(doc.createTextNode(m_description));
+ root.appendChild(el);
+ el=doc.createElement("Room");
+ el.appendChild(doc.createTextNode(m_roomid));
+ root.appendChild(el);
+ if(isCancelled()){
+ el=doc.createElement("CancelReason");
+ el.appendChild(doc.createTextNode(m_cancelreason));
+ root.appendChild(el);
+ }
+ doc.appendChild(root);
+ //call
+ req->request("seteventdata",doc.toByteArray());
+ //get new ID
+ if(req->responseStatus()==MWebRequest::Ok){
+ QString r=QString::fromAscii(req->responseBody()).trimmed();
+ bool b;
+ int eid=r.toInt(&b);
+ if(b && eid>=0)eventid=eid;
+ return "";
+ }else{
+ return req->errorString()+" ";
+ }
}
QRegExp MEvent::priceRegExp()const
ret+=QString::number((m_defaultprice/10)%10);
ret+=QString::number(m_defaultprice%10);
return ret;
+}
+
+void MEvent::setCancelled(bool ic,QString cr)
+{
+ if(ic){
+ m_cancelreason=cr.trimmed();
+ if(m_cancelreason=="")m_cancelreason=" ";
+ }else
+ m_cancelreason="";
+}
+
+void MEvent::setPrice(QString str)
+{
+ QStringList ps=str.split(QCoreApplication::translate("MEvent",".","price decimal dot"));
+ int prc=0;
+ if(ps.size()>=1)prc=ps[0].toInt()*100;
+ if(ps.size()>=2)prc+=ps[1].toInt();
+ m_defaultprice=prc;
}
\ No newline at end of file
#include <QString>
class MWebRequest;
+class QDomElement;
+/**encapsulation of an event, this class handles all there is to know about events and how to communicate with the database*/
class MEvent
{
public:
+ /**creates an event by ID, the constructor asks the server/database for details*/
MEvent(MWebRequest*,int);
+ /**creates an event via a DOM-element, used by WebRequest::getAllEvents*/
+ MEvent(MWebRequest*,QDomElement&);
+ /**destructs an event*/
~MEvent();
- void save();
+ /**updates data from the database, can be used to upgrade an incomplete event to a complete one*/
+ void refresh();
+ /**saves all data back to the database, it returns an empty string on success, it does not do anything if the event is invalid or incomplete*/
+ QString save();
+
+ /**returns the database ID of the event, a valid event will always have an ID >=0*/
+ int eventId()const{return eventid;}
+
+ /**returns the title of the event*/
QString title()const{return m_title;}
+ /**returns the artist of the event*/
QString artist()const{return m_artist;}
+ /**returns the description of the event (HTML)*/
QString description()const{return m_description;}
+ /**returns the start time of the event as Unix timestamp*/
int startTime()const{return m_starttime;}
+ /**returns the end time of the event as Unix timestamp*/
int endTime()const{return m_endtime;}
+ /**returns the room of the event, the room must be one out of the list of valid rooms*/
QString room()const{return m_roomid;}
+ /**returns the amount of tickets than can be sold for this event, initially this should be a copy of the rooms capacity*/
int capacity()const{return m_capacity;}
+ /**returns the normal price of tickets in cent*/
int price()const{return m_defaultprice;}
+ /**returns whether the event is cancelled*/
bool isCancelled()const{return !m_cancelreason.isEmpty();}
+ /**returns the reason why the event is cancelled*/
QString cancelReason()const{return m_cancelreason.trimmed();}
+ void setTitle(QString t){m_title=t;}
+ void setArtist(QString t){m_artist=t;}
+ void setDescription(QString t){m_description=t;}
+ void setRoom(QString t){m_roomid=t;}
+ void setStartTime(int t){m_starttime=t;}
+ void setEndTime(int t){m_endtime=t;}
+ void setCapacity(int c){m_capacity=c;}
+ void setPrice(int p){if(p>=0)m_defaultprice=p;}
+ void setPrice(QString);
+ void setCancelled(bool,QString cr=QString());
+
+ /**returns the price as a localized string*/
QString priceString()const;
+ /**returns the local regular expression for prices*/
QRegExp priceRegExp()const;
+ /**returns whether the event is valid. an event can be invalid if it is uninitialized (negative ID) or the server request failed*/
bool isValid()const{return m_valid;}
+ /**returns whether the event is complete - this depends on the amount of data sent by the server*/
+ bool isComplete()const{return m_complete;}
+ /**forces the event to believe it is valid and complete; used for saving new events*/
+ void makeValid(){m_valid=true;m_complete=true;}
private:
+ //used by both constructors:
+ void initFromElement(QDomElement&);
+
MWebRequest*req;
int eventid;
//display data
//if not null/empty: event has been cancelled
QString m_cancelreason;
//holds whether the loaded data is valid
- bool m_valid;
+ bool m_valid,m_complete;
};
#endif
//
#include "eventedit.h"
+#include "webrequest.h"
#include <QGridLayout>
#include <QBoxLayout>
#include <QTextEdit>
#include <QTimer>
#include <QMessageBox>
+#include <QListWidget>
+#include <QInputDialog>
MEventEditor::MEventEditor(QWidget*w,MWebRequest*r,qint32 id)
:QDialog(w),event(r,id)
vl->addLayout(hl=new QHBoxLayout,0);
hl->addStretch();
hl->addWidget(p=new QPushButton(tr("Save")));
- connect(p,SIGNAL(clicked()),this,SLOT(accept()));
+// connect(p,SIGNAL(clicked()),this,SLOT(accept()));
connect(p,SIGNAL(clicked()),this,SLOT(writeBack()));
hl->addWidget(p=new QPushButton(tr("Cancel")));
connect(p,SIGNAL(clicked()),this,SLOT(reject()));
}
void MEventEditor::writeBack()
-{}
+{
+ //copy contents to event
+ event.setTitle(title->text());
+ event.setStartTime(starttime->dateTime().toTime_t());
+ event.setEndTime(endtime->dateTime().toTime_t());
+ event.setArtist(artist->text());
+ event.setRoom(room->text());
+ event.setPrice(price->text());
+ event.setCancelled(cancelcheck->isChecked(),cancelreason->text());
+ event.setDescription(description->toPlainText());
+ event.setCapacity(capacity->value());
+ //send to server
+ event.makeValid();
+ QString r=event.save();
+ if(r!=""){
+ QMessageBox::warning(this,tr("Warning"),tr("Problem while uploading event: %s").arg(r));
+ }else
+ accept();
+}
void MEventEditor::selectRoom()
-{}
\ No newline at end of file
+{
+ QList<MRoom>rlst=req->getAllRooms();
+ QDialog d;
+ d.setWindowTitle(tr("Select a Room"));
+ QVBoxLayout*vl;
+ d.setLayout(vl=new QVBoxLayout);
+ QListWidget*rlstw;
+ vl->addWidget(rlstw=new QListWidget,10);
+ for(int i=0;i<rlst.size();i++)
+ rlstw->addItem(rlst[i].roomId());
+ QHBoxLayout*hl;
+ vl->addLayout(hl=new QHBoxLayout,0);
+ hl->addStretch(10);
+ QPushButton*p;
+ hl->addWidget(p=new QPushButton(tr("New...","new room")),0);
+ connect(p,SIGNAL(clicked()),this,SLOT(newRoom()));
+ connect(p,SIGNAL(clicked()),&d,SLOT(reject()));
+ hl->addWidget(p=new QPushButton(tr("Select","select room")),0);
+ connect(p,SIGNAL(clicked()),&d,SLOT(accept()));
+ hl->addWidget(p=new QPushButton(tr("Cancel")),0);
+ connect(p,SIGNAL(clicked()),&d,SLOT(reject()));
+ if(d.exec()==QDialog::Rejected)return;
+ //get selection
+ QList<QListWidgetItem*>wlst=rlstw->selectedItems();
+ if(wlst.size()<1)return;
+ room->setText(wlst[0]->text());
+}
+
+void MEventEditor::newRoom()
+{
+ QString rid=QInputDialog::getText(this,tr("New Room"),tr("Name of new room:"));
+ if(rid!=""){
+ MRoom rm(req,rid);
+ rm.makeValid();
+ rm.save();
+ room->setText(rid);
+ }
+}
private slots:
void writeBack();
void selectRoom();
+ void newRoom();
private:
MWebRequest*req;
MEvent event;
void MOverview::updateEvents()
{
- QList<MWebRequest::Eventlet>evl=req->getAllEvents();
+ QList<MEvent>evl=req->getAllEvents();
eventmodel->clear();
eventmodel->insertColumns(0,2);
eventmodel->insertRows(0,evl.size());
eventmodel->setHorizontalHeaderLabels(QStringList()<<tr("Start Time")<<tr("Title"));
for(int i=0;i<evl.size();i++){
- eventmodel->setData(eventmodel->index(i,0),evl[i].id,Qt::UserRole);
- eventmodel->setData(eventmodel->index(i,0),evl[i].start.toString(tr("ddd MMMM d yyyy, h:mm ap","time format")));
- eventmodel->setData(eventmodel->index(i,1),evl[i].title);
+ eventmodel->setData(eventmodel->index(i,0),evl[i].eventId(),Qt::UserRole);
+ eventmodel->setData(eventmodel->index(i,0),QDateTime::fromTime_t(evl[i].startTime()).toString(tr("ddd MMMM d yyyy, h:mm ap","time format")));
+ eventmodel->setData(eventmodel->index(i,1),evl[i].title());
}
eventtable->resizeColumnToContents(0);
eventtable->resizeColumnToContents(1);
#define MAGICSMOKE_OVERVIEW_H
#include <QMainWindow>
+#include <QPointer>
class MWebRequest;
class QTabWidget;
void updateEvents();
private:
//my session object
- MWebRequest*req;
+ QPointer<MWebRequest>req;
//the profile associated with this session
QString profilekey;
//widgets
--- /dev/null
+//
+// C++ Implementation: room
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "room.h"
+#include "webrequest.h"
+
+#include <QtXml>
+
+MRoom::MRoom(MWebRequest*r,QDomElement&el)
+{
+ req=r;
+ m_valid=m_complete=false;
+ m_capacity=0;
+ initFromElement(el);
+}
+
+MRoom::MRoom(MWebRequest*r,QString rn)
+{
+ req=r;
+ m_roomid=rn;
+ refresh();
+}
+
+void MRoom::refresh()
+{
+ m_valid=m_complete=false;
+ m_capacity=0;
+ //request
+ QDomDocument doc1;
+ QDomElement root=doc1.createElement("GetRooms");
+ root.setAttribute("detail","full");
+ QDomElement el=doc1.createElement("Room");
+ el.appendChild(doc1.createTextNode(m_roomid));
+ root.appendChild(el);
+ doc1.appendChild(root);
+ if(req->request("getroomdata",doc1.toByteArray())){
+ if(req->responseStatus()!=MWebRequest::Ok)return;
+ QDomDocument doc2;
+ if(!doc2.setContent(req->responseBody()))return;
+ root=doc2.documentElement();
+ QDomNodeList nl=root.elementsByTagName("Room");
+ for(int i=0;i<nl.size();i++){
+ el=nl.at(i).toElement();
+ if(el.isNull())continue;
+ QDomNodeList nl2=el.elementsByTagName("ID");
+ if(nl2.size()<1)continue;
+ if(nl2.at(0).toElement().text()==m_roomid)
+ initFromElement(el);
+ }
+ }
+}
+
+void MRoom::initFromElement(QDomElement&el)
+{
+ bool b;
+ m_valid=true;
+ int cap=el.attribute("capacity","x").trimmed().toInt(&b);
+ if(b && cap>=0)m_capacity=cap;
+ else m_valid=false;
+ QDomNodeList nl=el.elementsByTagName("ID");
+ if(nl.size()>0){
+ m_roomid=nl.at(0).toElement().text();
+ if(m_roomid=="")m_valid=false;
+ }else
+ m_valid=false;
+ nl=el.elementsByTagName("Description");
+ if(nl.size()>0){
+ m_description=nl.at(0).toElement().text();
+ m_complete=true;
+ }else
+ m_complete=false;
+}
+
+void MRoom::save()
+{
+ if(!m_valid || !m_complete)return;
+ QDomDocument doc;
+ QDomElement root=doc.createElement("RoomData");
+ QDomElement room=doc.createElement("Room");
+ room.setAttribute("capacity",m_capacity);
+ QDomElement el=doc.createElement("ID");
+ el.appendChild(doc.createTextNode(m_roomid));
+ room.appendChild(el);
+ el=doc.createElement("Description");
+ el.appendChild(doc.createTextNode(m_description));
+ room.appendChild(el);
+ root.appendChild(room);
+ doc.appendChild(root);
+ req->request("setroomdata",doc.toByteArray());
+}
--- /dev/null
+//
+// C++ Interface: room
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef ROOM_H
+#define ROOM_H
+
+#include <QString>
+
+class MWebRequest;
+class QDomElement;
+
+class MRoom
+{
+ public:
+ MRoom(MWebRequest*,QDomElement&);
+ MRoom(MWebRequest*,QString);
+
+ QString roomId()const{return m_roomid;}
+ QString description()const{return m_description;}
+ int capacity()const{return m_capacity;}
+
+ void setDescription(QString s){m_description=s;}
+ void setCapacity(int c){if(c>=0)m_capacity=c;}
+
+ bool isValid()const{return m_valid;}
+ bool isComplete()const{return m_complete;}
+ void makeValid(){m_valid=m_complete=true;}
+
+ void save();
+ void refresh();
+
+ private:
+ void initFromElement(QDomElement&);
+ MWebRequest*req;
+ QString m_roomid,m_description;
+ int m_capacity;
+ bool m_valid,m_complete;
+};
+
+#endif
#RC-File containing the icon:
RC_FILE += win.rc
}
-\r
-#compilation output:\r
-DESTDIR = ../src\r
-OBJECTS_DIR = .ctmp\r
-MOC_DIR = .ctmp\r
-RCC_DIR = .ctmp\r
-\r
+
+#compilation output:
+DESTDIR = ../src
+OBJECTS_DIR = .ctmp
+MOC_DIR = .ctmp
+RCC_DIR = .ctmp
+
SOURCES = \
main.cpp \
webrequest.cpp \
overview.cpp \
eventedit.cpp \
- event.cpp
+ event.cpp \
+ room.cpp
HEADERS = \
keygen.h \
mainwindow.h \
webrequest.h \
overview.h \
eventedit.h \
- event.h
+ event.h \
+ room.h
RESOURCES += files.qrc
if(url.scheme().toLower()=="http")port=80;
else port=443;
}
- qDebug("connecting to host=%s port=%i scheme=%s",url.host().toAscii().data(),(int)port,url.scheme().toAscii().data());
+ qDebug("connecting to host=%s port=%i scheme=%s request=%s",url.host().toAscii().data(),(int)port,url.scheme().toAscii().data(),hreq.toAscii().data());
QHttp::ConnectionMode conm;
if(url.scheme().toLower()=="http")conm=QHttp::ConnectionModeHttp;
else conm=QHttp::ConnectionModeHttps;
hrh.setValue("X-MagicSmoke-Session",sessionid);
hrh.setContentLength(data.size());
hrh.setContentType("application/x-magicsmoke");
- qDebug("Requesting data with:\n%s",hrh.toString().toAscii().data());
+ qDebug("Requesting data with:\n%s\n\n%s",hrh.toString().toAscii().data(),data.data());
waitid=req.request(hrh,data);
qDebug("started req %i",waitid);
fin=false;errstr="";
return roles.contains(r.toLower());
}
-QList<MWebRequest::Eventlet> MWebRequest::getAllEvents()
+QList<MEvent> MWebRequest::getAllEvents()
{
errstr="";
- if(!request("geteventlist"))return QList<Eventlet>();
+ if(!request("geteventlist"))return QList<MEvent>();
//parse return document
QDomDocument doc;
QString msg;int ln,cl;
if(!doc.setContent(rspdata,&msg,&ln,&cl)){
errstr=tr("Error parsing EventList XML data (line %1 column %2): %3").arg(ln).arg(cl).arg(msg);
- return QList<Eventlet>();
+ return QList<MEvent>();
}
QDomElement root=doc.documentElement();
QDomNodeList nl=root.elementsByTagName("Event");
- QList<Eventlet>ret;
+ QList<MEvent>ret;
for(int i=0;i<nl.size();i++){
QDomElement el=nl.at(i).toElement();
if(el.isNull())continue;
- Eventlet ev;
- ev.title=el.text();
- bool b;
- ev.id=el.attribute("id").toInt(&b);
- if(!b || ev.id<0)continue;
- ev.start=QDateTime::fromTime_t(el.attribute("start").toInt(&b));
- if(!b)continue;
- ret.append(ev);
+ MEvent ev(this,el);
+ if(ev.isValid())ret.append(ev);
+ }
+ return ret;
+}
+
+QList<MRoom> MWebRequest::getAllRooms()
+{
+ errstr="";
+ if(!request("getroomdata","<GetRooms detail=\"basic\"/>"))return QList<MRoom>();
+ //parse return document
+ QDomDocument doc;
+ QString msg;int ln,cl;
+ if(!doc.setContent(rspdata,&msg,&ln,&cl)){
+ errstr=tr("Error parsing EventList XML data (line %1 column %2): %3").arg(ln).arg(cl).arg(msg);
+ return QList<MRoom>();
+ }
+ QDomElement root=doc.documentElement();
+ QDomNodeList nl=root.elementsByTagName("Room");
+ QList<MRoom>ret;
+ for(int i=0;i<nl.size();i++){
+ QDomElement el=nl.at(i).toElement();
+ if(el.isNull())continue;
+ MRoom rm(this,el);
+ if(rm.isValid())ret.append(rm);
}
return ret;
}
#include <QList>
#include <QDateTime>
+#include "room.h"
+#include "event.h"
+
/**abstraction of requests to the web server, handles sessions and all data transfer*/
class MWebRequest:public QObject
{
InvalidRequest=5,
/**the request data had syntactical errors*/
SyntaxError=6,
- /**the HTTP transport failed or the server was unable to execute the script*/
+ /**the HTTP transport failed (time out) or the server was unable to execute the script; this code is set in all cases in which request returns false*/
HttpError=100
};
/**returns whether the user has a specific role/right*/
bool hasRole(QString);
- /**represents the minimal info about an event that comes from a getAllEvents*/
- struct Eventlet{
- int id;
- QString title;
- QDateTime start;
- };
- /**returns a list of all events*/
- QList<Eventlet>getAllEvents();
+ /**returns a list of all events (in incomplete state)*/
+ QList<MEvent>getAllEvents();
+
+ /**returns a list of all rooms (without description, which is loaded dynamically if requested)*/
+ QList<MRoom>getAllRooms();
public slots:
/**set how long to wait for a web request*/
/**escapes integers; the default implementation just makes sure it is an int*/
public function escapeInt($i)
{
+ if($i === false)return "NULL";
return $i + 0;
}
/**escapes strings; the default uses addslashes and encloses the value in ''*/
public function escapeString($s)
{
+ if($s === false) return "NULL";
return "'".addslashes($s)."'";
}
echo $xml->saveXml();
}
+/**Wrapper around event table*/
class Event
{
private $evid;
echo $xml->saveXml();
}
+/**Machine-Interface: set an event (it's not possible to set from Web-Browser)*/
+function setEventXml($xmldata)
+{
+ global $db;
+ //stage 1: parse XML
+ $xml=new DOMDocument;
+ if($xml->loadXML($xmldata)===false){
+ header("X-MagicSmoke-Status: SyntaxError");
+ echo "Unable to parse XML.";
+ return;
+ }
+ //stage 2: extract data from XML
+ $doc=$xml->documentElement;
+ $eventid=trim($doc->getAttribute("id"));
+ $start=trim($doc->getAttribute("start"))+0;
+ $end=trim($doc->getAttribute("end"))+0;
+ $capacity=trim($doc->getAttribute("capacity"))+0;
+ $defaultprice=trim($doc->getAttribute("defaultprice"))+0;
+ $cancelled=trim($doc->getAttribute("cancelled"));
+ $title=$artist=$description=$room=$cancelreason="";
+ foreach($doc->getElementsByTagName("Title") as $el)
+ foreach($el->childNodes as $cn)
+ if($cn->nodeType==XML_TEXT_NODE)
+ $title=trim($cn->wholeText);
+ foreach($doc->getElementsByTagName("Artist") as $el)
+ foreach($el->childNodes as $cn)
+ if($cn->nodeType==XML_TEXT_NODE)
+ $artist=trim($cn->wholeText);
+ foreach($doc->getElementsByTagName("Description") as $el)
+ foreach($el->childNodes as $cn)
+ if($cn->nodeType==XML_TEXT_NODE)
+ $description=trim($cn->wholeText);
+ foreach($doc->getElementsByTagName("Room") as $el)
+ foreach($el->childNodes as $cn)
+ if($cn->nodeType==XML_TEXT_NODE)
+ $room=trim($cn->wholeText);
+ foreach($doc->getElementsByTagName("CancelReason") as $el)
+ foreach($el->childNodes as $cn)
+ if($cn->nodeType==XML_TEXT_NODE)
+ $cancelreason=trim($cn->wholeText);
+ //stage 3: validate input
+ if(ereg("^([0-9]+)|(new)$",$eventid)===false){
+ header("X-MagicSmoke-Status: Error");
+ echo "Invalid Event ID, must be positive integer or 'new'.";
+ return;
+ }
+ if($cancelled!="true" && $cancelled!="false"){
+ header("X-MagicSmoke-Status: Error");
+ echo "Event neither cancelled, nor non-cancelled.";
+ return;
+ }
+ if($title==""){
+ header("X-MagicSmoke-Status: Error");
+ echo "Empty Title.";
+ return;
+ }
+ if($artist==""){
+ header("X-MagicSmoke-Status: Error");
+ echo "No Artist.";
+ return;
+ }
+ $db->beginTransaction();
+ $res=$db->select("room","roomid","roomid='".addslashes($room)."'");
+ if(count($res)<1){
+ //end DB transaction
+ $db->rollbackTransaction();
+ //error
+ header("X-MagicSmoke-Status: Error");
+ echo "Invalid Room.";
+ return;
+ }
+
+ //stage 4: call DB
+ $data["title"]=$title;
+ $data["artist"]=$artist;
+ $data["description"]=$description;
+ $data["starttime"]=$start;
+ $data["endtime"]=$end;
+ $data["roomid"]=$room;
+ $data["capacity"]=$capacity;
+ $data["defaultprice"]=$defaultprice;
+ if($cancelled=="true")
+ $data["cancelreason"]=$cancelreason." ";
+ else
+ $data["cancelreason"]=false;
+ if($eventid=="new"){
+ //create new ID
+ $res=$db->select("event","max(eventid)","");
+ if(count($res)==0)$eventid=0;
+ else $eventid=$res[0][0]+1;
+ //create event
+ $data["eventid"]=$eventid;
+ $db->insert("event",$data);
+ }else{
+ //check ID
+ $eventid=$eventid+0;
+ $res=$db->select("event","eventid","eventid=".$eventid);
+ if(count($res)==0){
+ header("X-MagicSmoke-Status: Error");
+ echo "Invalid Event: eventid does not exist in database.";
+ $db->rollbackTransaction();
+ return;
+ }
+ $db->update("event",$data,"eventid=".$eventid);
+ }
+ $db->commitTransaction();
+ header("X-MagicSmoke-Status: Ok");
+ echo $eventid;
+}
+
?>
\ No newline at end of file
--- /dev/null
+<?
+//
+// PHP Implementation: room
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+//TODO: implement:
+class Room
+{
+ public function __construct($roomid){}
+ public function exists(){return false;}
+
+};
+
+function getRoomsXml($xmldata)
+{
+ global $db;
+ //TODO: check xml data
+ //return rooms
+ $res=$db->select("room","roomid,capacity,description","");
+ $xml=new DOMDocument;
+ $root=$xml->createElement("RoomData");
+ if(count($res)>0)
+ foreach($res as $k => $rm){
+ $room=$xml->createElement("Room");
+ $room->setAttribute("capacity",$rm["capacity"]);
+ $id=$xml->createElement("ID",$rm["roomid"]);
+ $room->appendChild($id);
+ $des=$xml->createElement("Description",$rm["description"]);
+ $room->appendChild($des);
+ $root->appendChild($room);
+ }
+ $xml->appendChild($root);
+ header("X-MagicSmoke-Status: Ok");
+ print($xml->saveXML());
+}
+
+function setRoomsXml($xmldata)
+{
+ //TODO:implement
+}
+
+?>
\ No newline at end of file
die("Database is not correctly configured. Giving up.");
//load class-files
include('inc/event.php');
+include('inc/room.php');
?>
\ No newline at end of file
//all requests below here need authentication
"getmyroles", //role management
//all requests below here need a role entry in the DB
- "geteventlist", "geteventdata", //event infos
+ "geteventlist", "geteventdata", "seteventdata", //event infos
+ "getroomdata","setroomdata",//room infos
"getcustomerlist" //customer info
);
/**contains the low-level request name from the client*/
exit();
}
+//set an event
+if($SMOKEREQUEST=="seteventdata"){
+ setEventXml($REQUESTDATA);
+ exit();
+}
+
+//get room
+if($SMOKEREQUEST=="getroomdata"){
+ getRoomsXml($REQUESTDATA);
+ exit();
+}
+
+//set room
+if($SMOKEREQUEST=="setroomdata"){
+ setRoomsXml($REQUESTDATA);
+ exit();
+}
+
//EOF
header("X-MagicSmoke-Status: Error");
die("Internal Error: unknown command, hiccup in code structure.");