X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=emacs_el%2Forg-google-weather.el;h=2acf96010413f5f93eb075ec40bc631127fd81ca;hb=3d9e3a2d70d86fb98f5e72f1992a84e30ad3be03;hp=9961601b5ef09c52597c66654b249aa2bcfb32f6;hpb=0152527e90fffa31e2c90c6d596f2689f781305d;p=lib.git diff --git a/emacs_el/org-google-weather.el b/emacs_el/org-google-weather.el index 9961601..2acf960 100644 --- a/emacs_el/org-google-weather.el +++ b/emacs_el/org-google-weather.el @@ -36,17 +36,29 @@ (require 'google-weather) (require 'image) +(require 'format-spec) +(require 'solar) (defgroup org-google-weather nil "Google Weather for Org mode." - :group 'comm) + :group 'comm + :group 'org) -;; Org mode support -(defcustom org-google-weather-location - "Paris" +(defcustom org-google-weather-location calendar-location-name "Default location for org-google-weather." :group 'org-google-weather) +(defcustom org-google-weather-format "%i %c, [%l,%h] %s" + "String to return to describe the weather. +Valid %-sequences are: + - %i the icon + - %c means the weather condition + - %L the supplied location + - %C the city the weather is for + - %l the lower temperature + - %h the higher temperature + - %s the temperature unit symbol") + (defcustom org-google-weather-cache-time 43200 "Define for how many seconds we should cache the weather." :group 'org-google-weather) @@ -62,56 +74,102 @@ (defcustom org-google-weather-icon-alist '((chance_of_rain . "weather-showers-scattered.png") (chance_of_snow . "weather-snow.png") - (chance_of_storm "weather-storm.png") + (chance_of_storm . "weather-storm.png") + (cn_cloudy . "weather-overcast.png") + (cn_heavyrun . "weather-showers.png") + (cn_sunny . "weather-clear.png") (cloudy . "weather-overcast.png") (dust . "weather-fog.png") (flurries . "weather-storm.png") (fog . "weather-fog.png") (haze . "weather-fog.png") (icy . "weather-snow.png") + (jp_sunny . "weather-clear.png") + (jp_cloudy . "weather-overcast.png") (mist . "weather-storm.png") (mostly_cloudy . "weather-overcast.png") (mostly_sunny . "weather-clear.png") (partly_cloudy . "weather-few-clouds.png") (rain . "weather-showers.png") + (rain_snow . "weather-snow.png") (sleet . "weather-snow.png") (smoke . "weather-fog.png") (snow . "weather-snow.png") (storm . "weather-storm.png") (thunderstorm . "weather-storm.png") (sunny . "weather-clear.png")) - "Icons to used to illustrate the weather.") + "Icons to use to illustrate the weather." + :group 'org-google-weather) +(defcustom org-google-weather-use-google-icons nil + "Fetch icons from Google or use local ones. +If you decide to use local ones, you should check +`org-google-weather-icon-directory' and +`org-google-weather-icon-alist'. Otherwise, if you want to use +icons from Google, you have nothing to do." + :group 'org-google-weather + :type 'boolean) + +(defun org-google-weather-get-icon (url) + (with-current-buffer + (google-weather-retrieve-data-raw url org-google-weather-cache-time) + (goto-char (point-min)) + (unless (search-forward "\n\n" nil t) + (error "Data not found")) + (let ((data (buffer-substring (point) (point-max)))) + (kill-buffer (current-buffer)) + data))) + +;;;###autoload (defun org-google-weather (&optional location language) "Return Org entry with the weather for LOCATION in LANGUAGE. If LOCATION is not set, use org-google-weather-location." - (let* ((data (google-weather-get-data (or location - org-google-weather-location) - language - org-google-weather-cache-time)) - (forecast (google-weather-data->forecast-for-date data date))) - (when forecast - (let ((condition (cadr (assoc 'condition forecast))) - (low (cadr (assoc 'low forecast))) - (high (cadr (assoc 'high forecast))) - ;; But *they* told me it's just about calling functions! - (icon (cdr - (assoc - (intern - (file-name-sans-extension - (file-name-nondirectory - (cadr (assoc 'icon forecast))))) - org-google-weather-icon-alist))) - (temp-symbol (google-weather-data->temperature-symbol data))) - (concat - (if org-google-weather-display-icon-p - (concat (propertize "icon" - 'display - (create-image - (concat org-google-weather-icon-directory "/" icon)) - 'rear-nonsticky '(display)) - " ") - "") - condition ", " low "-" high " " temp-symbol))))) + (let* ((location (or location org-google-weather-location)) + (data (ignore-errors + (google-weather-get-data location + language + org-google-weather-cache-time))) + (problem-cause (when data (google-weather-data->problem-cause data))) + (forecast (when (and (null problem-cause) data) + (google-weather-data->forecast-for-date data date)))) + (if problem-cause + (message "%s: %s" location problem-cause) + (when forecast + (let ((condition (cadr (assoc 'condition forecast))) + (low (cadr (assoc 'low forecast))) + (high (cadr (assoc 'high forecast))) + (city (google-weather-data->city data)) + ;; But *they* told me it's just about calling functions! + (icon (when (and org-google-weather-display-icon-p (display-images-p)) + (if org-google-weather-use-google-icons + (create-image (org-google-weather-get-icon + (cadr (assoc 'icon forecast))) + nil t) + (create-image + (concat + org-google-weather-icon-directory + "/" + (cdr + (assoc + (intern + (file-name-sans-extension + (file-name-nondirectory + (cadr (assoc 'icon forecast))))) + org-google-weather-icon-alist))))))) + (temp-symbol (google-weather-data->temperature-symbol data))) + (format-spec org-google-weather-format + `((?i . ,(if icon + (propertize "icon" + 'display + (append + icon '(:ascent center)) + 'rear-nonsticky '(display)) + "")) + (?c . ,condition) + (?L . ,location) + (?C . ,city) + (?l . ,low) + (?h . ,high) + (?s . ,temp-symbol)))))))) (provide 'org-google-weather)