/* * Weather Underground module for Ayttm * * Copyright (C) 2007, Philip S Tellis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifdef __MINGW32__ #define __IN_PLUGIN__ #include #endif #include "intl.h" #include #include #ifndef strcasestr char *strcasestr(const char *haystack, const char *needle); #endif #include #include #ifndef isblank int isblank(int c); #endif #include #include "externs.h" #include "prefs.h" #include "plugin_api.h" #include "llist.h" #include "platform_defs.h" #include "tcp_util.h" /******************************************************************************* * Begin Module Code ******************************************************************************/ /* Module defines */ #define plugin_info weather_LTX_plugin_info #define module_version weather_LTX_module_version /* Function Prototypes */ static char *weatherify(const eb_local_account * local, const eb_account * remote, const struct contact *contact, const char * s); static int weather_init(); static int weather_finish(); static int do_weather = 0; static char weather_host[] = "pipes.yahoo.com"; static char weather_path[] = "/pipes/pipe.run?_id=49eba00a0a1337451645d1dd6f02d9ff&_render=json&loc="; static int ref_count = 0; /* Module Exports */ PLUGIN_INFO plugin_info = { PLUGIN_FILTER, "Weather shortcut", "Fetch weather for a city using [weather: City, Country] syntax", "$Revision: 1.0 $", "$Date: 2007/11/12 20:26:49 $", &ref_count, weather_init, weather_finish, NULL, NULL }; /* End Module Exports */ unsigned int module_version() {return CORE_VERSION;} static int weather_init() { input_list *il = calloc(1, sizeof(input_list)); plugin_info.prefs = il; il->widget.checkbox.value = &do_weather; il->name = "do_weather"; il->label = _("Enable weather shortcuts"); il->type = EB_INPUT_CHECKBOX; eb_debug(DBG_MOD, "Weather initialised\n"); outgoing_message_filters = l_list_prepend(outgoing_message_filters, &weatherify); incoming_message_filters = l_list_append(incoming_message_filters, &weatherify); return 0; } static int weather_finish() { eb_debug(DBG_MOD, "Weather shutting down\n"); outgoing_message_filters = l_list_remove(outgoing_message_filters, &weatherify); incoming_message_filters = l_list_remove(incoming_message_filters, &weatherify); while(plugin_info.prefs) { input_list *il = plugin_info.prefs->next; free(plugin_info.prefs); plugin_info.prefs = il; } return 0; } /******************************************************************************* * End Module Code ******************************************************************************/ static int isurlchar(unsigned char c) { return (isalnum(c) || '-' == c || '_' == c); } static char *weather_urlencode(const char *instr) { int ipos=0, bpos=0; char *str = NULL; int len = strlen(instr); if(!(str = malloc(sizeof(char) * (3*len + 1)) )) return strdup(""); while(instr[ipos]) { while(isurlchar(instr[ipos])) str[bpos++] = instr[ipos++]; if(!instr[ipos]) break; snprintf(&str[bpos], 4, "%%%.2x", (instr[ipos]=='\r' || instr[ipos]=='\n'? ' ':instr[ipos])); bpos+=3; ipos++; } str[bpos]='\0'; /* free extra alloc'ed mem. */ len = strlen(str); str = realloc(str, sizeof(char) * (len+1)); return str; } static int do_http_get(const char *city) { char buff[4096]; int fd, i; char *city_enc = weather_urlencode(city); for(i=0; city_enc[i]; i++) city_enc[i] = tolower(city_enc[i]); fd = ay_socket_new(weather_host, 80); if (fd > 0) { snprintf(buff, sizeof(buff), "GET %s%s HTTP/1.1\r\n" "Host: %s\r\n" "User-Agent: Mozilla/4.5 [en] (%s/%s)\r\n" "\r\n", weather_path, city_enc, weather_host, PACKAGE, VERSION); write(fd, buff, strlen(buff)); } free(city_enc); return fd; } static char *weatherify(const eb_local_account * local, const eb_account * remote, const struct contact *contact, const char * s) { char *p=NULL, *start, *city_name, *suffix, *prefix; int len, pos=0; suffix = p = strdup(s); if (!do_weather) return p; /* We need to run s/\[weather:? ([a-zA-Z, ]+)\]//g */ if(!strcasestr(suffix, "[weather: ") && !strcasestr(suffix, "[weather ")) return p; while((start = strcasestr(suffix, "[weather: ")) || (start = strcasestr(suffix, "[weather "))) { int fd, i; char buf[1024]; int offset = 0; char *weather_line=NULL; start++; city_name = start+strlen("weather"); if(city_name[0] == ':') city_name++; for(; isblank(*city_name); city_name++) ; for(suffix = city_name; *suffix && *suffix != ']'; suffix++) ; /* if we don't have ] after "[weather: xyz" then syntax is wrong */ if(*suffix != ']') continue; /* XXX Do NOT destroy/modify the string before this point */ *(start-1) = '\0'; /* terminate string at [ so we can copy that from s */ suffix++; *(suffix-1) = '\0'; /* terminate string at ] so we can copy the city_name */ fd = do_http_get(city_name); while((ay_tcp_readline(buf+offset, sizeof(buf)-offset, fd)) > 0) { char *end, *st = strstr(buf, "\"content\":\""); offset=0; if(!st) continue; st += strlen("\"content\":\""); end = strstr(st, "\",\"description\""); if(end) { *end='\0'; weather_line = st; break; } else { /* append next line */ offset = strlen(buf); } } prefix = p; len = strlen(prefix) + strlen(suffix); if(weather_line) { for(i=0; weather_line[i]; i++) if(weather_line[i] == '\\' && (weather_line[i+1] == '"'|| weather_line[i+1] == '/')) memmove(weather_line+i, weather_line+i+1, strlen(weather_line+i+1)+1); len += strlen(weather_line); } else { len += strlen(city_name) + strlen("[weather: ]"); } p = calloc(len+1, sizeof(char)); if(weather_line) snprintf(p, len+1, "%s%s", prefix, weather_line); else snprintf(p, len+1, "%s[weather: %s]", prefix, city_name); pos = strlen(p); strncat(p, suffix, len-pos); suffix = p+pos; s = p; free(prefix); } return p; }