Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/updater/src/gui/orxonox_gui_update.cc @ 3286

Last change on this file since 3286 was 3286, checked in by bensch, 19 years ago

orxonox/branches/updater: it downloads the fileindex into a tempdir.

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