togglを使って作業の記録などを行っていたが,これをslackなどから管理できるようになるといいなとか,ログを見てみたいな,とか思ってtogglのapiを調べて見ました.
そして,今後何かしら使うときにすぐ使えるようにと,機能のいくつかをTogglDriverとしてクラス化しました.python勉強中なので,何かしら変なコード多いかも.
ソースコードはこちら
初期化
togglAPIを利用するときに必要となるのは,メールアドレスとapiトークンの二つだけ.基本的に呼び出し時は,この二つを引数で渡してもらえればよい.
class TogglDriver:
def __init__( self , _token = None , _mail_address = None , _workspace_id = None ):
self._token = _token# api_token
self._mail_address = _mail_address # your mailaddres
self._workspace_id = _workspace_id
self.usr = None
self._headers = {'Content-Type': 'application/json'}
self._pid_dict = {}
self._now_id = None
self.day_logs = []
#初期化時にself._pid_dictの更新
self.get_workspace_id()
self.request_pid()
togglでは,ログを取得するのに,個人のプロジェクトを管理するワークスペースのid(workspace_id)が必要になる.これはapi_tokenがあればapiで取得できるようなので,初期化時にapiから取得しておく.
'''
workcpace_idの取得
'''
def get_workspace_id( self ):
#TogglのMy profileから、API_Tokenを取得(入力)
_api_token = self._token
r = requests.get('https://www.toggl.com/api/v8/workspaces',
auth=(_api_token, 'api_token'))
#JSON形式でデータのエクスポート
data = r.json()
Data = data[0]
id = Data['id']
self._workspace_id = id
togglのタイマーを動かしたり,プロジェクトのログをとりたいときに,プロジェクトのid(pid)と呼ばれるものが必要になるらしい.しかし,自分の持っているプロジェクトのpidのみを,apiで一括で取得する方法がなかった.
そこで1年分のログをapiで持ってきて,その中からプロジェクト名とpidを保存する辞書配列の作成を行った.
'''
過去一年分のpidを取得
'''
def request_pid( self ):
# 日付の取得
end_day = dt.now().strftime('%Y-%m-%d')
t = timedelta(days = 1)
start_day = dt.now() - t
#Togglのデータ取得
_params = {
'user_agent': self._mail_address, #登録しているメールアドレス
'workspace_id': self._workspace_id, # TogglのworkspaceID
'start': start_day, # データ取得開始
'until': end_day # データ取得終了
}
# TogglのAPIに接続
r = requests.get('https://toggl.com/reports/api/v2/details',
auth=HTTPBasicAuth(self._token, 'api_token'),
params=_params)
print( 'HTTP status :' , r.status_code )
# JSONファイルからのデータ取得
data = r.json()
Data = data['data']
#データを1行ずつ読み,pidを取得
for dataset in Data:
if dataset["pid"] not in self._pid_dict and not dataset["pid"] is None:
print(dataset["pid"])
self._pid_dict[str(dataset["project"]).lower()] = dataset["pid"]
ログの取得
ログの取得は基本的にこのrequest_logメゾットで取得する.開始日(start_day)と終了日(end_day)を指定して,その期間に発生したログを一括で取得する,
'''
start_day~end_dayのlogをとる
'''
def request_log( self , start_day , end_day):
#パラメータ設定
_params = {
'user_agent': self._mail_address, #登録しているメールアドレス
'workspace_id': self._workspace_id, # TogglのworkspaceID
'start': start_day, # データ取得開始
'until': end_day # データ取得終了
}
# TogglのAPIに接続
r = requests.get('https://toggl.com/reports/api/v2/details',
auth=HTTPBasicAuth(self._token, 'api_token'),
params=_params)
print( 'HTTP status :' , r.status_code )
# JSONファイルからのデータ取得?
data = r.json()
Data = data['data']
row = 0
#データを1行ずつ整形
for i in Data:
dataset = Data[row]
if dataset["pid"] not in self._pid_dict and not dataset["pid"] is None:
self._pid_dict[str(dataset["project"]).lower()] = dataset["pid"]
#タスク名を取得
project = dataset["project"]
data01 = dataset['description']
#開始日ー開始時間
start = dataset['start']
sd = start[0:10]
st = start[11:19]
#文字コードを日時に変換
s = sd + ' ' + st
date_s = dt.strptime(s,'%Y-%m-%d %H:%M:%S')
# 終了時間を取得
end = dataset['end']
ed = end[0:10]
et = end[11:19]
#文字コードを日時に変換
e = ed + ' ' + et
date_e = dt.strptime(e,'%Y-%m-%d %H:%M:%S')
#かかった時間を取得
dur = date_e - date_s
#データを保存
data02 = sd
data03 = st
data04 = ed
data05 = et
data06 = dur
#次の行に移動
row += 1
data_log = { 'Project':project ,'Description':data01 , 'start_day':data02 , 'start_time':data03 , 'end_day':data04 , 'end_time':data05 , 'during':data06 }
self.day_logs.append( data_log )
時間の計測
計測のスタート
apiからtogglのタイマーをスタートさせるメゾット.descriotion
にプロジェクトの説明,pid
が計測をスタートするプロジェクトのidとなる.
'''
プロジェクトをスタート
'''
def start( self , description , pid ):
try:
_pid = self.convert_pid( pid )
except KeyError:# 存在しないときにpidの更新
self.request_pid()
_pid = self.convert_pid( pid )
params = {"time_entry":{"description":description,"pid": _pid ,"created_with":"python"}}
# TogglのAPIに接続
r = requests.post('https://www.toggl.com/api/v8/time_entries/start',
auth=HTTPBasicAuth(self._token, 'api_token'),
headers = self._headers,
data = json.dumps(params))
data = r.json()
self._now_id = data['data']['id']
print( 'HTTP status :' , r.status_code )
ここで引数がpidだと直感的にわかりにくいので,プロジェクト名からpidに変換するメゾットを作成した.
'''
プロジェクト名の文字列をpidに変換
'''
def convert_pid( self , pid ):
pid_format = pid.lower()
if isinstance( pid_format , str):
_pid = int(self._pid_dict[ pid_format ])
else:
_pid = int(pid)
return _pid
計測をストップ
先ほどのプログラムでスタートしたタイマーを止める.スタート時にpidを格納しているので,引数などはなし.
'''
プロジェクトをストップ
'''
def stop( self ):
# TogglのAPIに接続
url = 'https://www.toggl.com/api/v8/time_entries/'+str(self._now_id)+'/stop'
r = requests.put( url,auth=HTTPBasicAuth(self._token, 'api_token'),headers = self._headers)
print( 'HTTP status :' , r.status_code )
return r
おわりに
とりあえずやりたい機能の下地はできたので,あとはslackからたたけるようにするとか,ログを視覚化するとかやってみたいですね.