zoukankan      html  css  js  c++  java
  • 为知笔记回收站批量还原

    背景

    不小心删了为知里的笔记,想要还原,然而傻眼了,一次只能还原20个,然而我删了4000多个,手工点这得何年何月啊。
    于是查看了为知笔记的请求,写个代码批量发请求,还原笔记。

    思路

    浏览器打开调试模式,发现了为知笔记获取回收站列表和还原文件的uri为:

    • 回收站列表 /wizks/k/deleted?client_type=web&api_version=10&token=%s&kb_guid=%s&obj_type=document&_=%d
    • 恢复文件 /ks/deleted/recycle/%s?type=document&clientType=web&clientVersion=3.0.0&apiVersion=10&lang=zh-cn

    另外发现cookie里还存有token和多个字段,测试了一下,只需要cookie里带着token就可以了

    代码

    没有什么难点,就直接上代码了,其中guid在地址栏里直接获取到,token得从cookie里取

    package main
    
    import (
    	"net/http"
    	"time"
    	"fmt"
    	"gopkg.in/resty.v1"
    	"github.com/tidwall/gjson"
    	"github.com/corpix/uarand"
    )
    
    const BaseUrl = "https://note.wiz.cn"
    
    //token  operator_guid  时间戳毫秒
    const RecyleUri = "/wizks/k/deleted?client_type=web&api_version=10&token=%s&kb_guid=%s&obj_type=document&_=%d"
    
    //operator_guid
    const RestoreUri = "/ks/deleted/recycle/%s?type=document&clientType=web&clientVersion=3.0.0&apiVersion=10&lang=zh-cn"
    
    //请更换为将登录后的参数
    var token = ""
    var operatorGuid = ""
    
    var retry = 0
    
    func main() {
    	cookie := http.Cookie{}
    	cookie.Name = "token"
    	cookie.Value = token
    	cookie.Domain = ".wiz.cn"
    
    	start := time.Now().Unix()
    
    	fmt.Println("task begin")
    
    	requester := resty.SetHostURL(BaseUrl).SetCookie(&cookie).R()
    
    	ch := make(chan int)
    
    	go restore(requester, ch)
    ForEnd:
    	for {
    		select {
    		case v := <-ch:
    			retry++
    			if retry >= 30 || v == 2 {
    				break ForEnd
    			}
    			if v == 1 {
    				time.Sleep(time.Second * 3)
    				fmt.Println("retry task again")
    				requester.SetHeader("User-Agent", uarand.GetRandom())
    				go restore(requester, ch)
    			}
    		}
    
    	}
    
    	fmt.Printf("task completed,use %d seconds.
    ", time.Now().Unix()-start)
    }
    
    func restore(requester *resty.Request, ch chan int) {
    
    	resp, err := requester.Get(fmt.Sprintf(RecyleUri, token, operatorGuid, time.Now().Nanosecond()/1000000))
    	if err != nil || resp.StatusCode() != 200 {
    		ch <- 1
    		return
    	}
    	if resp.String() == "[]" {
    		ch <- 2
    	}
    
    	//数据结构为
    	//[{"operator_guid":"","dt_deleted":1507821257000,"deleted_guid":"","deleted_content":""},{...}]
    	result := gjson.ParseBytes(resp.Body())
    	if result.IsArray() {
    		guids := make([]string, 0)
    		result.ForEach(func(key, value gjson.Result) bool {
    			dGuid := value.Get("deleted_guid").String()
    			if dGuid == "" {
    				ch <- 1
    				return false
    			}
    			guids = append(guids, dGuid)
    			if len(guids) >= 100 {
    				res := requestRestore(requester, guids, ch)
    				guids = nil
    				return res
    			}
    			return true
    		})
    
    		if guids != nil {
    			requestRestore(requester, guids, ch)
    			guids = nil
    		}
    
    	} else {
    		fmt.Println(resp.String())
    		ch <- 1
    	}
    
    }
    
    func requestRestore(requester *resty.Request, guids []string, ch chan int) bool {
    	resp, err := requester.SetBody(guids).Post(fmt.Sprintf(RestoreUri, operatorGuid)) //[]string{dGuid}
    	if err != nil {
    		fmt.Println(err)
    		ch <- 1
    		return false
    	}
    	if resp.StatusCode() != 200 || gjson.Get(resp.String(), "returnMessage").String() != "OK" {
    		ch <- 1
    		return false
    	}
    	fmt.Printf("a bulk of %d doc restore", len(guids))
    	return true
    }
    
    

    吐槽一下,为知笔记恢复,在恢复一页时,居然发了20个请求,然而后端实际上是可以批量恢复的,只需要把这20条的guid一次发过去就可以了。上面的代码就一次发了100个guid。

  • 相关阅读:
    [deviceone开发]-底部弹出选择
    [deviceone开发]-动态添加组件add方法的示例
    [deviceone开发]-openPage的动画效果示例
    [deviceone开发]-do_Album的简单示例
    [deviceone开发]-Star分享的几个示例
    [deviceone开发]-do_Webview的基本示例
    [deviceone开发]-do_Webview加载JQueryMobile的示例
    [deviceone开发]-心形点赞动画示例
    函数式编程思维学习 (1)
    android 14.04 64位 adb cannot run program adb
  • 原文地址:https://www.cnblogs.com/xdao/p/golang_wiz.html
Copyright © 2011-2022 走看看