Browse Source

long2short

marion 4 years ago
parent
commit
af5d5bcf0b
1 changed files with 178 additions and 0 deletions
  1. 178 0
      long2short.go

+ 178 - 0
long2short.go

@@ -0,0 +1,178 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"git.aionnect.com/aionnect/go-common/utils"
+	"git.aionnect.com/aionnect/go-common/utils/jsonutil"
+	"github.com/tealeg/xlsx"
+	"net/http"
+	"strings"
+	"sync"
+)
+
+/*
+调用微信公众平台接口,长链接批量转短链接小工具
+
+long2short.exe 是Windows版本
+long2short 是Mac版本
+
+不是直接双击使用,需要在控制台或终端中输入命令调用
+用 long2short -help 查看命令参数说明
+
+使用步骤:
+1. 准备好包含长链接的Excel文件,文件务必保存为xlsx格式
+2. 问研发或管理员获取最新有效的微信公众号AccessToken
+3. 打开Windows控制台或Mac终端,执行类似下面的命令
+
+Windows:
+
+.\long2short.exe -i .\input.xlsx -o .\output.xlsx -h 长链接 -t AccessToken的值
+
+Mac:
+
+./long2short -i ./input.xlsx -o ./output.xlsx -h 长链接 -t AccessToken的值
+
+4. 如果出错,会在命令窗口打印错误信息,如果顺利,会在程序所在目录下输出新的xlsx文件
+*/
+
+func main() {
+	var inputFileName string
+	var accessToken string
+	var headerName string
+	var outputFileName string
+	flag.StringVar(&inputFileName, "i", "input.xlsx", "xlsx输入文件路径,默认值\"input.xlsx\"")
+	flag.StringVar(&accessToken, "t", "", "Access Token,必填")
+	flag.StringVar(&headerName, "h", "合成链接", "长链接列名,默认值\"合成链接\"")
+	flag.StringVar(&outputFileName, "o", "output.xlsx", "xlsx输出文件路径,会在文件名后加上时间戳,默认值\"output.xlsx\"")
+	flag.Parse()
+	if accessToken == "" {
+		println("-t AccessToken 参数是必须的")
+		return
+	}
+	reqUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/shorturl?access_token=%s", accessToken)
+
+	file, err := xlsx.OpenFile(inputFileName)
+	if err != nil {
+		panic(fmt.Sprintf("读取输入文件%s失败 %s", inputFileName, err.Error()))
+	}
+
+	sheets := file.Sheets
+	if nil == sheets || len(sheets) == 0 {
+		println("输入文件中没有工作表")
+		return
+	}
+	for _, sheet := range file.Sheets {
+		rows := sheet.Rows
+		if nil == rows || len(rows) < 2 {
+			fmt.Printf("工作表%s中没有数据\n", sheet.Name)
+			continue
+		}
+		header := rows[0]
+		idx := -1
+		for i, cell := range header.Cells {
+			text := cell.String()
+			if strings.TrimSpace(text) == headerName {
+				idx = i
+			}
+		}
+		if idx < 0 {
+			fmt.Printf("工作表%s中没有找到长链接列名列名\"%s\"\n", sheet.Name, headerName)
+			continue
+		}
+		newHeader := header.AddCell()
+		newHeader.SetString("短链接")
+
+		length := len(rows) - 1
+		pNo := 1
+		if length > 5 {
+			pNo = 5
+		}
+		if length > 100 {
+			pNo = 10
+		}
+		if length > 500 {
+			pNo = 100
+		}
+		size := length / pNo
+		var firstArr []*RowInfo
+		rowGroup := [][]*RowInfo{firstArr}
+		var j, ct int
+		for i := 1; i < len(rows); i++ {
+			rowGroup[j] = append(rowGroup[j], &RowInfo{Row: rows[i], RowNo: i + 1})
+			ct++
+			if ct >= size {
+				var newArr []*RowInfo
+				rowGroup = append(rowGroup, newArr)
+				ct = 0
+				j++
+			}
+		}
+
+		var counter sync.WaitGroup
+		counter.Add(length)
+		for i := 0; i < len(rowGroup); i++ {
+			arr := rowGroup[i]
+			go func(reqUrl string, idx int, sheetName string, arr []*RowInfo) {
+				for j := 0; j < len(arr); j++ {
+					info := arr[j]
+					call(reqUrl, idx, sheetName, info)
+					counter.Done()
+				}
+			}(reqUrl, idx, sheet.Name, arr)
+		}
+		counter.Wait()
+	}
+
+	dotIdx := strings.LastIndex(outputFileName, ".")
+	outputFileName = fmt.Sprintf("%s_%d.xlsx", outputFileName[:dotIdx], utils.NextId())
+	err = file.Save(outputFileName)
+	if nil != err {
+		panic(fmt.Sprintf("写输出文件%s失败 %s", outputFileName, err.Error()))
+	}
+}
+
+func call(reqUrl string, idx int, sheetName string, info *RowInfo) {
+	row := info.Row
+	var longUrl string
+	if len(row.Cells) > idx {
+		longUrl = row.Cells[idx].String()
+	}
+	longUrl = strings.TrimSpace(longUrl)
+	if longUrl == "" {
+		fmt.Printf("工作表%s中第%d行长链接值为空\n", sheetName, info.RowNo)
+		return
+	}
+
+	reqBody := fmt.Sprintf(`{"action":"long2short","long_url":"%s"}`, longUrl)
+	respBody, err := utils.NewRequest().Call(http.MethodPost, reqUrl, strings.NewReader(reqBody))
+	if nil != err {
+		fmt.Printf("工作表%s中第%d行请求短链接失败 %s\n", sheetName, info.RowNo, err.Error())
+		return
+	}
+	var res ShortResult
+	err = jsonutil.Unmarshal(respBody, &res)
+	if nil != err {
+		fmt.Printf("工作表%s中第%d行请求短链接返回了意外的结果 %s\n", sheetName, info.RowNo, string(respBody))
+		return
+	}
+	res.ShortUrl = strings.TrimSpace(res.ShortUrl)
+	if res.ErrCode != 0 || res.ShortUrl == "" {
+		fmt.Printf("工作表%s中第%d行请求短链接出错 %s\n", sheetName, info.RowNo, string(respBody))
+		return
+	}
+
+	newCell := row.AddCell()
+	newCell.SetString(res.ShortUrl)
+}
+
+type RowInfo struct {
+	Row   *xlsx.Row
+	RowNo int
+}
+
+type ShortResult struct {
+	ErrCode  int    `json:"errcode"`
+	ErrMsg   string `json:"errmsg"`
+	ShortUrl string `json:"short_url"`
+}