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


相关文章
|
Java 开发工具 Android开发
猿创征文|工具百宝箱-代码编辑器-版本控制工具-终端神器-项目与事务跟踪工具-SFTP客户端
猿创征文|工具百宝箱-代码编辑器-版本控制工具-终端神器-项目与事务跟踪工具-SFTP客户端
105 0
|
数据可视化 Ubuntu Linux
研发实用工具,推荐一款代码统计神器GitStats
研发实用工具,推荐一款代码统计神器GitStats
1356 0
研发实用工具,推荐一款代码统计神器GitStats
|
JavaScript 关系型数据库 测试技术
接口文档管理神器RAP2安装和部署
一 RAP2 RAP2是在RAP1基础上重做的新项目,它包含两个组件(对应两个Github Repository)。 rap2-delos: 后端数据API服务器,基于Koa + MySQLlink rap2-dolores: 前端静态资源,基于React link 什么是RAP? rap是一款API 文档管理工具,在 RAP 中,可以定义接口的 URL、请求 & 响应细节格式等等。
12976 0
|
3月前
|
搜索推荐 API 数据处理
Python魔法:打造个性化天气查询工具
【8月更文挑战第31天】 在这篇文章中,我们将一起探索如何用Python构建一个个性化的天气查询工具。不同于传统的技术文章,我们将通过一个简单的故事引入主题,让读者感受到编程的乐趣和实用性。文章将介绍如何使用API获取数据,处理这些数据,并以用户友好的方式展示信息。无论你是编程新手还是想扩展你的项目库,这篇文章都会给你提供有价值的见解和代码示例。
|
3月前
|
开发者 存储 API
Xamarin 开发者的社区资源概览:从官方文档到GitHub示例,全面探索提升开发技能与解决问题的多元化渠道与实用工具
【8月更文挑战第31天】Xamarin 开发者社区资源概览旨在提升开发效率与解决问题,涵盖官方文档、社区论坛、GitHub 项目等。官方文档详尽,涵盖 Xamarin.Forms 使用、性能优化等;社区论坛供交流心得;GitHub 提供示例代码。此外,第三方博客、视频教程及 Xamarin University 等资源也丰富多样,适合各阶段开发者学习与提升。通过综合利用这些资源,开发者可不断进步,应对技术挑战。
48 0
|
6月前
|
NoSQL 关系型数据库 MySQL
『GitHub项目圈选03』Star 4.9k! 很全的一款适合开发人员的在线工具集
『GitHub项目圈选03』Star 4.9k! 很全的一款适合开发人员的在线工具集
|
6月前
|
前端开发
阿萨学工具:Apifox的高级Mock 功能
阿萨学工具:Apifox的高级Mock 功能
191 0
|
6月前
|
人工智能 JSON 开发工具
基于Python开发的AI智能联系人管理程序(源码+可执行程序+程序配置说明书+程序使用说明书)
基于Python开发的AI智能联系人管理程序(源码+可执行程序+程序配置说明书+程序使用说明书)
102 0
|
6月前
|
JSON 定位技术 开发工具
基于Python开发的高德地图+58租房系统(源码+可执行程序+程序配置说明书+程序使用说明书)
基于Python开发的高德地图+58租房系统(源码+可执行程序+程序配置说明书+程序使用说明书)
125 0