mirror of
				https://github.com/cdryzun/tg_bot_collections.git
				synced 2025-10-31 14:06:43 +08:00 
			
		
		
		
	Merge pull request #2 from frostming/fix/command
fix: use spooled temp file to reduce memory usage
This commit is contained in:
		
							
								
								
									
										51
									
								
								hy_tg.py
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								hy_tg.py
									
									
									
									
									
								
							| @ -1,8 +1,10 @@ | |||||||
| import argparse | import argparse | ||||||
| import gc | import gc | ||||||
| import io |  | ||||||
| import random | import random | ||||||
|  | import shutil | ||||||
| import subprocess | import subprocess | ||||||
|  | import traceback | ||||||
|  | from tempfile import SpooledTemporaryFile | ||||||
|  |  | ||||||
| import numpy as np | import numpy as np | ||||||
| import PIL | import PIL | ||||||
| @ -16,8 +18,7 @@ from telebot import TeleBot  # type: ignore | |||||||
| from telebot.types import Message  # type: ignore | from telebot.types import Message  # type: ignore | ||||||
|  |  | ||||||
| PIL.Image.MAX_IMAGE_PIXELS = 933120000 | PIL.Image.MAX_IMAGE_PIXELS = 933120000 | ||||||
| file_in = "map.jpg" | MAX_IN_MEMORY = 10 * 1024 * 1024  # 10MiB | ||||||
| file_out = "map_out.jpg" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plot(PrettyPlot): | class Plot(PrettyPlot): | ||||||
| @ -52,35 +53,38 @@ class Plot(PrettyPlot): | |||||||
|  |  | ||||||
|  |  | ||||||
| def sizeof_image(image): | def sizeof_image(image): | ||||||
|     with io.BytesIO() as buff: |     with SpooledTemporaryFile(max_size=MAX_IN_MEMORY) as f: | ||||||
|         image.save(buff, format="JPEG", quality=95) |         image.save(f, format="JPEG", quality=95) | ||||||
|         return buff.tell() |         return f.tell() | ||||||
|  |  | ||||||
|  |  | ||||||
| def compress_image(input_path, output_path, target_size): | def compress_image(input_image, output_image, target_size): | ||||||
|     quality = 95 |     quality = 95 | ||||||
|     factor = 1.0 |     factor = 1.0 | ||||||
|     with Image.open(input_path) as img: |     with Image.open(input_image) as img: | ||||||
|         target_bytes = 10 * 1024 * 1024 |         while sizeof_image(img) > target_size: | ||||||
|  |  | ||||||
|         while sizeof_image(img) > target_bytes: |  | ||||||
|             factor -= 0.05 |             factor -= 0.05 | ||||||
|             width, height = img.size |             width, height = img.size | ||||||
|             img = img.resize( |             img = img.resize( | ||||||
|                 (int(width * factor), int(height * factor)), |                 (int(width * factor), int(height * factor)), | ||||||
|                 PIL.Image.Resampling.LANCZOS, |                 PIL.Image.Resampling.LANCZOS, | ||||||
|             ) |             ) | ||||||
|             if sizeof_image(img) <= target_bytes: |         img.save(output_image, format="JPEG", quality=quality) | ||||||
|                 img.save(output_path, format="JPEG", quality=quality) |     output_image.seek(0) | ||||||
|                 return |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def draw_pretty_map(location, file_name, style): | def draw_pretty_map(location, style, output_file): | ||||||
|     aoi = get_aoi(address=location, radius=1100, rectangular=True) |     aoi = get_aoi(address=location, radius=1100, rectangular=True) | ||||||
|     df = get_osm_geometries(aoi=aoi) |     df = get_osm_geometries(aoi=aoi) | ||||||
|     fig = Plot(df=df, aoi_bounds=aoi.bounds, draw_settings=STYLES[style]).plot_all() |     fig = Plot(df=df, aoi_bounds=aoi.bounds, draw_settings=STYLES[style]).plot_all() | ||||||
|     fig.savefig(file_name) |     with SpooledTemporaryFile(max_size=MAX_IN_MEMORY) as buffer: | ||||||
|     compress_image(file_in, file_out, 9)  # telegram tog need png less than 10MB |         fig.savefig(buffer, format="jpeg") | ||||||
|  |         buffer.seek(0) | ||||||
|  |         compress_image( | ||||||
|  |             buffer, | ||||||
|  |             output_file, | ||||||
|  |             10 * 1024 * 1024,  # telegram tog need png less than 10MB | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
| def main(): | def main(): | ||||||
| @ -146,16 +150,19 @@ def main(): | |||||||
|         style = random.choice(styles_list) |         style = random.choice(styles_list) | ||||||
|         try: |         try: | ||||||
|             # TODO why this memory leak? |             # TODO why this memory leak? | ||||||
|             draw_pretty_map(location, file_in, style) |             with SpooledTemporaryFile(max_size=MAX_IN_MEMORY) as out_image: | ||||||
|  |                 draw_pretty_map(location, style, out_image) | ||||||
|                 # tg can only send image less than 10MB |                 # tg can only send image less than 10MB | ||||||
|             with open(file_out, "rb") as photo: |                 with open("map_out.jpg", "wb") as f:  # for debug | ||||||
|  |                     shutil.copyfileobj(out_image, f) | ||||||
|  |                 out_image.seek(0) | ||||||
|                 bot.send_photo( |                 bot.send_photo( | ||||||
|                     message.chat.id, photo, reply_to_message_id=message.message_id |                     message.chat.id, out_image, reply_to_message_id=message.message_id | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|         except Exception as e: |         except Exception: | ||||||
|  |             traceback.print_exc() | ||||||
|             bot.reply_to(message, "Something wrong please check") |             bot.reply_to(message, "Something wrong please check") | ||||||
|             print(str(e)) |  | ||||||
|         bot.delete_message(reply_message.chat.id, reply_message.message_id) |         bot.delete_message(reply_message.chat.id, reply_message.message_id) | ||||||
|         # we need this, fuck it |         # we need this, fuck it | ||||||
|         gc.collect() |         gc.collect() | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user