Skip to content

Commit 6b8579b

Browse files
authored
Merge pull request #9 from F33RNI/next
Next version
2 parents 3864f72 + 6ea053a commit 6b8579b

File tree

5 files changed

+132
-60
lines changed

5 files changed

+132
-60
lines changed

Diff for: AIHandler.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ def gpt_loop(self):
170170
# Error
171171
except Exception as e:
172172
# Wake up authenticator check loop from sleep
173-
if container.request_type == RequestResponseContainer.REQUEST_TYPE_CHATGPT:
174-
self.authenticator.chatbot_working = False
173+
self.authenticator.chatbot_working = False
175174

176175
# Print error message
177176
error_message = str(e)

Diff for: Authenticator.py

+121-54
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1515
OTHER DEALINGS IN THE SOFTWARE.
1616
"""
17-
17+
import copy
1818
import logging
19+
import multiprocessing
1920
import random
2021
import threading
2122
import time
@@ -28,16 +29,53 @@
2829
PROXY_FROM_URL = 'http://free-proxy-list.net/'
2930

3031

32+
def kill_all_processes(processes_and_times):
33+
"""
34+
Kills all processes
35+
:param processes_and_times: list of (process, time_started)
36+
:return:
37+
"""
38+
for (process_, time_) in processes_and_times:
39+
if process_ is not None and time_ is not None and process_.is_alive():
40+
logging.info('Killing process with PID: ' + str(process_.pid))
41+
try:
42+
process_.kill()
43+
process_.join()
44+
except:
45+
logging.warning('Error killing process with PID: ' + str(process_.pid))
46+
47+
48+
def initialize_chatbot(proxy, config, chatbots_and_proxies_queue):
49+
"""
50+
Pops first proxy and tries to initialize chatbot
51+
:return:
52+
"""
53+
try:
54+
# Get config
55+
config_ = copy.deepcopy(config)
56+
config_['proxy'] = proxy
57+
58+
# Initialize chatbot
59+
chatbot = Chatbot(config=config_)
60+
61+
# Append working chatbot and proxy
62+
if chatbot is not None:
63+
chatbots_and_proxies_queue.put((chatbot, proxy))
64+
except:
65+
pass
66+
67+
3168
class Authenticator:
3269
def __init__(self, settings):
3370
self.settings = settings
3471

3572
self.chatbot = None
3673
self.chatbot_working = False
74+
self.chatbots_and_proxies_queue = multiprocessing.Queue(maxsize=int(self.settings['proxy']
75+
['max_number_of_processes']) * 2)
3776
self.current_proxy = None
3877
self.conversation_id = None
3978
self.proxy_list = []
40-
self.proxy_list_index = 0
4179
self.check_loop_running = False
4280

4381
def start_check_loop(self):
@@ -74,7 +112,6 @@ def proxy_get(self):
74112
"""
75113
# Reset proxy list
76114
self.proxy_list = []
77-
self.proxy_list_index = 0
78115

79116
# Try to get proxy
80117
try:
@@ -162,70 +199,100 @@ def proxy_checker_loop(self):
162199

163200
# Check is not successful
164201
else:
165-
# Get config
166-
config = self.get_chatbot_config()
167-
168202
# Get proxy
169203
if self.settings['proxy']['enabled']:
170-
proxy = None
171204
# Auto proxy
172205
if self.settings['proxy']['auto']:
173-
# Already have proxy_list -> get new proxy from it
174-
if self.proxy_list_index < len(self.proxy_list) - 1:
175-
# If half list checked
176-
if self.proxy_list_index >= len(self.proxy_list) // 2:
177-
# Try to get new proxies
178-
logging.info('Trying to update proxy-list...')
179-
proxy_list_old = self.proxy_list
180-
proxy_list_index_old = self.proxy_list_index
181-
self.proxy_get()
182-
183-
# Check if new proxies are identical or empty
184-
if proxy_list_old == self.proxy_list or len(self.proxy_list) == 0:
185-
# Restore previous
186-
logging.info('New proxies are identical or empty. Restoring previous...')
187-
self.proxy_list = proxy_list_old
188-
self.proxy_list_index = proxy_list_index_old
189-
190-
# Switch to next proxy
191-
self.proxy_list_index += 1
192-
logging.info('Loading next proxy: ' + str(self.proxy_list_index + 1) + '/'
193-
+ str(len(self.proxy_list)))
194-
195-
# Load proxy
196-
proxy = self.proxy_list[self.proxy_list_index]
197-
198-
# No proxy or all checked
199-
else:
200-
# Get new proxy list
206+
# Get new proxy list
207+
if len(self.proxy_list) <= 0:
201208
self.proxy_get()
202-
203-
# Get proxy from list
204-
if len(self.proxy_list) > 0:
205-
proxy = self.proxy_list[0]
206-
207209
# Manual proxy
208210
else:
209-
proxy = self.settings['proxy']['manual_proxy']
210-
211-
# Add proxy to config
212-
self.current_proxy = proxy
213-
if proxy is not None:
214-
logging.info('Using proxy: ' + proxy)
215-
config['proxy'] = proxy
211+
self.proxy_list = [self.settings['proxy']['manual_proxy']]
212+
# Proxy disabled
213+
else:
214+
break
216215

217216
# Remove old chatbot
218217
if self.chatbot is not None:
219218
del self.chatbot
220219
self.chatbot = None
221220

222-
# Initialize new chatbot
223-
logging.info('Initializing new chatbot with config: ' + str(config))
224-
try:
225-
self.chatbot = Chatbot(config=config)
226-
# Error initializing chatbot
227-
except Exception as e:
228-
logging.warning('Error initializing chatbot! ' + str(e))
221+
# Create list of processes and start times
222+
processes_and_times = []
223+
224+
# Get default config
225+
default_config = self.get_chatbot_config()
226+
227+
while True:
228+
# Create and start processes
229+
while len(self.proxy_list) > 0 \
230+
and len(processes_and_times) < int(self.settings['proxy']['max_number_of_processes']):
231+
proxy = self.proxy_list.pop(0)
232+
process = multiprocessing.Process(target=initialize_chatbot,
233+
args=(proxy,
234+
default_config,
235+
self.chatbots_and_proxies_queue,))
236+
process.start()
237+
time_started = time.time()
238+
processes_and_times.append((process, time_started))
239+
logging.info('Started new initialization process for proxy: ' + proxy + '. PID: '
240+
+ str(process.pid) + ' Total: ' + str(len(processes_and_times)) + ' processes')
241+
242+
# Limit connection intervals
243+
time.sleep(0.5)
244+
245+
# Wait some time each cycle
246+
time.sleep(0.5)
247+
248+
# No more proxies
249+
if len(self.proxy_list) == 0:
250+
# Get new proxy list in auto mode
251+
if self.settings['proxy']['auto']:
252+
self.proxy_get()
253+
254+
# Exit if manual mode and no more processes
255+
elif len(processes_and_times) == 0:
256+
logging.info('Cannot connect with manual proxy. Exiting loop...')
257+
kill_all_processes(processes_and_times)
258+
break
259+
260+
# Check chatbots
261+
try:
262+
# Get from queue
263+
chatbot_, proxy_ = self.chatbots_and_proxies_queue.get(block=False)
264+
265+
# Found initialized one
266+
if chatbot_ is not None and proxy_ is not None and len(proxy_) > 0:
267+
self.chatbot = chatbot_
268+
self.current_proxy = proxy_
269+
except:
270+
pass
271+
272+
# Kill all processes and exit from loop
273+
if self.chatbot is not None and self.current_proxy is not None:
274+
kill_all_processes(processes_and_times)
275+
logging.info('Found working proxy: ' + self.current_proxy + ' exiting loop...')
276+
break
277+
278+
# Check timeouts
279+
for i in range(len(processes_and_times)):
280+
process_, time_ = processes_and_times[i]
281+
if process_ is not None and time_ is not None:
282+
# Kill on timeout or exit
283+
if time.time() - time_ > int(self.settings['proxy']['initialization_timeout']) \
284+
or not process_.is_alive():
285+
if process_.is_alive():
286+
logging.info('Killing process with PID: ' + str(process_.pid) + ' due to timeout')
287+
try:
288+
process_.kill()
289+
process_.join()
290+
except:
291+
logging.warning('Error killing process with PID: ' + str(process_.pid))
292+
processes_and_times[i] = (None, None)
293+
294+
# Remove Nones
295+
processes_and_times = [i for i in processes_and_times if i[0] is not None]
229296

230297
# Sleep 1 second to limit connections interval
231298
time.sleep(1)

Diff for: README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ Example `settings.json`:
7676
"proxy": {
7777
"enabled": true,
7878
"auto": true,
79-
"https_only": true,
79+
"https_only": true,
8080
"manual_proxy": "http://111.222.123.111:443",
8181
"check_interval_seconds": 300,
8282
"check_message": "1+1",
8383
"check_message_timeout": 120,
84-
"check_reply_must_include": "2"
84+
"check_reply_must_include": "2",
85+
"max_number_of_processes": 5,
86+
"initialization_timeout": 60
8587
},
8688

8789
"dalle": {
@@ -185,6 +187,8 @@ If you have proxy that definitely works you can specify it in `manual_proxy` in
185187
- `check_message` - This message will be sent as a request
186188
- `check_message_timeout` - How long should a response take?
187189
- `check_reply_must_include` - The response message must contain this text to consider that the check was successful
190+
- `max_number_of_processes` - How many background processes are used for checking proxy
191+
- `initialization_timeout` - How long to wait for initialization with proxy
188192

189193
----------
190194

Diff for: main.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import Authenticator
2828
import BotHandler
2929

30-
TELEGRAMUS_VERSION = 'beta_1.4.0'
30+
TELEGRAMUS_VERSION = 'beta_1.5.0'
3131

3232
# Logging level (INFO for debug, WARN for release)
3333
LOGGING_LEVEL = logging.INFO

Diff for: settings.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
"check_interval_seconds": 300,
3030
"check_message": "1+1",
3131
"check_message_timeout": 240,
32-
"check_reply_must_include": "2"
32+
"check_reply_must_include": "2",
33+
"max_number_of_processes": 5,
34+
"initialization_timeout": 60
3335
},
3436

3537
"__comment11__": "PROVIDE YOUR API_KEY FROM https://platform.openai.com/account/api-keys FOR REQUESTS TO DALL-E",

0 commit comments

Comments
 (0)