-
Notifications
You must be signed in to change notification settings - Fork 1
/
runner.py
123 lines (100 loc) · 3.91 KB
/
runner.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
# python lib
import asyncio
import time
from pyee import AsyncIOEventEmitter
from ruamel.yaml import YAML
from typing import Optional
# custom lib
import utils
from login import Login
from raffle import Raffle
from printer import cprint
from storage import Storage
from account import Account
from bilibili import Bilibili
from exceptions import LoginException
from AreaChecker import AreaList
from rafflereceiver import RaffleReceiver
from SessionController import new_session
class Runner:
'''
This class reads the configuration, sign in (optional) to bilibili,
attempts to connect to the server and if successful, listens to the
push notifications.
'''
def __init__(self,
loop: Optional[asyncio.AbstractEventLoop] = None):
loop = loop if loop is not None else asyncio.get_event_loop()
self.loop = loop
self.yaml = None
self.aiohttp_session = None
self.aiohttp_session_waiter = None
self.aiohttp_session_closer = None
self.raffle_emitter = None
self.servers = None
self.account_files = []
self.accounts = []
self.yaml = YAML()
waiter, closer = new_session(loop=self.loop,
headers={ 'Connection': 'close' },
raise_for_status=True)
self.aiohttp_session_waiter = waiter
self.aiohttp_session_closer = closer
def read_config(self):
data_file = utils.resolve_to_cwd('config.yaml')
with open(data_file, mode='r', encoding='UTF-8') as iofile:
settings = self.yaml.load(iofile)
self.account_files = settings['users']
self.servers = settings['servers']
Storage.bili = settings['bilibili']
Storage.servers = self.servers
def process_login(self):
accounts = [ Account(data_file, self.yaml) for data_file in self.account_files ]
self.accounts = accounts
wait = False
for acc in accounts:
if not acc.usable and acc.username and acc.password:
l = Login(acc, output_file=acc.input_file, yaml=self.yaml)
try:
cprint(f'{acc.input_file!r}: Logging in...', color='green')
l.login()
acc.reload()
acc.cprint(f'登录成功', color='green')
if wait:
time.sleep(5)
except LoginException as exc:
acc.cprint(f'登录失败 - {exc}', error=True)
wait = True
elif acc.usable:
msg = (f'{acc.input_file!r}: cookies读取成功')
acc.cprint(f'{msg}', color='green')
else:
msg = (f'登录信息不完整 && cookies未提供. - '
f' {acc.input_file!r} Skipped.')
cprint(f'{msg}', color='yellow')
async def run(self):
self.read_config()
self.process_login()
self.aiohttp_session = await self.aiohttp_session_waiter
Bilibili.client = self.aiohttp_session
await AreaList.arealist()
self.raffle_emitter = AsyncIOEventEmitter(loop=self.loop)
# 监听抽奖event 执行抽奖
raffles = [ Raffle(self.raffle_emitter, loop=self.loop, account=a)
for a in self.accounts
if a.usable ]
servers = self.servers
receiver = RaffleReceiver(servers,
emitter=self.raffle_emitter,
loop=self.loop).run()
done, pending = await asyncio.wait(
[
receiver,
],
loop=self.loop,
return_when=asyncio.FIRST_EXCEPTION,
)
await self.aiohttp_session_closer.close_session()
for task in done:
if task.exception():
raise task.exception()