Просмотр исходного кода

Functioning shell. Version check from flatcam.org. Usage report on version check.

Juan Pablo Caram 11 лет назад
Родитель
Сommit
63a97bb15b
4 измененных файлов с 126 добавлено и 12 удалено
  1. 111 10
      FlatCAMApp.py
  2. 13 0
      FlatCAMObj.py
  3. 1 1
      defaults.json
  4. 1 1
      recent.json

+ 111 - 10
FlatCAMApp.py

@@ -172,10 +172,18 @@ class App(QtCore.QObject):
         self.load_defaults()
         self.load_defaults()
 
 
         chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
         chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
-        if self.defaults['serial'] == 0:
+        if self.defaults['serial'] == 0 or len(str(self.defaults['serial'])) < 10:
             self.defaults['serial'] = ''.join([random.choice(chars) for i in range(20)])
             self.defaults['serial'] = ''.join([random.choice(chars) for i in range(20)])
             self.save_defaults()
             self.save_defaults()
 
 
+        def auto_save_defaults():
+            try:
+                self.save_defaults()
+            finally:
+                QtCore.QTimer.singleShot(20000, auto_save_defaults)
+
+        QtCore.QTimer.singleShot(20000, auto_save_defaults)
+
         self.options_form = GlobalOptionsUI()
         self.options_form = GlobalOptionsUI()
         self.options_form_fields = {
         self.options_form_fields = {
             "units": self.options_form.units_radio,
             "units": self.options_form.units_radio,
@@ -400,6 +408,20 @@ class App(QtCore.QObject):
         # Send to worker
         # Send to worker
         self.worker_task.emit({'fcn': worker_task, 'params': [self]})
         self.worker_task.emit({'fcn': worker_task, 'params': [self]})
 
 
+    def report_usage(self, resource):
+        """
+        Increments usage counter for the given resource
+        in self.defaults['stats'].
+
+        :param resource: Name of the resource.
+        :return: None
+        """
+
+        if resource in self.defaults['stats']:
+            self.defaults['stats'][resource] += 1
+        else:
+            self.defaults['stats'][resource] = 1
+
     def exec_command(self, text):
     def exec_command(self, text):
         """
         """
         Hadles input from the shell. See FlatCAMApp.setup_shell for shell commands.
         Hadles input from the shell. See FlatCAMApp.setup_shell for shell commands.
@@ -407,6 +429,8 @@ class App(QtCore.QObject):
         :param text: Input command
         :param text: Input command
         :return: None
         :return: None
         """
         """
+        self.report_usage('exec_command')
+
         text = str(text)
         text = str(text)
 
 
         try:
         try:
@@ -606,6 +630,12 @@ class App(QtCore.QObject):
                 self.log.error("options_write_form(): No field for: %s" % option)
                 self.log.error("options_write_form(): No field for: %s" % option)
 
 
     def on_about(self):
     def on_about(self):
+        """
+        Displays the "about" dialog.
+
+        :return: None
+        """
+        self.report_usage("on_about")
 
 
         class AboutDialog(QtGui.QDialog):
         class AboutDialog(QtGui.QDialog):
             def __init__(self, parent=None):
             def __init__(self, parent=None):
@@ -655,6 +685,15 @@ class App(QtCore.QObject):
         self.save_defaults()
         self.save_defaults()
 
 
     def save_defaults(self):
     def save_defaults(self):
+        """
+        Saves application default options
+        ``self.defaults`` to defaults.json.
+
+        :return: None
+        """
+
+        self.report_usage("save_defaults")
+
         # Read options from file
         # Read options from file
         try:
         try:
             f = open("defaults.json")
             f = open("defaults.json")
@@ -697,6 +736,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_options_app2project")
+
         self.defaults_read_form()
         self.defaults_read_form()
         self.options.update(self.defaults)
         self.options.update(self.defaults)
         self.options_write_form()
         self.options_write_form()
@@ -709,6 +750,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_options_project2app")
+
         self.options_read_form()
         self.options_read_form()
         self.defaults.update(self.options)
         self.defaults.update(self.options)
         self.defaults_write_form()
         self.defaults_write_form()
@@ -721,6 +764,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_options_project2object")
+
         self.options_read_form()
         self.options_read_form()
         obj = self.collection.get_active()
         obj = self.collection.get_active()
         if obj is None:
         if obj is None:
@@ -740,6 +785,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_options_object2project")
+
         obj = self.collection.get_active()
         obj = self.collection.get_active()
         if obj is None:
         if obj is None:
             self.inform.emit("WARNING: No object selected.")
             self.inform.emit("WARNING: No object selected.")
@@ -758,6 +805,9 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
+
+        self.report_usage("on_options_object2app")
+
         obj = self.collection.get_active()
         obj = self.collection.get_active()
         if obj is None:
         if obj is None:
             self.inform.emit("WARNING: No object selected.")
             self.inform.emit("WARNING: No object selected.")
@@ -777,6 +827,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_options_app2object")
+
         self.defaults_read_form()
         self.defaults_read_form()
         obj = self.collection.get_active()
         obj = self.collection.get_active()
         if obj is None:
         if obj is None:
@@ -798,6 +850,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_toggle_units")
+
         if self.toggle_units_ignore:
         if self.toggle_units_ignore:
             return
             return
 
 
@@ -904,6 +958,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_delete")
+
         # Keep this for later
         # Keep this for later
         try:
         try:
             name = copy(self.collection.get_active().options["name"])
             name = copy(self.collection.get_active().options["name"])
@@ -924,6 +980,12 @@ class App(QtCore.QObject):
         self.inform.emit("Object deleted: %s" % name)
         self.inform.emit("Object deleted: %s" % name)
 
 
     def on_plots_updated(self):
     def on_plots_updated(self):
+        """
+        Callback used to report when the plots have changed.
+        Adjust axes and zooms to fit.
+
+        :return: None
+        """
         self.plotcanvas.auto_adjust_axes()
         self.plotcanvas.auto_adjust_axes()
         self.on_zoom_fit(None)
         self.on_zoom_fit(None)
 
 
@@ -933,6 +995,8 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
+
+        self.report_usage("on_toolbar_replot")
         self.log.debug("on_toolbar_replot()")
         self.log.debug("on_toolbar_replot()")
 
 
         try:
         try:
@@ -947,6 +1011,12 @@ class App(QtCore.QObject):
         self.ui.notebook.setCurrentWidget(self.ui.selected_tab)
         self.ui.notebook.setCurrentWidget(self.ui.selected_tab)
 
 
     def on_object_created(self, obj):
     def on_object_created(self, obj):
+        """
+        Event callback for object creation.
+
+        :param obj: The newly created FlatCAM object.
+        :return: None
+        """
         self.log.debug("on_object_created()")
         self.log.debug("on_object_created()")
         self.inform.emit("Object (%s) created: %s" % (obj.kind, obj.options['name']))
         self.inform.emit("Object (%s) created: %s" % (obj.kind, obj.options['name']))
         self.collection.append(obj)
         self.collection.append(obj)
@@ -962,6 +1032,7 @@ class App(QtCore.QObject):
         :param event: Ignored.
         :param event: Ignored.
         :return: None
         :return: None
         """
         """
+
         xmin, ymin, xmax, ymax = self.collection.get_bounds()
         xmin, ymin, xmax, ymax = self.collection.get_bounds()
         width = xmax - xmin
         width = xmax - xmin
         height = ymax - ymin
         height = ymax - ymin
@@ -1062,6 +1133,9 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
+
+        self.report_usage("on_file_new")
+
         # Remove everything from memory
         # Remove everything from memory
         App.log.debug("on_file_new()")
         App.log.debug("on_file_new()")
 
 
@@ -1077,18 +1151,16 @@ class App(QtCore.QObject):
         # Re-fresh project options
         # Re-fresh project options
         self.on_options_app2project()
         self.on_options_app2project()
 
 
-    def on_options_app2project(self):
+    def on_fileopengerber(self):
         """
         """
-        Callback for Options->Transfer Options->App=>Project. Copies options
-        from application defaults to project defaults.
+        File menu callback for opening a Gerber.
 
 
         :return: None
         :return: None
         """
         """
 
 
-        self.options.update(self.defaults)
-
-    def on_fileopengerber(self):
+        self.report_usage("on_fileopengerber")
         App.log.debug("on_fileopengerber()")
         App.log.debug("on_fileopengerber()")
+
         try:
         try:
             filename = QtGui.QFileDialog.getOpenFileName(caption="Open Gerber",
             filename = QtGui.QFileDialog.getOpenFileName(caption="Open Gerber",
                                                          directory=self.last_folder)
                                                          directory=self.last_folder)
@@ -1107,7 +1179,15 @@ class App(QtCore.QObject):
                                    'params': [filename]})
                                    'params': [filename]})
 
 
     def on_fileopenexcellon(self):
     def on_fileopenexcellon(self):
+        """
+        File menu callback for opening an Excellon file.
+
+        :return: None
+        """
+
+        self.report_usage("on_fileopenexcellon")
         App.log.debug("on_fileopenexcellon()")
         App.log.debug("on_fileopenexcellon()")
+
         try:
         try:
             filename = QtGui.QFileDialog.getOpenFileName(caption="Open Excellon",
             filename = QtGui.QFileDialog.getOpenFileName(caption="Open Excellon",
                                                          directory=self.last_folder)
                                                          directory=self.last_folder)
@@ -1126,6 +1206,13 @@ class App(QtCore.QObject):
                                    'params': [filename]})
                                    'params': [filename]})
 
 
     def on_fileopengcode(self):
     def on_fileopengcode(self):
+        """
+        File menu call back for opening gcode.
+
+        :return: None
+        """
+
+        self.report_usage("on_fileopengcode")
         App.log.debug("on_fileopengcode()")
         App.log.debug("on_fileopengcode()")
 
 
         try:
         try:
@@ -1146,6 +1233,13 @@ class App(QtCore.QObject):
                                    'params': [filename]})
                                    'params': [filename]})
 
 
     def on_file_openproject(self):
     def on_file_openproject(self):
+        """
+        File menu callback for opening a project.
+
+        :return: None
+        """
+
+        self.report_usage("on_file_openproject")
         App.log.debug("on_file_openproject()")
         App.log.debug("on_file_openproject()")
 
 
         try:
         try:
@@ -1174,6 +1268,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_file_saveproject")
+
         if self.project_filename is None:
         if self.project_filename is None:
             self.on_file_saveprojectas()
             self.on_file_saveprojectas()
         else:
         else:
@@ -1190,6 +1286,8 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
+        self.report_usage("on_file_saveprojectas")
+
         try:
         try:
             filename = QtGui.QFileDialog.getSaveFileName(caption="Save Project As ...",
             filename = QtGui.QFileDialog.getSaveFileName(caption="Save Project As ...",
                                                          directory=self.last_folder)
                                                          directory=self.last_folder)
@@ -1472,7 +1570,7 @@ class App(QtCore.QObject):
 
 
     def setup_shell(self):
     def setup_shell(self):
         """
         """
-        Creates shell functions.
+        Creates shell functions. Runs once at startup.
 
 
         :return: None
         :return: None
         """
         """
@@ -1994,13 +2092,16 @@ class App(QtCore.QObject):
         """
         """
         Checks for the latest version of the program. Alerts the
         Checks for the latest version of the program. Alerts the
         user if theirs is outdated. This method is meant to be run
         user if theirs is outdated. This method is meant to be run
-        in a saeparate thread.
+        in a separate thread.
 
 
         :return: None
         :return: None
         """
         """
 
 
         self.log.debug("version_check()")
         self.log.debug("version_check()")
-        full_url = App.version_url + "?s=" + str(self.defaults['serial']) + "&v=" + str(self.version)
+        full_url = App.version_url + \
+            "?s=" + str(self.defaults['serial']) + \
+            "&v=" + str(self.version) + \
+            "&" + urllib.urlencode(self.defaults["stats"])
         App.log.debug("Checking for updates @ %s" % full_url)
         App.log.debug("Checking for updates @ %s" % full_url)
 
 
         try:
         try:

+ 13 - 0
FlatCAMObj.py

@@ -71,12 +71,15 @@ class FlatCAMObj(QtCore.QObject):
         self.app.info("Name changed from %s to %s" % (old_name, new_name))
         self.app.info("Name changed from %s to %s" % (old_name, new_name))
 
 
     def on_offset_button_click(self):
     def on_offset_button_click(self):
+        self.app.report_usage("obj_on_offset_button")
+
         self.read_form()
         self.read_form()
         vect = self.ui.offsetvector_entry.get_value()
         vect = self.ui.offsetvector_entry.get_value()
         self.offset(vect)
         self.offset(vect)
         self.plot()
         self.plot()
 
 
     def on_scale_button_click(self):
     def on_scale_button_click(self):
+        self.app.report_usage("obj_on_scale_button")
         self.read_form()
         self.read_form()
         factor = self.ui.scale_entry.get_value()
         factor = self.ui.scale_entry.get_value()
         self.scale(factor)
         self.scale(factor)
@@ -317,6 +320,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
         self.ui.generate_noncopper_button.clicked.connect(self.on_generatenoncopper_button_click)
         self.ui.generate_noncopper_button.clicked.connect(self.on_generatenoncopper_button_click)
 
 
     def on_generatenoncopper_button_click(self, *args):
     def on_generatenoncopper_button_click(self, *args):
+        self.app.report_usage("gerber_on_generatenoncopper_button")
+
         self.read_form()
         self.read_form()
         name = self.options["name"] + "_noncopper"
         name = self.options["name"] + "_noncopper"
 
 
@@ -332,6 +337,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
         self.app.new_object("geometry", name, geo_init)
         self.app.new_object("geometry", name, geo_init)
 
 
     def on_generatebb_button_click(self, *args):
     def on_generatebb_button_click(self, *args):
+        self.app.report_usage("gerber_on_generatebb_button")
         self.read_form()
         self.read_form()
         name = self.options["name"] + "_bbox"
         name = self.options["name"] + "_bbox"
 
 
@@ -346,6 +352,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
         self.app.new_object("geometry", name, geo_init)
         self.app.new_object("geometry", name, geo_init)
 
 
     def on_generatecutout_button_click(self, *args):
     def on_generatecutout_button_click(self, *args):
+        self.app.report_usage("gerber_on_generatecutout_button")
         self.read_form()
         self.read_form()
         name = self.options["name"] + "_cutout"
         name = self.options["name"] + "_cutout"
 
 
@@ -387,6 +394,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
         self.app.new_object("geometry", name, geo_init)
         self.app.new_object("geometry", name, geo_init)
 
 
     def on_iso_button_click(self, *args):
     def on_iso_button_click(self, *args):
+        self.app.report_usage("gerber_on_iso_button")
         self.read_form()
         self.read_form()
         self.isolate()
         self.isolate()
 
 
@@ -615,6 +623,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         self.ui.generate_cnc_button.clicked.connect(self.on_create_cncjob_button_click)
         self.ui.generate_cnc_button.clicked.connect(self.on_create_cncjob_button_click)
 
 
     def on_create_cncjob_button_click(self, *args):
     def on_create_cncjob_button_click(self, *args):
+        self.app.report_usage("excellon_on_create_cncjob_button")
         self.read_form()
         self.read_form()
 
 
         # Get the tools from the list
         # Get the tools from the list
@@ -796,6 +805,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
         self.plot()
         self.plot()
 
 
     def on_exportgcode_button_click(self, *args):
     def on_exportgcode_button_click(self, *args):
+        self.app.report_usage("cncjob_on_exportgcode_button")
 
 
         try:
         try:
             filename = QtGui.QFileDialog.getSaveFileName(caption="Export G-Code ...",
             filename = QtGui.QFileDialog.getSaveFileName(caption="Export G-Code ...",
@@ -895,6 +905,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         self.ui.generate_paint_button.clicked.connect(self.on_paint_button_click)
         self.ui.generate_paint_button.clicked.connect(self.on_paint_button_click)
 
 
     def on_paint_button_click(self, *args):
     def on_paint_button_click(self, *args):
+        self.app.report_usage("geometry_on_paint_button")
+
         self.app.info("Click inside the desired polygon.")
         self.app.info("Click inside the desired polygon.")
         self.read_form()
         self.read_form()
         tooldia = self.options["painttooldia"]
         tooldia = self.options["painttooldia"]
@@ -926,6 +938,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         self.app.new_object("geometry", name, gen_paintarea)
         self.app.new_object("geometry", name, gen_paintarea)
 
 
     def on_generatecnc_button_click(self, *args):
     def on_generatecnc_button_click(self, *args):
+        self.app.report_usage("geometry_on_generatecnc_button")
         self.read_form()
         self.read_form()
         self.generatecncjob()
         self.generatecncjob()
 
 

+ 1 - 1
defaults.json

@@ -1 +1 @@
-{"gerber_noncopperrounded": false, "geometry_paintoverlap": 0.15, "cncjob_append": "", "excellon_feedrate": 3.0, "gerber_plot": true, "geometry_plot": true, "excellon_drillz": -0.1, "geometry_feedrate": 3.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "gerber_isopasses": 1, "excellon_plot": true, "gerber_isotooldia": 0.016, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.1, "excellon_solid": true, "geometry_paintmargin": 0.0, "geometry_cutz": -0.002, "geometry_cnctooldia": 0.016, "gerber_cutouttooldia": 0.07, "gerber_gaps": "4", "gerber_bboxmargin": 0.0, "cncjob_plot": true, "gerber_cutoutgapsize": 0.15, "gerber_isooverlap": 0.15, "gerber_bboxrounded": false, "gerber_noncoppermargin": 0.0, "geometry_painttooldia": 0.07}
+{}

+ 1 - 1
recent.json

@@ -1 +1 @@
-[{"kind": "gerber", "filename": "tests/CBS-F_Cu.gtl"}, {"kind": "gerber", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/test_files/maitest.gtl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\maitest.gtl"}, {"kind": "gerber", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/cirkuix/tests/CBS-F_Cu.gtl"}, {"kind": "excellon", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/cirkuix/tests/CBS.drl"}, {"kind": "gerber", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/test_files/Gerbers/AVR_Transistor_Tester_copper_top.GTL"}, {"kind": "excellon", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/test_files/LockController_v1.0_pcb-RoundHoles.TXT/LockController_v1.0_pcb-RoundHoles.TXT"}, {"kind": "excellon", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/test_files/Gerbers/AVR_Transistor_Tester.DRL"}, {"kind": "excellon", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/test_files/FlatCam_Drilling_Test/FlatCam_Drilling_Test.drl"}, {"kind": "excellon", "filename": "C:/Users/jpcaram/Dropbox/CNC/pcbcam/test_files/Excellon_Planck/X-Y CONTROLLER - Drill Data - Through Hole.drl"}]
+[]