summaryrefslogtreecommitdiff
path: root/protocols/Weather/src/weather_update.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2012-11-28 18:45:54 +0000
committerGeorge Hazan <george.hazan@gmail.com>2012-11-28 18:45:54 +0000
commita70382b0e8bed265a1d314d9f6aae8f2dd48d20b (patch)
tree9a99a073c0d7b9483dab51a0eebf04a9119f61ed /protocols/Weather/src/weather_update.cpp
parent68fb5b69ea8403a3f9dcb70b3133eb10e1711000 (diff)
ex-protos moved to the Plugins folder
git-svn-id: http://svn.miranda-ng.org/main/trunk@2545 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Weather/src/weather_update.cpp')
-rw-r--r--protocols/Weather/src/weather_update.cpp615
1 files changed, 0 insertions, 615 deletions
diff --git a/protocols/Weather/src/weather_update.cpp b/protocols/Weather/src/weather_update.cpp
deleted file mode 100644
index d07af7865b..0000000000
--- a/protocols/Weather/src/weather_update.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
-Weather Protocol plugin for Miranda IM
-Copyright (c) 2012 Miranda NG Team
-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)
-{
- TCHAR str[256], str2[MAX_TEXT_SIZE];
- DBVARIANT dbv;
- BOOL Ch = FALSE;
-
- if (hContact == NULL) return 1; // some error prevention
-
- dbv.pszVal = "";
-
- // log to netlib log for debug purpose
- Netlib_LogfT(hNetlibUser, _T("************************************************************************"));
- int dbres = DBGetContactSettingTString(hContact, WEATHERPROTONAME, "Nick", &dbv);
-
- Netlib_LogfT(hNetlibUser, _T("<-- Start update for station -->"));
-
- // download the info and parse it
- // result are stored in database
- int 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_sntprintf(str, SIZEOF(str)-105,
- TranslateT("Unable to retrieve weather information for %s"), dbv.ptszVal);
- _tcscat(str, _T("\n"));
- _tcscat(str, GetError(code));
- WPShowMessage(str, SM_WARNING);
- }
- // log to netlib
- Netlib_LogfT(hNetlibUser, _T("Error! Update cannot continue... Start to free memory"));
- Netlib_LogfT(hNetlibUser, _T("<-- Error occurs while updating station: %s -->"), dbv.ptszVal);
- if ( !dbres) db_free(&dbv);
- return 1;
- }
- if ( !dbres) db_free(&dbv);
-
- // initialize, load new weather Data
- WEATHERINFO winfo = LoadWeatherInfo(hContact);
-
- // translate weather condition
- _tcscpy(winfo.cond, TranslateTS(winfo.cond));
-
- // compare the old condition and determine if the weather had changed
- if (opt.UpdateOnlyConditionChanged) { // consider condition change
- if ( !DBGetContactSettingTString(hContact, WEATHERPROTONAME, "LastCondition", &dbv)) {
- if (_tcsicmp(winfo.cond, dbv.ptszVal)) Ch = TRUE; // the weather condition is changed
- db_free(&dbv);
- }
- else Ch = TRUE;
- if ( !DBGetContactSettingTString(hContact, WEATHERPROTONAME, "LastTemperature", &dbv)) {
- if (_tcsicmp(winfo.temp, dbv.ptszVal)) Ch = TRUE; // the temperature is changed
- db_free(&dbv);
- }
- else Ch = TRUE;
- }
- else { // consider update time change
- if ( !DBGetContactSettingTString(hContact, WEATHERPROTONAME, "LastUpdate", &dbv)) {
- if (_tcsicmp(winfo.update, dbv.ptszVal)) Ch = TRUE; // the update time is changed
- db_free(&dbv);
- }
- else Ch = TRUE;
- }
-
- // have weather alert issued?
- dbres = DBGetContactSettingTString(hContact, WEATHERCONDITION, "Alert", &dbv);
- if ( !dbres && dbv.ptszVal[0] != 0) {
- if (opt.AlertPopup && !db_get_b(hContact, WEATHERPROTONAME, "DPopUp", 0) && Ch) {
- // display alert popup
- wsprintf(str, _T("Alert for %s%c%s"), winfo.city, 255, dbv.ptszVal);
- WPShowMessage(str, SM_WEATHERALERT);
- }
- // alert issued, set display to italic
- if (opt.MakeItalic)
- db_set_w(hContact, WEATHERPROTONAME, "ApparentMode", ID_STATUS_OFFLINE);
- SkinPlaySound("weatheralert");
- }
- // alert dropped, set the display back to normal
- else db_unset(hContact, WEATHERPROTONAME, "ApparentMode");
- if ( !dbres) db_free(&dbv);
-
- // backup current condition for checking if the weather is changed or not
- db_set_ts(hContact, WEATHERPROTONAME, "LastLog", winfo.update);
- db_set_ts(hContact, WEATHERPROTONAME, "LastCondition", winfo.cond);
- db_set_ts(hContact, WEATHERPROTONAME, "LastTemperature", winfo.temp);
- db_set_ts(hContact, WEATHERPROTONAME, "LastUpdate", winfo.update);
-
- // display condition on contact list
- if (opt.DisCondIcon && winfo.status != ID_STATUS_OFFLINE)
- db_set_w(hContact, WEATHERPROTONAME, "Status", ID_STATUS_ONLINE);
- else
- db_set_w(hContact, WEATHERPROTONAME, "Status", winfo.status);
- AvatarDownloaded(hContact);
-
- GetDisplay(&winfo, opt.cText, str2);
- db_set_ts(hContact, "CList", "MyHandle", str2);
-
- GetDisplay(&winfo, opt.sText, str2);
- if (str2[0])
- db_set_ts(hContact, "CList", "StatusMsg", str2);
- else
- db_unset(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);
- db_set_ts(hContact, "UserInfo", "MyNotes", str2);
- GetDisplay(&winfo, opt.xText, str2);
- db_set_ts(hContact, WEATHERCONDITION, "WeatherInfo", str2);
-
- // set the update tag
- db_set_b(hContact, WEATHERPROTONAME, "IsUpdated", TRUE);
-
- // save info for default weather condition
- if ( !_tcscmp(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 (db_get_b(hContact, WEATHERPROTONAME, "File", 0)) {
- // external log
- if ( !DBGetContactSettingTString(hContact,WEATHERPROTONAME, "Log",&dbv)) {
- // for the option for overwriting the file, delete old file first
- if (db_get_b(hContact,WEATHERPROTONAME, "Overwrite",0))
- DeleteFile(dbv.ptszVal);
- // open the file and set point to the end of file
- FILE *file = _tfopen( dbv.ptszVal, _T("a"));
- db_free(&dbv);
- if (file != NULL) {
- // write data to the file and close
- GetDisplay(&winfo, opt.eText, str2);
- _fputts(str2, file);
- fclose(file);
- } } }
-
- if (db_get_b(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|DBEF_UTF;
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.pBlob = (PBYTE)mir_utf8encodeT(str2);
- dbei.cbBlob = (DWORD)strlen((char*)dbei.pBlob)+1;
-
- // add the history event
- CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
- }
-
- // show the popup
- NotifyEventHooks(hHookWeatherUpdated, (WPARAM)hContact, (LPARAM)Ch);
- }
-
- Netlib_LogfT(hNetlibUser, _T("Update Completed - Start to free memory"));
- Netlib_LogfT(hNetlibUser, _T("<-- Update successful for station -->"));
-
- // Update frame data
- UpdateMwinData(hContact);
-
- // update brief info if its opened
- HWND 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 = (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)
-{
- WaitForSingleObject(hUpdateMutex, INFINITE);
-
- UPDATELIST *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 = db_find_first();
- while (hContact != NULL)
- {
- if (IsMyContact(hContact))
- {
- if ( !db_get_b(hContact,WEATHERPROTONAME, "AutoUpdate",FALSE) || !AutoUpdate)
- {
- if (RemoveData) DBDataManage((HANDLE)hContact, WDBM_REMOVE, 0, 0);
- UpdateListAdd(hContact);
- }
- }
- hContact = db_find_next(hContact);
- }
-
- // 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)
-{
- // get eacnh part of the id's
- TCHAR id[256];
- GetStationID(hContact, id, SIZEOF(id));
-
- // test ID format
- TCHAR* szInfo = _tcschr(id, '/');
- if (szInfo == NULL)
- return INVALID_ID_FORMAT;
-
- GetID(id);
-
- TCHAR Svc[256];
- 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)
- WIDATA *Data = GetWIData(Svc);
- if (Data == NULL)
- return SVC_NOT_FOUND; // the ini for the station cannot be found
-
- WIDATAITEMLIST* Item;
- WORD cond = NA;
- char loc[256];
- char* szId = mir_t2a( id );
- for ( int i=0; i<4; ++i) {
- // generate update URL
- switch(i) {
- case 0:
- _snprintf(loc, SIZEOF(loc), Data->UpdateURL, szId);
- break;
-
- case 1:
- _snprintf(loc, SIZEOF(loc), Data->UpdateURL2, szId);
- break;
-
- case 2:
- _snprintf(loc, SIZEOF(loc), Data->UpdateURL3, szId);
- break;
-
- case 3:
- _snprintf(loc, SIZEOF(loc), Data->UpdateURL4, szId);
- break;
- }
-
- if ( loc[0] == 0 )
- continue;
-
- // download the html file from the internet
- TCHAR* szData = NULL;
- int retval = InternetDownloadFile(loc, Data->Cookie, &szData);
- if (retval != 0) {
- mir_free(szData);
- return retval;
- }
- if ( _tcsstr(szData, _T("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;
- }
-
- TCHAR DataValue[MAX_DATA_LEN];
- 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 ( _tcscmp(Item->Item.Name, _T("Condition")) && _tcsicmp(Item->Item.Unit, _T("Cond")))
- _tcscpy(DataValue, TranslateTS(DataValue));
- break;
-
- case WID_SET:
- {
- // for the "Set Data=" operation
- DBVARIANT dbv;
- TCHAR *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 {
- // the end of the string, last item
- chop = _tcsstr(str, _T(" & "));
- if (chop == NULL)
- chop = _tcschr(str, '\0');
-
- stl = min(sizeof(str2)-1, (unsigned)(chop-str-2));
- _tcsncpy(str2, str+1, stl);
- str2[stl] = 0;
-
- switch(str[0]) {
- case '[': // variable, add the value to the result string
- hasvar = TRUE;
- if ( !DBGetData(hContact, _T2A(str2), &dbv)) {
- _tcsncat(DataValue, dbv.ptszVal, SIZEOF(DataValue) - _tcslen(DataValue));
- DataValue[SIZEOF(DataValue)-1] = 0;
- db_free(&dbv);
- }
- break;
-
- case'\"': // constant, add it to the result string
- _tcsncat(DataValue, TranslateTS(str2), SIZEOF(DataValue) - _tcslen(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
- DBVARIANT dbv;
- if ( !DBGetData(hContact, _T2A(Item->Item.Start), &dbv)) {
- _tcsncpy(DataValue, dbv.ptszVal, SIZEOF(DataValue));
- DataValue[SIZEOF(DataValue)-1] = 0;
- db_free(&dbv);
- }
- else {
- DataValue[0] = 0;
- break; // do not continue if the source is invalid
- }
-
- // generate the strings
- TCHAR* end = _tcsstr(DataValue, Item->Item.Break);
- if (end == NULL) {
- DataValue[0] = 0;
- break; // exit if break string is not found
- }
- *end = '\0';
- end += _tcslen(Item->Item.Break);
- while (end[0] == ' ')
- end++; // remove extra space
-
- ConvertDataValue(&Item->Item, DataValue);
-
- // write the 2 strings created from the break operation
- if (Item->Item.End[0])
- db_set_ts(hContact, WEATHERCONDITION, _T2A(Item->Item.End), end);
- break;
- } }
-
- // don't store data if it is not available
- if ((DataValue[0] != 0 && _tcscmp(DataValue, NODATA) &&
- _tcscmp(DataValue, TranslateTS(NODATA)) && _tcscmp(Item->Item.Name, _T("Ignore"))) ||
- ( !_tcscmp(Item->Item.Name, _T("Alert")) && i == 0))
- {
- // temporary workaround for mToolTip to show feel-like temperature
- if ( !_tcscmp(Item->Item.Name, _T("Feel")))
- db_set_ts(hContact, WEATHERCONDITION, "Heat Index", DataValue);
- GetStationID(hContact, Svc, SIZEOF(Svc));
- if ( !_tcscmp(Svc, opt.Default))
- db_set_ts(NULL, DEFCURRENTWEATHER, _T2A(Item->Item.Name), DataValue);
- if ( !_tcscmp(Item->Item.Name, _T("Condition"))) {
- TCHAR buf[128], *cbuf;
- mir_sntprintf(buf, SIZEOF(buf), _T("#%s Weather"), DataValue);
- cbuf = TranslateTS(buf);
- if (cbuf[0] == '#')
- cbuf = TranslateTS(DataValue);
- db_set_ts(hContact, WEATHERCONDITION, _T2A(Item->Item.Name), cbuf);
- CharLowerBuff(DataValue, (DWORD)_tcslen(DataValue));
- cond = GetIcon(DataValue, Data);
- }
- else if ( _tcsicmp(Item->Item.Unit, _T("Cond")) == 0) {
- TCHAR buf[128], *cbuf;
- mir_sntprintf(buf, SIZEOF(buf), _T("#%s Weather"), DataValue);
- cbuf = TranslateTS(buf);
- if (cbuf[0] == '#')
- cbuf = TranslateTS(DataValue);
- db_set_ts(hContact, WEATHERCONDITION, _T2A(Item->Item.Name), cbuf);
- }
- else db_set_ts(hContact, WEATHERCONDITION, _T2A(Item->Item.Name), DataValue);
- }
- Item = Item->Next;
- }
- mir_free(szData);
- }
-
- // assign condition icon
- db_set_w(hContact, WEATHERPROTONAME, "StatusIcon", cond);
- db_set_ts(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);
- }
-}
-