Skip to content

Commit

Permalink
Merge pull request #85 from jneilliii/dev
Browse files Browse the repository at this point in the history
gco hotfix
  • Loading branch information
jneilliii authored Jan 6, 2022
2 parents c444df4 + 558d20c commit c82ebdb
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ dist
*.egg*
.DS_Store
*.zip
/git-flow-plus.config
55 changes: 36 additions & 19 deletions octoprint_prusaslicerthumbnails/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import datetime
import io
from PIL import Image
import re
import base64


class PrusaslicerthumbnailsPlugin(octoprint.plugin.SettingsPlugin,
Expand All @@ -27,8 +29,9 @@ def __init__(self):
self._folderRemovalLastAdded = {}
self._waitForAnalysis = False
self._analysis_active = False
self.regex_extension = re.compile("\.(?:gco(?:de)?|tft)$")

##~~ SettingsPlugin mixin
# ~~ SettingsPlugin mixin

def get_settings_defaults(self):
return dict(
Expand All @@ -46,24 +49,22 @@ def get_settings_defaults(self):
scale_inline_thumbnail_position=False
)

##~~ AssetPlugin mixin
# ~~ AssetPlugin mixin

def get_assets(self):
return dict(
js=["js/prusaslicerthumbnails.js"],
css=["css/prusaslicerthumbnails.css"]
)

##~~ TemplatePlugin mixin
# ~~ TemplatePlugin mixin

def get_template_configs(self):
return [
dict(type="settings", custom_bindings=False, template="prusaslicerthumbnails_settings.jinja2"),
]

def _extract_thumbnail(self, gcode_filename, thumbnail_filename):
import re
import base64
regex = r"(?:^; thumbnail begin \d+[x ]\d+ \d+)(?:\n|\r\n?)((?:.+(?:\n|\r\n?))+?)(?:^; thumbnail end)"
regex_mks = re.compile('(?:;(?:simage|;gimage):).*?M10086 ;[\r\n]', re.DOTALL)
lineNum = 0
Expand Down Expand Up @@ -133,6 +134,7 @@ def find_best_thumbnail(self, gcode_encoded_images):
# Return size and trimmed string
return (200, 200), image[9:]


# Check for simage
for image in gcode_encoded_images:
if image.startswith(';simage:'):
Expand All @@ -142,7 +144,16 @@ def find_best_thumbnail(self, gcode_encoded_images):
# Image not found
return None

##~~ EventHandlerPlugin mixin
# Check for simage
for image in gcode_encoded_images:
if image.startswith(';simage:'):
# Return size and trimmed string
return (100, 100), image[8:]

# Image not found
return None

# ~~ EventHandlerPlugin mixin

def on_event(self, event, payload):
if event not in ["FileAdded", "FileRemoved", "FolderRemoved", "FolderAdded"]:
Expand All @@ -158,22 +169,20 @@ def on_event(self, event, payload):
results = self._process_gcode(local_files[file_key], results)
self._logger.debug("Scan results: {}".format(results))
if event in ["FileAdded", "FileRemoved"] and payload["storage"] == "local" and "gcode" in payload["type"]:
thumbnail_filename = self.get_plugin_data_folder() + "/" + payload["path"].replace(".gcode", ".png")
thumbnail_path = self.regex_extension.sub(".png", payload["path"])
thumbnail_filename = "{}/{}".format(self.get_plugin_data_folder(), thumbnail_path)

if os.path.exists(thumbnail_filename):
os.remove(thumbnail_filename)
if event == "FileAdded":
gcode_filename = self._file_manager.path_on_disk("local", payload["path"])
self._extract_thumbnail(gcode_filename, thumbnail_filename)
if os.path.exists(thumbnail_filename):
thumbnail_url = "plugin/prusaslicerthumbnails/thumbnail/" + payload["path"].replace(".gcode",
".png") + "?" + "{:%Y%m%d%H%M%S}".format(
datetime.datetime.now())
self._file_manager.set_additional_metadata("local", payload["path"], "thumbnail",
thumbnail_url.replace("//", "/"), overwrite=True)
self._file_manager.set_additional_metadata("local", payload["path"], "thumbnail_src",
self._identifier, overwrite=True)
thumbnail_url = "plugin/prusaslicerthumbnails/thumbnail/{}?{:%Y%m%d%H%M%S}".format(thumbnail_path, datetime.datetime.now())
self._file_manager.set_additional_metadata("local", payload["path"], "thumbnail", thumbnail_url.replace("//", "/"), overwrite=True)
self._file_manager.set_additional_metadata("local", payload["path"], "thumbnail_src", self._identifier, overwrite=True)

##~~ SimpleApiPlugin mixin
# ~~ SimpleApiPlugin mixin

def _process_gcode(self, gcode_file, results=[]):
self._logger.debug(gcode_file["path"])
Expand All @@ -199,7 +208,6 @@ def get_api_commands(self):

def on_api_command(self, command, data):
import flask
import json
from octoprint.server import user_permission
if not user_permission.can():
return flask.make_response("Insufficient rights", 403)
Expand All @@ -214,9 +222,17 @@ def on_api_command(self, command, data):
results = self._process_gcode(LocalFiles[key], results)
return flask.jsonify(results)

##~~ Routes hook
# ~~ extension_tree hook
def get_extension_tree(self, *args, **kwargs):
return dict(
machinecode=dict(
gcode=["tft"]
)
)

# ~~ Routes hook
def route_hook(self, server_routes, *args, **kwargs):
from octoprint.server.util.tornado import LargeResponseHandler, UrlProxyHandler, path_validation_factory
from octoprint.server.util.tornado import LargeResponseHandler, path_validation_factory
from octoprint.util import is_hidden_path
return [
(r"thumbnail/(.*)", LargeResponseHandler, dict(path=self.get_plugin_data_folder(),
Expand All @@ -225,7 +241,7 @@ def route_hook(self, server_routes, *args, **kwargs):
lambda path: not is_hidden_path(path), status_code=404)))
]

##~~ Softwareupdate hook
# ~~ Softwareupdate hook

def get_update_information(self):
return dict(
Expand Down Expand Up @@ -266,5 +282,6 @@ def __plugin_load__():
global __plugin_hooks__
__plugin_hooks__ = {
"octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information,
"octoprint.filemanager.extension_tree": __plugin_implementation__.get_extension_tree,
"octoprint.server.http.routes": __plugin_implementation__.route_hook
}
28 changes: 16 additions & 12 deletions octoprint_prusaslicerthumbnails/static/js/prusaslicerthumbnails.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ $(function() {
self.crawl_results = ko.observableArray([]);

self.filesViewModel.prusaslicerthumbnails_open_thumbnail = function(data) {
if(data.name.indexOf('.gcode') > 0){
var thumbnail_title = data.path.replace('.gcode','');
if(data.thumbnail_src === "prusaslicerthumbnails"){
var thumbnail_title = data.name.replace(/\.(?:gco(?:de)?|tft)$/,'');
self.thumbnail_url(data.thumbnail);
self.thumbnail_title(thumbnail_title);
self.file_details(data);
$('div#prusa_thumbnail_viewer').modal("show");
}
}
};

self.DEFAULT_THUMBNAIL_SCALE = "100%";
self.filesViewModel.thumbnailScaleValue = ko.observable(self.DEFAULT_THUMBNAIL_SCALE);
Expand Down Expand Up @@ -55,19 +55,20 @@ $(function() {
self.crawl_results.push({name: ko.observable(key), files: ko.observableArray(data[key])});
}
}
if(self.crawl_results().length == 0){
if(self.crawl_results().length === 0){
self.crawl_results.push({name: ko.observable('No convertible files found'), files: ko.observableArray([])});
}
self.filesViewModel.requestData({force: true});
self.crawling_files(false);
}).fail(function(data){
self.crawling_files(false);
})
}
});
};

self.onBeforeBinding = function() {
// inject filelist thumpnail into template
let regex = /<div class="btn-group action-buttons">([\s\S]*)<.div>/mi;
// inject filelist thumbnail into template

let regex = /<div class="btn-group action-buttons">([\s\S]*)<.div>/mi;
let template = '<div class="btn btn-mini" data-bind="click: function() { if ($root.loginState.isUser()) { $root.prusaslicerthumbnails_open_thumbnail($data) } else { return; } }, visible: ($data.thumbnail_src == \'prusaslicerthumbnails\' && $root.settingsViewModel.settings.plugins.prusaslicerthumbnails.inline_thumbnail() == false)" title="Show Thumbnail" style="display: none;"><i class="fa fa-image"></i></div>';

let inline_thumbnail_template = '<div class="inline_prusa_thumbnail" ' +
Expand All @@ -76,12 +77,13 @@ $(function() {
'visible: ($data.thumbnail_src == \'prusaslicerthumbnails\' && $root.settingsViewModel.settings.plugins.prusaslicerthumbnails.inline_thumbnail() == true), ' +
'click: function() { if ($root.loginState.isUser() && !($(\'html\').attr(\'id\') === \'touch\')) { $root.prusaslicerthumbnails_open_thumbnail($data) } else { return; } },' +
'style: {\'width\': (!$root.thumbnailPositionLeft()) ? $root.thumbnailScaleValue() : \'100%\' }" ' +
'style="display: none;"/></div>'
'style="display: none;"/></div>';


$("#files_template_machinecode").text(function () {
var return_value = inline_thumbnail_template + $(this).text();
return_value = return_value.replace(regex, '<div class="btn-group action-buttons">$1 ' + template + '></div>');
return return_value
return return_value;
});

// assign initial scaling
Expand Down Expand Up @@ -116,7 +118,8 @@ $(function() {
self.filesViewModel.thumbnailScaleValue(newValue + "%");
});
self.settingsViewModel.settings.plugins.prusaslicerthumbnails.state_panel_thumbnail_scale_value.subscribe(function(newValue){
$('#prusaslicer_state_thumbnail').attr({'width': self.settingsViewModel.settings.plugins.prusaslicerthumbnails.state_panel_thumbnail_scale_value() + '%'})
$('#prusaslicer_state_thumbnail').attr({'width': self.settingsViewModel.settings.plugins.prusaslicerthumbnails.state_panel_thumbnail_scale_value() + '%'});

});

// observe alignment changes
Expand Down Expand Up @@ -168,7 +171,8 @@ $(function() {
$('#prusaslicer_state_thumbnail').remove();
}
});
}
};

}

OCTOPRINT_VIEWMODELS.push({
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
plugin_name = "Slicer Thumbnails"

# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "1.0.0"
plugin_version = "1.0.1rc1"

# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module
Expand Down

0 comments on commit c82ebdb

Please sign in to comment.