implement token generation, config write

This commit is contained in:
Kaz Saita(raspi4) 2024-03-12 11:50:20 +09:00
parent 66d4941c20
commit 9277e85b2c
9 changed files with 145 additions and 78 deletions

3
.gitignore vendored
View file

@ -1,3 +1,4 @@
.venv/*
tokens.yml
.env
config.yaml
__pycache__/

1
capture_bot_san/__init__.py Executable file
View file

@ -0,0 +1 @@
# empty file

15
capture_bot_san/__main__.py Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from . import token
from . import config
def main():
config.read_config()
token.read_tokens()
if __name__ == '__main__':
main()

View file

@ -1,83 +1,52 @@
import yaml
from dropbox import DropboxOAuth2FlowNoRedirect
CONFIG_VERSION = 1
CONFIG_FILE = 'tokens.yml'
# read or create config file
# find the config file, if it doesn't exist, create it
from . import constants
class Config:
def __init__(self):
self.Comment = '# Capture Bot San Config File'
self.DISCORD_TOKEN = ''
self.DROPBOX_APP_KEY = ''
self.DROPBOX_APP_SECRET = ''
self.DROPBOX_REFRESH_TOKEN = ''
def create_config():
self.DROPBOX_TEXTFILE_FOLDER = ''
self.DROPBOX_MEDIA_FOLDER = ''
self.MARKDOWN_FILENAME = ''
# read or create config file
# find the config file or create it otherwise
def create_config():
print('Creating config...')
try:
open(CONFIG_FILE, 'w')
open(constants.CONFIG_FILE, 'w')
except OSError as e:
print(f'Error: {e.strerror}')
exit(1)
def read_config():
config = Config()
print('Reading config...')
write_back = False
try:
with open(CONFIG_FILE, 'r') as f:
file_content = yaml.safe_load(f)
if file_content is None:
file_content = {}
with open(constants.CONFIG_FILE, 'r') as file:
parsed = yaml.safe_load(file) or {}
config.DROPBOX_TEXTFILE_FOLDER = parsed.get('DROPBOX_TEXTFILE_FOLDER') or ''
config.DROPBOX_MEDIA_FOLDER = parsed.get('DROPBOX_MEDIA_FOLDER') or ''
config.MARKDOWN_FILENAME = parsed.get('MARKDOWN_FILENAME') or ''
config.DISCORD_TOKEN = file_content.get('DISCORD_TOKEN') or ''
config.DROPBOX_APP_KEY = file_content.get('DROPBOX_APP_KEY') or ''
config.DROPBOX_APP_SECRET = file_content.get('DROPBOX_APP_SECRET') or ''
config.DROPBOX_REFRESH_TOKEN = file_content.get('DROPBOX_REFRESH_TOKEN') or ''
write_back = False
if config.DISCORD_TOKEN == '':
if config.DROPBOX_TEXTFILE_FOLDER == '':
write_back = True
print('Discord token not set')
print('Go to https://discord.com/developers/applications/ and create it.')
print('New Application -> Bot -> Token -> Copy!')
config.DISCORD_TOKEN = input('Discord Token: ').strip()
if config.DROPBOX_APP_KEY == '' or config.DROPBOX_APP_SECRET == '':
print('Dropbox textfile folder not set')
config.DROPBOX_TEXTFILE_FOLDER = input('Dropbox textfile folder(e.g. /notes): ').strip()
if config.DROPBOX_MEDIA_FOLDER == '':
write_back = True
print('Dropbox app key or secret not set')
print('Go to https://www.dropbox.com/developers/apps and create it.')
print('1. Scoped Access, 2. Full Dropbox, 3. [whatever]')
print('Dropbox App key and App secret will be displayed.')
config.DROPBOX_APP_KEY = input('App key: ').strip()
config.DROPBOX_APP_SECRET = input('App secret: ').strip()
if config.DROPBOX_REFRESH_TOKEN == '':
print('Dropbox media folder not set')
config.DROPBOX_MEDIA_FOLDER = input('Dropbox media folder(e.g. /notes/media): ').strip()
if config.MARKDOWN_FILENAME == '':
write_back = True
print('Dropbox refresh token not set. Try to get it...')
if config.DROPBOX_APP_KEY == '' or config.DROPBOX_APP_SECRET == '':
print('Requries Dropbox app key and secret. Give up.')
exit(1)
auth_flow = DropboxOAuth2FlowNoRedirect(config.DROPBOX_APP_KEY, consumer_secret=config.DROPBOX_APP_SECRET, use_pkce=False, token_access_type='offline')
authorize_url = auth_flow.start()
print('1. Go to:', authorize_url)
print('2. Click "Allow" (you might have to log in first)')
print('3. Copy the authorization code.')
auth_code = input('Enter the authorization code here: ').strip()
try:
oauth_result = auth_flow.finish(auth_code)
print("Refresh token:", oauth_result.refresh_token)
config.DROPBOX_REFRESH_TOKEN = oauth_result.refresh_token
except Exception as e:
print('Error:', e)
exit(1)
print('Markdown filename not set')
config.MARKDOWN_FILENAME = input('Markdown filename(e.g. capture.md): ').strip()
if write_back:
with open(CONFIG_FILE, 'w') as f:
yaml.dump(config.__dict__, f)
print('Writing back to config...')
yaml.dump({'DROPBOX_TEXTFILE_FOLDER': config.DROPBOX_TEXTFILE_FOLDER, 'DROPBOX_MEDIA_FOLDER': config.DROPBOX_MEDIA_FOLDER, 'MARKDOWN_FILENAME': config.MARKDOWN_FILENAME}, open(constants.CONFIG_FILE, 'w'))
except FileNotFoundError:
file_content = create_config()
print('Config file not found. Creating...')
create_config()
read_config()
return config

2
capture_bot_san/constants.py Executable file
View file

@ -0,0 +1,2 @@
TOKEN_FILE = '.env'
CONFIG_FILE = 'config.yaml'

View file

@ -1,10 +0,0 @@
#!/usr/bin/env python3
import config
config.read_config()

72
capture_bot_san/token.py Executable file
View file

@ -0,0 +1,72 @@
import dotenv
dotenv.load_dotenv()
import os
from dropbox import DropboxOAuth2FlowNoRedirect
from . import constants
class Token:
def __init__(self):
self.DISCORD_TOKEN = ''
self.DROPBOX_APP_KEY = ''
self.DROPBOX_APP_SECRET = ''
self.DROPBOX_REFRESH_TOKEN = ''
# read or create token file
# find the
def read_tokens():
print('Reading tokens...')
token = Token()
token.DISCORD_TOKEN = os.getenv('DISCORD_TOKEN') or ''
token.DROPBOX_APP_KEY = os.getenv('DROPBOX_APP_KEY') or ''
token.DROPBOX_APP_SECRET = os.getenv('DROPBOX_APP_SECRET') or ''
token.DROPBOX_REFRESH_TOKEN = os.getenv('DROPBOX_REFRESH_TOKEN') or ''
write_back = False
if token.DISCORD_TOKEN == '':
write_back = True
print('Discord token not set')
print('Go to https://discord.com/developers/applications/ and create it.')
print('New Application -> Bot -> Token -> Copy!')
token.DISCORD_TOKEN = input('Discord Token: ').strip()
if token.DROPBOX_APP_KEY == '' or token.DROPBOX_APP_SECRET == '':
write_back = True
print('Dropbox app key or secret not set')
print('Go to https://www.dropbox.com/developers/apps and create it.')
print('1. Scoped Access, 2. Full Dropbox, 3. [whatever]')
print('Dropbox App key and App secret will be displayed.')
token.DROPBOX_APP_KEY = input('App key: ').strip()
token.DROPBOX_APP_SECRET = input('App secret: ').strip()
if token.DROPBOX_REFRESH_TOKEN == '':
write_back = True
print('Dropbox refresh token not set. Try to get it...')
if token.DROPBOX_APP_KEY == '' or token.DROPBOX_APP_SECRET == '':
print('Requries Dropbox app key and secret. Give up.')
exit(1)
auth_flow = DropboxOAuth2FlowNoRedirect(token.DROPBOX_APP_KEY, consumer_secret=token.DROPBOX_APP_SECRET, use_pkce=False, token_access_type='offline')
authorize_url = auth_flow.start()
print('1. Go to:', authorize_url)
print('2. Click "Allow" (you might have to log in first)')
print('3. Copy the authorization code.')
auth_code = input('Enter the authorization code here: ').strip()
try:
oauth_result = auth_flow.finish(auth_code)
print("Refresh token:", oauth_result.refresh_token)
token.DROPBOX_REFRESH_TOKEN = oauth_result.refresh_token
except Exception as e:
print('Error:', e)
exit(1)
if write_back:
dotenv.set_key(constants.TOKEN_FILE, 'DISCORD_TOKEN', token.DISCORD_TOKEN)
dotenv.set_key(constants.TOKEN_FILE, 'DROPBOX_APP_KEY', token.DROPBOX_APP_KEY)
dotenv.set_key(constants.TOKEN_FILE, 'DROPBOX_APP_SECRET', token.DROPBOX_APP_SECRET)
dotenv.set_key(constants.TOKEN_FILE, 'DROPBOX_REFRESH_TOKEN', token.DROPBOX_REFRESH_TOKEN)
print('Tokens written to .env file.')
return token

16
poetry.lock generated
View file

@ -496,6 +496,20 @@ files = [
{file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"},
]
[[package]]
name = "python-dotenv"
version = "1.0.1"
description = "Read key-value pairs from a .env file and set them as environment variables"
optional = false
python-versions = ">=3.8"
files = [
{file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
{file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
]
[package.extras]
cli = ["click (>=5.0)"]
[[package]]
name = "pytz"
version = "2024.1"
@ -738,4 +752,4 @@ multidict = ">=4.0"
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
content-hash = "0cec85b8dce92143d2f503fb44a9c8cafe4cabe88f1aa29472b2dfa8bb288793"
content-hash = "f94df9517f6942e31a03c96b92a1eb0851ea71c7a61e4443c4590c1a9cdf18a5"

View file

@ -6,13 +6,16 @@ authors = ["kaz Saita <saita@kinoshita-lab.org>"]
license = "MIT"
readme = "README.md"
package-mode = false
packages = [
{ include = "capture_bot_san" }
]
[tool.poetry.dependencies]
python = "^3.11"
discord = "^2.3.2"
dropbox = "^11.36.2"
pytz = "^2024.1"
pyyaml = "^6.0.1"
python-dotenv = "^1.0.1"
[build-system]