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 "";
}