All pastes #962343 Raw Edit

Miscellany

public text v1 · immutable
#962343 ·published 2008-03-29 18:14 UTC
rendered paste body
#include <sys/stat.h>
#include <iostream>
#include <ctime>
#include "config.h"
#include "weather.hpp"
#include "weather_config.hpp"
#include "gettext.hpp"
#include "graphics.hpp"
#include "busy_indicator.hpp"

#include "startmenu.hpp"
#include "updater.hpp"
#include "common-feature.hpp"
#include "tinyxml.h"
#include <string>
#include <sstream>

#ifdef use_nls
#include <langinfo.h>
#include <locale.h>
#endif
using namespace std;

class CData {
  string city;
  string country;
  string wtime;
  struct {
    int hi;
    int low;
    int code;
    string name;
  } day[5];


public:
// Update script, City Code, XML File with result, Unit
  CData ( string, string, string, string);
  int get_code ( int );
  int get_high_temp ( int );
  int get_low_temp ( int );
  string get_name ( int );
  string get_city ( void );
  string get_country ( void );
  string get_time ( void );
};


string CData::get_name ( int dindex ) {
   if ( day[ dindex ].name == "Today" )  
      day[ dindex ].name = dgettext("mms-weather","Today");
   else if ( day[ dindex ].name == "Tomorrow" ) 
      day[ dindex ].name = dgettext("mms-weather","Tomorrow");
   else if ( day[ dindex ].name == "Monday" ) 
      day[ dindex ].name = dgettext("mms-weather","Monday");
   else if ( day[ dindex ].name == "Tuesday" ) 
      day[ dindex ].name = dgettext("mms-weather","Tuesday");
   else if ( day[ dindex ].name == "Wednesday" ) 
      day[ dindex ].name = dgettext("mms-weather","Wednesday");
   else if ( day[ dindex ].name == "Thursday" ) 
      day[ dindex ].name = dgettext("mms-weather","Thursday");
   else if ( day[ dindex ].name == "Friday" ) 
      day[ dindex ].name = dgettext("mms-weather","Friday");
   else if ( day[ dindex ].name == "Saturday" ) 
      day[ dindex ].name = dgettext("mms-weather","Saturday");
   else if ( day[ dindex ].name == "Sunday" ) 
      day[ dindex ].name = dgettext("mms-weather","Sunday");
    
   return (string) day[ dindex ].name;
}

int CData::get_code ( int dindex ) {
   return day[ dindex ].code;
}

int CData::get_high_temp ( int dindex ) {
   return day[ dindex ].hi;
}

int CData::get_low_temp ( int dindex ) {
   return day[ dindex ].low;
}

string CData::get_city ( void ) {
   return city;
}

string CData::get_country ( void ) {
   return country;
}

string CData::get_time ( void ) {
   return wtime;
}


CData::CData ( string xml_filename, string city_code, string data_file ,string data_unit)
{
  int iter=0;
   /*
  printf("weather: Using <%s> for updating weather information.\n", xml_filename.c_str() );
  printf("weather: Using <%s> as the code for your city.\n", city_code.c_str() );
  printf("weather: Using <%s> for file where information is stored.\n", data_file.c_str() );
  printf("weather: Using <%c> as unit (c=Celsius; f=Fahrenheit).\n", data_unit.c_str() );
*/
  TiXmlDocument doc(data_file.c_str());
  TiXmlElement* root_element;
  TiXmlElement* element;
  bool loadOkay = doc.LoadFile();
  if (loadOkay)
    {
      //      printf("\n%s:\n", data_file.c_str());
      //dump_to_stdout( &doc ); // defined later in the tutorial
    }
  else
    {
      cout << "weather: DEBUG: Failed to load file " <<  data_file << endl;
      day[0].name  = "missing";
      return;
    }

  root_element = doc.RootElement();
  day[0].name  = "N/A";
  TiXmlHandle myhandle(&doc);
  if (root_element != 0)
  {
     element=myhandle.FirstChild("weather").FirstChild("location").Element();
     city=element->Attribute("city");
     country=element->Attribute("country");
     element=myhandle.FirstChild("weather").FirstChild("location").FirstChild("currently").Element();
     if (element != 0) {
         wtime=element->Attribute("time24");
      
     } else  {
      /*
         wtime="N/A";
        struct stat s;
        stat (  data_file.c_str(), &s);
         cout << "weather: stat: " << conv::itos(s.st_mtime).c_str() << endl;
        time_t date;
        time(&date);
        time_t ddate = s.st_mtime;
        cout << "weather : time: " << ctime(&date)<< endl;
        cout << "weather : time2: " << ctime(&ddate)<< endl;
      */
        wtime = "N/A";

     }
     element = myhandle.FirstChild("weather").FirstChild("location").FirstChild("forecast").FirstChild("day").Element();
     if ( element == NULL ) {
       DialogWaitPrint pdialog(3000);
       pdialog.add_line(dgettext("mms-weather", "Weather information"));
       pdialog.add_line(dgettext("mms-weather", "currently not available."));
       pdialog.add_line("");
       pdialog.add_line(dgettext("mms-weather", "Please try again later."));
       pdialog.print();
     } else {
     for ( element; element ; element=element->NextSiblingElement("day") )
       {
         day[iter].name   = (string)element->Attribute("name");
         element->FirstChildElement("temp")->QueryIntAttribute("high", &day[iter].hi);
         element->FirstChildElement("temp")->QueryIntAttribute("low",  &day[iter].low);
         element->FirstChildElement("condition")->QueryIntAttribute("code", &day[iter].code);
         iter++;
         /*
         //Gutes Bsp, um an den Text zwischen den Tags zu kommen
         TiXmlHandle myhandle(child);
         TiXmlText* text = myhandle.FirstChildElement("hi").FirstChild().Text();
         const char* message = text->Value();
         printf("weather: DEBUG: Temperature: hi:<%s>\n",  message );
         */
       }
     }
   }
}

Weather::Weather()
{
#ifdef use_nls
   setlocale(LC_ALL, ""); /* set from the environment variables */
   bindtextdomain("mms-weather", mms_prefix"/share/locale");
   bind_textdomain_codeset("mms-weather", nl_langinfo(CODESET));
#endif
   curlayer = 0;

}
std::string Weather::Print()
{
  WeatherConfig *weather_conf = S_WeatherConfig::get_instance();
  string Unit="°C";

  CData wdata (weather_conf->p_weather_update_script(),
          weather_conf->p_weather_city_code(),
          weather_conf->p_weather_data(),
          weather_conf->p_weather_unit()   
  );
  if ( wdata.get_name(0) == "N/A" ) return "failed";
  if ( weather_conf->p_weather_unit() != "c" ) 
    Unit="°F";
  else 
    Unit="°C";

  //if (!file_exists(weather_conf->p_weather_data())) {
  if ( wdata.get_name(0) == "missing" ) {

    DialogWaitPrint pdialog(3000);

    pdialog.add_line(dgettext("mms-weather", "Error downloading weather data"));
    pdialog.add_line("");
    pdialog.add_line(dgettext("mms-weather", "Please check your connection"));
    pdialog.add_line(dgettext("mms-weather", "and/or configuration file"));
    pdialog.print();

    return "failed";
  }

  render->prepare_new_image();

  render->current.add(new PObj(themes->weather_background, 0, 0, 0, SCALE_FULL));
  render->current.add(new PObj(themes->startmenu_weather, 25, 10, 1, NOSCALING));
  render->current.add(new TObj(dgettext("mms-weather","Weather"), "Vera/28", 100, 5,
                themes->weather_header_font1, themes->weather_header_font2,
                themes->weather_header_font3, 2));

  // Go and get weather data
  int dx_pos=conf->p_h_res() / 6;
  render->current.add(new TObj( wdata.get_city() + ", "  +  
                                wdata.get_country() /*+ " (" + 
                                dgettext("mms-weather","Info from: " ) +  
                                wdata.get_time() + ")" */,
            "Vera/16", dx_pos/2, 70,
            themes->weather_header_font1,
            themes->weather_header_font2,
            themes->weather_header_font3, 2) );
     for ( int iicon=0; iicon <5; iicon ++ ) {

       /* horizontal icon position of icons on screen */
       int x_pos=dx_pos*iicon + dx_pos;
       int icon_width = 110 ;

       render->current.add(new PObj("./weather/large_icons/" + conv::itos(wdata.get_code(iicon)) + ".png", x_pos - icon_width / 2, 170, 1, NOSCALING));

       int name_width = string_format::calculate_string_width( wdata.get_name(iicon) , "Vera/18");

       render->current.add(new TObj( wdata.get_name(iicon),
                 "Vera/18", x_pos - name_width / 2 , 120,
                 themes->weather_header_font1,
                 themes->weather_header_font2,
                 themes->weather_header_font3, 2) );

       string hw = dgettext("mms-weather","High:") + conv::itos(wdata.get_high_temp(iicon)) + Unit;
       int high_width = string_format::calculate_string_width(hw , "Vera/16");
       render->current.add(new TObj( hw, "Vera/16", x_pos - high_width / 2 , 280,
                 themes->weather_header_font1,
                 themes->weather_header_font2,
                 themes->weather_header_font3, 2) );

       string lw = dgettext("mms-weather","Low:") + conv::itos(wdata.get_low_temp(iicon)) + Unit;
       int low_width = string_format::calculate_string_width( lw, "Vera/16");
       render->current.add(new TObj( lw, "Vera/16", x_pos - low_width / 2 , 320,
                 themes->weather_header_font1,
                 themes->weather_header_font2,
                 themes->weather_header_font3, 2) );
    }

  render->device->animation_section_begin();
  render->device->switch_to_layer(curlayer+1);
  render->device->reset_layout_attribs_nowait();
  render->device->animation_zoom(0.90,0.90,1,1,40,curlayer+1);
  render->device->animation_fade(0,1,50,curlayer+1);
  render->device->animation_fade(1,0,60,curlayer);
  render->device->animation_section_end();

  render->draw_and_release("mms-weather");

  return "";
}

std::string Weather::mainloop()
{
  bool exit_loop=false;
  bool update_needed=false;
  bool failed=false;

  BusyIndicator *busy_indicator = S_BusyIndicator::get_instance();
  WeatherConfig *weather_conf = S_WeatherConfig::get_instance();

  string wget_string = "wget -q -t 4 -T 20 \"http://weather.yahooapis.com/forecastxml?p=" + 
                           weather_conf->p_weather_city_code() + "&u=" +
                           weather_conf->p_weather_unit() + "\" -O " + 
                           weather_conf->p_weather_data();

  cout << "wget: " << wget_string << endl;
  run::external_program( wget_string );
  cout << "wget executed successfully" << endl;
  render->device->animation_section_begin();
  curlayer = render->device->get_current_layer();
  render->device->animation_section_end();
  if (Print() == "failed")
    return "";

  Input input;

  // main input loop
  while (!exit_loop) {
    if (update_needed){
      update_needed=false;

      render->device->animation_section_begin();
      render->device->swap_layers(curlayer, curlayer+1);
      render->device->animation_section_end();
      failed =  ( Print() == "failed" );
    }
    //else 
      input = input_master->device->get_input_busy_wrapped(busy_indicator);
    
    if (input.command == "back" || failed == true )
    {
        exit_loop=true;
    }
    else
      update_needed=!global->check_commands(input);
  }
  render->device->animation_section_begin();
  render->device->switch_to_layer(curlayer);
  render->device->reset_layout_attribs_nowait();
  render->device->animation_fade(0,1,80,curlayer);
  render->device->animation_zoom(1,1,4,4,40,curlayer+1);
  render->device->animation_fade(1,0,40,curlayer+1);
  render->device->animation_section_end();
  return "";
}