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"]}}
@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