]> git.donarmstrong.com Git - lib.git/commitdiff
update google weather
authorDon Armstrong <don@donarmstrong.com>
Thu, 4 Oct 2012 19:42:27 +0000 (19:42 +0000)
committerDon Armstrong <don@donarmstrong.com>
Thu, 4 Oct 2012 19:42:27 +0000 (19:42 +0000)
emacs_el/google-weather.el
emacs_el/org-google-weather.el

index be09e34cc4ed2a92d13fce8ee9ac4056cbc29814..4ecf3bc9f330e562bb28460fd83a0009f4995453 100644 (file)
   "Google Weather."
   :group 'comm)
 
-(defcustom google-weather-use-https t
+(defcustom google-weather-use-https nil
   "Default protocol to use to access the Google Weather API."
-  :group 'google-weather)
+  :group 'google-weather
+  :type 'boolean)
 
 (defconst google-weather-url
   "www.google.com/ig/api"
@@ -75,7 +76,7 @@
     (url-cache-extract (url-cache-create-filename url))
     (current-buffer)))
 
-(defun google-weather-retrieve-data (url &optional expire-time)
+(defun google-weather-retrieve-data-raw (url &optional expire-time)
   "Retrieve URL and return its data as string.
 If EXPIRE-TIME is set, the data will be fetched from the cache if
 their are not older than EXPIRE-TIME seconds. Otherwise, they
@@ -88,7 +89,18 @@ to 0 force a cache renewal."
                      (url-retrieve-synchronously url)
                    (google-weather-cache-fetch url)))
          data)
-    (with-current-buffer buffer
+    (when (and expired expire-time)
+      (url-store-in-cache buffer))
+    buffer))
+
+(defun google-weather-retrieve-data (url &optional expire-time)
+  "Retrieve URL and return its data as string.
+If EXPIRE-TIME is set, the data will be fetched from the cache if
+their are not older than EXPIRE-TIME seconds. Otherwise, they
+will be fetched and then cached. Therefore, setting EXPIRE-TIME
+to 0 force a cache renewal."
+    (with-current-buffer (google-weather-retrieve-data-raw
+                          url expire-time)
       (goto-char (point-min))
       (unless (search-forward "\n\n" nil t)
         (error "Data not found"))
@@ -96,11 +108,9 @@ to 0 force a cache renewal."
        (point) (point-max)
        (detect-coding-region (point) (point-max) t))
       (set-buffer-multibyte t)
-      (setq data (xml-parse-region (point) (point-max)))
-      (when (and expired expire-time)
-        (url-store-in-cache (current-buffer)))
-      (kill-buffer (current-buffer))
-      data)))
+      (let ((data (xml-parse-region (point) (point-max))))
+        (kill-buffer (current-buffer))
+        data)))
 
 (defun google-weather-build-url (location &optional language)
   "Build URL to retrieve weather for LOCATION in LANGUAGE."
@@ -186,4 +196,20 @@ It uses `google-weather-unit-system-temperature-assoc' to find a
 match."
   (cdr (assoc (google-weather-data->unit-system data) google-weather-unit-system-temperature-assoc)))
 
+
+(defun google-weather-data->problem-cause (data)
+  "Return a string if DATA contains a problem cause, `nil' otherwise.
+
+An error message example:
+
+((xml_api_reply
+  ((version . \"1\"))
+  (weather
+   ((module_id . \"0\") (tab_id . \"0\") (mobile_row . \"0\")
+    (mobile_zipped . \"1\") (row . \"0\") (section . \"0\"))
+   (problem_cause ((data . \"Information is temporarily unavailable.\"))))))))"
+  (google-weather-assoc
+   'problem_cause
+   (google-weather-data->weather data)))
+
 (provide 'google-weather)
index ccb4e46e1b4fae888c6ef08979f1fbc37af60280..2acf96010413f5f93eb075ec40bc631127fd81ca 100644 (file)
@@ -41,7 +41,8 @@
 
 (defgroup org-google-weather nil
   "Google Weather for Org mode."
-  :group 'comm)
+  :group 'comm
+  :group 'org)
 
 (defcustom org-google-weather-location calendar-location-name
   "Default location for org-google-weather."
@@ -97,50 +98,78 @@ Valid %-sequences are:
     (storm . "weather-storm.png")
     (thunderstorm . "weather-storm.png")
     (sunny . "weather-clear.png"))
-  "Icons to use 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 (ignore-errors
-                 (google-weather-get-data (or location
-                                              org-google-weather-location)
+  (let* ((location (or location org-google-weather-location))
+         (data (ignore-errors
+                 (google-weather-get-data location
                                           language
                                           org-google-weather-cache-time)))
-         (forecast (when data (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)))
-            (city (google-weather-data->city data))
-            ;; But *they* told me it's just about calling functions!
-            (icon (when window-system
-                    (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 (and icon org-google-weather-display-icon-p)
-                                  (propertize "icon"
-                                              'display
-                                              (append
-                                               (create-image
-                                                (concat
-                                                 org-google-weather-icon-directory
-                                                 "/"
-                                                 icon)) '(:ascent center))
-                                              'rear-nonsticky '(display))
-                                ""))
-                       (?c . ,condition)
-                       (?L . ,location)
-                       (?C . ,city)
-                       (?l . ,low)
-                       (?h . ,high)
-                       (?s . ,temp-symbol)))))))
+         (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)