使用Golang编写一个在Mac通知栏上显示ETH价格的小工具

一、前言

作为一个刚接触Go语言的初学者,总得写点代码练习一下。考虑到自身需求,就写了个这么一个小工具。记录在这里和大家一起分享,给有需求的同志提供一点参考。

这个工具很简单,用网上现成的库,并将附带的示例稍微修改下就可以了。

二、准备工作

  1. 打开https://github.com/getlantern/systray并git clone,我们工作就是在它给出的example中进行修改。
  2. 网上下载一张以太坊的Logo(PNG格式的)
  3. 安装最新版本go(1.13以上)并设置GOPATH,这个可以去官网看教程
  4. 设置GOPROXY="https://goproxy.io"。建议在.bash_profile里设置。

三、创建工程

打开终端,建立工程目录并使用go module。如下示例:

➜  ~ cd work/
➜  work mkdir ethprice
➜  work cd ethprice/
➜  ethprice go mod init ethprice
go: creating new go.mod: module ethprice
➜  ethprice 

注意这里的work不要在GOPATH目录下。使用vscode打开刚才的ethprice文件夹,在根目录下建立main.go文件和icon文件夹,并将以太坊logo改名为logo.png放入icon文件夹下。将如下图:
在这里插入图片描述

四、处理logo

将前面下载的systray中example\icon\make_icon.sh也copy到icon目录下。在vscode里打开终端,切换到该目录并运行sh ./make_icon.sh logo.png,它会在当前目录下生成一个iconunix.go的文件,这就是我们小工具所需要的logo。下面是make_icon.sh里的代码:

#/bin/sh

if [ -z "$GOPATH" ]; then
    echo GOPATH environment variable not set
    exit
fi

if [ ! -e "$GOPATH/bin/2goarray" ]; then
    echo "Installing 2goarray..."
    go get github.com/cratonica/2goarray
    if [ $? -ne 0 ]; then
        echo Failure executing go get github.com/cratonica/2goarray
        exit
    fi
fi

if [ -z "$1" ]; then
    echo Please specify a PNG file
    exit
fi

if [ ! -f "$1" ]; then
    echo $1 is not a valid file
    exit
fi    

OUTPUT=iconunix.go
echo Generating $OUTPUT
echo "//+build linux darwin" > $OUTPUT
echo >> $OUTPUT
cat "$1" | $GOPATH/bin/2goarray Data icon >> $OUTPUT
if [ $? -ne 0 ]; then
    echo Failure generating $OUTPUT
    exit
fi
echo Finished

可以看到,它安装了一个2goarray库并且将转换后的数据输出到iconunix.go中,变量名为Data,包名为icon。这里也可以自己修改为不同的名字。

五、编写主程序

参照systray中的示例,我们在main.go中写入如下代码:

package main

import (
	"encoding/json"
	"ethprice/icon"
	"fmt"
	"net/http"
	"time"

	"github.com/getlantern/systray"
)

const URL = "https://api.pro.coinbase.com/products/ETH-USD/ticker"

type EthPrice struct {
	Price string `json:price`
}
type Callback func(s string)

var priceInfo = new(EthPrice)
var t *time.Ticker

var step = 15

func backgroundTask(cb Callback) {
	t = time.NewTicker(time.Duration(step) * time.Second)
	for range t.C {
		cb(fetchPrice())
	}
}

func fetchPrice() string {
	resp, err := http.Get(URL)
	if err != nil {
		return "-"
	}
	defer resp.Body.Close()
	json.NewDecoder(resp.Body).Decode(priceInfo)
	return fmt.Sprintf("ETH $%s(每%d秒)", priceInfo.Price, step)
}

func main() {
	systray.Run(onReady, onExit)
}

func onReady() {
	go backgroundTask(systray.SetTitle)
	systray.SetIcon(icon.Data)
	systray.SetTitle(fmt.Sprintf("ETH $%s(每%d秒)", priceInfo.Price, step))
	systray.SetTooltip("定时刷新ETH价格")
	oneMinite := systray.AddMenuItem("每分钟", "每分钟刷新一次")
	halfMinite := systray.AddMenuItem("每半分钟", "每30秒刷新一次")
	quartor := systray.AddMenuItem("每15秒", "每15秒刷新一次")
	mQuit := systray.AddMenuItem("退出", "退出程序")
	systray.SetTitle(fetchPrice())

	go func() {
		for {
			select {
			case <-mQuit.ClickedCh:
				systray.Quit()
				return
			case <-oneMinite.ClickedCh:
				if step != 60 {
					step = 60
					systray.SetTitle(fmt.Sprintf("ETH $%s(每%d秒)", priceInfo.Price, step))
					t = time.NewTicker(time.Duration(step) * time.Second)
				}

			case <-halfMinite.ClickedCh:
				if step != 30 {
					step = 30
					systray.SetTitle(fmt.Sprintf("ETH $%s(每%d秒)", priceInfo.Price, step))
					t = time.NewTicker(time.Duration(step) * time.Second)
				}

			case <-quartor.ClickedCh:
				if step != 15 {
					step = 15
					systray.SetTitle(fmt.Sprintf("ETH $%s(每%d秒)", priceInfo.Price, step))
					t = time.NewTicker(time.Duration(step) * time.Second)
				}
			}
		}
	}()

}

// clean up here
func onExit() {
	t.Stop()
}

这里icon包位于本地包(目录)ethprice之下,本地包就是go mod init时定义的包。由于是初学者,代码写的不完善,还有一些需要优化的地方,见谅。

六、编译运行

切换到项目根目录并运行go build,会在根目录下生成ethprice可执行文件。让我们后台运行它:

./ethprice &

这里就可以在屏幕通知栏看到ETH价格了,点击它还可以改变查询间隔和退出程序。
在这里插入图片描述

七、设置开机自动运行

我们把它设置成开机自动运行,先点击程序选择退出,然后再把它copy到用户根目录:

cp ethprice ~

接着我们在vscode外部打开一个终端,键入vim auto.sh,内容如下:

#!/bin/sh
./ethprice &

escape,再按":"进入底部命令模式,输入wq回车保存。注意,接下来这一步相当重要,就是chmod 777 auto.sh

设置开机启动,先参照https://jingyan.baidu.com/article/77b8dc7fbc943c6175eab64e.html ,在登录项这一步,点击左下角+号,将auto.sh添加进去并选中隐藏。如下图:
在这里插入图片描述

这里需要事先设定使用终端打开.sh文件。打开Finder,右键点击auto.sh,选择打开方式,此时如果第一项为xcode的话需要改过来。选择其它,在启用那里选所有程序,搜索里键入终端,然后点击左边列表里的终端。如下图:
在这里插入图片描述
点击打开,并不会有输出。此时再右键点击auto.sh,打开方式第一项已经变成终端了。

八、注销重登录

注销当前用户,再重新登录,我们就可以在通知栏看到ETH价格啦!Over!

这里其实可以再扩展一下,比如把点击弹出来的菜单不弄成设定查询间隔,而是查询BTC\EOS等。有兴趣和需求的同志自己动手了!

欢迎大家留言指出错误或者提出改进意见。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
编写一个验证码识别工具,您需要对图像处理和机器学习有一定的了解。以下是一个基本的验证码识别程序的Golang实现,它使用了SVM机器学习算法和OpenCV库来处理和识别验证码。 ```go package main import ( "fmt" "image" "image/color" "image/draw" "image/jpeg" "log" "math/rand" "os" "path/filepath" "time" "github.com/otiai10/gosseract" "gocv.io/x/gocv" ) const ( letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" width, height = 200, 80 ) func main() { rand.Seed(time.Now().UnixNano()) // 生成随机验证码 img := generateCaptcha() // 保存验证码 captchaFile, _ := os.Create("captcha.jpg") jpeg.Encode(captchaFile, img, nil) captchaFile.Close() // 识别验证码 result := recognizeCaptcha("captcha.jpg") fmt.Println(result) } // 生成随机验证码 func generateCaptcha() *image.RGBA { // 创建一个黑色背景的图像 img := image.NewRGBA(image.Rect(0, 0, width, height)) draw.Draw(img, img.Bounds(), &image.Uniform{color.Black}, image.ZP, draw.Src) // 随机生成4个字符 var lettersRunes = []rune(letters) str := make([]rune, 4) for i := range str { str[i] = lettersRunes[rand.Intn(len(lettersRunes))] } // 在图像上绘制字符 for i, r := range str { face := gocv.FontHersheyPlain size := 2.0 + rand.Float64()*4.0 thickness := 1.0 + rand.Float64()*3.0 pt := gocv.Point{X: rand.Intn(width/4) + i*50 + 20, Y: rand.Intn(height/2) + 20} gocv.PutText(img, string(r), pt, face, size, color.RGBA{R: uint8(rand.Intn(256)), G: uint8(rand.Intn(256)), B: uint8(rand.Intn(256)), A: uint8(rand.Intn(256))}, int(thickness)) } // 添加噪点 for i := 0; i < 1000; i++ { pt := gocv.Point{X: rand.Intn(width), Y: rand.Intn(height)} gocv.Circle(img, pt, 1, color.RGBA{R: uint8(rand.Intn(256)), G: uint8(rand.Intn(256)), B: uint8(rand.Intn(256)), A: uint8(rand.Intn(256))}, -1) } return img } // 识别验证码 func recognizeCaptcha(captchaFile string) string { // 读取验证码图像 img := gocv.IMRead(captchaFile, gocv.IMReadColor) defer img.Close() // 灰度化 gray := gocv.NewMat() gocv.CvtColor(img, &gray, gocv.ColorBGRToGray) // 二值化 thresh := gocv.NewMat() gocv.AdaptiveThreshold(gray, &thresh, 255, gocv.AdaptiveThresholdGaussian, gocv.ThresholdBinary, 11, 2) // 轮廓检测 contours := gocv.FindContours(thresh, gocv.RetrievalExternal, gocv.ChainApproxSimple) captcha := gocv.NewMat() defer captcha.Close() // 识别每个字符 var result string for _, cnt := range contours { // 包围盒 x, y, w, h := gocv.BoundingRect(cnt) if w < 10 || h < 10 { continue } // 提取字符图像 roi := thresh.Region(image.Rectangle{Min: image.Point{X: x, Y: y}, Max: image.Point{X: x + w, Y: y + h}}) gocv.Resize(roi, &captcha, image.Point{X: 40, Y: 40}, 0, 0, gocv.InterpolationCubic) // OCR识别 captchaFile, _ := filepath.Abs("captcha_roi.jpg") gocv.IMWrite(captchaFile, captcha) client := gosseract.NewClient() client.SetImage(captchaFile) text, _ := client.Text() result += text } return result } ``` 上面的程序使用了随机生成的字符来生成验证码图像,然后使用OpenCV库和SVM机器学习算法来识别每个字符。在识别每个字符时,它使用了Tesseract OCR引擎来提高识别准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AiMateZero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值