diff options
| author | Craig Jennings <c@cjennings.net> | 2025-11-08 10:26:17 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-11-08 10:26:17 -0600 |
| commit | 44d48bad4d317ce8fd9361314d349b1256e6c25b (patch) | |
| tree | 90eeae6fd6512dc5418da1600e198a52cd29ee35 /wttrin.el | |
| parent | 7673e72ed4dc4af9c3db9a5962c4673bd1ce90e3 (diff) | |
| download | emacs-wttrin-44d48bad4d317ce8fd9361314d349b1256e6c25b.tar.gz emacs-wttrin-44d48bad4d317ce8fd9361314d349b1256e6c25b.zip | |
refactor: fetch: extract duplicate URL fetching logic into wttrin--fetch-url
- Created wttrin--fetch-url helper to eliminate code duplication
- Refactored wttrin-fetch-raw-string to use helper (27 lines -> 3 lines)
- Refactored wttrin--mode-line-fetch-weather to use helper (~30 lines -> ~10 lines)
- Added comprehensive ERT test suite with 9 tests covering normal, boundary, and error cases
- All tests passing
This refactoring provides a single point of truth for async URL fetching,
making the code more maintainable and reducing duplication by ~40 lines.
Diffstat (limited to 'wttrin.el')
| -rw-r--r-- | wttrin.el | 54 |
1 files changed, 19 insertions, 35 deletions
@@ -183,12 +183,12 @@ This is a pure function with no side effects, suitable for testing." (wttrin-additional-url-params) "A")) -(defun wttrin-fetch-raw-string (query callback) - "Asynchronously fetch weather information for QUERY. -CALLBACK is called with the weather data string when ready, or nil on error." - (let* ((url (wttrin--build-url query)) - (url-request-extra-headers (list wttrin-default-languages)) - (url-user-agent "curl")) +(defun wttrin--fetch-url (url callback) + "Asynchronously fetch URL and call CALLBACK with decoded response. +CALLBACK is called with the weather data string when ready, or nil on error. +Handles header skipping, UTF-8 decoding, and error handling automatically." + (let ((url-request-extra-headers (list wttrin-default-languages)) + (url-user-agent "curl")) (url-retrieve url (lambda (status) @@ -212,6 +212,11 @@ CALLBACK is called with the weather data string when ready, or nil on error." (setq data nil))) (funcall callback data)))))) +(defun wttrin-fetch-raw-string (query callback) + "Asynchronously fetch weather information for QUERY. +CALLBACK is called with the weather data string when ready, or nil on error." + (wttrin--fetch-url (wttrin--build-url query) callback)) + (defun wttrin-exit () "Exit the wttrin buffer." (interactive) @@ -401,38 +406,17 @@ Uses wttr.in custom format for concise weather with emoji." "?format=%l:+%c+%t+%C")) (url (concat "https://wttr.in/" (url-hexify-string location) - format-params)) - (url-request-extra-headers (list wttrin-default-languages)) - (url-user-agent "curl")) + format-params))) (when (featurep 'wttrin-debug) (message "wttrin mode-line: URL = %s" url)) - (url-retrieve + (wttrin--fetch-url url - (lambda (status) - (let ((data nil)) - (condition-case err - (if (plist-get status :error) - (progn - (message "wttrin mode-line: Network error - %s" - (cdr (plist-get status :error))) - (setq data nil)) - (unwind-protect - (progn - ;; Skip HTTP headers - (goto-char (point-min)) - (re-search-forward "\r?\n\r?\n" nil t) - (setq data (string-trim - (decode-coding-string - (buffer-substring-no-properties (point) (point-max)) - 'utf-8))) - (when (featurep 'wttrin-debug) - (message "wttrin mode-line: Received data = %S" data))) - (kill-buffer (current-buffer)))) - (error - (message "wttrin mode-line: Error - %s" (error-message-string err)) - (setq data nil))) - (when data - (wttrin--mode-line-update-display data)))))))) + (lambda (data) + (when data + (let ((trimmed-data (string-trim data))) + (when (featurep 'wttrin-debug) + (message "wttrin mode-line: Received data = %S" trimmed-data)) + (wttrin--mode-line-update-display trimmed-data)))))))) (defun wttrin--mode-line-update-display (weather-string) "Update mode-line display with WEATHER-STRING. |
