[checkmk-commits] Check_MK Git: check_mk: Added icon upload

Lars Michelsen lm at mathias-kettner.de
Mon Apr 13 11:03:55 CEST 2015


Module: check_mk
Branch: master
Commit: d3cfc01588cdadff582c5bc2cf706cce377ed4ff
URL:    http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=d3cfc01588cdadff582c5bc2cf706cce377ed4ff

Author: Lars Michelsen <lm at mathias-kettner.de>
Date:   Mon Mar 30 14:09:12 2015 +0200

Added icon upload

---

 web/htdocs/pages.css         |   13 +++++--
 web/htdocs/valuespec.py      |   29 +++++++++++-----
 web/htdocs/views.py          |   78 ++++++++++++++++++++++++++++++++++++++++++
 web/plugins/pages/shipped.py |    2 ++
 4 files changed, 112 insertions(+), 10 deletions(-)

diff --git a/web/htdocs/pages.css b/web/htdocs/pages.css
index c9d876b..d8d28b0 100644
--- a/web/htdocs/pages.css
+++ b/web/htdocs/pages.css
@@ -976,8 +976,8 @@ body.main table.footer .popup_menu a:hover {
 
 #popup_menu .icons li a:hover {
     text-decoration: none;
-    color:#779D2A;
-    background-color: #fbfbfb;
+    background-color: #629BB1;
+    color: #fff;
 }
 
 #popup_menu .icons li.active a {
@@ -1000,6 +1000,15 @@ body.main table.footer .popup_menu a:hover {
     height: 20px;
 }
 
+body.icon_upload {
+    background: transparent;
+}
+
+body.icon_upload div.error,
+body.icon_upload div.success {
+    margin: 0;
+}
+
 /*--Various----------------------------------------------------------------.
 |                __     __         _                                       |
 |                \ \   / /_ _ _ __(_) ___  _   _ ___                       |
diff --git a/web/htdocs/valuespec.py b/web/htdocs/valuespec.py
index 1b5cfc8..bd2b677 100644
--- a/web/htdocs/valuespec.py
+++ b/web/htdocs/valuespec.py
@@ -3174,8 +3174,9 @@ class FileUpload(ValueSpec):
             return ''
 
     def validate_value(self, value, varprefix):
-        if not self._allow_empty and value == None:
+        if not self._allow_empty and (value == None or value[0] == ''):
             raise MKUserError(varprefix, _('Please select a file.'))
+        self.custom_validate(value, varprefix)
 
     def render_input(self, varprefix, value):
         html.upload_file(varprefix)
@@ -3185,24 +3186,25 @@ class FileUpload(ValueSpec):
         return html.uploaded_file(varprefix)
 
 class IconSelector(ValueSpec):
+    _categories = [
+        ('logos',   _('Logos')),
+        ('parts',   _('Parts')),
+        ('misc',    _('Misc')),
+    ]
+
     def __init__(self, **kwargs):
         ValueSpec.__init__(self, **kwargs)
         self._prefix      = kwargs.get('prefix', '')
         self._allow_empty = kwargs.get('allow_empty', True)
         self._html_path   = 'images/icons'
         self._empty_img   = kwargs.get('emtpy_img', 'empty')
+        self._upload      = kwargs.get('upload', True)
 
         self._exclude = [
             'trans',
             'empty',
         ]
 
-        self._categories = [
-            ('logos', _('Logos')),
-            ('parts', _('Parts')),
-            ('misc',  _('Misc')),
-        ]
-
     # All icons within the images/icons directory have the ident of a category
     # witten in the PNG meta data. For the default images we have done this scripted.
     # During upload of user specific icons, the meta data is added to the images.
@@ -3297,7 +3299,8 @@ class IconSelector(ValueSpec):
 
         # Render tab navigation
         html.write('<ul>')
-        for category_name, category_alias, icons in available_icons:
+        upload = self._upload and [('upload', _('Upload'), [])] or []
+        for category_name, category_alias, icons in available_icons + upload:
             active = active_category == category_name and ' class="active"' or ''
             html.write('<li%s>' % active)
             html.write('<a id="%s_%s_nav" class="%s_nav" href="javascript:vs_iconselector_toggle(\'%s\', \'%s\')">%s</a>' %
@@ -3315,8 +3318,18 @@ class IconSelector(ValueSpec):
                     onclick = 'vs_iconselector_select(event, \'%s\', \'%s\')' % (varprefix, icon),
                     title = _('Choose this icon'), id = varprefix + '_i_' + icon)
             html.write('</div>')
+
+        if self._upload:
+            html.write('<div style="display:none" id="%s_%s_container" class="%s_container">' %
+                                                                 (varprefix, 'upload', varprefix))
+            html.write('<iframe allowTransparency="true" frameborder="0" width="100%" height="100%" '
+                       'src="icon_upload.py">')
+            html.write('</iframe>')
+            html.write('</div>')
         html.write('</div>')
 
+
+
     def from_html_vars(self, varprefix):
         icon = html.var(varprefix + '_value')
         if icon == 'empty':
diff --git a/web/htdocs/views.py b/web/htdocs/views.py
index bfbbe93..d32c022 100644
--- a/web/htdocs/views.py
+++ b/web/htdocs/views.py
@@ -2428,3 +2428,81 @@ def ajax_popup_icon_selector():
 
     vs = IconSelector(allow_empty=allow_empty)
     vs.render_popup_input(varprefix, value)
+
+def validate_icon(value, varprefix):
+    from PIL import Image
+    from StringIO import StringIO
+    file_name, mime_type, content = value
+    if file_name[-4:] != '.png' \
+       or mime_type != 'image/png' \
+       or not content.startswith('\x89PNG'):
+        raise MKUserError(varprefix, _('Please choose a PNG icon.'))
+
+    try:
+        im = Image.open(StringIO(content))
+    except IOError:
+        raise MKUserError(varprefix, _('Please choose a valid PNG icon.'))
+
+    w, h = im.size
+    if w > 80 or h > 80:
+        raise MKUserError(varprefix, _('Maximum image size: 80x80px'))
+
+def page_icon_upload():
+    vs_upload = Tuple(
+        title = _('Icon'),
+        elements = [
+            FileUpload(
+                title = _('Icon'),
+                allow_empty = False,
+                validate = validate_icon,
+            ),
+            DropdownChoice(
+                title = _('Category'),
+                choices = IconSelector._categories,
+                no_preselect = True,
+            )
+        ]
+    )
+
+    html.set_render_headfoot(False)
+    # FIXME: Hack. Make this possible without the html.var
+    html.set_var('_body_class', 'icon_upload')
+    html.header(_('Icon Upload'), stylesheets=['pages', 'views', 'status'])
+
+    if html.var('save') and html.check_transaction():
+        try:
+            icon_info = vs_upload.from_html_vars('upload_icon')
+            vs_upload.validate_value(icon_info, 'upload_icon')
+
+            # Now add the icon category to the PNG comment
+            from PIL import Image, PngImagePlugin
+            from StringIO import StringIO
+            im = Image.open(StringIO(icon_info[0][2]))
+            im.info['Comment'] = icon_info[1]
+            meta = PngImagePlugin.PngInfo()
+            for k,v in im.info.iteritems():
+                if k not in ('interlace', 'gamma', 'dpi', 'transparency', 'aspect'):
+                    meta.add_text(k, v, 0)
+
+            # and finally save the image
+            if defaults.omd_root:
+                dest_dir = "%s/local/share/check_mk/web/htdocs/images/icons" % defaults.omd_root
+            else:
+                dest_dir = "%s/htdocs/images/icons" % defaults.web_dir
+            make_nagios_directories(dest_dir)
+            im.save(dest_dir+'/'+icon_info[0][0], 'PNG', pnginfo=meta)
+
+            html.message(_('Upload succeeded.'))
+
+        except MKUserError, e:
+            html.write('<div class=error>%s</div>\n' % e.message)
+            html.add_user_error(e.varname, e.message)
+
+    html.begin_form('upload_icon', method='POST')
+    vs_upload.render_input('upload_icon', None)
+
+    html.button('save', _('Upload'), 'submit')
+
+    html.hidden_fields()
+    html.end_form()
+    html.footer()
diff --git a/web/plugins/pages/shipped.py b/web/plugins/pages/shipped.py
index 9c187ed..7055f4f 100644
--- a/web/plugins/pages/shipped.py
+++ b/web/plugins/pages/shipped.py
@@ -104,7 +104,9 @@ pagehandlers.update({
    "notify"                   : notify.page_notify,
 
    "ajax_inv_render_tree"     : views.ajax_inv_render_tree,
+
    "ajax_popup_icon_selector" : views.ajax_popup_icon_selector,
+   "icon_upload"              : views.page_icon_upload,
 
    "webapi"                   : webapi.page_api,
 



More information about the checkmk-commits mailing list