PythonでSlackのメッセージを削除する(WebClient)
$ export SLACK_USER_TOKEN="xoxp-xxxxxxxxxx-xxxxxxxxx-xxxxxx"
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Delete Slack message # 2020-12-23 (Wed.) import os import logging from slack_sdk import WebClient from slack_sdk.errors import SlackApiError logger = logging.getLogger('LoggingTest') # Set log level logger.setLevel(20) # Preparation for console output sh = logging.StreamHandler() logger.addHandler(sh) client = WebClient(token=os.environ.get("SLACK_USER_TOKEN")) message_id = "1608674401.016100" channel_id = "C01FVF0Z32" try: result = client.chat_delete( channel = channel_id, ts = message_id ) logger.info(result) except SlackApiError as e: logger.error(f"Error deleting message: {e}")
Fedora 33 Workstation インストール手順書
[VirtualBox Guest Additions CDのインストール]
$ sudo dnf -y install gcc bzip2 make dkms perl
$ sudo dnf -y install kernel-devel-5.8.15-301.fc33.x86_64
$ sudo /run/media/jack/VBox_GAs_6.1.16/VBoxLinuxAdditions.run
$ sudo /sbin/rcvboxadd setup
[CLIでブートするようにする]
$ sudo systemctl set-default multi-user.target
$ sudo reboot
[SSH daemon setup]
$ sudo vi /etc/ssh/sshd_config
Port 22
PubkeyAuthentication yes
PasswordAuthentication yes -> no
PermitEmptyPasswords no
[パッケージのアップデート]
$ sudo dnf check-update
$ sudo dnf -y update
$ sudo dnf -y remove PackageKit-command-not-found
[Ruby, PHP, Node.js, React.js setup]
[PHP74] v7.4.13
$ dnf -y install https://rpms.remirepo.net/fedora/remi-release-33.rpm
$ sudo dnf -y install php php-devel
[Ruby]
$ sudo dnf -y install ruby ruby-devel
php mbstring
[Python 3.9]
pre-installed
;; Disable SELinux
$ sudo setenforce 0
$ sudo vi /etc/selinux/config
SELINUX=enforcing -> disabled
[Node.js]
whi$ sudo dnf -y install snap
$ sudo systemctl enable --now snapd.socket
$ sudo ln -s /var/lib/snapd/snap /snap
add /var/lib/snapd/snap/bin was not found in your $PATH
$ sudo snap install node --classic --channel=14
;;; Python 3.8 package install
$ python3 -m pip install selenium --user
openpyxl
[React.js install]
$ mkdir sample_app
$ cd sample_app
$ npm init -y
(Generates package.json)
[Django]
[その他]
$ sudo dnf -y install nkf
$ sudo dnf -y install screen
Windows 7からWindows10へのアップグレード方法まとめ
1. Windows 7のインストールはUEFI方式ではなくLegacy方式で行うこと。
2. Windowx 7 OEM(SLP) -> Windows 10 OEM_DMでデジタルライセンス認証。
3. Windows 10をクリーンインストールするとRetail版として認証されている。
Expand vdi
C:\Program Files\Oracle\VirtualBox>
VBoxManage.exe modifyhd "~.vdi" --resize 49152
(48GB)
Launch Vbox guest, and expand C-Drive /w diskmgmt.msc
SQLとER_DUP_ENTRY例外1062についてまとめ
1. UNIQUEキーを設定せずに通常通りにINSERTすると
重複データが挿入されてしまう。
2. UNIQUEキーを設定せずにWHERE NOT EXISTSでINSERTすると
重複データは挿入されないが、Warningも表示されない(ここ重要)。
3. UNIQUEキーを設定せずにINSERT IGNOREでINSERTすると
重複データは挿入されないが、Warningも表示されない(ここ重要)。
4. UNIQUEキーを設定して通常通りにINSERTすると
ER_DUP_ENTRYエラーが発生しデータの挿入はなされない。
5. UNIQUEキーを設定してWHERE NOT EXISTSでINSERTすると
重複データは挿入されないが、Warningも表示されない(ここ重要)。
6. UNIQUEキーを設定してINSERT IGNOREでINSERTすると
重複データは挿入されないが、Warningも表示されない(ここ重要)。
ということで、PHPやPythonなどの言語側で「SQL文を実行したがWarningが生じてしまった」
ことをtry~catch構文で例外処理する場合、UNIQUEキーを設定したうえで
通常通りのSQL文でデータを挿入することになる。
PHPコード:
<?php $id = "5"; $name = "Test 5"; // DB connection info $user = 'dbuser1'; $pass = '12ab'; try { // Connect to DB $dsn = 'mysql:host=localhost;dbname=php_enquete;charset=utf8mb4'; $conn = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); // Add data $sql = "INSERT IGNORE INTO s_table1(id, name) SELECT '$id', '$name'"; //$sql = "INSERT INTO s_table1(id, name) SELECT '$id', '$name' FROM dual WHERE NOT EXISTS (SELE CT 1 FROM s_table1 WHERE name = '$name')"; $stmt = $conn -> prepare($sql); $ret = $stmt -> execute(); } catch (PDOException $e) { var_dump($e->getMessage()); if (strpos($e->getMessage(), '1062') !== false) { echo "ER_DUP_ENTRY: すでに送信済みのデータです"; } } ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Registered!</title> </head> <body> <p>Thank you for the registration.</p> <p><a href="input.php">入力画面に戻る</a></p> </body></html>
Windows 10/8.1の公式ISOからProのみのディスクを作成する方法
1. UltraISOなどのISOファイル編集ができるソフトで\sources\install.wimを抽出する。
2. 管理者権限のコマンドプロンプトより
C:\work>dism.exe /Get-WimInfo /WimFile:"install.wim"
とすると、Pro版が収録されているIndexが表示される。
3. Pro版のinstall.wimを抽出する。
C:\work>mkdir Pro_image
(Windows 10の場合)
C:\work>dism.exe /Export-Image /SourceImageFile:"install.wim" /SourceIndex:3 /DestinationImageFile:".\Pro_image\install.wim" /Compress:max /CheckIntegrity
(Windows 8.1の場合)
C:\work>dism.exe /Export-Image /SourceImageFile:"install.wim" /SourceIndex:1 /DestinationImageFile:".\Pro_image\install.wim" /Compress:max /CheckIntegrity
4. UltraISOで\sources\install.wimを差し替えて保存する。
以上
Python3.8.3でGmailの特定条件のメールを検索し100件まで表示する
PythonでGmailの特定条件のメールを検索し100件まで表示する
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Ryo Chiba # 2019/06/13 (Sat.) from __future__ import print_function from googleapiclient.discovery import build from httplib2 import Http from oauth2client import file, client, tools class GmailAPI: def __init__(self): # If modifying these scopes, delete the file token.json. self._SCOPES = 'https://www.googleapis.com/auth/gmail.readonly' def ConnectGmail(self): store = file.Storage('token.json') creds = store.get() if not creds or creds.invalid: flow = client.flow_from_clientsecrets('client_secret_665638201308-6i9a4tqnmtl9asdp14sghefdm3tpnudm.apps.googleusercontent.com.json', self._SCOPES) creds = tools.run_flow(flow, store) service = build('gmail', 'v1', http=creds.authorize(Http())) return service def GetMessageList(self,DateFrom,DateTo,MessageFrom,MessageBody): #APIに接続 service = self.ConnectGmail() MessageList = [] query = '' # 検索用クエリを指定する if DateFrom != None and DateFrom !="": query += 'after:' + DateFrom + ' ' if DateTo != None and DateTo !="": query += 'before:' + DateTo + ' ' if MessageFrom != None and MessageFrom !="": query += 'From:' + MessageFrom + ' ' if MessageBody != None and MessageBody !="": query += MessageBody+ ' ' # メールIDの一覧を取得する(最大100件) messageIDlist = service.users().messages().list(userId='me',maxResults=100,q=query).execute() #該当するメールが存在しない場合は、処理中断 if messageIDlist['resultSizeEstimate'] == 0: print("Message is not found") return MessageList #メッセージIDを元に、メールの詳細情報を取得 for message in messageIDlist['messages']: row = {} row['ID'] = message['id'] MessageDetail = service.users().messages().get(userId='me',id=message['id']).execute() for header in MessageDetail['payload']['headers']: #日付、送信元、件名を取得する if header['name'] == 'Date': row['Date'] = header['value'] elif header['name'] == 'From': row['From'] = header['value'] elif header['name'] == 'Subject': row['Subject'] = header['value'] MessageList.append(row) return MessageList if __name__ == '__main__': test = GmailAPI() #パラメータは、任意の値を指定する messages = test.GetMessageList( DateFrom='2020-06-10', DateTo='2020-06-13', MessageFrom='', MessageBody='(パスワード|ロック) -(UnitBase|password-reset@aim.aoyama.ac.jp)' ) # messages = test.GetMessageList(DateFrom='2020-04-01',DateTo='2020-05-15',MessageFrom='contact@aim.aoyama.ac.jp') #結果を出力 for message in messages: print(message)
Flask(Python)でCisco Webex Teamsのスペースにオウム返しするBotを作成
FlaskでのBot作成Hello World的なもの
main.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Ryo Chiba # 2019/06/13 (Sat.) from __future__ import print_function import requests import sys import json import os import time from flask import * from requests_toolbelt.multipart.encoder import MultipartEncoder import functools token = 'NWIyYTk4NDItY2MzZS00YWEwLThjOWItOWRlM2RiYmFkMzI4ZjZkZGZkMzMtMTI3_PF84_e929f3de-bb48-434c-8d2e-20437b17e683' ms_flag = True app = Flask(__name__) def post_message(room_id, txt, token): global ms_flag if ms_flag == True: ms_flag = False m = MultipartEncoder({'roomId': room_id, 'text': txt}) r = requests.post('https://api.ciscospark.com/v1/messages', data=m,headers={'Authorization': 'Bearer %s' % token,'Content-Type': m.content_type}) else: time.sleep(5) ms_flag = True @app.route("/panel", methods=['GET']) def main_page(): return render_template("mainpage.html") @app.route("/", methods=['POST']) def handle_message(): json = request.json message_id = json["data"]["id"] user_id = json["data"]["personId"] email = json["data"]["personEmail"] room_id = json["data"]["roomId"] bot_id = "Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OL2M1ZTYzZjQ5LTcwNzItNDRlMy1hNDE0LWVkZWZlNjc3MDc5MQ" print(message_id, file = sys.stdout) print(user_id, file = sys.stdout) print(email, file = sys.stdout) print(room_id, file = sys.stdout) if user_id != bot_id: global token header = {"Authorization": "Bearer %s" % token} get_rooms_url = "https://api.ciscospark.com/v1/messages/" + message_id api_response = requests.get(get_rooms_url, headers=header, verify=False) response_json = api_response.json() message = response_json["text"] print(message, file= sys.stdout) if message == "Hello": post_message(room_id,"Bonjour!",token) return "Success" else: # print("fooo", file=sys.stdout) return "Pass" term_output_json = os.popen('curl http://127.0.0.1:4040/api/tunnels').read() tunnel_info = json.loads(term_output_json) public_url = tunnel_info['tunnels'][0]['public_url'] # Registering Webhook header = {"Authorization": "Bearer %s" % token, "content-type": "application/json"} requests.packages.urllib3.disable_warnings() # Removing SSL warnings post_message_url = "https://api.ciscospark.com/v1/webhooks" payload = { "resource": "messages", "event": "all", "targetUrl": public_url, "name": "BotDemoWebHook" } api_response = requests.post(post_message_url, json=payload, headers=header, verify=False) # Registering Webhook if api_response.status_code != 200: print('Webhook registration Error !') exit(0) if __name__ == '__main__': app.run(host='localhost', use_reloader=True, debug=True)