-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.py
229 lines (179 loc) · 8.64 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
import requests
import os
from datetime import datetime
from io import BytesIO
from bs4 import BeautifulSoup
from discord import Game, Embed, File
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv() # load bot token
def from_text(ctx):
# msg_fr = msg.server.name + ' > ' + msg.channel.name + ' > ' + msg.author.name
# msg.server --> msg.guild
# https://discordpy.readthedocs.io/en/latest/migrating.html#server-is-now-guild
return f'{ctx.guild.name} > {ctx.channel.name} > {ctx.author.name}'
def log(fr, text):
print(f'{fr} | {str(datetime.now())} | {text}') # TODO: 시간대 조정
BOT_TOKEN = os.getenv('BOT_TOKEN')
if "PREFIX" in os.environ:
COMMAND_PREFIX = os.getenv("PREFIX")
else:
COMMAND_PREFIX = "!"
DCCON_HOME_URL = 'https://dccon.dcinside.com/'
DCCON_SEARCH_URL = 'https://dccon.dcinside.com/hot/1/title/'
DCCON_DETAILS_URL = 'https://dccon.dcinside.com/index/package_detail'
EMBED_COLOR = 0x4559e9
INVITE_URL = 'https://discordapp.com/oauth2/authorize?&client_id=464437182887886850&scope=bot&permissions=101376'
bot = commands.Bot(command_prefix=COMMAND_PREFIX)
'''
@bot.command(name='콘')
async def send_dccon(ctx, *args):
await ctx.channel.send(args)
'''
@bot.event
async def on_ready():
await bot.change_presence(activity=Game(name=f'{COMMAND_PREFIX}도움'))
log('SYSTEM', 'Bot ready')
@bot.command(name='도움')
async def help(ctx):
log(from_text(ctx), 'help command')
embed = Embed(title='안녕하세요! 디시콘 핫산이에요!',
description='명령어들은 아래에서 전부 보실 수 있어요.',
color=EMBED_COLOR)
embed.add_field(
name='사용 방법', value=f'{COMMAND_PREFIX}콘 "디시콘 패키지 제목" "콘 이름"', inline=False)
embed.add_field(
name='사용 예시 1', value=f'{COMMAND_PREFIX}콘 멘헤라콘 15, {COMMAND_PREFIX}콘 "마히로콘 리메이크" 꿀잠, {COMMAND_PREFIX}콘 "좋은말콘 스페셜 에디션" 응원, ...', inline=False)
embed.add_field(
name='사용 예시 2', value=f'{COMMAND_PREFIX}콘 "나나히라 라인", {COMMAND_PREFIX}콘 카구야는인사받고싶어, ... (디시콘 패키지 이름만 입력 시 디시콘 목록 출력)', inline=False)
embed.add_field(
name='명령어', value=f'{COMMAND_PREFIX}콘, {COMMAND_PREFIX}도움, {COMMAND_PREFIX}대하여, {COMMAND_PREFIX}초대링크', inline=False)
embed.set_footer(text='그코좆망겜')
await ctx.channel.send(embed=embed)
@bot.command(name='초대링크')
async def invite_link(ctx):
log(from_text(ctx), 'invite_link command')
await ctx.channel.send(f'봇 초대 링크 : {INVITE_URL}')
@bot.command(name='대하여')
async def about(ctx):
log(from_text(ctx), 'about command')
embed = Embed(title='디시콘 핫산',
description='디시콘을 디스코드에서 쓸 수 있게 해주는 디스코드 봇입니다.',
color=EMBED_COLOR)
embed.add_field(name='Repository',
value='https://github.com/Dogdriip/dccon_hassan', inline=False)
await ctx.channel.send(embed=embed)
@bot.command(name='콘')
async def send_dccon(ctx, *args):
log(from_text(ctx), 'send_dccon command')
if not args or len(args) > 2:
log(from_text(ctx), 'empty args')
await ctx.channel.send(f'사용법을 참고해주세요. ({COMMAND_PREFIX}도움)')
await ctx.channel.send('디시콘 패키지명이나 디시콘명에 공백이 있을 경우 큰따옴표로 묶어야 합니다.')
return
list_print_mode = False
package_name = args[0]
idx = 'list_print_mode'
if len(args) == 2:
idx = args[1]
else:
list_print_mode = True
log(from_text(ctx),
f'interpreted: {package_name}, {idx}. list_print_mode: {list_print_mode}')
############################################################################################################
# respect https://github.com/gw1021/dccon-downloader/blob/master/python/app.py#L7:L18
# TODO: 변수명 간단히
s = requests.Session()
package_search_req = s.get(DCCON_SEARCH_URL + package_name)
package_search_html = BeautifulSoup(package_search_req.text, 'html.parser')
package_search_list = package_search_html.select(
'#right_cont_wrap > div > div.dccon_listbox > ul > li')
try:
# pick first dccon package (bs4 obj) from search list
target_package = package_search_list[0]
except IndexError as e: # maybe no search result w/ IndexError?
log(from_text(ctx), 'error! (maybe no search result) : ' + str(e))
await ctx.channel.send(f'"{package_name}" 디시콘 패키지 정보를 찾을 수 없습니다.')
else:
# get dccon number of target dccon package
target_package_num = target_package.get('package_idx')
log(from_text(ctx), 'processing with: ' + target_package_num)
# for i in package_search_req.cookies:
# print(i.name, i.value)
package_detail_req = s.post(DCCON_DETAILS_URL,
# content-type: application/x-www-form-urlencoded; charset=UTF-8
cookies={'ci_c': package_search_req.cookies['ci_c'],
'PHPSESSID': package_search_req.cookies['PHPSESSID']},
headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': DCCON_SEARCH_URL + str(package_name.encode('utf-8')),
'Origin': DCCON_HOME_URL,
'X-Requested-With': 'XMLHttpRequest'},
data={'ci_t': package_search_req.cookies['ci_c'],
'package_idx': target_package_num,
'code': ''})
# 에러 핸들링 여기서 해야함
package_detail_json = package_detail_req.json()
'''
info / 'package_idx'
'seller_no'
'seller_id'
'title'
'category'
'path'
'description'
'price'
'period'
'icon_cnt'
'state'
'open'
'sale_count'
'reg_date'
'seller_name'
'code'
'seller_type'
'mandoo'
'main_img_path'
'list_img_path'
'reg_date_short'
detail / () / 'idx'
'package_idx'
'title'
'sort'
'ext'
'path'
'''
# 검색 결과로 바꿔치기
package_name = package_detail_json['info']['title']
if list_print_mode:
available_dccon_list = []
for dccon in package_detail_json['detail']:
available_dccon_list.append(dccon['title'])
await ctx.channel.send(f'"{package_name}"에서 사용 가능한 디시콘 : ' + ', '.join(available_dccon_list).rstrip(', '))
else:
succeed = False
for dccon in package_detail_json['detail']:
if dccon['title'] == idx:
dccon_img = "http://dcimg5.dcinside.com/dccon.php?no=" + \
dccon['path']
dccon_img_request = s.get(
dccon_img, headers={'Referer': DCCON_HOME_URL})
buffer = BytesIO(dccon_img_request.content)
filename = package_name + '_' + \
dccon['title'] + '.' + dccon['ext']
await ctx.channel.send(file=File(buffer, filename))
succeed = True
break
if succeed:
log(from_text(ctx), 'succeed')
else:
log(from_text(ctx), 'not found')
await ctx.channel.send(f'"{package_name}" 디시콘 패키지에서 "{idx}" 디시콘을 찾지 못했습니다.')
await ctx.channel.send('인자로 패키지 이름만 넘길 경우 사용 가능한 디시콘 목록이 출력됩니다.')
#
############################################################################################################
@bot.event
async def on_command_error(ctx, error):
log(from_text(ctx), error)
await ctx.channel.send(error)
if __name__ == "__main__":
bot.run(BOT_TOKEN)