def main(): project_dir = Path(__file__).parents[1] token_dir = project_dir.joinpath('token') token_paths = { 'pickle_path': token_dir.joinpath('token.pickle'), 'json_path': token_dir.joinpath('client_id.json') } # 必須ファイルなければ終了 if not required_files_exists(token_dir, token_paths): sys.exit() g_mail = Gmail(token_paths) label_list = g_mail.label_list() labels = [label['name'] for label in label_list if label['type'] == 'user'] filter_frame = [[ sg.OptionMenu(['from', 'to', 'subject'], disabled=True, key='filter_type', size=(5, 1)), sg.InputText(disabled=True, key='filter_txt', default_text='', size=(20, 1)) ]] layout = [[sg.Text('ラベル'), sg.Combo(labels, key='label', size=(25, 1))], [sg.Checkbox('フィルターを作成する', key='is_filter', enable_events=True)], [sg.Frame('フィルター', filter_frame, key='filter')], [ sg.Column([[sg.Button('作成', key='create', size=(6, 1))]], justification='right') ]] window = sg.Window('GMail Filter', layout, finalize=True, icon='icon/filtan.ico') while True: event, values = window.read() # ×ボタン押下(None)で閉じる if event is None: break else: input_label = values['label'] input_filter_type = values['filter_type'] input_filter_txt = values['filter_txt'] if event == 'is_filter': # フィルターチェックボックスでフィルター入力可・不可切り替え if values['is_filter'] is True: window['filter_type'].update(disabled=False) window['filter_txt'].update(disabled=False) else: window['filter_type'].update(disabled=True) window['filter_txt'].update('', disabled=True) elif event == 'create': # 作成ボタン押下禁止 window['create'].update(disabled=True) success_msg = '' error_msg = 'ラベルを入力してください。\n' if input_label == '' else '' # チェックボックス.get() => True: 1, False: 0 if window['is_filter'].get() == 1 and input_filter_txt == '': error_msg += 'フィルターを入力してください。' if error_msg != '': sg.Popup('Error', error_msg) else: # チェックボックス.get() => True: 1, False: 0 if window['is_filter'].get() == 1: # 入力したラベル名からラベルID取得 label_id = '' for label in label_list: if label['name'] == values['label']: label_id = label['id'] break # 既存のラベルじゃなければ作成 if label_id == '': label_result = g_mail.create_label(input_label) if type(label_result) is dict: success_msg += 'ラベル「{}」の作成に成功しました。\n'.format( input_label) # ラベルリスト更新 labels = [ label['name'] for label in g_mail.label_list() if label['type'] == 'user' ] window['label'].update(value=label_result['name'], values=labels) # フィルター作成 filter_result = g_mail.create_filter( input_filter_type, input_filter_txt, label_result['id']) else: filter_result = None error_msg += label_result else: filter_result = g_mail.create_filter( input_filter_type, input_filter_txt, label_id) if type(filter_result) is dict: success_msg += 'フィルター「{}:{}」の作成に成功しました。\n'.format( input_filter_type, input_filter_txt) else: error_msg += filter_result else: if input_label in labels: error_msg += 'そのラベル名はすでにあります。\n別の名前を付けてください。' else: label_result = g_mail.create_label(input_label) if label_result['name'] == values['label']: success_msg = 'ラベル「{}」の作成に成功しました。'.format( label_result['name']) labels = [ label['name'] for label in g_mail.label_list() if label['type'] == 'user' ] window['label'].update(value=label_result['name'], values=labels) # ポップアップ表示 if success_msg: sg.Popup('Success', success_msg) elif error_msg: sg.Popup('Error', error_msg) # ボタン押下禁止解除 window['create'].update(disabled=False) window.close()
class FalconClient: def __init__(self, email): self.email = email self.gmail = Gmail() self.gmail.auth(self.email, method='Desktop') self._labels = None def get_labels(self): if self._labels is None: self._labels = { i['id']: i for i in self.gmail.list_labels()['labels'] } return self._labels def get_label_by_name(self, name): labels_by_name = {i['name']: i for i in self.get_labels().values()} return labels_by_name.get(name, None) def create_label(self, name): created = False if self.get_label_by_name(name) is None: try: label_body = { 'name': name, 'type': 'user', 'labelListVisibility': 'labelShow', 'messageListVisibility': 'show', 'messagesTotal': 0, 'threadsUnread': 0, 'messagesUnread': 0, 'threadsTotal': 0, 'color': { "textColor": '#000000', "backgroundColor": '#ffffff', } } label = self.gmail.create_label(label_body) self._labels[label['id']] = label created = True except Exception as e: logging.exception(e) return created def save_mails(self, filter_q): start_time = datetime.now() base_dir = os.path.join(root_dir, 'data', self.email) # load state file state_file_path = os.path.join(base_dir, 'state.pickle') os.makedirs(os.path.dirname(state_file_path), exist_ok=True) state = {} if os.path.exists(state_file_path): with open(state_file_path, 'rb') as fp: state = pickle.load(fp) query = filter_q if filter_q is not None else '' last_modified_date = state.get('lastModifiedDate', None) if last_modified_date is not None: query += f" after:{last_modified_date.strftime('%Y/%m/%d')}" query = query.strip() print(f'Modified mail listing query [{query}]') # do my thing with mails mails = self.gmail.list_mails(query=query, max_pages=10000, include_spam_and_trash=True) print(f'Number of mails for [{self.email}] : [{len(mails)}].') for index, mail in enumerate(mails, 0): mail_id = mail['id'] thread_id = mail['threadId'] mail_path = os.path.join(base_dir, thread_id, mail_id, 'mail.json') if os.path.exists(mail_path): print( f'Skipping mail #[{index}], Id [{mail_id}], ThreadId [{thread_id}].' ) continue print(f'Mail #[{index}], Id [{mail_id}], ThreadId [{thread_id}].') mail_body = self.gmail.get_mail(mail_id) os.makedirs(os.path.dirname(mail_path), exist_ok=True) with open(mail_path, 'w') as fp: json.dump(mail_body, fp) # Avoid too many api hits time.sleep(0.5) # update state state['lastModifiedDate'] = start_time with open(state_file_path, 'wb') as fp: pickle.dump(state, fp)