Skip to content

Commit c1c86b2

Browse files
committed
Best UX ever (beta)
1 parent 7aae11a commit c1c86b2

File tree

3 files changed

+133
-46
lines changed

3 files changed

+133
-46
lines changed

config.example.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,4 @@ inviter_source_group: 'tulaanimefest'
126126
inviter_target_group: 'yuki_no_odori_10'
127127
inviter_add_friends: True
128128
inviter_start_at: 0
129+
inviter_captcha_scale_factor: 3

vk-inviter/make.ps1

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
param (
22
[switch] $InstallRequirements,
33
[switch] $InstallPyInstaller,
4+
[switch] $Clean,
45
[switch] $Compile
56
)
67
Set-Location $PSScriptRoot
@@ -18,9 +19,14 @@ if ($InstallPyInstaller) {
1819
& py -m pip install --user --upgrade pyinstaller
1920
$didSomething = $true
2021
}
22+
if ($Clean) {
23+
Remove-Item -Recurse -Force ./dist
24+
$didSomething = $true
25+
}
2126
if ($Compile) {
22-
& py -m PyInstaller --onefile --specpath ./build ./vk_inviter.py
23-
Remove-Item -Recurse ./build, ./__pycache__
27+
& py -m PyInstaller --specpath ./build ./vk_inviter.py
28+
Remove-Item -Recurse -Force ./build, ./__pycache__
29+
'"%~dp0vk_inviter\vk_inviter.exe"' | Out-File "Приглашатор.bat" -Encoding Ascii
2430
$didSomething = $true
2531
}
2632

vk-inviter/vk_inviter.py

Lines changed: 124 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ def collect_members(self, source_group, add_friends=True):
2424
self.members_to_invite = []
2525
if source_group:
2626
self.members_to_invite += self.__massive_collect(self.VK.groups.getMembers,
27-
v=self.vk_api_v,
28-
group_id=source_group,
29-
fields='id')
27+
v=self.vk_api_v,
28+
group_id=source_group,
29+
fields='id')
3030
if add_friends:
3131
self.members_to_invite += self.__massive_collect(self.VK.friends.get,
32-
v=self.vk_api_v,
33-
fields='id')
32+
v=self.vk_api_v,
33+
fields='id')
3434

3535
self.members_to_invite = sorted(self.members_to_invite, key=lambda x: x['id'])
3636
self.members_to_invite = {user_info['id']: user_info for user_info in self.members_to_invite}
@@ -127,42 +127,122 @@ def solve_captcha(self, img: Image):
127127
def __submit_captcha(self, _):
128128
self.captcha_submitted.set(True)
129129

130-
131-
132-
if __name__ == '__main__':
133-
import os
134-
from yaml import load, FullLoader
135-
136-
root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
137-
config = load(
138-
open(os.path.join(root_dir, 'config.yml'), 'r', encoding='utf-8').read(),
139-
Loader=FullLoader)
140-
vk_token = config['vk_token']
141-
142-
captcha_scale_factor = 3
143-
source_group = config['inviter_source_group']
144-
target_group = config['inviter_target_group']
145-
add_friends = config['inviter_add_friends']
146-
start_at = config['inviter_start_at']
147-
148-
captchas_dir_name = 'vk_captchas'
149-
if os.name == 'posix':
150-
home_dir = os.path.expanduser('~')
151-
home_dir_desc = f'в "{home_dir}"'
152-
else:
153-
home_dir = os.path.join(os.environ['USERPROFILE'], 'Desktop')
154-
home_dir_desc = 'на рабочий стол'
155-
captchas_dir = os.path.join(home_dir, captchas_dir_name)
156-
157-
captcha_size = (130*captcha_scale_factor, 50*captcha_scale_factor)
158-
manual_solver = CaptchaManualSolver(tk.Tk(), captcha_size)
159-
inviter = Inviter(vk_token, manual_solver.solve_captcha, captchas_dir)
160-
inviter.collect_members(source_group, add_friends)
161-
inviter.invite_all_members(target_group, start_at)
162-
163-
print('\nГотово! Мы сохранили все введённые Вами капчи ' +
164-
f'{home_dir_desc} в папку "{captchas_dir_name}". ' +
165-
'Если Вы хотите поспособствовать разработке автоматического ' +
166-
'распознавателя капчи, заархивируйте эту папку и скиньте Химуре ' +
167-
'(например, в телегу: https://t.me/Himura_Kazuto). ' +
168-
'Если нет, то можно просто её удалить :(')
130+
try:
131+
if __name__ == '__main__':
132+
import os
133+
from sys import exit
134+
from subprocess import call
135+
from yaml import load, FullLoader
136+
137+
base_config = """
138+
# Это настройки Приглашатора.
139+
# Данный файл можно открывать и редактировать программой "Блокнот".
140+
141+
# Для начала, необходимо получить доступ к Вашей странице ВК.
142+
# Пожалуйста, перейдите по ссылке и разрешите приложению доступ.
143+
# https://oauth.vk.com/authorize?v=5.126&response_type=token&display=page&redirect_uri=https://oauth.vk.com/blank.html&scope=friends,groups&client_id=7728992
144+
145+
# Должна открыться белая страница с предупреждением.
146+
# Скопируйте из адресной строки длинный набор букв и цифр между 'access_token=' и '&expires_in'.
147+
148+
# Вставьте его сюда между ковычками.
149+
vk_token: ""
150+
151+
# Через 24 часа этот токен перестанет работать и придётся повторить процедуру.
152+
# Никому его не показывайте: токен можно использовать вместо пароля от Вашей страницы ВК.
153+
154+
155+
# Теперь, укажите из какой группы приглашать людей.
156+
# Сейчас указана группа https://vk.com/tulaanimefest
157+
# Замените слово tulaanimefest между ковычками на id своей группы.
158+
inviter_source_group: "tulaanimefest"
159+
160+
# Далее, аналогичным образом, укажите куда приглашать людей.
161+
# Помните, что массово приглашать можно только в мероприятие, организатором
162+
# которого является указанная выше группа, а Вы должны быть админом этой группы.
163+
inviter_target_group: "yuki_no_odori_10"
164+
165+
# Если Вы не хотите приглашать своих собственных друзей,
166+
# замените True на False
167+
inviter_add_friends: True
168+
169+
# Приглашатор умеет начинать рассылку приглашений с середины,
170+
# так что поглядывайте на текущий номер. Если работа программы прервётся,
171+
# Вы сможете указать его тут и продолжить рассылку.
172+
inviter_start_at: 0
173+
174+
# В процессе рассылки, Вам придётся много вводить капчу. Капча очень маленькая
175+
# и для удобства будет увеличиваться в указанно тут число раз.
176+
inviter_captcha_scale_factor: 3
177+
"""
178+
179+
def load_config():
180+
config_name = 'config.yml'
181+
config_encoding = 'utf-8'
182+
script_dir = os.path.dirname(os.path.realpath(__file__))
183+
184+
config_path = os.path.join(os.path.dirname(script_dir), config_name)
185+
if os.path.isfile(config_path):
186+
config = load(open(config_path, 'r', encoding=config_encoding).read(), Loader=FullLoader)
187+
config['__file_path'] = config_path
188+
return config
189+
190+
with open(config_path, 'w', encoding=config_encoding) as f:
191+
f.write(base_config)
192+
config_path = os.path.realpath(config_path)
193+
print('Добро пожаловать в Приглашатор! Мы не нашли файл с настройками и создали его ' +
194+
f'вот здесь:\n\n{config_path}\n\nСейчас файл настроек должен был открыться ' +
195+
'рядом в программе Блокнот.\n\nПожалуйста,\nотредактируйте файл настроек,\n' +
196+
'сохраните его,\nзакройте блокнот (это окно закроется вместе с ним),\n' +
197+
'и запустите Приглашатор ещё раз.')
198+
call(['notepad', config_path])
199+
exit(1)
200+
201+
202+
config = load_config()
203+
vk_token = config['vk_token']
204+
source_group = config['inviter_source_group']
205+
target_group = config['inviter_target_group']
206+
add_friends = config['inviter_add_friends']
207+
start_at = config['inviter_start_at']
208+
captcha_scale_factor = config['inviter_captcha_scale_factor']
209+
210+
captchas_dir_name = 'vk_captchas'
211+
if os.name == 'posix':
212+
home_dir = os.path.expanduser('~')
213+
home_dir_desc = f'в "{home_dir}"'
214+
else:
215+
home_dir = os.path.join(os.environ['USERPROFILE'], 'Desktop')
216+
home_dir_desc = 'на рабочий стол'
217+
captchas_dir = os.path.join(home_dir, captchas_dir_name)
218+
219+
captcha_size = (130*captcha_scale_factor, 50*captcha_scale_factor)
220+
manual_solver = CaptchaManualSolver(tk.Tk(), captcha_size)
221+
inviter = Inviter(vk_token, manual_solver.solve_captcha, captchas_dir)
222+
try:
223+
inviter.collect_members(source_group, add_friends)
224+
except vk.exceptions.VkAPIError as e:
225+
print('Похоже, что токен не работает... Вот, что про него говорит ВК:\n\n' +
226+
f'{e.message} (ошибка {e.code})\n\n' +
227+
'Пожалуйста,\nзамените vk_token в открытом файле настроек,\n' +
228+
'сохраните его,\nзакройте блокнот (это окно закроется вместе с ним),\n' +
229+
'и запустите Приглашатор ещё раз.')
230+
call(['notepad', config['__file_path']])
231+
exit(1)
232+
233+
inviter.invite_all_members(target_group, start_at)
234+
235+
print('\nГотово! Мы сохранили все введённые Вами капчи ' +
236+
f'{home_dir_desc} в папку "{captchas_dir_name}".\n\n' +
237+
'Если Вы хотите поспособствовать разработке автоматического ' +
238+
'распознавателя капчи, заархивируйте эту папку и скиньте Химуре ' +
239+
'(например, в телегу: https://t.me/Himura_Kazuto).\n' +
240+
'Если нет, то можно просто её удалить :(')
241+
242+
except Exception as e:
243+
import traceback
244+
print("К сожалению, произошла неведомая фигня.\nВот немного технических деталей...\n" +
245+
"пожалуйста, свяжитесь с Химурой (например, в телеге: https://t.me/Himura_Kazuto), " +
246+
"и покажите ему это..\n")
247+
traceback.print_exc()
248+
input("\nПрограмма закроется, если нажать Enter. Больше она уже ничего не умеет...")

0 commit comments

Comments
 (0)