55import base64
66from typing import TYPE_CHECKING
77
8- import aiohttp
98from pydantic import ValidationError
109
1110from ...models .machine_info import FFGcodeFileEntry
1211from ...models .responses import GCodeListResponse , ThumbnailResponse
1312from ..constants .endpoints import Endpoints
14- from ..network .utils import NetworkUtils
13+ from ..network .utils import NetworkUtils , json_from_response
1514
1615if TYPE_CHECKING :
1716 from ...client import FlashForgeClient
@@ -65,74 +64,65 @@ async def get_recent_file_list(self) -> list[FFGcodeFileEntry]:
6564 payload = {"serialNumber" : self .client .serial_number , "checkCode" : self .client .check_code }
6665
6766 try :
68- async with aiohttp .ClientSession () as session :
69- async with session .post (
70- self .client .get_endpoint (Endpoints .GCODE_LIST ),
71- json = payload ,
72- headers = {"Content-Type" : "application/json" },
73- ) as response :
74- if response .status != 200 :
75- return []
76-
77- # Fix for FlashForge printer's malformed Content-Type header
78- # Some printers return "appliation/json" instead of "application/json"
79- try :
80- data = await response .json ()
81- except aiohttp .ContentTypeError :
82- # Fallback: manually parse as JSON if Content-Type is malformed
83- text = await response .text ()
84- import json
85-
86- data = json .loads (text )
87-
88- if not NetworkUtils .is_ok (data ):
89- print (f"Error retrieving file list: { NetworkUtils .get_error_message (data )} " )
90- return []
91-
92- # Parse the response using GCodeListResponse
93- try :
94- result = GCodeListResponse (** data )
95- except ValidationError :
96- raw_list = data .get ("gcodeList" , [])
97- if isinstance (raw_list , list ):
98- entries : list [FFGcodeFileEntry ] = []
99- for file_name in raw_list :
100- if isinstance (file_name , str ):
101- entries .append (
102- FFGcodeFileEntry (
103- gcodeFileName = file_name ,
104- printingTime = 0 ,
105- )
106- )
107- return entries
108- return []
109-
110- # AD5X and newer printers provide detailed info in gcodeListDetail
111- if result .gcode_list_detail and len (result .gcode_list_detail ) > 0 :
112- return result .gcode_list_detail
113-
114- # Fallback for older printers using gcodeList
115- if result .gcode_list and len (result .gcode_list ) > 0 :
116- # Check if it's a list of strings or already FFGcodeFileEntry objects
117- first_item = result .gcode_list [0 ]
118-
119- if isinstance (first_item , str ):
120- # Convert string array to FFGcodeFileEntry objects
121- return [
122- FFGcodeFileEntry (gcodeFileName = file_name , printingTime = 0 )
123- for file_name in result .gcode_list
124- if isinstance (file_name , str )
125- ]
126- elif isinstance (first_item , FFGcodeFileEntry ):
127- # Already FFGcodeFileEntry objects - need explicit type narrowing
128- return [
129- item
130- for item in result .gcode_list
131- if isinstance (item , FFGcodeFileEntry )
132- ]
67+ session = await self .client .get_http_session ()
68+ async with session .post (
69+ self .client .get_endpoint (Endpoints .GCODE_LIST ),
70+ json = payload ,
71+ headers = {"Content-Type" : "application/json" },
72+ ) as response :
73+ if response .status != 200 :
74+ return []
13375
76+ data = await json_from_response (response )
77+
78+ if not NetworkUtils .is_ok (data ):
79+ print (f"Error retrieving file list: { NetworkUtils .get_error_message (data )} " )
13480 return []
13581
82+ # Parse the response using GCodeListResponse
83+ try :
84+ result = GCodeListResponse (** data )
85+ except ValidationError :
86+ raw_list = data .get ("gcodeList" , [])
87+ if isinstance (raw_list , list ):
88+ entries : list [FFGcodeFileEntry ] = []
89+ for file_name in raw_list :
90+ if isinstance (file_name , str ):
91+ entries .append (
92+ FFGcodeFileEntry (
93+ gcodeFileName = file_name ,
94+ printingTime = 0 ,
95+ )
96+ )
97+ return entries
98+ return []
99+
100+ # AD5X and newer printers provide detailed info in gcodeListDetail
101+ if result .gcode_list_detail and len (result .gcode_list_detail ) > 0 :
102+ return result .gcode_list_detail
103+
104+ # Fallback for older printers using gcodeList
105+ if result .gcode_list and len (result .gcode_list ) > 0 :
106+ # Check if it's a list of strings or already FFGcodeFileEntry objects
107+ first_item = result .gcode_list [0 ]
108+
109+ if isinstance (first_item , str ):
110+ # Convert string array to FFGcodeFileEntry objects
111+ return [
112+ FFGcodeFileEntry (gcodeFileName = file_name , printingTime = 0 )
113+ for file_name in result .gcode_list
114+ if isinstance (file_name , str )
115+ ]
116+ elif isinstance (first_item , FFGcodeFileEntry ):
117+ # Already FFGcodeFileEntry objects - need explicit type narrowing
118+ return [
119+ item
120+ for item in result .gcode_list
121+ if isinstance (item , FFGcodeFileEntry )
122+ ]
123+
124+ return []
125+
136126 except Exception as err :
137127 print (f"GetRecentFileList error: { err } " )
138128 return []
@@ -156,33 +146,24 @@ async def get_gcode_thumbnail(self, file_name: str) -> bytes | None:
156146 }
157147
158148 try :
159- async with aiohttp .ClientSession () as session :
160- async with session .post (
161- self .client .get_endpoint (Endpoints .GCODE_THUMB ),
162- json = payload ,
163- headers = {"Content-Type" : "application/json" },
164- ) as response :
165- if response .status != 200 :
166- return None
167-
168- # Fix for FlashForge printer's malformed Content-Type header
169- # Some printers return "appliation/json" instead of "application/json"
170- try :
171- data = await response .json ()
172- except aiohttp .ContentTypeError :
173- # Fallback: manually parse as JSON if Content-Type is malformed
174- text = await response .text ()
175- import json
176-
177- data = json .loads (text )
178-
179- if NetworkUtils .is_ok (data ):
180- # Parse response and return decoded image bytes
181- result = ThumbnailResponse (** data )
182- return base64 .b64decode (result .image_data )
183- else :
184- print (f"Error retrieving thumbnail: { NetworkUtils .get_error_message (data )} " )
185- return None
149+ session = await self .client .get_http_session ()
150+ async with session .post (
151+ self .client .get_endpoint (Endpoints .GCODE_THUMB ),
152+ json = payload ,
153+ headers = {"Content-Type" : "application/json" },
154+ ) as response :
155+ if response .status != 200 :
156+ return None
157+
158+ data = await json_from_response (response )
159+
160+ if NetworkUtils .is_ok (data ):
161+ # Parse response and return decoded image bytes
162+ result = ThumbnailResponse (** data )
163+ return base64 .b64decode (result .image_data )
164+ else :
165+ print (f"Error retrieving thumbnail: { NetworkUtils .get_error_message (data )} " )
166+ return None
186167
187168 except Exception as err :
188169 print (f"GetGcodeThumbnail error: { err } " )
0 commit comments