通过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


相关文章
|
4月前
|
数据采集 数据挖掘 Go
踏入网页抓取的旅程:使用 grequests 构建 Go 视频下载器
使用 Go 和 grequests 构建 Bilibili 视频下载器,结合爬虫代理 IP 提高下载稳定性与速度。通过获取视频信息、构建下载链接、设置代理IP及异步请求,实现视频的本地保存。代码示例展示了如何运用 grequests 请求选项配置代理及处理请求。
踏入网页抓取的旅程:使用 grequests 构建 Go 视频下载器
|
11月前
|
Java 开发工具 Android开发
猿创征文|工具百宝箱-代码编辑器-版本控制工具-终端神器-项目与事务跟踪工具-SFTP客户端
猿创征文|工具百宝箱-代码编辑器-版本控制工具-终端神器-项目与事务跟踪工具-SFTP客户端
|
数据可视化 Ubuntu Linux
研发实用工具,推荐一款代码统计神器GitStats
研发实用工具,推荐一款代码统计神器GitStats
1290 0
研发实用工具,推荐一款代码统计神器GitStats
|
JSON Java API
一款适合IT团队的在线API文档、技术文档工具-showdoc介绍
为大家推荐一款适合IT团队的在线API文档、技术文档工具,有免费开源和在线托管的版本。可以直接使用官网搭建好的地址,也可以在自己的服务器上搭建。
一款适合IT团队的在线API文档、技术文档工具-showdoc介绍
|
14天前
|
开发者 存储 API
Xamarin 开发者的社区资源概览:从官方文档到GitHub示例,全面探索提升开发技能与解决问题的多元化渠道与实用工具
【8月更文挑战第31天】Xamarin 开发者社区资源概览旨在提升开发效率与解决问题,涵盖官方文档、社区论坛、GitHub 项目等。官方文档详尽,涵盖 Xamarin.Forms 使用、性能优化等;社区论坛供交流心得;GitHub 提供示例代码。此外,第三方博客、视频教程及 Xamarin University 等资源也丰富多样,适合各阶段开发者学习与提升。通过综合利用这些资源,开发者可不断进步,应对技术挑战。
29 0
|
4月前
|
运维 监控 前端开发
功能强大的国产API管理神器 Eolink,亲测好用
功能强大的国产API管理神器 Eolink,亲测好用
174 0
功能强大的国产API管理神器 Eolink,亲测好用
|
4月前
|
JSON 定位技术 开发工具
基于Python开发的高德地图+58租房系统(源码+可执行程序+程序配置说明书+程序使用说明书)
基于Python开发的高德地图+58租房系统(源码+可执行程序+程序配置说明书+程序使用说明书)
|
传感器 芯片
MicTR01 Tester 开发套件(工程监测仪器开发)使用说明
MicTR01 是专门为稳控科技的系列振弦模块 VM5/6/7和电子标签读写模块 TR01 开发测试、开发套件。使用 STC8 位 51 单片机为核心部件,演示上述各个型号模块的基本用法,包括了模块使用时的硬件连接和软件驱动的常规方法。也可以使用本套件的公开技术资料自行编写代码在套件上进行软硬件测试。
MicTR01 Tester 开发套件(工程监测仪器开发)使用说明
|
机器学习/深度学习 开发者 Python
FastAPI的小兄弟,开发命令行工具更给力
FastAPI的小兄弟,开发命令行工具更给力
222 0
FastAPI的小兄弟,开发命令行工具更给力