暑假写的暂时没空解释,先贴代码。

大致的接口是这样,下面这个代码有很很多是被我写死了,需要自己去找下特定的字段。

from hyper.contrib import HTTP20Adapter
from requests import session
import urllib.parse
from datetime import datetime, timedelta
from random import randint,sample
from local import Local
import json,time
class Params(object):
    """docstring for Params"""
    def __init__(self ):
        super(Params, self).__init__()
        self.headers = {
            "main": {
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-site",
            "log": {
                "sec-fetch-dest": "image",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "cross-site"
    def id(self,num=24,**s):
        H = 'abcdef0123456789'*3
        tg = "".join(sample(H,num))
        return tg
    def projectGroup(self,name="text",**s):
        return {
            "showAll": True,
            "open": False,
            "name": name,
            "teamId": None,
            "listType": "group",
            "sortType": "",
            "id": self.id()
    def task(self,**s):
        # "repeatFlag":"RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=SU,TU,WE,TH
        # "repeatFlag": "ERULE:NAME=TT_WORKDAY;CYCLE=0",
        return {
            "items": [],
            "reminders": [],
            "exDate": [],
            "isAllDay": False,
            "repeatFrom": "0",
            "startDate": "020-07-20",
            "dueDate": "2020-07-21T07",
            "id": self.id() ,
            "projectId": self.projectId ,
            "title": "测试开发",
            "content": " api测试接口 ",
            "desc":"",
            "tags": [],
            "priority": 0,
            "progress": 0,
            "assignee": None,
            "isFloating": False,
            "status": 0,
            "modifiedTime": self.getTime() ,
            "timeZone": "Asia/Shanghai",
    def habit(self,**s):
        return {
            "color": "#70CE62",
            "iconRes": "txt_棒",
            "createdTime": self.getTime(),
            "encouragement": "",
            "etag": "",
            "goal": 1,
            "id": self.id(),
            "modifiedTime": self.getTime(),
            "name": "太棒了",
            "recordEnable": True,
            "reminders": ["10:00"],
            "repeatRule": "RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA",
            # "sortOrder": -2473901162496,
            "status": 0,
            "step": 0,
            "totalCheckIns": 0,
            "type": "Boolean",
            "unit": "Count"
    def getTime(self,day=0,hour=0,minute=0,strTime="",template="%Y-%m-%dT%H:%M:%S.000+0000",**s):
        if strTime: 
            now_time = datetime.strptime(strTime, "%Y-%m-%d %H:%M:%S")
            hour=0;minute=0
        else:
            if not day and not hour and not minute: return None
            hour = int(hour)
            if day: hour += int(day)*24
            now_time = datetime.now()
        hour += 8
        utc_time = now_time - timedelta(hours=hour,minutes=minute)              # UTC只是比北京时间提前了8个小时
        utc_time = utc_time.strftime(template)    # 转换成Aliyun要求的传参格式...
        return utc_time
    def print(self,data,**s):
        print(json.dumps(data,indent=4,ensure_ascii=False))
class Ticktick_api( Params ):
    """docstring for Ticktick_api"""
    def __init__(self, base_url="https://api.dida365.com" ):
        super(Ticktick_api, self).__init__()
        self.base_url = base_url
        self.requests = session()
        self.local = Local("ticktick_api.pkl")
        # print(self.headers)
        self.headers = self.headers
        self.requests.headers["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
        self.requests.headers["x-device"] = "web_app, Chrome 83.0.4103.116, 3700, 这有一串字符 你自己去找, web_app"
        self.requests.headers["referer"] = "https://dida365.com/webapp/"
        cookies = {
            "t": "你的cookie 一直都不会改变",
        for cookie in cookies:
            self.requests.cookies.set(cookie,cookies[cookie])
        self.user = self.status()
        self.projectId = self.user["inboxId"]
        self.projects = {}
        self.getProjects()
        print("Welcome ",self.user["username"])
    def prePare(self,url,method="GET",headers="",**s):
        # if not self.requests.headers.get(":authority","") or self.requests.headers[":authority"] not in url:
        self.requests.mount(url, HTTP20Adapter())
        urlParse = urllib.parse.urlparse(url)
        self.requests.headers.update( {
            ":authority": urlParse.hostname,
            ":method": method ,
            ":scheme": urlParse.scheme ,
            ":path": urlParse.path+"?"+urlParse.query ,
            "cache-control": "no-cache",
            "pragma": "no-cache"
        if method=="POST" : self.requests.headers.update({"content-type":"application/json;charset=UTF-8"})
        else: 
            if "content-type" in self.requests.headers: del self.requests.headers["content-type"]
            self.requests.headers.update({"accept":"application/json, text/plain, */*"})
        if headers: self.requests.headers.update( self.headers.get(headers,{}) )
    def subTask(self,tasks=[],status=0,**s):
        if not tasks: return []
        items = [];index=0
        for task in tasks:
            index+=1
            items.append( {"id":self.id(),"status":status,"title":task,"sortOrder":index } )
        return items
    def reminders(self,schedule=[],**s):
        if not schedule: return []
        items = []
        for task in schedule:
            items.append( {"id":self.id(),"trigger": "TRIGGER:%s"%task} )
        return items
    def login(self,**s):
    def changeStatus(self,items=[],status=1 ,**s):
        for item in items: item.update({"status":status})
        data = {
            "add": [],
            "update": items,
            "delete": []
        return self.submit( data )
    def add(self,params={},project="",**s):
        task = self.task()
        task.update( params )
        if project: task["projectId"] = self.getProjects(key=project,default="")
        if task.get("content") and task["items"]: task["desc"] += " "+task["content"] ; task["content"]=""
        elif task.get("desc") and not task["items"]: task["content"] += " "+task["desc"] ; task["desc"] = ""
        data = {
            "add": [task],
            "update": [],
            "delete": []
        # print(task)
        return self.submit( data )
    def delete(self,tasks=[],item="",**s):
        # task = {"taskId":"5f12bcdaa3503f747e78a4d8","projectId":"5f09032f715c121b752a9db6"}
        if item not in self.projects: return self.projects
        for task in tasks:
            task["taskId"] = task["id"]
            task["projectId"] = self.getProjects(key=item,default=task["id"])
        data = {
            "add": [],
            "update": [],
            "delete": tasks
        return self.submit( data )
    def update(self,params={},**s):
        # 使用已有id进行修改
        task = self.task()
        task.update( params )
        data = {
            "add": [],
            "update": [task],
            "delete": []
        return self.submit( data )
    def move(self,**s):
        url = "https://api.dida365.com/api/v2/batch/taskProject"
        data = [{"fromProjectId":"5f11096e967ee416e7b856e4","toProjectId":"5f09032f715c121b752a9db6","sortOrder":-1924145348608,"taskId":"5f12bcdaa3503f747e78a4d8"}]
    def submit(self,data,**s):
        url = "https://api.dida365.com/api/v2/batch/task"
        self.prePare(url,"POST",headers="main")
        res = self.requests.post(url,data=json.dumps(data))
        print(res.text)
        return res.text
    def search(self,params={},**s):
        if not params: return []
        query = urllib.parse.urlencode(params)
        url = "https://api.dida365.com/api/v2/search/task?"+query
        print("搜索",params)
        self.prePare(url,headers="main")
        res = self.requests.get(url)
        result = res.json()
        # for i in result:
        #     print(i,"\n")
        return result
    def getRemote(self,status=0,**s):
        url = "https://api.dida365.com/api/v2/batch/check/%s"%status
        self.prePare(url,headers="main")
        # print(url)
        res = self.requests.get(url)
        result = res.json().get("syncTaskBean",{}).get("update",{})
        # print(json.dumps(result,indent=4,ensure_ascii=False))
        return result
    def search_by_project(self,project,key="",day=0,**s):
        projectId = self.getProjects(key=project)
        result = self.getRemote()
        targetItems = []
        # print(result)
        # print(key,key in str(result),type(result),len(result))
        if key and key in str(result ):
            # print(key)
            for item in result:
                content = "%s %s %s"%(item["title"],item.get("content",""),item.get("desc",""))
                print(projectId==item.get("projectId"), content,1)
                if projectId==item.get("projectId"):
                    if key in str(item) : 
                        item["taskId"] = item["id"]
                        targetItems.append( item )
                        print("%s %s %s"%(item["title"],item.get("content",""),item.get("desc","")))
        # elif not key: return result
        return targetItems
        # print(json.dumps(result,indent=4,ensure_ascii=False))
    def search_by_key(self,key="",append_dict={},**arg):
        result = self.getRemote(1)
        targetItems = []
        if key and key in str(result):
            for item in result:
                if key in str(item) : 
                    item["taskId"] = item["id"]
                    if append_dict: item.update( append_dict )
                    targetItems.append( item )
        elif not key: return result
        return targetItems
        # print(json.dumps(result,indent=4,ensure_ascii=False))
    def getProjects(self,update=False,key="",default="",**s):
        if self.projects:
            if key and key in self.projects:
                return self.projects.get(key)
            elif not update: return default
        url = "https://api.dida365.com/api/v2/projects"
        self.prePare(url,headers="main")
        res = self.requests.get(url)
        projects = res.json()
        self.projects = {}
        for project in projects:
            self.projects[project["name"]] = project["id"]
            self.projects[project["id"]] = project["name"]
        print(self.projects)
        return self.projects
    def status(self,**s):
        url = "https://api.dida365.com/api/v2/user/status"
        self.prePare(url,headers="main")
        res = self.requests.get(url).json()
        if "username" not in res : return {}
        result = { res.get("username"):"t=%s"%self.requests.cookies.get("t") }
        self.local.add(result)
        return res
    def check(self,username,**s):
        return username==self.user.username
    def getRecent(self,day=1,**s):
        # url = "https://api.dida365.com/api/v2/project/all/trash/pagination?start=0&limit=1000&status=1"
        url = "https://api.dida365.com/api/v2/project/all/completedInAll/"
        params = {
            "from": self.getTime(day,template="%Y-%m-%d%%20%H:%M:%S"),
            "to": self.getTime(template="%Y-%m-%d%%20%H:%M:%S") ,
            "limit": "50",
        url += "?"+urllib.parse.urlencode(params)
        self.prePare(url,headers="main")
        res = self.requests.get(url)
        result = res.json()
        print(json.dumps(result,indent=4,ensure_ascii=False))
        return res.json()
    def habits(self,**s):
        url = "https://api.dida365.com/api/v2/habits/batch"
        data = {"add":[self.habit()],"update":[],"delete":[]}
        print(data)
        self.prePare(url,"POST",headers="main")
        res = self.requests.post(url,data=json.dumps(data))
        print(res.text)
class Ticktick( Ticktick_api ):
    """docstring for Ticktick"""
    def __init__(self):
        super(Ticktick, self).__init__()
    def addTask(self,data,**s):
        # self.add( {"items": items,"status":0,"title":"子任务来了","priority":3,"startDate":"2020-07-19T14:00:00.000+0000","dueDate":"2020-07-19T15:00:00.000+0000","tags":tags } )
        self.add(data)
    def complete_by_key(self,key="",project="",**s):
        if project in self.projects: 
            self.getProjects(update=True)
            items = self.search_by_project(project=project,key=key)
        else:
            items = self.search_by_key(project=project,key=key)
        if items: self.changeStatus(items,1)
    def redo_by_key(self,key="",project="",**s):
        if not key: return 
        items = self.search_by_key(project=project,key=key)
        if items: self.changeStatus(items,0)
    def delete_by_key(self,key="",project="",**s):
        if project in self.projects: 
            self.getProjects(update=True)
            items = self.search_by_project(project=project,key=key)
        else:
            items = self.search_by_key(project=project,key=key)
        data = {"add": [],"update": [],"delete": items }
        if items: return self.submit( data )
    def update_by_key(self,key,update={},**s):
        if not key: return 
        items = self.search_by_key(key=key,append_dict=update)
        data = {"add": [],"update": items,"delete": [] }
        # print(items)
        return self.submit( data )
if __name__ == '__main__':
    TaskList = Ticktick()
    # items = TaskList.subTask(["吃饭","喝水","冲冲冲","睡觉","学习","考试"])
    # reminders = TaskList.reminders(["-PT11M","-PT15M","-PT33M","-PT41M","-PT61M"])
    # TaskList.add( {"reminders":reminders,"items":items,"title":"我的日常","content":"生活只剩下刚需","startDate":TaskList.getTime(hour=-6),"dueDate":TaskList.getTime(hour=-16)},project="学习助手" )
    # # 删
    # TaskList.delete_by_key(key="我的")
    # # 改
    res = TaskList.update_by_key("背单词",data = {
        "remaind":["PT0S","-PT30M","-PT13H40M","-PT10H"],
        "title": "数据结构" ,
        "content": "数据结构" ,
        "project":"学习" ,
        "priority":"1" 
    print(res)
    # TaskList.update_by_key("批量",{"title":"重新修改 支持批量","desc":"相当拉风","content":"没毛病","items":TaskList.subTask(["吃饭","睡觉","学习","喝水","冲冲冲","考试"])})
    # TaskList.complete_by_key("批量","洗发膏")
    # TaskList.redo_by_key("批量","洗发膏")
    result = TaskList.search_by_key(key = "学习强国")
    # TaskList.print(result)
                                    【插件简介】 
 简洁, 易用的待办和任务管理工具, 帮助您高效完成所有的事情, 合理规划时间, 让生活更轻松!滴答清单是Todo管理神器TickTick的中文版,能帮您随时随地记录和管理所有事项。您可以用它制定学习、工作计划,生成读书、购物、旅行清单,设置生日、约会、还款提醒等。 
 【插件小贴士】 
 亲测,非常好用的TODO应用 
 【插件网站】 
 https://ticktick.com/ 
 【插件更新】 
 2020-07-15 16:33:27 
 【插件版本】 
 1.1.3.7 
 【插件标签】 
 工具 办公效率 Chrome插件 
 【插件安装教程】 
 请下载文件后先解压,然后进入页面: chrome://extensions/  将文件拖拽到该页面,完成安装。
具体步骤: https://t.csdnimg.cn/NxMv  
 【热门插件】
·CSDN 浏览器助手: https://plugin.csdn.net/
var rest = new fwREST();
            var objStr = "accounts?$select=hms_sapcustomerid&$filter=accountid eq (" + customerid + ")";
            rest.get(objStr).then(function (ob) {
                if (ob.value.error != undefined || ob.val
关于「滴答清单滴答清单是一款不可多得的 GTD 效率工具,它有着清晰明了的界面设计、恰到好处的功能设置、稳定的同步服务,如果你还缺少一款简洁而有效的 GTD 时间管理工具,滴答清单是不错的选择。
—— 少数派
滴答清单是一款跨平台同步的待办事项和任务提醒软件;
滴答清单能够协助您完成待办事务,比如工作计划、生日提醒、旅行安排、会议准...
                                    此项目是仿滴答清单做的一个日程表,现包括的功能有:日视图、三日视图、周视图、月视图、列表视图(周月可自由切换,左右滑动切换周或月份)。1、 网络请求功能完善;2、 同步手机的日程表;3、 可以增加日历事件,并可选择是否同步到手机本身日程表;4、 可设置提醒事件功能;5、 日历事件保存到数据库;6、 同步google邮件账号或是其他黄历事件;7、 事件功能分类展示;8、 暂进还没想到功能完善。此工程...
                                    原文简书地址(http://www.jianshu.com/p/7a3f0a37e0ef)简介由于项目的需求,研究了众多日历软件。本软件是一款高仿小米、华为、滴答清单、365、钉钉等的自定义日历控件,周月视图平滑滚动,平滑切换,可以在xml文件中进行属性的配置定制,内部切入了RecyclerView。主要的优点:1:完全自定义,原理简单,可扩展性强 
2:支持平滑切换和快速滑动 
3:支持农历和阴历
https://www.ixigua.com/7017702820048536071
后端接口仓库地址:
https://gitee.com/maoshushare/fast-todolist
第一节 项目计划和准备工作
本项目是一个fastadmin+微信小程序的实战案例,一个简单的todolist任务管理功能,包括后台数据增删改查、数据统计、api接口开发(小程序对接登录、小程序端管理数据)等。
功能比较简单,覆盖到的知识点不会太多,适合初学者,尤其适合没有做过小程序
Sublime Text - 一个比较简洁大方带插件管理系统的流行编辑器,Sublime常用插件。
PyCharm - 一款 Python 开发集成环境,有专业版和社区版。
IntelliJ IDEA - 一款 Java 开发集成环境。(学生免费)
GoLand - JetBrains出品的Go开发IDE,智能,灵活
Visual Studio Code - 微软推出的免费/开源编辑器,TypeScript 支持杠杠的,VSCode常用插件
VSCodium 100% 开
    $(arr[i]).find(".title").click();
    window.setTimeout(function(){
        $(".editor-with-link .link-viewer").each(function(){
            console...
                                    滴答清单是Todo管理神器TickTick的中文版,能帮您随时随地记录和管理所有事项。您可以用它制定学习、工作计划,生成读书、购物、旅行清单,设置生日、约会、还款提醒等。