Skip to content

Instantly share code, notes, and snippets.

@Brunas
Last active June 9, 2020 07:28
Show Gist options
  • Save Brunas/124c8ef19f67f4ebcfff to your computer and use it in GitHub Desktop.
Save Brunas/124c8ef19f67f4ebcfff to your computer and use it in GitHub Desktop.
Slide show widget

Description

This is Dashing widget to include slide show on your dashboard or one of its pages.

##Usage

Make sure to install RMagick gem to support image resizing. The widget also needs my slightly improved standard image widget. Put the slide_show.rb file in your /jobs folder and slide_show_settings.json to /assets/config/.

Make sure directory /assets/config and /assets/images/slide_show are accessible by Dashing user.

To include the widget in a dashboard, add the following snippet to the dashboard layout file:

<li data-row="1" data-col="1" data-sizex="4" data-sizey="2">
  <div data-id="SlideShow" data-view="Image" data-width="100%"></div>
</li>

There are 2 scheduler jobs used: First one gets randomized list of image files with pattern from source directory, resizes them to needed size and puts them to /assets/images/slide_show/<widget name>. It is executed at 5:00 and 18:00. Second randomly loops every 30 seconds through the files in /assets/images/slide_show/<widget name> and sends event with random file URL

##Settings

Mount your images directory to any directory on your server to be accessible by Dashing user. Amend /assets/config/slide_show_settings.json to have parameters specified.

There is no need to restart service if job is already running and settings file is amended.

require 'net/http'
require 'rmagick'
class SlideShow
SETTINGS_FILE = "assets/config/slide_show_settings.json"
CURRENT_DIR = Dir.pwd
DEBUG = 0
def debug
DEBUG
end
# function to validate json
def valid_json? (json)
JSON.parse(json)
return true
rescue JSON::ParserError
return false
end
def get_settings
str = IO.read(SETTINGS_FILE)
return [] if not str or str.empty? or not valid_json?(str)
JSON.parse(str)
end
def get_dir_file_list(directory, pattern, exceptionDirs = [])
# Take directory files using pattern and delete exception subdirectories
Dir[directory+'/'+pattern].delete_if { |x| exceptionDirs.any? { |d| x =~ /#{d}/ } }
end
def resize_images(files, widget, directory, maxImageSize, quality = 50, fileCount = 100)
return if not files or files.length == 0
files[0..fileCount].each do |f|
newFile = f.sub directory, CURRENT_DIR+"/assets/images/slide_show/#{widget}"
next if File.exists?(newFile)
FileUtils.mkdir_p File.dirname(newFile)
img = Magick::Image.read(f).first
newImg = img.change_geometry(maxImageSize[0].to_s+'x'+maxImageSize[1].to_s) { |cols, rows, i|
newImg = i.resize(cols, rows)
newImg.write(newFile){ self.quality = quality }
}
end
end
def get_file_list(widget, settings)
widgetFileDir = CURRENT_DIR+"/assets/images/slide_show/#{widget}"
files = (get_dir_file_list(widgetFileDir, settings['pattern']).shuffle)[0..30]
return files if files and files.length > 0
# no files yet - get new list from source location and resize it
# take just 15 files not to freeze everything
resize_images(
get_dir_file_list(settings['directory'], settings['pattern'], settings['subDirectoryExceptions']).shuffle,
widget,
settings['directory'],
settings['maxImageSize'],
settings['quality'],
15)
# return 10 files not to make everything last too long
(get_dir_file_list(widgetFileDir, settings['pattern']).shuffle)[0..10]
end
def make_web_friendly(widget, directory, file)
file.sub directory, "/assets/slide_show/#{widget}" if file
end
end
@SS = SlideShow.new()
SCHEDULER.cron '* 5/18 * * *' do |job|
settings = @SS.get_settings
settings.each do |widget, project|
puts DateTime.now.to_s+" Resizing images for #{widget}, #{project.to_s}"
@SS.resize_images(
@SS.get_dir_file_list(project['directory'], project['pattern'], project['subDirectoryExceptions']).shuffle,
widget,
project['directory'],
project['maxImageSize'],
project['quality'])
end
end
@files = nil
SCHEDULER.every '30s', :first_in => 0 do |job|
settings = @SS.get_settings
settings.each do |widget, project|
@files = { widget => @SS.get_file_list(widget, project) } if not @files or not @files[widget] or @files[widget].length == 0
file = @files[widget][rand(@files[widget].length)]
puts DateTime.now.to_s+" Working with #{widget}, #{project.to_s}, #{file}" if @SS.debug > 0
img = Magick::Image::read(file).first
send_event(widget, {
image: @SS.make_web_friendly(widget, Dir.pwd+"/assets/images/slide_show/#{widget}", file),
image_width: img.columns,
image_height: img.rows
})
end
end
{"SlideShow":{"directory":"/mnt/images/Public TV","pattern":"**/*.{jpg,JPG,gif,GIF,png,PNG}","maxImageSize":[1920,1080],"quality":50,"subDirectoryExceptions":["very bad party","personal employee pictures","something very private"]}}
@Brunas
Copy link
Author

Brunas commented Sep 24, 2015

@slize,

Thanks for nice words and especially for your excellent QA work! Yesterday I started wondering myself, why those pictures are always the same ;). Code updated.

@Hartigon
Copy link

Hartigon commented Feb 7, 2016

Hi , thanks for your nice gadget but it generates a script leak memory for each new pictures.

@tkcharlie
Copy link

Hi Brunas,
I've been trying to get this to work but just can't get there,
can you give me a clue as to why I'd get this error when starting dashing

/Users/tkcharlie/ce_dashboard/jobs/slide_show.rb:90:in read' /Users/tkcharlie/ce_dashboard/jobs/slide_show.rb:90:inblock (2 levels) in <top (required)>'
/Users/tkcharlie/ce_dashboard/jobs/slide_show.rb:86:in each' /Users/tkcharlie/ce_dashboard/jobs/slide_show.rb:86:inblock in <top (required)>'

@stigert
Copy link

stigert commented Aug 25, 2018

I've been trying to get this to work for days, but it's not happening. It keeps getting RMagick error messages. Is it possible to get this widget without the resizing part?

@GuinnessStoutly
Copy link

Hi Brunas, Thanks for the widget. It's working, however there is still a problem with image duplications. Another question, how to stop the shuffling? Thanks.

@mandelbrotmedia
Copy link

Hi,

thanks for that great widget!
Is there a way to stop the randomized slideshow? Would be nice to display the images in a fixed order.

thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment