summaryrefslogtreecommitdiff
path: root/protocols/Weather/weather_update.cpp
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:10:43 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:10:43 +0000
commit725f68b6808a8a30778f58223fac75386f082785 (patch)
treeccba410760749d45139e5e78fd5e08f416ade1a0 /protocols/Weather/weather_update.cpp
parentf920ef497f3299ae24fe783ce03bdd93b419f764 (diff)
plugins folders renaming
git-svn-id: http://svn.miranda-ng.org/main/trunk@61 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Weather/weather_update.cpp')
-rw-r--r--protocols/Weather/weather_update.cpp678
1 files changed, 678 insertions, 0 deletions
diff --git a/protocols/Weather/weather_update.cpp b/protocols/Weather/weather_update.cpp
new file mode 100644
index 0000000000..9b81b023f5
--- /dev/null
+++ b/protocols/Weather/weather_update.cpp
@@ -0,0 +1,678 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+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; version 2
+of the License.
+
+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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related to updating new weather
+information, both automatic (by timer) and manually (by selecting
+menu items).
+*/
+
+#include "weather.h"
+
+UPDATELIST *UpdateListHead;
+UPDATELIST *UpdateListTail;
+
+extern HANDLE hUpdateMutex;
+
+//============ RETRIEVE NEW WEATHER ============
+
+// retrieve weather info and display / log them
+// hContact = current contact
+int UpdateWeather(HANDLE hContact)
+{
+ char str[256], str2[MAX_TEXT_SIZE], logstr[256];
+ int code;
+ FILE *file;
+ DBVARIANT dbv;
+ BOOL Ch = FALSE;
+ WEATHERINFO winfo;
+ HWND hMoreDataDlg;
+ int dbres;
+
+ if (hContact == NULL) return 1; // some error prevention
+
+ dbv.pszVal = "";
+
+ // log to netlib log for debug purpose
+ Netlib_Logf(hNetlibUser, "************************************************************************");
+ dbres = DBGetContactSettingString(hContact, WEATHERPROTONAME, "Nick", &dbv);
+
+ Netlib_Logf(hNetlibUser, "<-- Start update for station: %s -->", dbv.pszVal);
+ mir_snprintf(logstr, sizeof(logstr), "<-- Update successful for station: %s -->", dbv.pszVal);
+
+ // download the info and parse it
+ // result are stored in database
+ code = GetWeatherData(hContact);
+ if (code != 0)
+ {
+ // error occurs if the return value is not equals to 0
+ if (opt.ShowWarnings)
+ { // show warnings by popup
+ mir_snprintf(str, sizeof(str)-105,
+ Translate("Unable to retrieve weather information for %s"), dbv.pszVal);
+ strcat(str, "\n");
+ strcat(str, GetError(code));
+ WPShowMessage(str, SM_WARNING);
+ }
+ // log to netlib
+ Netlib_Logf(hNetlibUser, "Error! Update cannot continue... Start to free memory");
+ Netlib_Logf(hNetlibUser, "<-- Error occurs while updating station: %s -->", dbv.pszVal);
+ if (!dbres) DBFreeVariant(&dbv);
+ return 1;
+ }
+ if (!dbres) DBFreeVariant(&dbv);
+
+ // initialize, load new weather Data
+ winfo = LoadWeatherInfo(hContact);
+
+ // translate weather condition
+ strcpy(winfo.cond, Translate(winfo.cond));
+
+ // compare the old condition and determine if the weather had changed
+ if (opt.UpdateOnlyConditionChanged) // consider condition change
+ {
+ if (!DBGetContactSettingString(hContact, WEATHERPROTONAME, "LastCondition", &dbv))
+ {
+ if (_stricmp(winfo.cond, dbv.pszVal)) Ch = TRUE; // the weather condition is changed
+ DBFreeVariant(&dbv);
+ }
+ else Ch = TRUE;
+ if (!DBGetContactSettingString(hContact, WEATHERPROTONAME, "LastTemperature", &dbv))
+ {
+ if (_stricmp(winfo.temp, dbv.pszVal)) Ch = TRUE; // the temperature is changed
+ DBFreeVariant(&dbv);
+ }
+ else Ch = TRUE;
+ }
+ else // consider update time change
+ {
+ if (!DBGetContactSettingString(hContact, WEATHERPROTONAME, "LastUpdate", &dbv))
+ {
+ if (_stricmp(winfo.update, dbv.pszVal)) Ch = TRUE; // the update time is changed
+ DBFreeVariant(&dbv);
+ }
+ else Ch = TRUE;
+ }
+
+ // have weather alert issued?
+ dbres = DBGetContactSettingString(hContact, WEATHERCONDITION, "Alert", &dbv);
+ if (!dbres && dbv.pszVal[0] != 0)
+ {
+ if (opt.AlertPopup && !DBGetContactSettingByte(hContact, WEATHERPROTONAME, "DPopUp", 0) && Ch)
+ {
+ // display alert popup
+ wsprintf(str, "Alert for %s%c%s", winfo.city, 255, dbv.pszVal);
+ WPShowMessage(str, SM_WEATHERALERT);
+ }
+ // alert issued, set display to italic
+ if (opt.MakeItalic)
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "ApparentMode", ID_STATUS_OFFLINE);
+ SkinPlaySound("weatheralert");
+ }
+ // alert dropped, set the display back to normal
+ else DBDeleteContactSetting(hContact, WEATHERPROTONAME, "ApparentMode");
+ if (!dbres) DBFreeVariant(&dbv);
+
+ // backup current condition for checking if the weather is changed or not
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastLog", winfo.update);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastCondition", winfo.cond);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastTemperature", winfo.temp);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastUpdate", winfo.update);
+
+ // display condition on contact list
+ if (opt.DisCondIcon && winfo.status != ID_STATUS_OFFLINE)
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "Status", ID_STATUS_ONLINE);
+ else
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "Status", winfo.status);
+ AvatarDownloaded(hContact);
+
+ GetDisplay(&winfo, opt.cText, str2);
+ if (lpcp != CP_ACP)
+ {
+ LPWSTR m_psz = ConvToUnicode(str2);
+ DBWriteContactSettingWString(hContact, "CList", "MyHandle", m_psz);
+ mir_free(m_psz);
+ }
+ else
+ DBWriteContactSettingString(hContact, "CList", "MyHandle", str2);
+
+ GetDisplay(&winfo, opt.sText, str2);
+ if (str2[0])
+ {
+ if (lpcp != CP_ACP)
+ {
+ wchar_t* m_psz = ConvToUnicode(str2);
+ DBWriteContactSettingWString(hContact, "CList", "StatusMsg", m_psz);
+ mir_free(m_psz);
+ }
+ else
+ DBWriteContactSettingString(hContact, "CList", "StatusMsg", str2);
+ }
+ else
+ DBDeleteContactSetting(hContact, "CList", "StatusMsg");
+
+ ProtoBroadcastAck(WEATHERPROTONAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, NULL, (LPARAM)(str2[0] ? str2 : 0));
+
+ // save descriptions in MyNotes
+ GetDisplay(&winfo, opt.nText, str2);
+ DBWriteContactSettingString(hContact, "UserInfo", "MyNotes", str2);
+ GetDisplay(&winfo, opt.xText, str2);
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, "WeatherInfo", str2);
+
+ // set the update tag
+ DBWriteContactSettingByte(hContact, WEATHERPROTONAME, "IsUpdated", TRUE);
+
+ // save info for default weather condition
+ if (!strcmp(winfo.id, opt.Default) && !opt.NoProtoCondition) {
+ // save current condition for default station to be displayed after the update
+ old_status = status;
+ status = winfo.status;
+ // a workaround for a default station that currently have an n/a icon assigned
+ if (status == ID_STATUS_OFFLINE) status = NOSTATUSDATA;
+ ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
+ }
+
+ // logging
+ if (Ch)
+ {
+ // play the sound event
+ SkinPlaySound("weatherupdated");
+
+ if (DBGetContactSettingByte(hContact, WEATHERPROTONAME, "File", 0))
+ {
+ // external log
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"Log",&dbv))
+ {
+ // for the option for overwriting the file, delete old file first
+ if (DBGetContactSettingByte(hContact,WEATHERPROTONAME,"Overwrite",0))
+ DeleteFile(dbv.pszVal);
+ // open the file and set point to the end of file
+ file = fopen( dbv.pszVal, "a");
+ DBFreeVariant(&dbv);
+ if (file != NULL)
+ {
+ // write data to the file and close
+ GetDisplay(&winfo, opt.eText, str2);
+ fputs(str2, file);
+ fclose(file);
+ }
+ }
+ }
+
+ if (DBGetContactSettingByte(hContact, WEATHERPROTONAME, "History", 0))
+ {
+ DBEVENTINFO dbei = {0};
+ // internal log using history
+ GetDisplay(&winfo, opt.hText, str2);
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = WEATHERPROTONAME;
+ dbei.timestamp = (DWORD)time(NULL);
+ dbei.flags = DBEF_READ;
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.cbBlob = (DWORD)strlen(str2)+1;
+ dbei.pBlob = (PBYTE)str2;
+
+ // add the history event
+ CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
+ }
+
+ // show the popup
+ NotifyEventHooks(hHookWeatherUpdated, (WPARAM)hContact, (LPARAM)Ch);
+ }
+
+ Netlib_Logf(hNetlibUser, "Update Completed - Start to free memory");
+
+ // free memory
+ Netlib_Logf(hNetlibUser, logstr);
+
+ // Update frame data
+ UpdateMwinData(hContact);
+
+ // update brief info if its opened
+ hMoreDataDlg = WindowList_Find(hDataWindowList, hContact);
+ if (hMoreDataDlg != NULL) PostMessage(hMoreDataDlg, WM_UPDATEDATA, 0, 0);
+ return 0;
+}
+
+//============ UPDATE LIST ============
+
+// a linked list queue for updating weather station
+// this function add a weather contact to the end of queue for update
+// hContact = current contact
+void UpdateListAdd(HANDLE hContact)
+{
+ UPDATELIST *newItem;
+
+ newItem = (UPDATELIST*)mir_alloc(sizeof(UPDATELIST));
+ newItem->hContact = hContact;
+ newItem->next = NULL;
+
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+
+ if (UpdateListTail == NULL) UpdateListHead = newItem;
+ else UpdateListTail->next = newItem;
+ UpdateListTail = newItem;
+
+ ReleaseMutex(hUpdateMutex);
+}
+
+// get the first item from the update queue and remove it from the queue
+// return value = the contact for next update
+HANDLE UpdateGetFirst()
+{
+ HANDLE hContact = NULL;
+
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+
+ if (UpdateListHead != NULL)
+ {
+ UPDATELIST* Item = UpdateListHead;
+
+ hContact = Item->hContact;
+ UpdateListHead = Item->next;
+ mir_free(Item);
+
+ if (UpdateListHead == NULL) UpdateListTail = NULL;
+ }
+
+ ReleaseMutex(hUpdateMutex);
+
+ return hContact;
+}
+
+void DestroyUpdateList(void)
+{
+ UPDATELIST *temp;
+
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+
+ temp = UpdateListHead;
+
+ // free the list one by one
+ while (temp != NULL)
+ {
+ UpdateListHead = temp->next;
+ mir_free(temp);
+ temp = UpdateListHead;
+ }
+ // make sure the entire list is clear
+ UpdateListTail = NULL;
+
+ ReleaseMutex(hUpdateMutex);
+}
+
+
+//============ UPDATE WEATHER ============
+
+// update all weather station
+// AutoUpdate = true if it is from automatic update using timer
+// false if it is from update by clicking the main menu
+void UpdateAll(BOOL AutoUpdate, BOOL RemoveData)
+{
+ // add all weather contact to the update queue list
+ HANDLE hContact= (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact != NULL)
+ {
+ if(IsMyContact(hContact))
+ {
+ if (!DBGetContactSettingByte(hContact,WEATHERPROTONAME,"AutoUpdate",FALSE) || !AutoUpdate)
+ {
+ if (RemoveData) DBDataManage((HANDLE)hContact, WDBM_REMOVE, 0, 0);
+ UpdateListAdd(hContact);
+ }
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+
+ // if it is not updating, then start the update thread process
+ // if it is updating, the stations just added to the queue will get updated by the already-running process
+ if (!ThreadRunning)
+ mir_forkthread(UpdateThreadProc, NULL);
+}
+
+// update a single station
+// wParam = handle for the weather station that is going to be updated
+INT_PTR UpdateSingleStation(WPARAM wParam, LPARAM lParam)
+{
+ if(IsMyContact((HANDLE)wParam))
+ {
+ // add the station to the end of the update queue
+ UpdateListAdd((HANDLE)wParam);
+
+ // if it is not updating, then start the update thread process
+ // if it is updating, the stations just added to the queue will get
+ // updated by the already-running process
+ if (!ThreadRunning)
+ mir_forkthread(UpdateThreadProc, NULL);
+ }
+
+ return 0;
+}
+
+// update a single station with removing the old data
+// wParam = handle for the weather station that is going to be updated
+INT_PTR UpdateSingleRemove(WPARAM wParam, LPARAM lParam)
+{
+ if(IsMyContact((HANDLE)wParam))
+ {
+ // add the station to the end of the update queue, and also remove old data
+ DBDataManage((HANDLE)wParam, WDBM_REMOVE, 0, 0);
+ UpdateListAdd((HANDLE)wParam);
+
+ // if it is not updating, then start the update thread process
+ // if it is updating, the stations just added to the queue will get updated by the already-running process
+ if (!ThreadRunning)
+ mir_forkthread(UpdateThreadProc, NULL);
+ }
+
+ return 0;
+}
+
+// update all weather thread
+// this thread update each weather station from the queue
+void UpdateThreadProc(LPVOID hWnd)
+{
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+ if (ThreadRunning)
+ {
+ ReleaseMutex(hUpdateMutex);
+ return;
+ }
+ ThreadRunning = TRUE; // prevent 2 instance of this thread running
+ ReleaseMutex(hUpdateMutex);
+
+ // update weather by getting the first station from the queue until the queue is empty
+ while (UpdateListHead != NULL && !Miranda_Terminated())
+ UpdateWeather(UpdateGetFirst());
+
+ NetlibHttpDisconnect();
+
+ // exit the update thread
+ ThreadRunning = FALSE;
+}
+
+// the "Update All" menu item in main menu
+INT_PTR UpdateAllInfo(WPARAM wParam,LPARAM lParam)
+{
+ if (!ThreadRunning) UpdateAll(FALSE, FALSE);
+ return 0;
+}
+
+// the "Update All" menu item in main menu and remove the old data
+INT_PTR UpdateAllRemove(WPARAM wParam,LPARAM lParam) {
+ if (!ThreadRunning) UpdateAll(FALSE, TRUE);
+ return 0;
+}
+
+//============ GETTING WEATHER DATA ============
+
+// getting weather data and save them into the database
+// hContact = the contact to get the data
+int GetWeatherData(HANDLE hContact)
+{
+ char *loc, id[256], Svc[256], DataValue[MAX_DATA_LEN], *szData = NULL, *szInfo;
+ int retval, i;
+ WIDATAITEMLIST* Item;
+ WIDATA *Data;
+ WORD cond = NA;
+
+ // get eacnh part of the id's
+ GetStationID(hContact, id, sizeof(id));
+
+ // test ID format
+ loc = strchr(id, '/');
+ if (loc == NULL) return INVALID_ID_FORMAT;
+
+ GetID(id);
+ GetStationID(hContact, Svc, sizeof(Svc));
+ GetSvc(Svc);
+
+ // check for invalid station
+ if (id[0] == 0) return INVALID_ID;
+ if (Svc[0] == 0) return INVALID_SVC;
+
+ // get the update strings (loaded to memory from ini files)
+ Data = GetWIData(Svc);
+ if (Data == NULL) return SVC_NOT_FOUND; // the ini for the station cannot be found
+
+ for (i=0; i<4; ++i)
+ {
+ // generate update URL
+ switch(i)
+ {
+ case 0:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL)+128);
+ wsprintf(loc, Data->UpdateURL, id);
+ break;
+
+ case 1:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL2)+128);
+ wsprintf(loc, Data->UpdateURL2, id);
+ break;
+
+ case 2:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL3)+128);
+ wsprintf(loc, Data->UpdateURL3, id);
+ break;
+
+ case 3:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL4)+128);
+ wsprintf(loc, Data->UpdateURL4, id);
+ break;
+ }
+
+ if (loc[0] == 0)
+ {
+ mir_free(loc);
+ continue;
+ }
+
+ // download the html file from the internet
+ retval = InternetDownloadFile(loc, Data->Cookie, &szData);
+ mir_free(loc);
+
+ if (retval != 0)
+ {
+ mir_free(szData);
+ return retval;
+ }
+ else if (strstr(szData, "Document Not Found") != NULL) {
+ mir_free(szData);
+ return DOC_NOT_FOUND;
+ }
+
+ szInfo = szData;
+
+ Item = Data->UpdateData;
+
+ // begin parsing item by item
+ while (Item != NULL)
+ {
+ if (Item->Item.Url[0] != 0 && Item->Item.Url[0] != (i + '1'))
+ {
+ Item = Item->Next;
+ continue;
+ }
+
+ switch (Item->Item.Type)
+ {
+ case WID_NORMAL:
+ // if it is a normal item with start= and end=, then parse through the downloaded string
+ // to get a data value.
+ GetDataValue(&Item->Item, DataValue, &szInfo);
+ if (strcmp(Item->Item.Name, "Condition") && _stricmp(Item->Item.Unit, "Cond"))
+ strcpy(DataValue, Translate(DataValue));
+ break;
+
+ case WID_SET:
+ {
+ // for the "Set Data=" operation
+ DBVARIANT dbv;
+ char *chop, *str, str2[MAX_DATA_LEN];
+ BOOL hasvar = FALSE;
+ size_t stl;
+
+ // get the set data operation string
+ str = Item->Item.End;
+ DataValue[0] = 0;
+ // go through each part of the operation string seperated by the & operator
+ do {
+ chop = strstr(str, " & ");
+ // the end of the string, last item
+ if (chop == NULL) chop = strchr(str, '\0');
+
+ stl = min(sizeof(str2)-1, (unsigned)(chop-str-2));
+ strncpy(str2, str+1, stl);
+ str2[stl] = 0;
+
+ switch(str[0])
+ {
+ case '[': // variable, add the value to the result string
+ hasvar = TRUE;
+ if (!DBGetData(hContact, str2, &dbv))
+ {
+ strncat(DataValue, dbv.pszVal, sizeof(DataValue)-strlen(DataValue));
+ DataValue[sizeof(DataValue)-1]=0;
+ DBFreeVariant(&dbv);
+ }
+ break;
+
+ case'\"': // constant, add it to the result string
+ strncat(DataValue, Translate(str2), sizeof(DataValue)-strlen(DataValue));
+ DataValue[sizeof(DataValue)-1]=0;
+ break;
+ }
+
+ // remove the front part of the string that is done and continue parsing
+ str = chop + 3;
+ } while (chop[0] && str[0]);
+
+ if (!hasvar) ConvertDataValue(&Item->Item, DataValue);
+ break;
+ }
+ case WID_BREAK:
+ {
+ // for the "Break Data=" operation
+ char *end;
+ DBVARIANT dbv;
+ if (!DBGetData(hContact, Item->Item.Start, &dbv))
+ {
+ strncpy(DataValue, dbv.pszVal, sizeof(DataValue));
+ DataValue[sizeof(DataValue)-1] = 0;
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ DataValue[0] = 0;
+ break; // do not continue if the source is invalid
+ }
+
+ // generate the strings
+ end = strstr(DataValue, Item->Item.Break);
+ if (end == NULL)
+ {
+ DataValue[0] = 0;
+ break; // exit if break string is not found
+ }
+ *end = '\0';
+ end+=strlen(Item->Item.Break);
+ while (end[0] == ' ') end++; // remove extra space
+
+ ConvertDataValue(&Item->Item, DataValue);
+
+ // write the 2 strings created from the break operation
+// DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, DataValue);
+ if (Item->Item.End[0])
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.End, end);
+ break;
+ }
+ }
+
+ // don't store data if it is not available
+ if ((DataValue[0] != 0 && strcmp(DataValue, NODATA) &&
+ strcmp(DataValue, Translate(NODATA)) && strcmp(Item->Item.Name, "Ignore")) ||
+ (!strcmp(Item->Item.Name, "Alert") && i == 0))
+ {
+ // temporary workaround for mToolTip to show feel-like temperature
+ if (!strcmp(Item->Item.Name, "Feel"))
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, "Heat Index", DataValue);
+ GetStationID(hContact, Svc, sizeof(Svc));
+ if (strcmp(Svc, opt.Default) == 0)
+ DBWriteContactSettingString(NULL, DEFCURRENTWEATHER, Item->Item.Name, DataValue);
+ if (strcmp(Item->Item.Name, "Condition") == 0)
+ {
+ char buf[128], *cbuf;
+ mir_snprintf(buf, sizeof(buf), "#%s Weather", DataValue);
+ cbuf = Translate(buf);
+ if (cbuf[0] == '#')
+ cbuf = Translate(DataValue);
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, cbuf);
+ CharLowerBuff(DataValue, (int)strlen(DataValue));
+ cond = GetIcon(DataValue, Data);
+ }
+ else if (_stricmp(Item->Item.Unit, "Cond") == 0)
+ {
+ char buf[128], *cbuf;
+ mir_snprintf(buf, sizeof(buf), "#%s Weather", DataValue);
+ cbuf = Translate(buf);
+ if (cbuf[0] == '#')
+ cbuf = Translate(DataValue);
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, cbuf);
+ }
+ else
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, DataValue);
+ }
+ Item = Item->Next;
+ }
+ mir_free(szData);
+ }
+
+ // assign condition icon
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "StatusIcon", cond);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "MirVer", Data->DisplayName);
+
+ return 0;
+}
+
+//============ UPDATE TIMERS ============
+
+// main auto-update timer
+void CALLBACK timerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ // only run if it is not current updating and the auto update option is enabled
+ if (!ThreadRunning && opt.CAutoUpdate && !Miranda_Terminated() &&
+ (!opt.NoProtoCondition || status == ID_STATUS_ONLINE))
+ UpdateAll(TRUE, FALSE);
+}
+
+// temporary timer for first run
+// when this is run, it kill the old startup timer and create the permenant one above
+void CALLBACK timerProc2(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(NULL, timerId);
+ ThreadRunning = FALSE;
+
+ if (!Miranda_Terminated())
+ {
+ if (opt.StartupUpdate && !opt.NoProtoCondition)
+ UpdateAll(FALSE, FALSE);
+ timerId = SetTimer(NULL, 0, ((int)opt.UpdateTime)*60000, (TIMERPROC)timerProc);
+ }
+}
+