Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/gui/orxonox_gui_update.cc @ 3431

Last change on this file since 3431 was 3423, checked in by bensch, 20 years ago

orxonox/trunk: merged branches/updater back into the trunk
merged with command: svn merge branches/updater trunk -r 3241:HEAD
resolved conflicts in debug.h in favor of the trunk.

File size: 14.8 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3   Copyright (C) 2004 orx
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2, or (at your option)
8   any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software Foundation,
17   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
18
19
20   ### File Specific:
21   main-programmer: Benjamin Grauer
22
23*/
24
25#include "orxonox_gui_update.h"
26#include <iostream>
27#include <string>
28
29#include "orxonox_gui.h"
30#include <stdio.h>
31#include <stdlib.h>
32
33using namespace std;
34
35/**
36   \brief Creates an Update-Frame
37*/
38OrxonoxGuiUpdate::OrxonoxGuiUpdate(void)
39{
40  this->getSystemInfo();
41
42  this->updateFrame = new Frame("Update-Options:");
43  this->updateFrame->setGroupName("update");
44  this->updateBox = new Box('v');
45#ifdef HAVE_CURL
46
47  // the Button for autoUpdating
48  this->autoUpdate = new CheckButton("auto update");
49  this->updateBox->fill(this->autoUpdate);
50  this->autoUpdate->setFlagName("update", "u", 0);
51  this->autoUpdate->saveability();
52
53  this->updateSourceWindowCreate();
54  this->updateBox->fill(this->updateSourceWindowGetButton());
55
56  this->updateDataWindowCreate();
57  this->updateBox->fill(this->updateDataWindowGetButton());
58
59#else /* HAVE_CURL */
60  Label* noCurlLabel = new Label("since you do not have cURL,\nthis option is not availible");
61  this->updateBox->fill(noCurlLabel); 
62#endif /* HAVE_CURL */
63  this->updateFrame->fill(this->updateBox);
64}
65
66/**
67   \brief Destructs the Update-stuff
68*/
69OrxonoxGuiUpdate::~OrxonoxGuiUpdate(void)
70{
71  if(this->tmpDir)
72    delete []this->tmpDir;
73  if(this->homeDir)
74    delete []homeDir;
75  if(this->installDataDir)
76    delete []this->installDataDir;
77  if(this->installSourceDir)
78    delete []this->installSourceDir;
79  if(this->userName)
80    delete []this->userName;
81
82
83}
84
85/**
86   \brief Return the Frame
87   \return Returns the Audio-frame
88*/
89Widget* OrxonoxGuiUpdate::getWidget(void)
90{
91  return this->updateFrame;
92}
93
94/**
95    \brief Look what info we can get from this system
96*/
97bool OrxonoxGuiUpdate::getSystemInfo(void)
98{
99  PRINTF(3)("Grabbing system information\n");
100  this->tmpDir = getenv("TMPDIR");
101  if(!tmpDir)
102    this->tmpDir = "/tmp";
103  PRINTF(4)("Temporary directory is: %s\n", this->tmpDir);
104
105#ifdef __WIN32__
106  this->homeDir = getenv("USERPROFILE");
107#else
108  this->homeDir = getenv("HOME");
109#endif
110  PRINTF(4)("Home directory is %s\n", homeDir);
111
112  this->installDataDir = "/usr/share/games/orxonox";
113  PRINTF(4)("Installation of orxonox-data will go to this directory: %s\n", this->installDataDir);
114
115  this->installSourceDir = "/usr/games/bin";
116  PRINTF(4)("Installation of orxonox-source will go to this directory: %s\n", this->installSourceDir);
117
118  this->userName = getenv("USER");
119  PRINTF(4)("Logged in username is: %s\n", this->userName);
120}
121
122#ifdef HAVE_CURL
123bool* OrxonoxGuiUpdate::checkForUpdates(void)
124{
125  PRINTF(3)("checking for new version of orxonox\n");
126  FileInfo updateFileInfo;
127  updateFileInfo.fileName = "update_info";
128  updateFileInfo.webRoot = "http://www.orxonox.ethz.ch/files/data";
129  updateFileInfo.localRoot = this->tmpDir;
130 
131  download(&updateFileInfo);
132}
133#endif /* HAVE_CURL */
134#ifdef HAVE_CURL
135/**
136   \brief Creates a window, and all it contains for the Data-update.
137*/
138void OrxonoxGuiUpdate::updateDataWindowCreate(void)
139{
140  this->updateDataWindow = new Window("update orxonox::Data");   
141  this->updateDataBox = new Box('v');
142
143  // the close-Button of the Update Window.
144  //  updateWindowClose = new Button("close");
145#ifdef HAVE_GTK2
146  //  updateWindowClose->connectSignal("button_press_event", updateWindow, Window::windowClose);
147#endif /* HAVE_GTK2 */
148  //  updateWindowBox->fill(updateWindowClose);
149
150  this->updateDataBar = new ProgressBar();
151  this->updateDataBox->fill(this->updateDataBar);
152
153  FileInfo* dataInfo = new FileInfo;
154  dataInfo->bar = this->updateDataBar;
155
156  this->updateDataBegin = new Button("begin.");
157  dataInfo->stateButton = this->updateDataBegin;
158#ifdef HAVE_GTK2
159  dataInfo->buttonSignal = updateDataBegin->connectSignal("button_press_event", dataInfo, updateDataFunc);
160#endif /* HAVE_GTK2 */
161  this->updateDataBox->fill(this->updateDataBegin);
162
163  this->updateDataWindow->fill(this->updateDataBox);
164
165  this->updateDataWindowButton = new Button("update orxonox::Data");
166#ifdef HAVE_GTK2
167  this->updateDataWindowButton->connectSignal("button_press_event", this->updateDataWindow, Window::windowOpen);
168  this->updateDataWindow->connectSignal("destroy", this->updateDataWindow, Window::windowClose);
169  this->updateDataWindow->connectSignal("delete_event", this->updateDataWindow, Window::windowClose);
170#endif /* HAVE_GTK2 */
171
172}
173
174/**
175   \returns A Pointer to the Button of the UpdaterDataWindow
176*/
177Button* OrxonoxGuiUpdate::updateDataWindowGetButton(void)
178{
179  return this->updateDataWindowButton;
180}
181
182/**
183   \brief Creates a window, and all it contains for the Source-update.
184*/
185void OrxonoxGuiUpdate::updateSourceWindowCreate(void)
186{
187  // the button, that opens this Window.
188  this->updateSourceWindowButton = new Button("update orxonox::Source");
189
190  // the Window itself
191  this->updateSourceWindow = new Window("update orxonox::Source");
192
193  this->updateSourceBox = new Box();
194
195  this->updateSourceBar = new ProgressBar();
196  this->updateSourceBox->fill(this->updateSourceBar);
197  test = new Button("increment");
198
199#ifdef HAVE_GTK2
200  test->connectSignal("button_press_event", updateSourceBar, updateSourceFunc);
201#endif /* HAVE_GTK2 */
202
203  this->updateSourceBox->fill(test);
204  this->updateSourceWindow->fill(updateSourceBox); 
205#ifdef HAVE_GTK2
206  this->updateSourceWindowButton->connectSignal("button_press_event", this->updateSourceWindow, Window::windowOpen);
207  this->updateSourceWindow->connectSignal("destroy", this->updateSourceWindow, Window::windowClose);
208  this->updateSourceWindow->connectSignal("delete_event", this->updateSourceWindow, Window::windowClose);
209#endif /* HAVE_GTK2 */
210
211}
212
213/**
214   \returns A Pointer to the Button of the UpdaterSourceWindow
215*/
216Button* OrxonoxGuiUpdate::updateSourceWindowGetButton(void)
217{
218  return this->updateSourceWindowButton;
219}
220
221
222#ifdef HAVE_GTK2
223/**
224   \brief updates the Data of orxonox.
225   \param w The widget, that executed this Function.
226   \param event The event that trigered this Function.
227   \param button The Button, that triggered this event.
228*/
229gint OrxonoxGuiUpdate::updateDataFunc(GtkWidget* w, GdkEventKey* event, void* info)
230{
231  FileInfo* dataInfo =(FileInfo*)info;
232
233  dataInfo->fileName = "02%20orxonox%203.mp3";
234  dataInfo->webRoot  = "http://www.orxonox.ethz.ch/files/";
235  dataInfo->localRoot = "./";
236  PRINTF(3)("Preparing to download file %s.\n", dataInfo->fileName);
237  downloadWithStyle(dataInfo);
238}
239
240/**
241   \brief updates the source of orxonox.
242   \param w The widget, that executed this Function.
243   \param event The event that trigered this Function.
244   \param button The Button, that triggered this event.
245*/
246gint OrxonoxGuiUpdate::updateSourceFunc(GtkWidget* w, GdkEventKey* event, void* bar)
247{
248  ProgressBar* tmpBar = static_cast<ProgressBar*>(bar);
249  tmpBar->setTotalSize(20);
250  tmpBar->setProgress(tmpBar->getProgress()+1);
251}
252#endif /* HAVE_GTK2 */
253
254/**
255   \brief The Function Curl calls to write out the File.
256   \param ptr A Pointer to the date to write.
257   \param size The size in bytes of one nmemb to write.
258   \param nmemb The Count of size to write.
259   \param stream Filehandler to write to.
260*/
261size_t OrxonoxGuiUpdate::curlWriteFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
262{
263  return fwrite(ptr, size, nmemb, stream);
264}
265
266/**
267   \brief The Function Curl calls to write out the File.
268   \param ptr A Pointer to the date to write to.
269   \param size The size in bytes of one nmemb to write.
270   \param nmemb The Count of size to write.
271   \param stream Filehandler to get data from.
272*/
273size_t OrxonoxGuiUpdate::curlReadFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
274{
275  return fread(ptr, size, nmemb, stream);
276}
277
278
279/**
280   \brief An update Function for the GUI, to show the progress.
281   \param Bar th ProgressBar to update
282   \param totalSize The total size of the download in bytes.
283   \param progress The current Progress of the download in bytes.
284   \param upTotal not needed
285   \param upProgress not needed
286*/
287int OrxonoxGuiUpdate::curlProgressFunc(ProgressBar* bar, double totalSize, double progress, double upTotal, double upProgress)
288{
289  bar->setProgress(progress);
290  bar->setTotalSize(totalSize);
291#ifdef HAVE_GTK2
292#ifndef HAVE_PTHREAD_H
293  while(gtk_events_pending()) gtk_main_iteration();
294#endif
295#endif
296  return 0;
297}
298
299/**
300   \brief The Curl handle for only one CURL(static).
301*/
302CURL* OrxonoxGuiUpdate::curlHandle = NULL;
303
304#ifdef HAVE_PTHREAD_H
305/** \brief The download Thread ID */
306pthread_t* OrxonoxGuiUpdate::downloadThreadID = new pthread_t;
307/**   \brief The download Thread ID*/
308pthread_t* OrxonoxGuiUpdate::downloadThreadFinishID = new pthread_t;
309#endif /* HAVE_PTHREAD_H */
310/**
311   \brief A bool parameter that shows if we are downloading.
312*/
313bool OrxonoxGuiUpdate::isDownloading = false;
314
315
316/**
317   \brief Initializes a Download without displaying it.
318   \param fileInfo the FileInfo.
319
320   !! BE AWARE THIS WILL NOT BE THREADED. !!
321*/
322bool OrxonoxGuiUpdate::download(void* fileInfo)
323{
324  if(isDownloading)
325    {
326      PRINTF(2)("unable to Download. already getting some file\n");
327      return false;
328    }
329  PRINTF(3)("Downloading.\n");
330  FileInfo* info =(FileInfo*)fileInfo;
331  CURLcode res;
332  CURL* localCurl;
333  localCurl = curl_easy_init();
334  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+2];
335  strcpy(fileOnNet, info->webRoot);
336  if(fileOnNet[strlen(fileOnNet)] != '/') //!< \todo windows-shit
337    strcat(fileOnNet, "/");
338  strcat(fileOnNet, info->fileName);
339  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+2];
340  strcpy(fileOnDisk, info->localRoot);
341  if(fileOnDisk[strlen(fileOnDisk)] != '/') //!< \todo windows-shit
342    strcat(fileOnDisk, "/");
343  strcat(fileOnDisk, info->fileName);
344 
345  if(localCurl)
346    {
347     
348      info->fileHandle = fopen(fileOnDisk, "w");
349     
350      curl_easy_setopt(localCurl, CURLOPT_URL, fileOnNet);
351      curl_easy_setopt(localCurl, CURLOPT_WRITEDATA, info->fileHandle);
352      curl_easy_setopt(localCurl, CURLOPT_WRITEFUNCTION, curlWriteFunc);
353      curl_easy_setopt(localCurl, CURLOPT_READFUNCTION, curlReadFunc);
354      curl_easy_setopt(localCurl, CURLOPT_NOPROGRESS, true);
355     
356      curl_easy_perform(localCurl);
357
358      curl_easy_cleanup(localCurl);
359      fclose(info->fileHandle);
360    }
361}
362
363/**
364   \brief Initializes a Download with some style.
365   \param fileInfo the FileInfo.
366   \todo release thread-lock.
367
368   Downloading with a Button that gets a different Name while downloading, and a Bar, that gets to be updated. More to be followed
369*/
370bool OrxonoxGuiUpdate::downloadWithStyle(void* fileInfo)
371{
372  if(isDownloading)
373    {
374      PRINTF(2)("unable to Download. already getting some file\n");
375      return false;
376    }
377  PRINTF(3)("Downloading.\n");
378  FileInfo* info =(FileInfo*)fileInfo;
379  CURLcode res;
380  curlHandle = curl_easy_init();
381  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+1];
382  strcpy(fileOnNet, info->webRoot);
383  strcat(fileOnNet, info->fileName);
384  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+1];
385  strcpy(fileOnDisk, info->localRoot);
386  strcat(fileOnDisk, info->fileName);
387
388  if(curlHandle)
389    {
390     
391      info->fileHandle = fopen(fileOnDisk, "w");
392     
393      curl_easy_setopt(curlHandle, CURLOPT_URL, fileOnNet);
394      curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, info->fileHandle);
395      curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, curlWriteFunc);
396      curl_easy_setopt(curlHandle, CURLOPT_READFUNCTION, curlReadFunc);
397      curl_easy_setopt(curlHandle, CURLOPT_NOPROGRESS, false);
398      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSFUNCTION, curlProgressFunc);
399      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSDATA, info->bar);
400
401      if(!isDownloading)
402        {
403#ifdef HAVE_PTHREAD_H     
404          pthread_join(*downloadThreadFinishID, NULL);
405#endif /* HAVE_PTHREAD_H */
406#ifdef HAVE_GTK2
407          info->stateButton->disconnectSignal(info->buttonSignal);
408          info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, cancelDownload);
409#endif /* HAVE_GTK2 */
410#ifdef HAVE_PTHREAD_H
411          info->stateButton->setTitle("cancel");
412#else /* HAVE_PTHREAD_H */
413          info->stateButton->setTitle("please wait");
414#endif /* HAVE_PTHREAD_H */
415         
416          //! \todo check if threads really were created.
417#ifdef HAVE_PTHREAD_H
418          pthread_create(downloadThreadID, NULL, downloadThread, info);
419          pthread_create(downloadThreadFinishID, NULL, downloadThreadFinished, info); 
420#else
421          downloadThread(info);
422          downloadThreadFinished(info);
423#endif /* HAVE_PTHREAD_H */
424         
425          //      res = curl_easy_perform(curlHandle);
426         
427          //      fclose(outfile);
428        }
429      else 
430        PRINTF(1)("thread already in use\n");
431
432    }
433  return true;
434}
435
436/**
437   \brief The downloading process(either threaded or not).
438   \param fileInfo the FileInfo.
439
440   \todo Threads get locked, if the cancel button is pressed in to small intervals.
441*/
442void* OrxonoxGuiUpdate::downloadThread(void* fileInfo)
443{
444  isDownloading = true;
445  curl_easy_perform(curlHandle);
446}
447
448/**
449   \brief Finishes a downloading process.
450   \param fileInfo the FileInfo.
451*/
452void* OrxonoxGuiUpdate::downloadThreadFinished(void* fileInfo)
453{ 
454  FileInfo* info =(FileInfo*)fileInfo;
455#ifdef HAVE_PTHREAD_H
456  pthread_join(*downloadThreadID, NULL);
457#ifdef HAVE_GTK2
458  gdk_threads_enter();
459#endif /* HAVE_GTK2 */
460#endif /* HAVE_PTHREAD_H */
461  if(curlHandle)
462    curl_easy_cleanup(curlHandle);
463 
464  PRINTF(3)("Closing the downloaded file.\n");
465  fclose(info->fileHandle);
466
467  if(isDownloading)
468    info->stateButton->setTitle("go on");
469  //  else
470  //    info->stateButton->setTitle("done");
471#ifdef HAVE_GTK2
472  info->stateButton->disconnectSignal(info->buttonSignal);
473  info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, updateDataFunc);
474#endif /* HAVE_GTK2 */
475  isDownloading = false;
476#ifdef HAVE_PTHREAD_H
477#ifdef HAVE_GTK2
478  gdk_threads_leave();
479#endif /* HAVE_GTK2 */
480#endif /* HAVE_PTHREAD_H */
481
482}
483
484#ifdef HAVE_GTK2
485/**
486   \brief canceles a downloading session.
487   \param w The widget, that executed this Function.
488   \param event The event that trigered this Function.
489   \param bar The Bar, that triggered this event.
490
491   \todo canceling a session in non-threaded mode.
492*/
493gint OrxonoxGuiUpdate::cancelDownload(GtkWidget* w, GdkEventKey* event, void* bar)
494{
495#ifdef HAVE_PTHREAD_H
496  pthread_cancel(*downloadThreadID);
497#else
498  PRINTF(2)("Cannot cancle the Downloading process until after this File, because no threading was enabled");
499#endif /* HAVE_PTHREAD_H*/
500}
501#endif /* HAVE_GTK2 */
502
503#endif /* HAVE_CURL */
Note: See TracBrowser for help on using the repository browser.