252 lines
9.9 KiB
Python
252 lines
9.9 KiB
Python
# coding: utf-8
|
||
|
||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||
|
||
import datetime
|
||
from typing import TYPE_CHECKING, List
|
||
|
||
from dateutil import parser
|
||
from six.moves.urllib.parse import urlencode
|
||
|
||
from utils.feishu.dt_code import SimpleUser
|
||
from utils.feishu.dt_help import make_datatype
|
||
from utils.feishu.dt_meeting_room import Building, Room, RoomFreeBusy
|
||
from utils.feishu.helper import converter_enum, datetime_format_rfc3339
|
||
|
||
if TYPE_CHECKING:
|
||
from utils.feishu.api import OpenLark
|
||
|
||
|
||
class TimeZoneChina(datetime.tzinfo):
|
||
_offset = datetime.timedelta(hours=8)
|
||
_dst = datetime.timedelta(0)
|
||
_name = "+08"
|
||
|
||
def utcoffset(self, dt):
|
||
return self.__class__._offset
|
||
|
||
def dst(self, dt):
|
||
return self.__class__._dst
|
||
|
||
def tzname(self, dt):
|
||
return self.__class__._name
|
||
|
||
|
||
class APIMeetingRoomMixin(object):
|
||
def get_building_list(self, page_size=10, page_token='', order_by='', fields=None):
|
||
"""获取建筑物列表
|
||
|
||
:type self: OpenLark
|
||
:param page_size: 可选参数,请求期望返回的建筑物数量,不足则返回全部,该值默认为 10,最大为 100
|
||
:type page_size: int
|
||
:param page_token: 可选参数,用于标记当前请求的页数,将返回以当前页开始,往后 page_size 个元素
|
||
:type page_token: str
|
||
:param order_by: 可选参数,提供用于对名称进行升序/降序排序的方式查询,可选项有:"name-asc,name-desc",传入其他字符串不做处理,默认无序
|
||
:type order_by: str
|
||
:param fields: 可选参数,可选字段有:"id,name,description,floors",默认返回所有字段
|
||
:type fields: list[str]
|
||
:return: has_more, page_token, 建筑物列表
|
||
:rtype: (bool, str, list[Building])
|
||
|
||
该接口用于获取本企业下的建筑物(办公大楼)。
|
||
|
||
https://open.feishu.cn/document/ukTMukTMukTM/ugzNyUjL4cjM14CO3ITN
|
||
"""
|
||
if page_size > 100:
|
||
page_size = 100
|
||
elif page_size <= 0:
|
||
page_size = 10
|
||
|
||
params = {
|
||
'page_size': page_size,
|
||
}
|
||
if page_token:
|
||
params['page_token'] = page_token
|
||
if order_by:
|
||
params['order_by'] = order_by
|
||
if fields:
|
||
params['fields'] = ','.join(fields)
|
||
|
||
url = self._gen_request_url('/open-apis/meeting_room/building/list?{}'.format(urlencode(params)))
|
||
res = self._get(url, with_tenant_token=True)
|
||
data = res['data']
|
||
|
||
has_more = data.get('has_more', False)
|
||
page_token = data.get('page_token', '')
|
||
building_list = [make_datatype(Building, i) for i in data.get('buildings', [])]
|
||
return has_more, page_token, building_list
|
||
|
||
def batch_get_building(self, building_ids, fields=None):
|
||
"""查询建筑物详情
|
||
|
||
:type self: OpenLark
|
||
:param building_ids: 必须参数,用于查询指定建筑物的ID列表
|
||
:type building_ids: list[str]
|
||
:param fields: 可选参数,用于指定返回的字段名,可选字段有:"id,name,description,floors",默认返回所有字段
|
||
:return: 建筑物列表
|
||
:rtype: list[Building]
|
||
|
||
https://open.feishu.cn/document/ukTMukTMukTM/ukzNyUjL5cjM14SO3ITN
|
||
"""
|
||
params = {
|
||
'building_ids': building_ids,
|
||
}
|
||
if fields:
|
||
params['fields'] = ','.join(fields)
|
||
|
||
url = self._gen_request_url(
|
||
'/open-apis/meeting_room/building/batch_get?{}'.format(urlencode(params, doseq=True)))
|
||
|
||
res = self._get(url, with_tenant_token=True)
|
||
data = res.get('data', {})
|
||
buildings = data.get('buildings', [])
|
||
building_list = [make_datatype(Building, i) for i in buildings]
|
||
|
||
return building_list
|
||
|
||
def get_room_list(self, building_id, page_size=100, page_token='', order_by='', fields=None):
|
||
"""获取会议室列表
|
||
|
||
:type self: OpenLark
|
||
:param building_id: 被查询的建筑物ID
|
||
:type building_id: str
|
||
:param page_size: 请求期望返回的会议室数量,不足则返回全部,该值默认为 100,最大为 1000
|
||
:type page_size: int
|
||
:param page_token: 用于标记当前请求的页数,将返回以当前页开始,往后 page_size 个元素
|
||
:type page_token: str
|
||
:param order_by: 提供用于对名称/楼层进行升序/降序排序的方式查询,可选项有:"name-asc,name-desc,floor_name-asc,
|
||
floor_name-desc",传入其他字符串不做处理,默认无序
|
||
:type order_by: str
|
||
:param fields: 可选字段有:"id,name,description,capacity,building_id,building_name,floor_name,is_disabled,
|
||
display_id",默认返回所有字段
|
||
:type fields: list[str]
|
||
:return: has_more, page_token, 会议室列表
|
||
:rtype: (bool, str, list[Room])
|
||
|
||
https://open.feishu.cn/document/ukTMukTMukTM/uADOyUjLwgjM14CM4ITN
|
||
"""
|
||
if page_size > 1000:
|
||
page_size = 1000
|
||
elif page_size <= 0:
|
||
page_size = 100
|
||
|
||
params = {
|
||
'building_id': building_id,
|
||
'page_size': page_size
|
||
}
|
||
if page_token:
|
||
params['page_token'] = page_token
|
||
if order_by:
|
||
params['order_by'] = order_by
|
||
if fields:
|
||
params['fields'] = ','.join(fields)
|
||
|
||
url = self._gen_request_url('/open-apis/meeting_room/room/list?{}'.format(urlencode(params)))
|
||
res = self._get(url, with_tenant_token=True)
|
||
data = res.get('data', {})
|
||
rooms = data.get('rooms', [])
|
||
|
||
has_more = data.get('has_more', False)
|
||
page_token = data.get('page_token', '')
|
||
room_list = [make_datatype(Room, i) for i in rooms]
|
||
return has_more, page_token, room_list
|
||
|
||
def batch_get_room_list(self, room_ids, fields=None):
|
||
"""查询会议室详情
|
||
|
||
:type self: OpenLark
|
||
:param room_ids: 用于查询指定会议室的ID列表
|
||
:type room_ids: List[str]
|
||
:param fields: 可选字段有:"id,name,description,capacity,building_id,building_name,floor_name,is_disabled,
|
||
display_id",默认返回所有字段
|
||
:return: 会议室列表
|
||
:rtype: list[Room]
|
||
|
||
https://open.feishu.cn/document/ukTMukTMukTM/uEDOyUjLxgjM14SM4ITN
|
||
"""
|
||
params = {
|
||
'room_ids': room_ids,
|
||
}
|
||
if fields:
|
||
params['fields'] = ','.join(fields)
|
||
|
||
url = self._gen_request_url('/open-apis/meeting_room/room/batch_get?{}'.format(urlencode(params, doseq=True)))
|
||
|
||
res = self._get(url, with_tenant_token=True)
|
||
data = res.get('data', {})
|
||
rooms = data.get('rooms', [])
|
||
room_list = [make_datatype(Room, i) for i in rooms]
|
||
|
||
return room_list
|
||
|
||
def batch_get_room_freebusy(self, room_ids, time_min, time_max):
|
||
"""会议室忙闲查询
|
||
|
||
:type self: OpenLark
|
||
:param room_ids: 用于查询指定会议室的ID列表
|
||
:type room_ids: list[str]
|
||
:param time_min: 查询会议室忙闲的起始时间
|
||
:type time_min: datetime.datetime
|
||
:param time_max: 查询会议室忙闲的结束时间
|
||
:type time_max: datetime.datetime
|
||
:return: 查询会议室忙闲的起始时间(与请求参数完全相同), 查询会议室忙闲的结束时间(与请求参数完全相同), Dict['会议室ID', List[忙碌时间]]
|
||
:rtype: (datetime.datetime, datetime.datetime, dict[str, list[RoomFreeBusy]])
|
||
|
||
https://open.feishu.cn/document/ukTMukTMukTM/uIDOyUjLygjM14iM4ITN
|
||
"""
|
||
tz = TimeZoneChina()
|
||
params = {
|
||
'room_ids': room_ids,
|
||
'time_min': datetime_format_rfc3339(time_min, tz),
|
||
'time_max': datetime_format_rfc3339(time_max, tz)
|
||
}
|
||
|
||
url = self._gen_request_url(
|
||
'/open-apis/meeting_room/freebusy/batch_get?{}'.format(urlencode(params, doseq=True)))
|
||
|
||
res = self._get(url, with_tenant_token=True)
|
||
data = res.get('data', {})
|
||
time_min = data.get('time_min')
|
||
time_max = data.get('time_max')
|
||
if time_min:
|
||
time_min = parser.parse(time_min)
|
||
if time_max:
|
||
time_max = parser.parse(time_max)
|
||
|
||
return time_min, time_max, {
|
||
k: [RoomFreeBusy(
|
||
start_time=parser.parse(i.get('start_time')),
|
||
end_time=parser.parse(i.get('end_time')),
|
||
uid=i.get('uid'),
|
||
original_time=i.get('original_time'),
|
||
organizer_info=make_datatype(SimpleUser, i.get('organizer_info'))
|
||
) for i in v]
|
||
for k, v in data.get('free_busy', {}).items()}
|
||
|
||
def reply_meeting(self, room_id, uid, original_time, status):
|
||
"""回复会议室日程实例
|
||
|
||
:type self: OpenLark
|
||
:param room_id: 会议室的 ID
|
||
:type room_id: str
|
||
:param uid: 会议室的日程 ID
|
||
:type uid: str
|
||
:param original_time: 日程实例原始时间,非重复日程必为0。重复日程若为0则表示回复其所有实例,否则表示回复单个实例。
|
||
:type original_time: int
|
||
:param status: 回复状态,NOT_CHECK_IN 表示未签到,ENDED_BEFORE_DUE 表示提前结束
|
||
:type status: MeetingReplyStatus
|
||
:return: 查询会议室忙闲的起始时间(与请求参数完全相同), 查询会议室忙闲的结束时间(与请求参数完全相同), Dict['会议室ID', List[忙碌时间]]
|
||
:rtype: (datetime.datetime, datetime.datetime, dict[str, list[RoomFreeBusy]])
|
||
|
||
https://open.feishu.cn/document/ukTMukTMukTM/uIDOyUjLygjM14iM4ITN
|
||
"""
|
||
body = {
|
||
'room_id': room_id,
|
||
'uid': uid,
|
||
'original_time': original_time,
|
||
'status': converter_enum(status),
|
||
}
|
||
url = self._gen_request_url('/open-apis/meeting_room/instance/reply')
|
||
|
||
self._post(url, body=body, with_tenant_token=True)
|