]> git.donarmstrong.com Git - lib.git/blobdiff - emacs_el/google-weather.el
ess configuration is now in don-configuration.org
[lib.git] / emacs_el / google-weather.el
index d86165d23d781fee5c871ec19252734ecb713ce7..4ecf3bc9f330e562bb28460fd83a0009f4995453 100644 (file)
 (require 'xml)
 (require 'time-date)
 
+(eval-when-compile
+  (require 'cl))
+
 (defgroup google-weather nil
   "Google Weather."
   :group 'comm)
 
+(defcustom google-weather-use-https nil
+  "Default protocol to use to access the Google Weather API."
+  :group 'google-weather
+  :type 'boolean)
+
 (defconst google-weather-url
-  "http://www.google.com/ig/api"
-  "URL used to access the Google Weather API.")
+  "www.google.com/ig/api"
+  "URL of the Google Weather API.")
 
 (defconst google-weather-image-url
   "http://www.google.com"
@@ -57,7 +65,7 @@
              (if cache-time
                  (time-less-p
                   (time-add
-                   (url-is-cached url)
+                   cache-time
                    (seconds-to-time expire-time))
                   (current-time))
                t)))))
@@ -68,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
@@ -81,22 +89,32 @@ 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))
-      (search-forward "\n\n")
+      (unless (search-forward "\n\n" nil t)
+        (error "Data not found"))
       (decode-coding-region
        (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."
-  (concat google-weather-url "?weather=" (url-hexify-string location)
+  (concat "http" (when google-weather-use-https "s") "://" google-weather-url "?weather=" (url-hexify-string location)
           (when language
             (concat "&hl=" language))))
 
@@ -115,7 +133,7 @@ See `google-weather-retrieve-data' for the use of EXPIRE-TIME."
   (cddr (assoc 'forecast_information (google-weather-data->weather data))))
 
 (defun google-weather-assoc (key data)
-  "Do some sort of magic 'assoc to find fields in DATA."
+  "Extract value of field KEY from DATA."
   (cdr (assoc 'data (cadr (assoc key data)))))
 
 (defun google-weather-data->city (data)
@@ -125,19 +143,19 @@ See `google-weather-retrieve-data' for the use of EXPIRE-TIME."
    (google-weather-data->forecast-information data)))
 
 (defun google-weather-data->postal-code (data)
-  "Return the postal code where the data come from."
+  "Return the postal code where the DATA come from."
   (google-weather-assoc
    'postal_code
    (google-weather-data->forecast-information data)))
 
 (defun google-weather-data->unit-system (data)
-  "Return the unit system used for data."
+  "Return the unit system used for DATA."
   (google-weather-assoc
    'unit_system
    (google-weather-data->forecast-information data)))
 
 (defun google-weather-data->forecast-date (data)
-  "Return the unit system used for data."
+  "Return the unit system used for DATA."
   (google-weather-assoc
    'forecast_date
    (google-weather-data->forecast-information data)))
@@ -168,12 +186,30 @@ See `google-weather-retrieve-data' for the use of EXPIRE-TIME."
 
 (defun google-weather-data->forecast-for-date (data date)
   "Return forecast for DATE from DATA.
-DATE should be in the same format used by calendar i.e. (MONTH DAY YEAR)."
-  (cdr (assoc date
-              (google-weather-data->forecast data))))
+DATE should be in the same format used by calendar,
+i.e. (MONTH DAY YEAR)."
+  (cdr (assoc date (google-weather-data->forecast data))))
 
 (defun google-weather-data->temperature-symbol (data)
-  "Return the temperature to be used according to `google-weather-unit-system-temperature-assoc' in DATA."
+  "Return the temperature to be used according in DATA.
+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)