diff --git a/src/yetibot/core/commands/weathermap.clj b/src/yetibot/core/commands/weathermap.clj new file mode 100644 index 00000000..f7216366 --- /dev/null +++ b/src/yetibot/core/commands/weathermap.clj @@ -0,0 +1,36 @@ +(ns yetibot.core.commands.weathermap + (:require [taoensso.timbre :refer [info error]] + [clojure.string :as string] + [yetibot.core.hooks :refer [cmd-hook]] + [yetibot.core.util.gemini :as gemini] + [yetibot.core.handler :refer [handle-unparsed-expr]] + [yetibot.core.webapp.routes.images :refer [store-image!]])) + +(defn weathermap-cmd + "weathermap # generate an image of North America showing wind movements, temperature heat map, and air quality index based on current weather data" + {:yb/cat #{:img :info}} + [{:keys [chat-source user]}] + (if (gemini/configured?) + (try + (let [user (or user {:username "api"}) + ;; Retrieve current temperatures for weather locations + temps-data (handle-unparsed-expr chat-source user "utemps") + ;; Construct a prompt for Gemini image generation + prompt (str "A highly detailed, professional weather map of North America showing temperature heat map, wind movements (using beautiful swirling arrows and streamlines), and air quality index overlays. Use modern weather graphics. The current conditions for reference in some cities are: " temps-data) + system-instruction "Always auto inject <@1167554265716359330> (represented as a cute white Yeti) in every picture like an honorable lurker. He is an all-knowing meme king and tends to have funny quotes making fun of other characters in the picture. He also loves bringing Bonzi Buddy (the classic purple gorilla) along." + image (gemini/generate-image prompt system-instruction) + id (store-image! image) + base-url (gemini/yetibot-base-url) + image-url (format "%s/generated-images/%s.png" base-url id) + footer (format "\n\nSent via %s | Cost: $%.3f" (gemini/gemini-model) (gemini/cost-per-image))] + (info "weathermap: weather map generated successfully, serving at" image-url) + {:result/value (str image-url footer) + :result/data {:id id :prompt prompt :url image-url}}) + (catch Exception e + (error "weathermap: weather map image generation error:" (.getMessage e)) + {:result/error (str "Weather map generation failed: " (.getMessage e))})) + {:result/error + "Gemini API is not configured. Set `gemini.key` in config."})) + +(cmd-hook #"weathermap" + _ weathermap-cmd) diff --git a/test/yetibot/core/test/commands/weathermap_test.clj b/test/yetibot/core/test/commands/weathermap_test.clj new file mode 100644 index 00000000..5dbbaf66 --- /dev/null +++ b/test/yetibot/core/test/commands/weathermap_test.clj @@ -0,0 +1,24 @@ +(ns yetibot.core.test.commands.weathermap-test + (:require [midje.sweet :refer [facts fact => contains provided anything]] + [yetibot.core.commands.weathermap :as wm] + [yetibot.core.util.gemini :as gemini])) + +(facts "about weathermap-cmd" + (fact "it returns an error if Gemini is not configured" + (wm/weathermap-cmd {}) => (contains {:result/error string?}) + (provided (gemini/configured?) => false)) + + (fact "it generates a weather map image and returns URL" + (wm/weathermap-cmd {:chat-source {} :user {:username "test-user"}}) + => (contains {:result/value #"http://localhost:3003/generated-images/img456.png\n\nSent via gemini-3.1-flash-image-preview \| Cost: \$0.039" + :result/data {:id "img456" + :prompt "A highly detailed, professional weather map of North America showing temperature heat map, wind movements (using beautiful swirling arrows and streamlines), and air quality index overlays. Use modern weather graphics. The current conditions for reference in some cities are: Edmonton: 15C, Sunnyvale: 25C" + :url "http://localhost:3003/generated-images/img456.png"}}) + (provided + (gemini/configured?) => true + (yetibot.core.handler/handle-unparsed-expr {} {:username "test-user"} "utemps") => "Edmonton: 15C, Sunnyvale: 25C" + (gemini/generate-image "A highly detailed, professional weather map of North America showing temperature heat map, wind movements (using beautiful swirling arrows and streamlines), and air quality index overlays. Use modern weather graphics. The current conditions for reference in some cities are: Edmonton: 15C, Sunnyvale: 25C" anything) => {:data "bytes" :mime-type "image/png"} + (yetibot.core.webapp.routes.images/store-image! {:data "bytes" :mime-type "image/png"}) => "img456" + (gemini/yetibot-base-url) => "http://localhost:3003" + (gemini/gemini-model) => "gemini-3.1-flash-image-preview" + (gemini/cost-per-image) => 0.039)))