Skip to content

Commit feca951

Browse files
committed
0.0.1
Initial commit
0 parents  commit feca951

15 files changed

+588
-0
lines changed

.editorconfig

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# This file is for unifying the coding style for different editors and IDEs
2+
# editorconfig.org
3+
4+
root = true
5+
6+
[*]
7+
end_of_line = lf
8+
charset = utf-8
9+
insert_final_newline = true
10+
trim_trailing_whitespace = true
11+
12+
[**.py]
13+
indent_style = tab
14+
15+
[**.js]
16+
indent_style = space
17+
indent_size = 4

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*.pyc
2+
*.swp
3+
.idea
4+
*.iml
5+
build
6+
dist
7+
*.egg*
8+
.DS_Store
9+
*.zip

MANIFEST.in

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include README.md
2+
recursive-include octoprint_prusaslicerthumbnails/templates *
3+
recursive-include octoprint_prusaslicerthumbnails/translations *
4+
recursive-include octoprint_prusaslicerthumbnails/static *

README.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# OctoPrint-PrusaSlicerThumbnails
2+
3+
**TODO:** Describe what your plugin does.
4+
5+
## Setup
6+
7+
Install via the bundled [Plugin Manager](https://docs.octoprint.org/en/master/bundledplugins/pluginmanager.html)
8+
or manually using this URL:
9+
10+
https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip
11+
12+
**TODO:** Describe how to install your plugin, if more needs to be done than just installing it via pip or through
13+
the plugin manager.
14+
15+
## Configuration
16+
17+
**TODO:** Describe your plugin's configuration options (if any).

babel.cfg

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[python: */**.py]
2+
[jinja2: */**.jinja2]
3+
extensions=jinja2.ext.autoescape, jinja2.ext.with_
4+
5+
[javascript: */**.js]
6+
extract_messages = gettext, ngettext

extras/PrusaSlicerThumbnails.md

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
layout: plugin
3+
4+
id: PrusaSlicerThumbnails
5+
title: OctoPrint-PrusaSlicerThumbnails
6+
description: Plugin that extracts thumbnails from uploaded gcode files sliced by PrusaSlicer.
7+
author: jneilliii
8+
license: AGPLv3
9+
10+
# TODO
11+
date: today's date in format YYYY-MM-DD, e.g. 2015-04-21
12+
13+
homepage: https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails
14+
source: https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails
15+
archive: https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip
16+
17+
# TODO
18+
# Set this to true if your plugin uses the dependency_links setup parameter to include
19+
# library versions not yet published on PyPi. SHOULD ONLY BE USED IF THERE IS NO OTHER OPTION!
20+
#follow_dependency_links: false
21+
22+
# TODO
23+
tags:
24+
- a list
25+
- of tags
26+
- that apply
27+
- to your plugin
28+
- (take a look at the existing plugins for what makes sense here)
29+
30+
# TODO
31+
screenshots:
32+
- url: url of a screenshot, /assets/img/...
33+
alt: alt-text of a screenshot
34+
caption: caption of a screenshot
35+
- url: url of another screenshot, /assets/img/...
36+
alt: alt-text of another screenshot
37+
caption: caption of another screenshot
38+
- ...
39+
40+
# TODO
41+
featuredimage: url of a featured image for your plugin, /assets/img/...
42+
43+
# TODO
44+
# You only need the following if your plugin requires specific OctoPrint versions or
45+
# specific operating systems to function - you can safely remove the whole
46+
# "compatibility" block if this is not the case.
47+
48+
compatibility:
49+
50+
# List of compatible versions
51+
#
52+
# A single version number will be interpretated as a minimum version requirement,
53+
# e.g. "1.3.1" will show the plugin as compatible to OctoPrint versions 1.3.1 and up.
54+
# More sophisticated version requirements can be modelled too by using PEP440
55+
# compatible version specifiers.
56+
#
57+
# You can also remove the whole "octoprint" block. Removing it will default to all
58+
# OctoPrint versions being supported.
59+
60+
octoprint:
61+
- 1.2.0
62+
63+
# List of compatible operating systems
64+
#
65+
# Valid values:
66+
#
67+
# - windows
68+
# - linux
69+
# - macos
70+
# - freebsd
71+
#
72+
# There are also two OS groups defined that get expanded on usage:
73+
#
74+
# - posix: linux, macos and freebsd
75+
# - nix: linux and freebsd
76+
#
77+
# You can also remove the whole "os" block. Removing it will default to all
78+
# operating systems being supported.
79+
80+
os:
81+
- linux
82+
- windows
83+
- macos
84+
- freebsd
85+
86+
# Compatible Python version
87+
#
88+
# Plugins should aim for compatibility for Python 2 and 3 for now, in which case the value should be ">=2.7,<4".
89+
#
90+
# Plugins that only wish to support Python 3 should set it to ">=3,<4".
91+
#
92+
# If your plugin only supports Python 2 (worst case, not recommended for newly developed plugins since Python 2
93+
# is EOL), leave at ">=2.7,<3"
94+
95+
python: ">=2.7,<3"
96+
97+
---
98+
99+
**TODO**: Longer description of your plugin, configuration examples etc. This part will be visible on the page at
100+
http://plugins.octoprint.org/plugin/PrusaSlicerThumbnails/

extras/README.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Currently Cookiecutter generates the following helpful extras to this folder:
2+
3+
PrusaSlicerThumbnails.md
4+
Data file for plugins.octoprint.org. Fill in the missing TODOs once your
5+
plugin is ready for release and file a PR as described at
6+
http://plugins.octoprint.org/help/registering/ to get it published.
7+
8+
This folder may be safely removed if you don't need it.
+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# coding=utf-8
2+
from __future__ import absolute_import
3+
from __future__ import unicode_literals
4+
5+
import octoprint.plugin
6+
import octoprint.filemanager
7+
import octoprint.filemanager.util
8+
import octoprint.util
9+
import os
10+
11+
class ThumbnailProcessor(octoprint.filemanager.util.LineProcessorStream):
12+
13+
def __init__(self, fileBufferedReader, thumbnail_data, path, logger):
14+
super(ThumbnailProcessor, self).__init__(fileBufferedReader)
15+
self._thumbnail_data = thumbnail_data
16+
self._collecting_data = False
17+
self._logger = logger
18+
self._path = path
19+
20+
def process_line(self, origLine):
21+
if not len(origLine):
22+
return None
23+
24+
isBytesLineForPy3 = type(origLine) is bytes and not (type(origLine) is str)
25+
line = octoprint.util.to_unicode(origLine, errors="replace")
26+
line = line.lstrip()
27+
28+
if (len(line) != 0 and line.startswith("; thumbnail end")):
29+
self._collecting_data = False
30+
if len(self._thumbnail_data) > 0:
31+
import base64
32+
with open(self._path, "wb") as fh:
33+
fh.write(base64.b64decode(self._thumbnail_data))
34+
35+
if (len(line) != 0 and self._collecting_data == True):
36+
self._thumbnail_data += line.replace("; ","")
37+
38+
if (len(line) != 0 and line.startswith("; thumbnail begin")):
39+
if os.path.exists(self._path):
40+
os.remove(self._path)
41+
self._collecting_data = True
42+
43+
line = origLine
44+
45+
if (isBytesLineForPy3 and type(line) is str):
46+
# line = line.encode('utf8')
47+
# line = line.encode('ISO-8859-1')
48+
line = octoprint.util.to_bytes(line, errors="replace")
49+
else:
50+
if (isBytesLineForPy3 == False):
51+
# do nothing, because we don't modify the line
52+
if (type(line) is unicode):
53+
line = octoprint.util.to_native_str(line)
54+
return line
55+
56+
class PrusaslicerthumbnailsPlugin(octoprint.plugin.SettingsPlugin,
57+
octoprint.plugin.AssetPlugin,
58+
octoprint.plugin.TemplatePlugin):
59+
60+
def __init__(self):
61+
self._fileRemovalTimer = None
62+
self._fileRemovalLastDeleted = None
63+
self._fileRemovalLastAdded = None
64+
self._waitForAnalysis = False
65+
self._analysis_active = False
66+
self._thumbnail_data = ""
67+
68+
##~~ SettingsPlugin mixin
69+
70+
def get_settings_defaults(self):
71+
return dict(
72+
installed=True,
73+
inline_thumbnail=False,
74+
scale_inline_thumbnail=False,
75+
inline_thumbnail_scale_value="50",
76+
align_inline_thumbnail=False,
77+
inline_thumbnail_align_value="left"
78+
)
79+
80+
##~~ AssetPlugin mixin
81+
82+
def get_assets(self):
83+
return dict(
84+
js=["js/prusaslicerthumbnails.js"],
85+
css=["css/prusaslicerthumbnails.css"]
86+
)
87+
88+
##~~ TemplatePlugin mixin
89+
90+
def get_template_configs(self):
91+
return [
92+
dict(type="settings", custom_bindings=False, template="prusaslicerthumbnails_settings.jinja2"),
93+
]
94+
95+
##~~ preprocessor hook
96+
97+
def thumbnail_extractor(self, path, file_object, links=None, printer_profile=None, allow_overwrite=True, *args, **kwargs):
98+
if not octoprint.filemanager.valid_file_type(path, type="gcode"):
99+
return file_object
100+
101+
thumbnail_filename = self.get_plugin_data_folder() + "/" + path.replace(".gcode",".png")
102+
return octoprint.filemanager.util.StreamWrapper(file_object.filename, ThumbnailProcessor(file_object.stream(), self._thumbnail_data, thumbnail_filename, self._logger))
103+
# return file_object
104+
105+
##~~ Routes hook
106+
def route_hook(self, server_routes, *args, **kwargs):
107+
from octoprint.server.util.tornado import LargeResponseHandler, UrlProxyHandler, path_validation_factory
108+
from octoprint.util import is_hidden_path
109+
return [
110+
(r"thumbnail/(.*)", LargeResponseHandler, dict(path=self.get_plugin_data_folder(),
111+
as_attachment=False,
112+
path_validation=path_validation_factory(lambda path: not is_hidden_path(path),status_code=404)))
113+
]
114+
115+
##~~ Softwareupdate hook
116+
117+
def get_update_information(self):
118+
return dict(
119+
prusaslicerthumbnails=dict(
120+
displayName="Prusa Slicer Thumbnails",
121+
displayVersion=self._plugin_version,
122+
123+
# version check: github repository
124+
type="github_release",
125+
user="jneilliii",
126+
repo="OctoPrint-PrusaSlicerThumbnails",
127+
current=self._plugin_version,
128+
129+
# update method: pip
130+
pip="https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/{target_version}.zip"
131+
)
132+
)
133+
134+
__plugin_name__ = "Prusa Slicer Thumbnails"
135+
__plugin_pythoncompat__ = ">=2.7,<4" # python 2 and 3
136+
137+
def __plugin_load__():
138+
global __plugin_implementation__
139+
__plugin_implementation__ = PrusaslicerthumbnailsPlugin()
140+
141+
global __plugin_hooks__
142+
__plugin_hooks__ = {
143+
"octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information,
144+
"octoprint.filemanager.preprocessor": __plugin_implementation__.thumbnail_extractor,
145+
"octoprint.server.http.routes": __plugin_implementation__.route_hook
146+
}
147+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#prusa_thumbnail_viewer {
2+
width: 330px;
3+
margin-left: -165px;
4+
}
5+
6+
#prusa_thumbnail_viewer h3 {
7+
overflow: hidden;
8+
}

0 commit comments

Comments
 (0)