00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dlgupdate.h"
00026 #include "profilemanager.h"
00027 #include "md5.h"
00028 #include "parser.h"
00029
00030 #include <sstream>
00031
00032 #include <wx/file.h>
00033 #include <wx/radiobut.h>
00034
00035 namespace WDS
00036 {
00037
00038 BEGIN_EVENT_TABLE(CDlgUpdate, wxDialog)
00039 EVT_BUTTON( wxID_OK, CDlgUpdate::OnOK )
00040 EVT_BUTTON( wxID_CANCEL, CDlgUpdate::OnCancel )
00041 EVT_TIMER( IDT_TIMER, CDlgUpdate::OnTimer )
00042 END_EVENT_TABLE()
00043
00044
00045
00046
00047 CDlgUpdate::CDlgUpdate( wxWindow *pParent, CProfile* profile )
00048 : wxDialog(pParent, -1, "Update von phpmap - WDSMap",
00049 wxDefaultPosition, wxSize(400, 300), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
00050 m_timer(this, IDT_TIMER), m_pProfile(profile)
00051 {
00052
00053
00054 wxBoxSizer *sTop = new wxBoxSizer( wxVERTICAL );
00055
00056
00057 wxFlexGridSizer *sGrid = new wxFlexGridSizer( 2, 2, 5, 5 );
00058 sGrid->AddGrowableCol(1);
00059
00060
00061 wxBoxSizer *sDlAvg = new wxBoxSizer( wxHORIZONTAL );
00062
00063 wxBoxSizer *sButtons = new wxBoxSizer( wxHORIZONTAL );
00064
00065
00066
00067 wxStaticText *pLblServer = new wxStaticText( this, -1, "Server:" );
00068 wxTextCtrl *pEdtSource = new wxTextCtrl ( this, -1, m_pProfile->GetServer(),
00069 wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
00070
00071 wxStaticText *pLblProgress = new wxStaticText( this, -1, "Progress:" );
00072 m_pProgessBar = new wxGauge( this, IDC_PROGRESS_BAR, 10 );
00073
00074 m_pLblTransferred = new wxStaticText( this, -1, "Total: 0 bytes übertragen." );
00075 m_pLblAverageSpeed= new wxStaticText( this, -1, "00.0 kb/s" );
00076 m_pLblStatus = new wxStaticText( this, -1, "Status: Verbindung zum Server herstellen." );
00077
00078 wxStaticLine *pLine = new wxStaticLine( this, -1 );
00079
00080 m_pBtnCancel = new wxButton( this, wxID_CANCEL, "Abbruch" );
00081 m_pBtnOK = new wxButton( this, wxID_OK, "OK" );
00082
00083
00084
00085
00086 sGrid->Add( pLblServer, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxLEFT, 5 );
00087 sGrid->Add( pEdtSource, 0, wxEXPAND | wxTOP | wxRIGHT, 5 );
00088 sGrid->Add( pLblProgress, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5 );
00089 sGrid->Add( m_pProgessBar,0, wxEXPAND | wxRIGHT, 5 );
00090
00091 sDlAvg->Add( m_pLblTransferred , 1, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
00092 sDlAvg->Add( m_pLblAverageSpeed, 0, wxALIGN_RIGHT | wxRIGHT, 5 );
00093
00094 sButtons->Add( m_pBtnCancel, 0, wxALIGN_RIGHT | wxRIGHT, 5 );
00095 sButtons->Add( m_pBtnOK, 0, wxALIGN_RIGHT, 0 );
00096
00097 sTop->Add( sGrid , 0, wxEXPAND | wxALL, 5 );
00098 sTop->Add( sDlAvg, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
00099 sTop->Add( m_pLblStatus, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 10 );
00100 sTop->Add( pLine, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00101 sTop->Add( sButtons, 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM, 10 );
00102
00103
00104 SetAutoLayout( true );
00105 SetSizer( sTop );
00106
00107 sTop->SetSizeHints( this );
00108 SetClientSize( 400, GetSize().GetHeight() );
00109
00110 m_pBtnOK->SetFocus( );
00111 m_pBtnOK->SetDefault( );
00112 m_pBtnOK->Enable( false );
00113
00114
00115 m_state = US_INIT;
00116 m_httpRequest = new HTTP::GetRequest;
00117 m_timer.Start( 50 );
00118 }
00119
00120 CDlgUpdate::~CDlgUpdate()
00121 {
00122 if ( m_httpRequest )
00123 delete m_httpRequest;
00124
00125 }
00126
00127
00128
00129
00130
00131 const HTTP::GetRequest* CDlgUpdate::GetHTTPRequest()
00132 {
00133 return m_httpRequest;
00134 }
00135
00136
00137
00138
00139 void CDlgUpdate::OnTimer( wxTimerEvent& event )
00140 {
00141 wxString url, sport;
00142
00143 static wxStopWatch sw;
00144 static bool bGotSize = false;
00145
00146 switch ( m_state ) {
00147
00148 case US_INIT:
00149 m_httpRequest->setUserAgent( string("WDSMap/") + WDSMAP_VERSION );
00150 m_httpRequest->addHeader( "WDSMap-User", m_pProfile->GetUser().c_str() );
00151 m_httpRequest->addHeader( "WDSMap-Password", MD5::hash( m_pProfile->GetPassword().c_str() ) );
00152 m_httpRequest->addHeader( "WDSMap-Type", "update" );
00153 m_httpRequest->addHeader( "WDSMap-Version", 1 );
00154 m_httpRequest->addHeader( "WDSMap-Timestamp", m_pProfile->GetTimestamp() );
00155
00156 bGotSize = false;
00157
00158 cout << "INIT" << endl;
00159 m_state = US_CONNECT;
00160 break;
00161
00162 case US_CONNECT:
00163 cout << "CONNECT" << endl;
00164 url = m_pProfile->GetServer();
00165 sport = url.AfterFirst(':');
00166 long nport;
00167 (sport.BeforeFirst('/')).ToLong(&nport);
00168
00169 if ( m_httpRequest->connect( (url.BeforeFirst(':')).c_str(), int(nport) ) ) {
00170 m_pLblStatus->SetLabel( "Status: Verbindung zum Server herstellen." );
00171 m_state = US_REQUEST;
00172 } else {
00173 m_pLblStatus->SetLabel( "Fehler: Verbindung zum Server kann nicht hergestellt werden." );
00174 m_state = US_ERROR;
00175 }
00176 break;
00177
00178 case US_REQUEST:
00179 cout << "REQUEST" << endl;
00180 url = m_pProfile->GetServer().AfterFirst('/');
00181 url += "export.php";
00182
00183 if ( m_httpRequest->request( url.c_str() ) ) {
00184 sw.Start( 0 );
00185 m_pLblStatus->SetLabel( "Status: Daten werden übertragen." );
00186 m_state = US_PROCESS_DATA;
00187 } else {
00188 m_pLblStatus->SetLabel( "Fehler: Bei der Datenübertragung ist ein Fehler aufgetreten." );
00189 m_state = US_ERROR;
00190 }
00191 break;
00192
00193 case US_PROCESS_DATA:
00194 cout << "PROCESS" << endl;
00195 if ( ! m_httpRequest->process() ) m_state = US_MAYBE_SUCCESS;
00196
00197 if ( ! bGotSize ) {
00198
00199 string rawData = m_httpRequest->getRaw();
00200 unsigned int pos = rawData.find( "\r\nphpmap-DataSize: " );
00201
00202 if ( pos != string::npos ) {
00203 pos += 19;
00204
00205 int end = rawData.find( "\r\n", pos );
00206 if ( end != string::npos) {
00207 int size;
00208 stringstream ss;
00209 ss << rawData.substr(pos, end - pos);
00210 ss >> size;
00211 m_pProgessBar->SetRange( size );
00212 bGotSize = true;
00213 }
00214 }
00215 }
00216 m_pLblAverageSpeed->SetLabel(
00217 wxString::Format("%.1f kb/s", double (m_httpRequest->getRawSize())
00218 / (1024.0 * double(sw.Time()/1000.0))) );
00219
00220 m_pLblTransferred->SetLabel( wxString::Format( "Total: %d bytes übertragen.",
00221 m_httpRequest->getRawSize() ) );
00222
00223 m_pProgessBar->SetValue( m_httpRequest->getRawSize() );
00224 break;
00225
00226 case US_MAYBE_SUCCESS:
00227 cout << "MAYBESUCCESS" << endl;
00228 if ( ! m_httpRequest->success() )
00229 {
00230 m_pLblStatus->SetLabel( "Fehler: Unbekannter Fehler aufgetreten." );
00231 m_state = US_ERROR;
00232 }
00233 else
00234 {
00235
00236 m_timer.Stop();
00237 sw.Pause();
00238
00239 m_pProgessBar->SetRange( 10 );
00240 m_pProgessBar->SetValue( 10 );
00241 if ( CheckDownload() ) {
00242 m_pLblStatus->SetLabel( "Status: Fertig." );
00243 m_pBtnOK->Enable( true );
00244 }
00245 }
00246 break;
00247
00248 case US_ERROR:
00249 cout << m_httpRequest->getError() << endl;
00250 m_timer.Stop();
00251 sw.Pause();
00252 break;
00253
00254 default: break;
00255
00256 }
00257 }
00258
00264 bool CDlgUpdate::CheckDownload( )
00265 {
00266 if ( m_httpRequest->getHeaderAsInt("phpmap-ReturnCode") == 0 ) {
00267
00268
00269 int version = m_httpRequest->getHeaderAsInt( "phpmap-Version" );
00270
00271 if ( version != 1 ) {
00272 m_pLblStatus->SetLabel( wxString("Fehler: Falsche Version (")
00273 + m_httpRequest->getHeaderAsString("phpmap-Version").c_str()
00274 + ")." );
00275 return false;
00276 }
00277
00278 int timestamp = m_httpRequest->getHeaderAsInt( "phpmap-Timestamp" );
00279
00280
00281
00282
00283 m_strUpdate = m_httpRequest->getData();
00284
00285 return true;
00286 } else {
00287 m_pLblStatus->SetLabel( wxString("Fehler: ")
00288 + m_httpRequest->getHeaderAsString("phpmap-ErrorMessage").c_str()
00289 + " (#"
00290 + m_httpRequest->getHeaderAsString("phpmap-ReturnCode").c_str()
00291 + ")." );
00292 }
00293
00294 return false;
00295 }
00296
00297 void CDlgUpdate::OnCancel( wxCommandEvent &event )
00298 {
00299 m_timer.Stop();
00300 EndModal( wxID_CANCEL );
00301
00302 event.Skip( );
00303 }
00304
00305 void CDlgUpdate::OnOK( wxCommandEvent &event )
00306 {
00307 if ( m_httpRequest ) {
00308 if( m_httpRequest->success() ) {
00309 EndModal( wxID_OK );
00310 } else {
00311 EndModal( wxID_CANCEL );
00312 }
00313 }
00314
00315 event.Skip( );
00316 }
00317
00318
00319
00320
00321 }
00322
00323