@@ -82,7 +82,7 @@ def get_prefill_candidates(self, login: bool = False) -> Dict:
8282 data = {
8383 "android_device_id" : self .android_device_id ,
8484 "client_contact_points" : '[{"type":"omnistring","value":"%s","source":"last_login_attempt"}]'
85- % self .username ,
85+ % self .username ,
8686 "phone_id" : self .phone_id ,
8787 "usages" : '["account_recovery_omnibox"]' ,
8888 "logged_in_user_ids" : "[]" , # "[\"123456789\",\"987654321\"]",
@@ -188,7 +188,7 @@ def login_flow(self) -> bool:
188188 return all (check_flow )
189189
190190 def get_timeline_feed (
191- self , reason : TIMELINE_FEED_REASON = "pull_to_refresh" , max_id : str = None
191+ self , reason : TIMELINE_FEED_REASON = "pull_to_refresh" , max_id : str = None
192192 ) -> Dict :
193193 """
194194 Get your timeline feed
@@ -246,7 +246,7 @@ def get_timeline_feed(
246246 )
247247
248248 def get_reels_tray_feed (
249- self , reason : REELS_TRAY_REASON = "pull_to_refresh"
249+ self , reason : REELS_TRAY_REASON = "pull_to_refresh"
250250 ) -> Dict :
251251 """
252252 Get your reels tray feed
@@ -305,8 +305,10 @@ class LoginMixin(PreLoginFlowMixin, PostLoginFlowMixin):
305305 ig_www_claim = "" # e.g. hmac.AR2uidim8es5kYgDiNxY0UG_ZhffFFSt8TGCV5eA1VYYsMNx
306306
307307 def __init__ (self ):
308+ self .bloks_versioning_id = "ce555e5500576acd8e84a66018f54a05720f2dce29f0bb5a1f97f0c10d6fac48"
308309 self .user_agent = None
309310 self .settings = None
311+ self .override_app_version = False
310312
311313 def init (self ) -> bool :
312314 """
@@ -327,10 +329,6 @@ def init(self) -> bool:
327329 self .settings .get ("timezone_offset" , self .timezone_offset )
328330 )
329331 self .set_device (self .settings .get ("device_settings" ))
330- # c7aeefd59aab78fc0a703ea060ffb631e005e2b3948efb9d73ee6a346c446bf3
331- self .bloks_versioning_id = (
332- "ce555e5500576acd8e84a66018f54a05720f2dce29f0bb5a1f97f0c10d6fac48"
333- ) # this param is constant and will change by Instagram app version
334332 self .set_user_agent (self .settings .get ("user_agent" ))
335333 self .set_uuids (self .settings .get ("uuids" ) or {})
336334 self .set_locale (self .settings .get ("locale" , self .locale ))
@@ -377,11 +375,11 @@ def login_by_sessionid(self, sessionid: str) -> bool:
377375 return True
378376
379377 def login (
380- self ,
381- username : Union [str , None ] = None ,
382- password : Union [str , None ] = None ,
383- relogin : bool = False ,
384- verification_code : str = "" ,
378+ self ,
379+ username : Union [str , None ] = None ,
380+ password : Union [str , None ] = None ,
381+ relogin : bool = False ,
382+ verification_code : str = "" ,
385383 ) -> bool :
386384 """
387385 Login
@@ -603,20 +601,26 @@ def set_settings(self, settings: Dict) -> bool:
603601 self .init ()
604602 return True
605603
606- def load_settings (self , path : Union [str , Path ]) -> Dict :
604+ def load_settings (self , path : Union [str , Path ], override_app_version : bool = False ) -> Dict :
607605 """
608606 Load session settings
609607
610608 Parameters
611609 ----------
612610 path: Path
613611 Path to storage file
612+ override_app_version: bool, optional
613+ Mismatched app_version/version_code/bloks_versioning_id may
614+ increase risk. If True, override with a known version from
615+ APP_SETTINGS (in memory). Call dump_settings() to persist.
616+
614617
615618 Returns
616619 -------
617620 Dict
618621 Current session settings as a Dict
619622 """
623+ self .override_app_version = override_app_version
620624 with open (path , "r" ) as fp :
621625 self .set_settings (json .load (fp ))
622626 return self .settings
@@ -652,22 +656,77 @@ def set_device(self, device: Dict = None, reset: bool = False) -> bool:
652656 bool
653657 A boolean value
654658 """
655- self .device_settings = device or {
656- "app_version" : "269.0.0.18.75" ,
657- "android_version" : 26 ,
658- "android_release" : "8.0.0" ,
659- "dpi" : "480dpi" ,
660- "resolution" : "1080x1920" ,
661- "manufacturer" : "OnePlus" ,
662- "device" : "devitron" ,
663- "model" : "6T Dev" ,
664- "cpu" : "qcom" ,
665- "version_code" : "314665256" ,
666- }
667- self .settings ["device_settings" ] = self .device_settings
659+ device = device or {}
660+ self .device_settings = dict (config .DEVICE_SETTINGS )
661+ self .device_settings .update (device )
662+ seed = None
663+ if self .settings :
664+ uuids = self .settings .get ("uuids" ) or {}
665+ seed = uuids .get ("uuid" )
666+ self .set_app (seed = seed )
668667 if reset :
669668 self .set_uuids ({})
670- # self.settings = self.get_settings()
669+ return True
670+
671+ def set_app (self , app : Union [str , Dict ] = None , seed : str = None ) -> bool :
672+ """
673+ Helper to set app version settings
674+
675+ Parameters
676+ ----------
677+ app: Union[str, Dict], optional
678+ App version string or settings dict
679+ seed: str, optional
680+ Seed used for stable app selection
681+
682+ Returns
683+ -------
684+ bool
685+ A boolean value
686+ """
687+ app_keys = ("app_version" , "version_code" , "bloks_versioning_id" )
688+ if not getattr (self , "device_settings" , None ):
689+ self .device_settings = dict (config .DEVICE_SETTINGS )
690+ if not config .APP_SETTINGS :
691+ raise ValueError ("APP_SETTINGS is empty" )
692+ override_app_version = bool (getattr (self , "override_app_version" , False ))
693+
694+ def apply_settings (app_settings : Dict ) -> None :
695+ for key in app_keys :
696+ val = app_settings .get (key )
697+ if val :
698+ self .device_settings [key ] = val
699+
700+ def pick_by_seed () -> Dict :
701+ app_values = list (config .APP_SETTINGS .values ())
702+ if seed :
703+ digest = hashlib .sha256 (seed .encode ("utf-8" )).hexdigest ()
704+ idx = int (digest , 16 ) % len (app_values )
705+ return app_values [idx ]
706+ return random .choice (app_values )
707+
708+ if app :
709+ if isinstance (app , str ):
710+ matched = config .APP_SETTINGS .get (app )
711+ if not matched :
712+ raise ValueError (f"Unknown app_version: { app } " )
713+ apply_settings (matched )
714+ else :
715+ apply_settings (dict (app ))
716+ else :
717+ app_version = self .device_settings .get ("app_version" )
718+ matched = config .APP_SETTINGS .get (app_version ) if app_version else None
719+ if matched :
720+ apply_settings (matched )
721+ else :
722+ if override_app_version or not app_version :
723+ apply_settings (pick_by_seed ())
724+
725+ if override_app_version :
726+ self .set_user_agent ()
727+ self .bloks_versioning_id = self .device_settings .get ("bloks_versioning_id" )
728+ if self .settings is not None :
729+ self .settings ["device_settings" ] = self .device_settings
671730 return True
672731
673732 def set_user_agent (self , user_agent : str = "" , reset : bool = False ) -> bool :
0 commit comments