refactor: for public repository
This commit is contained in:
parent
323b6a7a86
commit
05caae7cf8
4
.env.example
Normal file
4
.env.example
Normal file
@ -0,0 +1,4 @@
|
||||
MISSKEY_TOKEN = YOUR_ACCESS_TOKEN_HERE
|
||||
MISSKEY_ORIGIN = YOUR_MISSKEY_SERVER_HERE
|
||||
MAX_DUPLICATE_COUNT = 3
|
||||
SPREADSHEET_URL = https://docs.google.com/spreadsheets/d/1KXt5mcAsdT87j94d8yHJWcdmHG-MadDKpOWmCfK8OGI/edit
|
70
README.md
70
README.md
@ -1,2 +1,68 @@
|
||||
# Autopost
|
||||
I want some random lines for my timeline
|
||||
# Misskey Autoposter
|
||||
간단한 Misskey (또는 CherryPick!) 전용 자동 노트 봇
|
||||
|
||||
⚠️ **이 봇을 사용할 때에는 봇 친화적인 서버, 또는 개인 서버에서 사용하시는 것을 권장합니다.**
|
||||
|
||||
도움이 필요하시다면 [@ALPINE_SECTOR@phater.live](https://phater.live/@ALPINE_SECTOR)로 알려주세요.
|
||||
|
||||
본 소스 코드의 수정 및 이용은 자유이나, 재배포 시애는 해당 리포지토리의 링크를 걸어주세요!
|
||||
|
||||
## What
|
||||
Google 스프레드시트를 기반으로 지정된 문구들을 자동적으로 노트로 작성합니다.
|
||||
|
||||
현재 이 소스 코드를 기반으로 작동하고 있는 봇을 [여기에서 확인](https://phater.live/@Stainless)하실 수 있습니다!
|
||||
|
||||
## Features
|
||||
* 최근 등장한 n개의 문구를 스킵할 수 있는 기능
|
||||
* @멘션 시 입력된 문구 정보와 함께 즉시 문구를 출력할 수 있는 기능
|
||||
|
||||
## Options
|
||||
.env.example 파일을 참조하여 .env 파일을 작성해주세요.
|
||||
```
|
||||
MISSKEY_TOKEN : 계정 액세스 토큰
|
||||
MISSKEY_ORIGIN : 호스트 서버 이름 (misskey.io, phater.live...)
|
||||
MAX_DUPLICATE_COUNT : 중복 시 출력되지 않게 할 간격
|
||||
(3으로 설정 시 다음 3개의 문구가 나올 동안은 출력되지 않음)
|
||||
WORKSHEET_URL : 문구를 불러올 스프레드시트 URL
|
||||
```
|
||||
|
||||
## How
|
||||
### Requirements
|
||||
* Git
|
||||
* Google Cloud Service Account
|
||||
* 구글 스프레드시트 연동을 위해 작업이 필요합니다. ([gspread 문서 참조](https://docs.gspread.org/en/latest/oauth2.html))
|
||||
* Ubuntu 20.04+ or Windows 10+
|
||||
* Python 3.10+
|
||||
* Google 스프레드시트 ([예시 스프레드시트](https://docs.google.com/spreadsheets/d/1nO70lwFFkyyK8AtVE4fWO7lW7KDtM5pNudGJydTaQdk/edit))
|
||||
* 예시에서 복사본을 생성하여 수정하세요. 양식이 맞지 않으면 오류가 발생합니다.
|
||||
### Clone source code
|
||||
GitHub에서 소스 코드를 복사 후, 해당 디렉토리로 이동합니다.
|
||||
```sh
|
||||
> git clone https://github.com/Unstarrified/Autopost.git
|
||||
> cd Autopost
|
||||
```
|
||||
### Setup venv (Optional)
|
||||
프로덕션 서버에서 작동하는 경우, 아래 명령어로 venv를 설정하시는 것을 권장합니다.
|
||||
```sh
|
||||
> python3 -m venv .venv
|
||||
# Ubuntu의 경우 가상 환경을 불러오려면 이 명령어를 실행하세요.
|
||||
> source ./.venv/bin/activate
|
||||
# Windows의 경우 가상 환경을 불러오려면 이 명령어를 실행하세요.
|
||||
> call ./.venv/Scripts/activate
|
||||
```
|
||||
### Install dependencies
|
||||
아래 명령어를 실행해 봇이 필요한 의존성 패키지를 설치합니다.
|
||||
```sh
|
||||
> pip install -r requirements.txt
|
||||
```
|
||||
### Run
|
||||
아래 명령어를 실행하면 봇이 동작하기 시작합니다.
|
||||
```sh
|
||||
> python3 main.py
|
||||
```
|
||||
끝입니다! 계속 실행되도록 하시려면 nohup이나 systemd 등을 사용해주세요.
|
||||
### Update
|
||||
추후 봇 코드가 변경되어 업데이트가 필요한 경우, 아래 명령어를 실행하세요.
|
||||
```sh
|
||||
> git pull
|
||||
```
|
@ -2,10 +2,9 @@ from datetime import datetime
|
||||
|
||||
from mipa.ext import commands, tasks
|
||||
from mipa.ext.commands.bot import Bot
|
||||
# from mipa.ext.commands.context import Context
|
||||
|
||||
|
||||
class Autopost(commands.Cog):
|
||||
class Post(commands.Cog):
|
||||
def __init__(self, bot: Bot) -> None:
|
||||
self.bot = bot
|
||||
self.posted = []
|
||||
@ -13,10 +12,10 @@ class Autopost(commands.Cog):
|
||||
@tasks.loop(seconds=60)
|
||||
async def _postLine(self) -> None:
|
||||
now = datetime.now()
|
||||
if now.minute not in [30, 00]:
|
||||
if now.minute not in [30, 00]: # Only post in n:30 and n:00
|
||||
return
|
||||
|
||||
line = self.bot.get_line()
|
||||
line = self.bot.get_random_line()
|
||||
while line in self.posted:
|
||||
line = self.bot.get_line()
|
||||
await self.bot.client.note.action.send(content=line, visibility="home")
|
||||
@ -26,6 +25,6 @@ class Autopost(commands.Cog):
|
||||
|
||||
|
||||
async def setup(bot: Bot):
|
||||
cog = Autopost(bot)
|
||||
cog = Post(bot)
|
||||
await cog._postLine.start()
|
||||
await bot.add_cog(cog)
|
72
main.py
72
main.py
@ -1,49 +1,21 @@
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
#from typing import Optional
|
||||
|
||||
#import aiomysql
|
||||
import gspread
|
||||
from aiohttp import ClientWebSocketResponse
|
||||
from gspread.worksheet import Worksheet
|
||||
from mipac.models.notification import NotificationNote
|
||||
from mipa.ext import commands
|
||||
# from mipac.models.note import Note
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
COGS = [
|
||||
"exts.tasks"
|
||||
]
|
||||
|
||||
class MyBot(commands.Bot):
|
||||
class Autoposter(commands.Bot):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.max_count = int(os.getenv("MAX_COUNT"))
|
||||
|
||||
# async def create_pool(self) -> None:
|
||||
# pool = await aiomysql.create_pool(
|
||||
# minsize=5,
|
||||
# maxsize=20,
|
||||
# host=os.getenv("MYSQL_HOST"),
|
||||
# port=int(os.getenv("MYSQL_PORT")),
|
||||
# user=os.getenv("MYSQL_USER"),
|
||||
# password=os.getenv("MYSQL_PASSWORD"),
|
||||
# db="autopost",
|
||||
# autocommit=True
|
||||
# )
|
||||
# self.pool = pool
|
||||
|
||||
# async def query(self, query: str, fetch: bool = False) -> Optional[dict]:
|
||||
# async with self.pool.acquire() as conn:
|
||||
# async with conn.cursor(aiomysql.DictCursor) as cur:
|
||||
# await cur.execute(query)
|
||||
# if fetch:
|
||||
# return await cur.fetchall()
|
||||
# else:
|
||||
# return "Query Successful"
|
||||
self.max_count = int(os.getenv("MAX_DUPLICATE_COUNT"))
|
||||
|
||||
def get_worksheet(self) -> Worksheet:
|
||||
gc = gspread.service_account()
|
||||
@ -51,7 +23,7 @@ class MyBot(commands.Bot):
|
||||
worksheet = sh.get_worksheet(0)
|
||||
return worksheet
|
||||
|
||||
def get_line(self) -> str:
|
||||
def get_random_line(self) -> str:
|
||||
sheet: Worksheet = self.get_worksheet()
|
||||
response = sheet.get("F4")
|
||||
if response is None or response == "":
|
||||
@ -62,35 +34,39 @@ class MyBot(commands.Bot):
|
||||
res = sheet.get(f"D{number}")
|
||||
text = res[0][0].strip()
|
||||
return text
|
||||
|
||||
def get_info(self, line: str) -> dict:
|
||||
sheet = self.get_worksheet()
|
||||
result = sheet.find(line, in_column=4)
|
||||
number = result.row - 2
|
||||
where = sheet.get(f"C{result.row}")
|
||||
where = where[0][0]
|
||||
return {"number": number, "from": where}
|
||||
|
||||
async def _connect_channel(self):
|
||||
await self.router.connect_channel(['main', 'global'])
|
||||
|
||||
async def on_ready(self, ws: ClientWebSocketResponse):
|
||||
print(f'connected: {self.user.username}')
|
||||
print(f"Connected as @{self.user.username}@{self.user.host}")
|
||||
await self._connect_channel()
|
||||
for cog in COGS:
|
||||
await self.load_extension(cog)
|
||||
extensions = [
|
||||
"exts.post"
|
||||
]
|
||||
for extension in extensions:
|
||||
await self.load_extension(extension)
|
||||
|
||||
async def on_reconnect(self, ws: ClientWebSocketResponse):
|
||||
print('Disconnected from server. Will try to reconnect.')
|
||||
print("Disconnected from server.")
|
||||
await self._connect_channel()
|
||||
|
||||
# async def on_note(self, note: Note):
|
||||
# print(f'{note.author.username}: {note.content}')
|
||||
|
||||
async def on_mention(self, notice: NotificationNote):
|
||||
sheet = self.get_worksheet()
|
||||
line = self.get_line()
|
||||
result = sheet.find(line, in_column=4)
|
||||
number = result.row - 2
|
||||
where = sheet.get(f"C{result.row}")
|
||||
where = where[0][0]
|
||||
await notice.note.api.action.reply(content=f"{line}\n \n<small>- {where}에서 발췌됨. ({number}번 대사)</small>", visibility="home", reply_id=notice.note.id)
|
||||
line = self.get_random_line()
|
||||
info = self.get_info(line)
|
||||
await notice.note.api.action.reply(content=f"{line}\n \n<small>- {info['where']}에서 발췌됨. ({info['number']}번 대사)</small>", reply_id=notice.note.id)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
bot = MyBot()
|
||||
bot = Autoposter()
|
||||
loop = asyncio.get_event_loop()
|
||||
# loop.run_until_complete(bot.create_pool())
|
||||
loop.run_until_complete(bot.start(os.getenv("MISSKEY_ORIGIN"), os.getenv("MISSKEY_TOKEN")))
|
||||
origin = os.getenv("MISSKEY_ORIGIN")
|
||||
loop.run_until_complete(bot.start(f"wss://{origin}/streaming", os.getenv("MISSKEY_TOKEN")))
|
||||
|
Loading…
Reference in New Issue
Block a user