44import  __builtin__ 
55import  copy 
66import  json 
7+ import  operator 
78import  os 
89import  platform 
910import  pprint 
1314import  datetime 
1415import  collections 
1516import  logging 
17+ import  unicodedata 
1618from  subprocess  import  check_output 
19+ import  pkg_resources 
1720
1821import  octoprint .plugin 
1922import  requests 
3134from  octoprint .settings  import  settings 
3235from  octoprint .events  import  Events  as  OctoPrintEvents 
3336
37+ from  octoprint_mrbeam .rest_handler .update_handler  import  UpdateRestHandlerMixin 
38+ from  octoprint_mrbeam .util .connectivity_checker  import  ConnectivityChecker 
39+ 
3440IS_X86  =  platform .machine () ==  "x86_64" 
41+ from  ._version  import  get_versions 
42+ 
43+ __version__  =  get_versions ()["version" ]
44+ if  isinstance (__version__ , unicode ):
45+     __version__  =  unicodedata .normalize ('NFKD' , __version__ ).encode ('ascii' , 'ignore' )
46+ 
47+ del  get_versions 
3548
36- from  octoprint_mrbeam .__version  import  __version__ 
3749from  octoprint_mrbeam .iobeam .iobeam_handler  import  ioBeamHandler , IoBeamEvents 
3850from  octoprint_mrbeam .iobeam .onebutton_handler  import  oneButtonHandler 
3951from  octoprint_mrbeam .iobeam .interlock_handler  import  interLockHandler 
4355from  octoprint_mrbeam .iobeam .hw_malfunction_handler  import  hwMalfunctionHandler 
4456from  octoprint_mrbeam .iobeam .laserhead_handler  import  laserheadHandler 
4557from  octoprint_mrbeam .iobeam .compressor_handler  import  compressor_handler 
58+ from  octoprint_mrbeam .jinja .filter_loader  import  FilterLoader 
4659from  octoprint_mrbeam .user_notification_system  import  user_notification_system 
4760from  octoprint_mrbeam .analytics .analytics_handler  import  analyticsHandler 
4861from  octoprint_mrbeam .analytics .usage_handler  import  usageHandler 
5366from  octoprint_mrbeam .mrb_logger  import  init_mrb_logger , mrb_logger 
5467from  octoprint_mrbeam .migrate  import  migrate 
5568from  octoprint_mrbeam .os_health_care  import  os_health_care 
69+ from  octoprint_mrbeam .rest_handler .docs_handler  import  DocsRestHandlerMixin 
70+ from  octoprint_mrbeam .services .settings_service  import  SettingsService 
71+ from  octoprint_mrbeam .services .burger_menu_service  import  BurgerMenuService 
72+ from  octoprint_mrbeam .services .document_service  import  DocumentService 
5673from  octoprint_mrbeam .wizard_config  import  WizardConfig 
5774from  octoprint_mrbeam .printing .profile  import  (
5875    laserCutterProfileManager ,
6481    get_update_information ,
6582    switch_software_channel ,
6683    software_channels_available ,
67-     SW_UPDATE_TIER_PROD ,
68-     SW_UPDATE_TIER_BETA ,
69-     SW_UPDATE_TIER_DEV ,
7084    BEAMOS_LEGACY_DATE ,
85+     SWUpdateTier ,
7186)
7287from  octoprint_mrbeam .support  import  check_support_mode , check_calibration_tool_mode 
7388from  octoprint_mrbeam .cli  import  get_cli_commands 
91106from  octoprint_mrbeam .util .uptime  import  get_uptime , get_uptime_human_readable 
92107from  octoprint_mrbeam .util  import  get_thread 
93108from  octoprint_mrbeam  import  camera 
109+ from  octoprint_mrbeam .util .version_comparator  import  compare_pep440_versions 
94110
95111# this is a easy&simple way to access the plugin and all injections everywhere within the plugin 
96112__builtin__ ._mrbeam_plugin_implementation  =  None 
@@ -110,6 +126,8 @@ class MrBeamPlugin(
110126    octoprint .plugin .SlicerPlugin ,
111127    octoprint .plugin .ShutdownPlugin ,
112128    octoprint .plugin .EnvironmentDetectionPlugin ,
129+     UpdateRestHandlerMixin ,
130+     DocsRestHandlerMixin ,
113131):
114132    # CONSTANTS 
115133    ENV_PROD  =  "PROD" 
@@ -144,6 +162,7 @@ class MrBeamPlugin(
144162    TIME_NTP_SYNC_CHECK_INTERVAL_FAST  =  10.0 
145163    TIME_NTP_SYNC_CHECK_INTERVAL_SLOW  =  120.0 
146164
165+ 
147166    def  __init__ (self ):
148167        self .mrbeam_plugin_initialized  =  False 
149168        self ._shutting_down  =  False 
@@ -164,6 +183,7 @@ def __init__(self):
164183        self ._serial_num  =  None 
165184        self ._mac_addrs  =  dict ()
166185        self ._model_id  =  None 
186+         self ._explicit_update_check  =  False 
167187        self ._grbl_version  =  None 
168188        self ._device_series  =  self ._device_info .get_series ()
169189        self .called_hosts  =  []
@@ -186,6 +206,9 @@ def __init__(self):
186206        # MrBeam Events needs to be registered in OctoPrint in order to be send to the frontend later on 
187207        MrBeamEvents .register_with_octoprint ()
188208
209+         # Jinja custom filters need to be loaded already on instance creation 
210+         FilterLoader .load_custom_jinja_filters ()
211+ 
189212    # inside initialize() OctoPrint is already loaded, not assured during __init__()! 
190213    def  initialize (self ):
191214        self ._plugin_version  =  __version__ 
@@ -243,10 +266,10 @@ def initialize(self):
243266        self .led_event_listener .set_fps (self ._settings .get (["leds" , "fps" ]))
244267        # start iobeam socket only once other handlers are already initialized so that we can handle info message 
245268        self .iobeam  =  ioBeamHandler (self )
246-         self .temperature_manager  =  temperatureManager (self )
247269        self .dust_manager  =  dustManager (self )
248270        self .hw_malfunction_handler  =  hwMalfunctionHandler (self )
249271        self .laserhead_handler  =  laserheadHandler (self )
272+         self .temperature_manager  =  temperatureManager (self )
250273        self .compressor_handler  =  compressor_handler (self )
251274        self .wizard_config  =  WizardConfig (self )
252275        self .job_time_estimation  =  JobTimeEstimation (self )
@@ -256,6 +279,10 @@ def initialize(self):
256279        self .mrbeam_plugin_initialized  =  True 
257280        self .fire_event (MrBeamEvents .MRB_PLUGIN_INITIALIZED )
258281
282+         # move octoprints connectivity checker to a new var so we can use our abstraction 
283+         self ._octoprint_connectivity_checker  =  self ._connectivity_checker 
284+         self ._connectivity_checker  =  ConnectivityChecker (self )
285+ 
259286        self ._do_initial_log ()
260287
261288    def  _init_frontend_logger (self ):
@@ -368,7 +395,7 @@ def get_settings_defaults(self):
368395                terminalMaxLines = 2000 ,
369396                env = self .ENV_PROD ,
370397                load_gremlins = False ,
371-                 software_tier = SW_UPDATE_TIER_PROD ,
398+                 software_tier = SWUpdateTier . STABLE . value ,
372399                iobeam_disable_warnings = False ,  # for development on non-MrBeam devices 
373400                suppress_migrations = False ,  # for development on non-MrBeam devices 
374401                support_mode = False ,
@@ -454,7 +481,9 @@ def on_settings_load(self):
454481            dev = dict (
455482                env = self .get_env (),
456483                software_tier = self ._settings .get (["dev" , "software_tier" ]),
457-                 software_tiers_available = software_channels_available (self ),
484+                 software_tiers_available = [
485+                     channel  for  channel  in  software_channels_available (self )
486+                 ],
458487                terminalMaxLines = self ._settings .get (["dev" , "terminalMaxLines" ]),
459488            ),
460489            gcode_nextgen = dict (
@@ -694,7 +723,7 @@ def get_assets(self):
694723                "css/hopscotch.min.css" ,
695724                "css/wizard.css" ,
696725                "css/tab_messages.css" ,
697-                 "css/software_update.css" 
726+                 "css/software_update.css" , 
698727            ],
699728            less = ["less/mrbeam.less" ],
700729        )
@@ -718,6 +747,16 @@ def calibration_tool_mode(self):
718747        self ._fixEmptyUserManager ()
719748        return  ret 
720749
750+     @property  
751+     def  explicit_update_check (self ):
752+         return  self ._explicit_update_check 
753+ 
754+     def  set_explicit_update_check (self ):
755+         self ._explicit_update_check  =  True 
756+ 
757+     def  clear_explicit_update_check (self ):
758+         self ._explicit_update_check  =  False 
759+ 
721760    ##~~ UiPlugin mixin 
722761
723762    def  will_handle_ui (self , request ):
@@ -791,7 +830,7 @@ def on_ui_render(self, now, request, render_kwargs):
791830                now = now ,
792831                init_ts_ms = time .time () *  1000 ,
793832                language = language ,
794-                 beamosVersionNumber = self ._plugin_version ,
833+                 mrBeamPluginVersionNumber = self ._plugin_version ,
795834                beamosVersionBranch = self ._branch ,
796835                beamosVersionDisplayVersion = display_version_string ,
797836                beamosVersionImage = self ._octopi_info ,
@@ -818,6 +857,10 @@ def on_ui_render(self, now, request, render_kwargs):
818857                terminalEnabled = self ._settings .get (["terminal" ]) or  self .support_mode ,
819858                lasersafety_confirmation_dialog_version = self .LASERSAFETY_CONFIRMATION_DIALOG_VERSION ,
820859                lasersafety_confirmation_dialog_language = language ,
860+                 settings_model = SettingsService (self ._logger , DocumentService (self ._logger )).get_template_settings_model (
861+                     self .get_model_id ()),
862+                 burger_menu_model = BurgerMenuService (self ._logger , DocumentService (self ._logger )).get_burger_menu_model (
863+                     self .get_model_id ()),
821864            )
822865        )
823866        r  =  make_response (render_template ("mrbeam_ui_index.jinja2" , ** render_kwargs ))
@@ -1257,6 +1300,16 @@ def generate_backlash_compenation_pattern_gcode(self, data):
12571300            res  =  dict (calibration_pattern = destFile , target = FileDestinations .LOCAL )
12581301            return  jsonify (res )
12591302
1303+     # simpleApiCommand: compare_pep440_versions; 
1304+     def  handle_pep440_comparison_result (self , data ):
1305+         try :
1306+             result  =  compare_pep440_versions (data ['v1' ], data ['v2' ], data ['operator' ])
1307+             return  make_response (json .dumps (result ), 200 )
1308+         except  KeyError  as  e :
1309+             self ._logger .error ("Key is missing in data: %s" , e )
1310+             return  make_response (json .dumps (None ), 500 )
1311+ 
1312+ 
12601313    # ~~ helpers 
12611314
12621315    # helper method to write data to user settings 
@@ -1323,7 +1376,7 @@ def calibration_wrapper(self):
13231376            locales = dict (),
13241377            supportedExtensions = [],
13251378            # beamOS version 
1326-             beamosVersionNumber = self ._plugin_version ,
1379+             mrBeamPluginVersionNumber = self ._plugin_version ,
13271380            beamosVersionBranch = self ._branch ,
13281381            beamosVersionDisplayVersion = display_version_string ,
13291382            beamosVersionImage = self ._octopi_info ,
@@ -1889,6 +1942,7 @@ def get_api_commands(self):
18891942            camera_stop_lens_calibration = [],
18901943            generate_calibration_markers_svg = [],
18911944            cancel_final_extraction = [],
1945+             compare_pep440_versions = []
18921946        )
18931947
18941948    def  on_api_command (self , command , data ):
@@ -2016,6 +2070,8 @@ def on_api_command(self, command, data):
20162070            )  # TODO move this func to other file 
20172071        elif  command  ==  "cancel_final_extraction" :
20182072            self .dust_manager .set_user_abort_final_extraction ()
2073+         elif  command  ==  "compare_pep440_versions" :
2074+             return  self .handle_pep440_comparison_result (data )
20192075
20202076        return  NO_CONTENT 
20212077
@@ -2957,10 +3013,10 @@ def __calc_time_ntp_offset(self, log_out_of_sync=False):
29573013                timer .start ()
29583014
29593015    def  is_beta_channel (self ):
2960-         return  self ._settings .get (["dev" , "software_tier" ]) ==  SW_UPDATE_TIER_BETA 
3016+         return  self ._settings .get (["dev" , "software_tier" ]) ==  SWUpdateTier . BETA . value 
29613017
29623018    def  is_develop_channel (self ):
2963-         return  self ._settings .get (["dev" , "software_tier" ]) ==  SW_UPDATE_TIER_DEV 
3019+         return  self ._settings .get (["dev" , "software_tier" ]) ==  SWUpdateTier . DEV . value 
29643020
29653021    def  _get_mac_addresses (self ):
29663022        if  not  self ._mac_addrs :
0 commit comments