通过cobra开发天气查询小工具

简介: 通过cobra开发天气查询小工具

介绍 cobra


cobra 是一个 Golang 包,它提供了简单的接口来创建命令行程序。同时它也是一个应用程序,用来生成应用框架,从而开发以 cobra 为基础的应用。在 GitHub 上,有更多关于 cobra 的介绍。网上也有关于此项目的一些文章,只是 10 篇文章到最后可能 9 篇都是重复的,仅此而已。


说明


为了不增加文章的重复率,也为了达到学习的效果,通过此项目来实现一些小功能。最终的效果是通过命令行输入城市名或者城市码获取当前城市的温度情况。


1668568346283.jpg


实现


入口文件的目的只有一个初始化 cobra

func main() {
    _ = cmd.Execute()
}
package cmd
import (
    "github.com/spf13/cobra"
)
var (
    weatherCmd = &cobra.Command{
        Use: "weather",
    }
)
func Execute() error {
    return weatherCmd.Execute()
}

然后在其他的两个文件中,分别定义了此 cmd 的两个子命令。分别表示通过城市名称 NameCmd 和通过城市码 CodeCmd 来查询天气情况。


通过城市名称


package cmd
import (
    "errors"
    "fmt"
    "os"
    "github.com/spf13/cobra"
    "github.com/wuqinqiang/go-weather/server"
    "github.com/wuqinqiang/go-weather/tools"
)
func init() {
    NameCmd.PersistentFlags().StringP("name", "n", "", "input city name")
    weatherCmd.AddCommand(NameCmd)
}
var NameCmd = &cobra.Command{
    Use:   "name",
    Short: "check city weather by city name",
    Args: func(cmd *cobra.Command, args []string) error {
        name, err := cmd.Flags().GetString("name")
        if err != nil {
            return errors.New("please input city name")
        }
        if len(name) == 0 {
            return errors.New("请携带参数-n 或者 --name")
        }
        return nil
    },
    Run: func(cmd *cobra.Command, args []string) {
        name, _ := cmd.Flags().GetString("name")
        code := tools.CityMap[name]
        if code == 0 {
            fmt.Println("这个城市我不想查")
            os.Exit(1)
        }
        info, err := server.GetWeather(code)
        if err != nil {
            fmt.Println(err.Error())
            os.Exit(1)
        }
        fmt.Println("查询的天气是:", info)
    },
}

通过城市码


package cmd
import (
    "errors"
    "fmt"
    "os"
    "github.com/spf13/cobra"
    "github.com/wuqinqiang/go-weather/server"
)
func init() {
    codeCmd.PersistentFlags().IntP("code", "c", 0, "城市码必须是6位的整数")
    weatherCmd.AddCommand(codeCmd)
}
var codeCmd = &cobra.Command{
    Use:   "code",
    Short: "check city weather by city code",
    Args: func(cmd *cobra.Command, args []string) error {
        code, err := cmd.Flags().GetInt("code")
        if err != nil {
            return errors.New("请输入城市码")
        }
        if code == 0 {
            return errors.New("请携带参数-c 或者 --code")
        }
        return nil
    },
    Run: func(cmd *cobra.Command, args []string) {
        code, _ := cmd.Flags().GetInt("code")
        info, err := server.GetWeather(code)
        if err != nil {
            fmt.Println(err.Error())
            os.Exit(1)
        }
        fmt.Println("查询的天气是:", info)
    },
}

cobra.Command 里面的 Args 主要做一些参数验证,Run 就是实际工作功能,也是核心部分,大部分命令只会实现这一点。


至于获取天气,你可以看到 server.GetWeather 其实就是对接高德的 api 接口,发送了一个 http 请求罢了。

const (
     Key = "xx" //高德key
    Uri = "https://restapi.amap.com/v3/weather/weatherInfo" //api地址
)
//响应天气数据
func GetWeather(code int) (map[string]interface{}, error) {
    info, err := GetWeatherRequest(code)
    if err != nil {
        return nil, err
    }
    infoMap := make(map[string]interface{})
    infoMap["城市:"] = info.Lives[0].City
    infoMap["天气现象:"] = info.Lives[0].Weather
    infoMap["实时气温:"] = info.Lives[0].Temperature
    infoMap["数据发布:"] = info.Lives[0].Reporttime
    return infoMap, nil
}
//请求接口
func GetWeatherRequest(code int) (entity.ResponseInfo, error) {
    info := entity.ResponseInfo{}
    client := &http.Client{Timeout: 2 * time.Second}
    url := fmt.Sprintf(Uri+"?key=%s&city=%d", Key, code)
    resp, err := client.Get(url)
    if err != nil {
        fmt.Println("查询错误:", err)
        return info, errors.New("查询失败")
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("read body err:", err)
        return info, errors.New("查询失败")
    }
    if err := json.Unmarshal(body, &info); err != nil {
        fmt.Println("unmarshal response err:", err)
        return info, errors.New("查询失败,请输入正确的城市码")
    }
    if info.Status != "1" {
        return info, errors.New("api 密钥key错误,请检查")
    }
    return info, nil
}

这一块没咋么设计,使得获取天气的信息高度依赖于高德的接口,假设我们现在用其他的方式来获取天气,那么就需要大调整当前的代码。这一块理应抽象化。

最后,整个项目的结构如下:


1668568411752.jpg


相关文章
|
8月前
|
数据采集 数据挖掘 Go
踏入网页抓取的旅程:使用 grequests 构建 Go 视频下载器
使用 Go 和 grequests 构建 Bilibili 视频下载器,结合爬虫代理 IP 提高下载稳定性与速度。通过获取视频信息、构建下载链接、设置代理IP及异步请求,实现视频的本地保存。代码示例展示了如何运用 grequests 请求选项配置代理及处理请求。
102 3
踏入网页抓取的旅程:使用 grequests 构建 Go 视频下载器
|
8月前
|
JSON 开发工具 数据格式
基于Python开发的火车票分析助手(源码+可执行程序+程序配置说明书+程序使用说明书)
基于Python开发的火车票分析助手(源码+可执行程序+程序配置说明书+程序使用说明书)
140 0
|
小程序 JavaScript API
【Pyqt实战】全国天气查询小程序(含UI界面,python代码)
【Pyqt实战】全国天气查询小程序(含UI界面,python代码)
|
JavaScript 关系型数据库 测试技术
接口文档管理神器RAP2安装和部署
一 RAP2 RAP2是在RAP1基础上重做的新项目,它包含两个组件(对应两个Github Repository)。 rap2-delos: 后端数据API服务器,基于Koa + MySQLlink rap2-dolores: 前端静态资源,基于React link 什么是RAP? rap是一款API 文档管理工具,在 RAP 中,可以定义接口的 URL、请求 & 响应细节格式等等。
13071 0
|
5月前
|
测试技术 API 开发者
Python 魔法:打造你的第一个天气查询小工具自动化测试框架的构建与实践
【8月更文挑战第31天】在这篇文章中,我们将一起踏上编程的奇妙旅程。想象一下,只需几行代码,就能让计算机告诉你明天是否要带伞。是的,你没有听错,我们将用Python这把钥匙,解锁天气预报的秘密。不论你是编程新手还是想拓展技能的老手,这篇文章都会为你带来新的视角和灵感。所以,拿起你的键盘,让我们一起创造属于自己的天气小工具吧!
|
5月前
|
搜索推荐 API 数据处理
Python魔法:打造个性化天气查询工具
【8月更文挑战第31天】 在这篇文章中,我们将一起探索如何用Python构建一个个性化的天气查询工具。不同于传统的技术文章,我们将通过一个简单的故事引入主题,让读者感受到编程的乐趣和实用性。文章将介绍如何使用API获取数据,处理这些数据,并以用户友好的方式展示信息。无论你是编程新手还是想扩展你的项目库,这篇文章都会给你提供有价值的见解和代码示例。
|
7月前
|
Kubernetes Go 开发工具
怎样上手cobra
Cobra是Go语言中一个强大的命令行构建工具,被知名项目如Docker、Kubernetes和Etcd广泛使用。它支持完善的特性,如帮助、子命令和标志。创建命令时,通常包括命令、参数和标志。
|
JSON 数据格式 Python
使用python开发天气预报程序(带gui)
使用python开发天气预报程序(带gui)
194 0
|
JSON 数据可视化 API
PhalApi 2.x 开发文档 运行Hello World 编写第一个API接口
此文章假设你已成功安装PhalApi2项目,如果尚未安装,可阅读下载与安装。
|
JSON API PHP
漏刻有时API接口实战开发系列(6):PHP开发API接口离不开的curl函数封装
漏刻有时API接口实战开发系列(6):PHP开发API接口离不开的curl函数封装
81 0