暑假写的暂时没空解释,先贴代码。
大致的接口是这样,下面这个代码有很很多是被我写死了,需要自己去找下特定的字段。
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的中文版,能帮您随时随地记录和管理所有事项。您可以用它制定学习、工作计划,生成读书、购物、旅行清单,设置生日、约会、还款提醒等。