#include #include #include #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 #include #ifdef use_nls #include #include #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 ""; }