radiovis-generator 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +109 -0
- data/bin/radiovis-generator +18 -0
- data/lib/radiovis-generator.rb +116 -0
- data/lib/radiovis-generator/slide.rb +132 -0
- data/lib/radiovis-generator/slides/branding_slide.rb +26 -0
- data/lib/radiovis-generator/slides/now_playing_slide.rb +14 -0
- data/templates/branding-slide.svg +153 -0
- data/templates/empty-slide.svg +75 -0
- data/templates/now-playing-slide.svg +173 -0
- metadata +97 -0
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
## RadioVIS Generator
|
2
|
+
|
3
|
+
This is a small gem which allows you to quickly and simply generate slides (comprising of a complex, rendered and composited image, and some text) customised for your station from an SVG source file, a set of substitutions (which can be dynamically driven) and optionally an image to composite behind the SVG output.
|
4
|
+
|
5
|
+
The generator also includes a framework for specifying slide durations and intelligently pushing them to your Stomp broker.
|
6
|
+
|
7
|
+
It's designed to let any station plug it directly into their infrastructure with a minimal amount of coding and a simple process for non-technical content creators.
|
8
|
+
|
9
|
+
### What is RadioVIS?
|
10
|
+
|
11
|
+
RadioVIS is a [RadioDNS](http://radiodns.org/) application. It's designed for hybrid radio receivers (Broadcast audio plus IP back channel) but can be used on other platforms such as the internet in addition. A [much better description](http://radiodns.org/about-radiodns/) can be found on the RadioDNS website.
|
12
|
+
|
13
|
+
Simply put (though if you want the spec, [it's here](http://radiodns.org/documentation/)) RadioVIS lets receivers and audio player software show an image and a line of text next to your station, and allows for the use of push technologies to update which image and text the receiver is displaying at a given point in time. This allows for content mapped to the output of your station (such as 'Now Playing' information or information on the current show) to be generated and displayed to your users.
|
14
|
+
|
15
|
+
## Dependencies
|
16
|
+
|
17
|
+
RadioVIS Generator depends on Inkscape (which does not require a GUI) and the ImageMagick project (the 'convert' and 'composite' binaries).
|
18
|
+
|
19
|
+
Aside from those two tools, Ruby is required, along with RubyGems. Recent versions are recommended.
|
20
|
+
|
21
|
+
You'll also need a Stomp broker, though this can be on another system. You'll probably need a web server like nginx or Apache on your system, though.
|
22
|
+
|
23
|
+
RadioVIS Generator is tested on Linux. Other operating systems are supported in principle, but not tested.
|
24
|
+
|
25
|
+
## Installation and Usage
|
26
|
+
|
27
|
+
Installing is simple. Install the dependencies (on Ubuntu, that's `sudo apt-get install imagemagick inkscape` - add `ruby1.9-full` if you're missing Ruby), and then simply install the gem with `gem install radiovis-generator`. Congratulations, you're good to go!
|
28
|
+
|
29
|
+
|
30
|
+
You can test the installation out by using the simple command line program bundled with the generator - see `radiovis-generator --help` for options. This will cycle between the slides provided by the gem, and is intended as a really simple starting point for your own runner.
|
31
|
+
|
32
|
+
|
33
|
+
### Simple Usage
|
34
|
+
|
35
|
+
RadioVIS Generator comes bundled with a couple of basic templates - one which shows two pieces of information (intended for Now Playing slides), and one which shows just a large title. These will get you off the ground, or at least show you how to customise your slides.
|
36
|
+
|
37
|
+
To run RadioVIS Generator is very simple. I'm going to assume you can set up a folder on your system and point your web server at it, and that you've got a Stomp broker running. If this is all correct, then you can run a simple demo by creating a file like this:
|
38
|
+
|
39
|
+
```
|
40
|
+
require 'rubygems'
|
41
|
+
require 'radiovis-generator'
|
42
|
+
gen = RadioVISGenerator::Generator.new
|
43
|
+
options = {
|
44
|
+
slides: [RadioVISGenerator::BrandingSlide.new, RadioVISGenerator::NowPlayingSlide.new],
|
45
|
+
url: 'http://localhost/radiovis/', # The path on your web server pointing at..
|
46
|
+
path: '/tmp/radiovis-output' # This path on your filesystem!
|
47
|
+
broadcast_parameters: 'fm/ecc/pi/freq', # See the RadioVIS spec for how to generate this.
|
48
|
+
username: 'system', # These details are for your Stomp broker.
|
49
|
+
password: 'manager',
|
50
|
+
host: 'localhost',
|
51
|
+
port: 61313
|
52
|
+
}
|
53
|
+
gen.run(options)
|
54
|
+
```
|
55
|
+
|
56
|
+
Running this file will perpetually serve up RadioVIS images and text, and send out Stomp messages. You can use a tool like CasterPlay's RadioVIS Monitor to check everything is working. The console output will also tell you more or less what it's doing, or at least let you know if it's obviously not working!
|
57
|
+
|
58
|
+
### Customising
|
59
|
+
|
60
|
+
Customisation should simply be a matter of making a new subclass of `RadioVISGenerator::Slide`, making a new SVG file and if required a background image, and then adding the new subclass to your runner rotation. So let's say we want a simple slide which is going to have a rotating title and a background image.
|
61
|
+
|
62
|
+
```
|
63
|
+
class MyCustomSlide < RadioVISGenerator::Slide
|
64
|
+
def generate
|
65
|
+
return {
|
66
|
+
'$$TITLE$$' => ['Some cool text!', 'Some other cool text!'].shuffle.first
|
67
|
+
}
|
68
|
+
end
|
69
|
+
# We don't want this one displayed so often.
|
70
|
+
def redisplay_delay
|
71
|
+
20
|
72
|
+
end
|
73
|
+
# Specify our filename - this is messy because it's relative to the gem.
|
74
|
+
def svg_filename
|
75
|
+
return "/some/path/to/my-custom-slide.svg"
|
76
|
+
end
|
77
|
+
# We want a background image!
|
78
|
+
def background_image
|
79
|
+
return "/some/path/to/my-background.png"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
Now all we need to do is pass `MyCustomSlide.new` to our runner as a slide to consider in the rotation and we're done! We can customise the SVG file or the background image, adjust the text we're dynamically adding in our slide class, or add new dynamic elements through the same mechanism. The only limit is the lengths to which you're willing to figure out how to do things with SVG.
|
85
|
+
|
86
|
+
|
87
|
+
Loads more information on how to make your own custom slides can be found in the RDoc documentation or by simply reading the `slide.rb` file.
|
88
|
+
|
89
|
+
|
90
|
+
## Credits and Acknowledgements
|
91
|
+
|
92
|
+
* This software package was developed by James Harrison, originally as part of the OCD Broadcast Content Management System for [Insanity Radio](http://insanityradio.com).
|
93
|
+
* RadioDNS is supported by a [lot of people](http://radiodns.org/supporters/).
|
94
|
+
* The [Inkscape](http://inkscape.org/) project provides the kick-ass SVG to PNG converter and a really slick SVG editor.
|
95
|
+
* [ImageMagick](http://www.imagemagick.org/script/index.php) has yet to not appear in anything I've ever written. All the contributors rock.
|
96
|
+
|
97
|
+
|
98
|
+
## License
|
99
|
+
|
100
|
+
Copyright (c) 2012, James Harrison
|
101
|
+
All rights reserved.
|
102
|
+
|
103
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
104
|
+
|
105
|
+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
106
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
107
|
+
* Neither the name of Insanity Radio nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
108
|
+
|
109
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JAMES HARRISON OR INSANITY RADIO BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'radiovis-generator'
|
4
|
+
require 'trollop'
|
5
|
+
opts = Trollop::options do
|
6
|
+
opt :url, "Base Image URL", type: String, default: 'http://localhost/radiovis/'
|
7
|
+
opt :path, "Base Image Path", type: String, default: '/tmp/radiovis-output'
|
8
|
+
opt :broadcast_parameters, "Broadcast Parameters", type: String
|
9
|
+
opt :username, "Stomp username", type: String, default: 'system'
|
10
|
+
opt :password, "Stomp password", type: String, default: 'manager'
|
11
|
+
opt :host, "Stomp host", type: String, default: 'localhost'
|
12
|
+
opt :port, "Stomp port", type: :int, default: 61613
|
13
|
+
end
|
14
|
+
gen = RadioVISGenerator::Generator.new
|
15
|
+
options = {
|
16
|
+
slides: [RadioVISGenerator::BrandingSlide.new, RadioVISGenerator::NowPlayingSlide.new]
|
17
|
+
}.merge(opts)
|
18
|
+
gen.run(options)
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'stomp'
|
2
|
+
|
3
|
+
module RadioVISGenerator
|
4
|
+
class Generator
|
5
|
+
def initialize
|
6
|
+
Generator.has_dependencies?
|
7
|
+
end
|
8
|
+
|
9
|
+
# Runs the generator!
|
10
|
+
# This does all the tying together of things and Stomp interaction.
|
11
|
+
# The generator accepts a hash of options:
|
12
|
+
# slides - An array of Slide instances.
|
13
|
+
# url - The root URL at which the pictures can be found from the outside world, ie 'http://blah.com/system/radiovis-images/'.
|
14
|
+
# path - The root path where we should write the images, ie '/opt/www/website/public/system/radiovis-images'
|
15
|
+
# broadcast_parameters - The broadcast parameters for your station in RadioVIS topic format, ie 'fm/ECC/PI/FREQUENCY' for FM (like 'fm/ce1/c08f/10320' for Insanity Radio 103.2 FM)
|
16
|
+
# username - The Stomp username
|
17
|
+
# password - The Stomp password
|
18
|
+
# host - The Stomp host
|
19
|
+
# port - The Stomp port
|
20
|
+
# Sensible defaults are provided for Stomp, but you should set them explicitly.
|
21
|
+
def run(options)
|
22
|
+
defaults = {
|
23
|
+
slides: [],
|
24
|
+
url: 'http://localhost/radiovis/',
|
25
|
+
path: '/tmp/radiovis-output',
|
26
|
+
broadcast_parameters: 'fm/ecc/pi/freq',
|
27
|
+
username: 'system',
|
28
|
+
password: 'manager',
|
29
|
+
host: 'localhost',
|
30
|
+
port: 61313
|
31
|
+
}
|
32
|
+
options = defaults.merge(options)
|
33
|
+
raise ArgumentsError, "No slide instances provided!" unless options[:slides].size > 0
|
34
|
+
puts "Generator starting - parameters #{options.inspect}"
|
35
|
+
begin
|
36
|
+
conn = Stomp::Connection.open options[:username], options[:password], options[:host], options[:port], false
|
37
|
+
while true do
|
38
|
+
# Okay - so here's the plan.
|
39
|
+
# We have a bunch of Slide subclasses which contain what we want.
|
40
|
+
# Every so often we check to see if any need rendering and render whichever has the highest priority.
|
41
|
+
slides_to_render = []
|
42
|
+
options[:slides].each do |slide|
|
43
|
+
slides_to_render.push(slide) if slide.changed?
|
44
|
+
end
|
45
|
+
# If we've got nothing that's changed, pick a redisplay instead.
|
46
|
+
if slides_to_render.size == 0
|
47
|
+
options[:slides].each do |slide|
|
48
|
+
slides_to_render.push(slide) if slide.redisplay?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
# Pick the lowest priority.
|
52
|
+
slides_to_render.sort_by!{|slide|slide.priority}
|
53
|
+
slide = slides_to_render.reverse[0] rescue nil
|
54
|
+
if slide
|
55
|
+
# Go for it!
|
56
|
+
puts "Rendering #{slide.inspect}"
|
57
|
+
puts "Chosen from #{slides_to_render.inspect}"
|
58
|
+
slide_output = slide.render(options[:path])
|
59
|
+
|
60
|
+
# Now we go ahead and send those messages.
|
61
|
+
image_topic = "/topic/#{options[:broadcast_parameters]}/image"
|
62
|
+
text_topic = "/topic/#{options[:broadcast_parameters]}/text"
|
63
|
+
image_message = "SHOW "+options[:url]+slide_output[:image_small]
|
64
|
+
text_message = "TEXT "+slide_output[:text]
|
65
|
+
puts "Publishing Stomp messages"
|
66
|
+
puts " - #{image_topic} <= #{image_message}"
|
67
|
+
puts " - #{text_topic} <= #{text_message}"
|
68
|
+
conn.publish(image_topic, image_message, {'persistent'=>'false'})
|
69
|
+
conn.publish(text_topic, text_message, {'persistent'=>'false'})
|
70
|
+
puts "Done, waiting #{slide.display_time} seconds to let people read this slide."
|
71
|
+
# Sleep for this long before we display anything else.
|
72
|
+
sleep slide.display_time
|
73
|
+
else
|
74
|
+
puts "No slide to render, sleeping a second."
|
75
|
+
sleep 1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
#rescue Exception => e
|
79
|
+
# puts "Got exception #{e}!"
|
80
|
+
# conn.disconnect rescue nil
|
81
|
+
# conn = nil
|
82
|
+
# sleep 5
|
83
|
+
# retry
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.has_dependencies?
|
88
|
+
unless self.which('inkscape')
|
89
|
+
raise SystemCallError, "Inkscape is required to use this library.\nYou can install it on Ubuntu/Debian with 'sudo apt-get install inkscape'. (And don't worry, it works headlessly and won't install a full GUI stack).\nSpecifically I need 'inkscape' in my PATH."
|
90
|
+
end
|
91
|
+
unless self.which('convert')
|
92
|
+
raise SystemCallError, "ImageMagick is required to use this library.\nYou can install it on Ubuntu/Debian with 'sudo apt-get install imagemagick'.\nSpecifically I need 'convert' in my PATH."
|
93
|
+
end
|
94
|
+
unless self.which('composite')
|
95
|
+
raise SystemCallError, "ImageMagick is required to use this library.\nYou can install it on Ubuntu/Debian with 'sudo apt-get install imagemagick'.\nSpecifically I need 'composite' in my PATH."
|
96
|
+
end
|
97
|
+
end
|
98
|
+
private
|
99
|
+
# Utility method to identify if a program is available and executable.
|
100
|
+
def self.which(cmd)
|
101
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
102
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
103
|
+
exts.each { |ext|
|
104
|
+
exe = "#{path}/#{cmd}#{ext}"
|
105
|
+
return exe if File.executable? exe
|
106
|
+
}
|
107
|
+
end
|
108
|
+
return nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
require 'radiovis-generator/slide'
|
114
|
+
require 'radiovis-generator/slides/branding_slide'
|
115
|
+
require 'radiovis-generator/slides/now_playing_slide'
|
116
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
class RadioVISGenerator::Slide
|
3
|
+
# Generate the substitution hash to process on this run. This is where we add our dynamic content!
|
4
|
+
# Returns a hash where "$$TARGET$$" => "Content", where $$TARGET$$ is the target string to replace in the SVG and Content is the substitute.
|
5
|
+
# This is passed to RadioVISGenerator::Slide.rewrite_svg
|
6
|
+
def generate
|
7
|
+
return {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# Generate the text to display alongside this slide.
|
11
|
+
def text
|
12
|
+
return "Default slide text - RadioVIS Generator"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Has this slide changed since last rendered?
|
16
|
+
# Reset anything you need to in the Slide#generate method.
|
17
|
+
# For instance, if I'm showing the current show or now playing, I'd check if the current track on air
|
18
|
+
# was the same as the one I'd stored last time I'd rendered. If it were different I'd return true.
|
19
|
+
# Then in Slide#generate, I'd store the current track on air.
|
20
|
+
# This means we can get very prompt updates on realtime events - maximum delay defined by your largest
|
21
|
+
# display_time of all the slides, ie 5 seconds with nothing overridden.
|
22
|
+
def changed?
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
|
26
|
+
# What is the priority of this slide? Lower numbers takes precedence. Default 50.
|
27
|
+
def priority
|
28
|
+
return 50
|
29
|
+
end
|
30
|
+
|
31
|
+
# How long should we display this slide for at a minimum? Values under 5 are rarely good.
|
32
|
+
def display_time
|
33
|
+
return 5
|
34
|
+
end
|
35
|
+
|
36
|
+
# How long should we wait between redisplays if we've got nothing better to do (ie no content changed)?
|
37
|
+
def redisplay_delay
|
38
|
+
return 15
|
39
|
+
end
|
40
|
+
|
41
|
+
# What image makes the background of this slide, and should be composited over it?
|
42
|
+
# Return nil to skip the composition stage and just display the SVG output.
|
43
|
+
# Defaults to nil.
|
44
|
+
def background_image
|
45
|
+
return nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# What SVG file are we going to render?
|
49
|
+
# Defaults to an empty slide.
|
50
|
+
def svg_filename
|
51
|
+
return "#{File.expand_path(File.dirname(File.dirname(__FILE__)))}/templates/empty-slide.svg"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Okay, show's over!
|
55
|
+
|
56
|
+
# That's it. Everything up there, define in your subclasses if you want to override them.
|
57
|
+
|
58
|
+
# Set up the slide. Just sets the last time this slide was rendered up.
|
59
|
+
def initialize
|
60
|
+
@last_render_time = Time.now
|
61
|
+
end
|
62
|
+
|
63
|
+
# Have we gotten bored enough to just show this again, assuming it's not been too little time
|
64
|
+
# (as defined in Slide#redisplay_delay)
|
65
|
+
def redisplay?
|
66
|
+
if @last_render_time < Time.now - 15
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# Render this slide, returns a hash with image_big, image_small, output_path, name and text. Paths returned are relative to the provided output_path.
|
74
|
+
# Will create the output path if needed.
|
75
|
+
# Shouldn't be overriden unless you know what you're doing.
|
76
|
+
# Calls Slide#generate and Slide#text to get dynamic content and then spits out some images.
|
77
|
+
def render(output_path)
|
78
|
+
# Reset time-based cycling
|
79
|
+
@last_render_time = Time.now
|
80
|
+
# Make sure our output path exists
|
81
|
+
FileUtils.mkdir_p(output_path) rescue nil
|
82
|
+
Dir.mkdir('/tmp/radiovis-generator') rescue nil # Make our temporary storage
|
83
|
+
RadioVISGenerator::Slide.rewrite_svg(svg_filename, "/tmp/#{self.name}.svg", self.generate)
|
84
|
+
if background_image
|
85
|
+
RadioVISGenerator::Slide.render_svg("/tmp/#{self.name}.svg", "/tmp/#{self.name}-precomp.png")
|
86
|
+
RadioVISGenerator::Slide.composite("/tmp/#{self.name}-precomp.png", background_image, File.join(output_path, "#{self.name}-640x480.png"))
|
87
|
+
else
|
88
|
+
RadioVISGenerator::Slide.render_svg("/tmp/#{self.name}.svg", File.join(output_path, "#{self.name}-640x480.png"))
|
89
|
+
end
|
90
|
+
FileUtils.rm_rf('/tmp/radiovis-generator') rescue nil # Clean up after ourselves
|
91
|
+
# Make our smaller-res version
|
92
|
+
RadioVISGenerator::Slide.resize_to_fit(File.join(output_path, "#{self.name}-640x480.png"), File.join(output_path, "#{self.name}-320x240.png"), '320x240')
|
93
|
+
return {
|
94
|
+
image_big: "#{self.name}-640x480.png",
|
95
|
+
image_small: "#{self.name}-320x240.png",
|
96
|
+
text: self.text,
|
97
|
+
output_path: output_path,
|
98
|
+
name: self.name
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns the name of this slide as a friendlyish string to be used in output image names.
|
103
|
+
def name
|
104
|
+
self.class.to_s.downcase.gsub("radiovisgenerator::","")
|
105
|
+
end
|
106
|
+
|
107
|
+
# Rewrites an SVG at a given input path with the information in the given hash to the given output path.
|
108
|
+
# Hash is of the format "$$TARGET$$" => "Content", where $$TARGET$$ is the target string to replace in the SVG and Content is the substitute.
|
109
|
+
def self.rewrite_svg(in_path, out_path, sub_hash)
|
110
|
+
svg_input = File.open(in_path).read()
|
111
|
+
sub_hash.each_pair do |k,v|
|
112
|
+
svg_input = svg_input.gsub(k,v)
|
113
|
+
end
|
114
|
+
File.open(out_path, 'w'){|f|f<<svg_input}
|
115
|
+
end
|
116
|
+
|
117
|
+
# Renders an SVG to a PNG
|
118
|
+
def self.render_svg(in_path, out_path)
|
119
|
+
`inkscape -f #{in_path} -e #{out_path}`
|
120
|
+
end
|
121
|
+
|
122
|
+
# Resize and (if needed) crop to the size of a slide (640x480 by default), using center gravity.
|
123
|
+
def self.resize_to_fit(in_path, out_path, size='640x480')
|
124
|
+
`convert #{in_path} -resize #{size}^ -gravity center -extent #{size} #{out_path}`
|
125
|
+
end
|
126
|
+
|
127
|
+
# Composite two images to another image. Center gravity.
|
128
|
+
def self.composite(top_in_path, bottom_in_path, out_path)
|
129
|
+
`composite -gravity center #{top_in_path} #{bottom_in_path} #{out_path}`
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class RadioVISGenerator::BrandingSlide < RadioVISGenerator::Slide
|
2
|
+
# Man, NowPlayingSlide thinks he's got problems. I'm a complete idiot compared to that guy.
|
3
|
+
# Hey, want to help me out? Maybe add some functionality to me?
|
4
|
+
def generate
|
5
|
+
return {
|
6
|
+
'$$STATIONNAME$$' => 'Your Radio Station'
|
7
|
+
}
|
8
|
+
end
|
9
|
+
# I'm just an example slide so I don't actually have a background image bundled.
|
10
|
+
# But here I'd return a full path to whatever I wanted behind my SVG with all the SVG's shiny opacity.
|
11
|
+
def background_image
|
12
|
+
return nil
|
13
|
+
end
|
14
|
+
# We don't want this one displayed so often.
|
15
|
+
def redisplay_delay
|
16
|
+
20
|
17
|
+
end
|
18
|
+
# And it's lower priority.
|
19
|
+
def priority
|
20
|
+
25
|
21
|
+
end
|
22
|
+
# Specify our filename - this is messy because it's relative to the gem.
|
23
|
+
def svg_filename
|
24
|
+
return "#{File.expand_path(File.dirname(File.dirname(File.dirname(File.dirname(__FILE__)))))}/templates/branding-slide.svg"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class RadioVISGenerator::NowPlayingSlide < RadioVISGenerator::Slide
|
2
|
+
# In here I'd do some clever stuff if I were being clever. But I'm not.
|
3
|
+
# I'm just an example slide. You're clever, right? You can help me out here!
|
4
|
+
def generate
|
5
|
+
return {
|
6
|
+
'$$STATIONNAME$$' => 'Your Radio Station',
|
7
|
+
'$$NOWPLAYING$$' => 'Some Track is Playing'
|
8
|
+
}
|
9
|
+
end
|
10
|
+
# Specify our filename - this is messy because it's relative to the gem.
|
11
|
+
def svg_filename
|
12
|
+
return "#{File.expand_path(File.dirname(File.dirname(File.dirname(File.dirname(__FILE__)))))}/templates/now-playing-slide.svg"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
7
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
10
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
11
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
12
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
13
|
+
width="640"
|
14
|
+
height="480"
|
15
|
+
id="svg4824"
|
16
|
+
version="1.1"
|
17
|
+
inkscape:version="0.48.2 r9819"
|
18
|
+
sodipodi:docname="now-playing-slide.svg">
|
19
|
+
<title
|
20
|
+
id="title4836">RadioVIS Generator Default Slide</title>
|
21
|
+
<defs
|
22
|
+
id="defs4826">
|
23
|
+
<linearGradient
|
24
|
+
id="linearGradient6807">
|
25
|
+
<stop
|
26
|
+
style="stop-color:#333333;stop-opacity:1;"
|
27
|
+
offset="0"
|
28
|
+
id="stop6809" />
|
29
|
+
<stop
|
30
|
+
style="stop-color:#333333;stop-opacity:0.71428573;"
|
31
|
+
offset="1"
|
32
|
+
id="stop6811" />
|
33
|
+
</linearGradient>
|
34
|
+
<linearGradient
|
35
|
+
inkscape:collect="always"
|
36
|
+
xlink:href="#linearGradient6807"
|
37
|
+
id="linearGradient6815"
|
38
|
+
x1="19.112589"
|
39
|
+
y1="972.36218"
|
40
|
+
x2="620.88739"
|
41
|
+
y2="972.36218"
|
42
|
+
gradientUnits="userSpaceOnUse"
|
43
|
+
spreadMethod="pad"
|
44
|
+
gradientTransform="matrix(0.2,0,0,5.0000001,908.36218,-5181.8111)" />
|
45
|
+
<linearGradient
|
46
|
+
inkscape:collect="always"
|
47
|
+
xlink:href="#linearGradient6807-5"
|
48
|
+
id="linearGradient6815-7"
|
49
|
+
x1="19.112589"
|
50
|
+
y1="972.36218"
|
51
|
+
x2="620.88739"
|
52
|
+
y2="972.36218"
|
53
|
+
gradientUnits="userSpaceOnUse"
|
54
|
+
spreadMethod="pad"
|
55
|
+
gradientTransform="matrix(0.2,0,0,5.0000001,908.36218,-5181.8111)" />
|
56
|
+
<linearGradient
|
57
|
+
id="linearGradient6807-5">
|
58
|
+
<stop
|
59
|
+
style="stop-color:#333333;stop-opacity:1;"
|
60
|
+
offset="0"
|
61
|
+
id="stop6809-7" />
|
62
|
+
<stop
|
63
|
+
style="stop-color:#333333;stop-opacity:0.71428573;"
|
64
|
+
offset="1"
|
65
|
+
id="stop6811-8" />
|
66
|
+
</linearGradient>
|
67
|
+
<linearGradient
|
68
|
+
y2="972.36218"
|
69
|
+
x2="620.88739"
|
70
|
+
y1="972.36218"
|
71
|
+
x1="19.112589"
|
72
|
+
spreadMethod="pad"
|
73
|
+
gradientTransform="matrix(0.13333332,0,0,5.0000001,589.6955,-5181.8111)"
|
74
|
+
gradientUnits="userSpaceOnUse"
|
75
|
+
id="linearGradient6834"
|
76
|
+
xlink:href="#linearGradient6807-5"
|
77
|
+
inkscape:collect="always" />
|
78
|
+
</defs>
|
79
|
+
<sodipodi:namedview
|
80
|
+
id="base"
|
81
|
+
pagecolor="#ffffff"
|
82
|
+
bordercolor="#666666"
|
83
|
+
borderopacity="1.0"
|
84
|
+
inkscape:pageopacity="0.0"
|
85
|
+
inkscape:pageshadow="2"
|
86
|
+
inkscape:zoom="0.7"
|
87
|
+
inkscape:cx="197.53061"
|
88
|
+
inkscape:cy="151.88693"
|
89
|
+
inkscape:document-units="px"
|
90
|
+
inkscape:current-layer="layer1"
|
91
|
+
showgrid="true"
|
92
|
+
inkscape:window-width="1122"
|
93
|
+
inkscape:window-height="722"
|
94
|
+
inkscape:window-x="25"
|
95
|
+
inkscape:window-y="25"
|
96
|
+
inkscape:window-maximized="0">
|
97
|
+
<inkscape:grid
|
98
|
+
type="xygrid"
|
99
|
+
id="grid4834"
|
100
|
+
empspacing="5"
|
101
|
+
visible="true"
|
102
|
+
enabled="true"
|
103
|
+
snapvisiblegridlinesonly="true" />
|
104
|
+
</sodipodi:namedview>
|
105
|
+
<metadata
|
106
|
+
id="metadata4829">
|
107
|
+
<rdf:RDF>
|
108
|
+
<cc:Work
|
109
|
+
rdf:about="">
|
110
|
+
<dc:format>image/svg+xml</dc:format>
|
111
|
+
<dc:type
|
112
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
113
|
+
<dc:title>RadioVIS Generator Default Slide</dc:title>
|
114
|
+
<dc:creator>
|
115
|
+
<cc:Agent>
|
116
|
+
<dc:title>James Harrison</dc:title>
|
117
|
+
</cc:Agent>
|
118
|
+
</dc:creator>
|
119
|
+
<dc:rights>
|
120
|
+
<cc:Agent>
|
121
|
+
<dc:title>Creative Commons C0</dc:title>
|
122
|
+
</cc:Agent>
|
123
|
+
</dc:rights>
|
124
|
+
</cc:Work>
|
125
|
+
</rdf:RDF>
|
126
|
+
</metadata>
|
127
|
+
<g
|
128
|
+
inkscape:label="Layer 1"
|
129
|
+
inkscape:groupmode="layer"
|
130
|
+
id="layer1"
|
131
|
+
transform="translate(0,-572.36218)">
|
132
|
+
<rect
|
133
|
+
style="fill:url(#linearGradient6834);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.44928122;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
134
|
+
id="rect4838-2"
|
135
|
+
width="80"
|
136
|
+
height="600"
|
137
|
+
x="592.36218"
|
138
|
+
y="-620"
|
139
|
+
transform="matrix(0,1,-1,0,0,0)" />
|
140
|
+
<text
|
141
|
+
xml:space="preserve"
|
142
|
+
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff8000;fill-opacity:1;stroke:none;font-family:Sans"
|
143
|
+
x="40"
|
144
|
+
y="652.36218"
|
145
|
+
id="text5348-7"
|
146
|
+
sodipodi:linespacing="125%"><tspan
|
147
|
+
sodipodi:role="line"
|
148
|
+
id="tspan5350-8"
|
149
|
+
x="40"
|
150
|
+
y="652.36218"
|
151
|
+
style="font-size:48px;fill:#ff8000;fill-opacity:1">$$STATIONNAME$$</tspan></text>
|
152
|
+
</g>
|
153
|
+
</svg>
|
@@ -0,0 +1,75 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
7
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
10
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
11
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
12
|
+
width="640"
|
13
|
+
height="480"
|
14
|
+
id="svg4824"
|
15
|
+
version="1.1"
|
16
|
+
inkscape:version="0.48.2 r9819"
|
17
|
+
sodipodi:docname="New document 23">
|
18
|
+
<title
|
19
|
+
id="title4836">RadioVIS Generator Default Slide</title>
|
20
|
+
<defs
|
21
|
+
id="defs4826" />
|
22
|
+
<sodipodi:namedview
|
23
|
+
id="base"
|
24
|
+
pagecolor="#ffffff"
|
25
|
+
bordercolor="#666666"
|
26
|
+
borderopacity="1.0"
|
27
|
+
inkscape:pageopacity="0.0"
|
28
|
+
inkscape:pageshadow="2"
|
29
|
+
inkscape:zoom="0.35"
|
30
|
+
inkscape:cx="-66.428571"
|
31
|
+
inkscape:cy="520"
|
32
|
+
inkscape:document-units="px"
|
33
|
+
inkscape:current-layer="layer1"
|
34
|
+
showgrid="true"
|
35
|
+
inkscape:window-width="1122"
|
36
|
+
inkscape:window-height="722"
|
37
|
+
inkscape:window-x="25"
|
38
|
+
inkscape:window-y="25"
|
39
|
+
inkscape:window-maximized="0">
|
40
|
+
<inkscape:grid
|
41
|
+
type="xygrid"
|
42
|
+
id="grid4834"
|
43
|
+
empspacing="5"
|
44
|
+
visible="true"
|
45
|
+
enabled="true"
|
46
|
+
snapvisiblegridlinesonly="true" />
|
47
|
+
</sodipodi:namedview>
|
48
|
+
<metadata
|
49
|
+
id="metadata4829">
|
50
|
+
<rdf:RDF>
|
51
|
+
<cc:Work
|
52
|
+
rdf:about="">
|
53
|
+
<dc:format>image/svg+xml</dc:format>
|
54
|
+
<dc:type
|
55
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
56
|
+
<dc:title>RadioVIS Generator Default Slide</dc:title>
|
57
|
+
<dc:creator>
|
58
|
+
<cc:Agent>
|
59
|
+
<dc:title>James Harrison</dc:title>
|
60
|
+
</cc:Agent>
|
61
|
+
</dc:creator>
|
62
|
+
<dc:rights>
|
63
|
+
<cc:Agent>
|
64
|
+
<dc:title>Creative Commons C0</dc:title>
|
65
|
+
</cc:Agent>
|
66
|
+
</dc:rights>
|
67
|
+
</cc:Work>
|
68
|
+
</rdf:RDF>
|
69
|
+
</metadata>
|
70
|
+
<g
|
71
|
+
inkscape:label="Layer 1"
|
72
|
+
inkscape:groupmode="layer"
|
73
|
+
id="layer1"
|
74
|
+
transform="translate(0,-572.36218)" />
|
75
|
+
</svg>
|
@@ -0,0 +1,173 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
7
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
10
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
11
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
12
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
13
|
+
width="640"
|
14
|
+
height="480"
|
15
|
+
id="svg4824"
|
16
|
+
version="1.1"
|
17
|
+
inkscape:version="0.48.2 r9819"
|
18
|
+
sodipodi:docname="now-playing-slide.svg">
|
19
|
+
<title
|
20
|
+
id="title4836">RadioVIS Generator Default Slide</title>
|
21
|
+
<defs
|
22
|
+
id="defs4826">
|
23
|
+
<linearGradient
|
24
|
+
id="linearGradient6807">
|
25
|
+
<stop
|
26
|
+
style="stop-color:#333333;stop-opacity:1;"
|
27
|
+
offset="0"
|
28
|
+
id="stop6809" />
|
29
|
+
<stop
|
30
|
+
style="stop-color:#333333;stop-opacity:0.71428573;"
|
31
|
+
offset="1"
|
32
|
+
id="stop6811" />
|
33
|
+
</linearGradient>
|
34
|
+
<linearGradient
|
35
|
+
inkscape:collect="always"
|
36
|
+
xlink:href="#linearGradient6807"
|
37
|
+
id="linearGradient6815"
|
38
|
+
x1="19.112589"
|
39
|
+
y1="972.36218"
|
40
|
+
x2="620.88739"
|
41
|
+
y2="972.36218"
|
42
|
+
gradientUnits="userSpaceOnUse"
|
43
|
+
spreadMethod="pad"
|
44
|
+
gradientTransform="matrix(0.2,0,0,5.0000001,908.36218,-5181.8111)" />
|
45
|
+
<linearGradient
|
46
|
+
inkscape:collect="always"
|
47
|
+
xlink:href="#linearGradient6807-5"
|
48
|
+
id="linearGradient6815-7"
|
49
|
+
x1="19.112589"
|
50
|
+
y1="972.36218"
|
51
|
+
x2="620.88739"
|
52
|
+
y2="972.36218"
|
53
|
+
gradientUnits="userSpaceOnUse"
|
54
|
+
spreadMethod="pad"
|
55
|
+
gradientTransform="matrix(0.2,0,0,5.0000001,908.36218,-5181.8111)" />
|
56
|
+
<linearGradient
|
57
|
+
id="linearGradient6807-5">
|
58
|
+
<stop
|
59
|
+
style="stop-color:#333333;stop-opacity:1;"
|
60
|
+
offset="0"
|
61
|
+
id="stop6809-7" />
|
62
|
+
<stop
|
63
|
+
style="stop-color:#333333;stop-opacity:0.71428573;"
|
64
|
+
offset="1"
|
65
|
+
id="stop6811-8" />
|
66
|
+
</linearGradient>
|
67
|
+
<linearGradient
|
68
|
+
y2="972.36218"
|
69
|
+
x2="620.88739"
|
70
|
+
y1="972.36218"
|
71
|
+
x1="19.112589"
|
72
|
+
spreadMethod="pad"
|
73
|
+
gradientTransform="matrix(0.13333332,0,0,5.0000001,589.6955,-5181.8111)"
|
74
|
+
gradientUnits="userSpaceOnUse"
|
75
|
+
id="linearGradient6834"
|
76
|
+
xlink:href="#linearGradient6807-5"
|
77
|
+
inkscape:collect="always" />
|
78
|
+
</defs>
|
79
|
+
<sodipodi:namedview
|
80
|
+
id="base"
|
81
|
+
pagecolor="#ffffff"
|
82
|
+
bordercolor="#666666"
|
83
|
+
borderopacity="1.0"
|
84
|
+
inkscape:pageopacity="0.0"
|
85
|
+
inkscape:pageshadow="2"
|
86
|
+
inkscape:zoom="0.7"
|
87
|
+
inkscape:cx="197.53061"
|
88
|
+
inkscape:cy="151.88693"
|
89
|
+
inkscape:document-units="px"
|
90
|
+
inkscape:current-layer="layer1"
|
91
|
+
showgrid="true"
|
92
|
+
inkscape:window-width="1122"
|
93
|
+
inkscape:window-height="722"
|
94
|
+
inkscape:window-x="25"
|
95
|
+
inkscape:window-y="25"
|
96
|
+
inkscape:window-maximized="0">
|
97
|
+
<inkscape:grid
|
98
|
+
type="xygrid"
|
99
|
+
id="grid4834"
|
100
|
+
empspacing="5"
|
101
|
+
visible="true"
|
102
|
+
enabled="true"
|
103
|
+
snapvisiblegridlinesonly="true" />
|
104
|
+
</sodipodi:namedview>
|
105
|
+
<metadata
|
106
|
+
id="metadata4829">
|
107
|
+
<rdf:RDF>
|
108
|
+
<cc:Work
|
109
|
+
rdf:about="">
|
110
|
+
<dc:format>image/svg+xml</dc:format>
|
111
|
+
<dc:type
|
112
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
113
|
+
<dc:title>RadioVIS Generator Default Slide</dc:title>
|
114
|
+
<dc:creator>
|
115
|
+
<cc:Agent>
|
116
|
+
<dc:title>James Harrison</dc:title>
|
117
|
+
</cc:Agent>
|
118
|
+
</dc:creator>
|
119
|
+
<dc:rights>
|
120
|
+
<cc:Agent>
|
121
|
+
<dc:title>Creative Commons C0</dc:title>
|
122
|
+
</cc:Agent>
|
123
|
+
</dc:rights>
|
124
|
+
</cc:Work>
|
125
|
+
</rdf:RDF>
|
126
|
+
</metadata>
|
127
|
+
<g
|
128
|
+
inkscape:label="Layer 1"
|
129
|
+
inkscape:groupmode="layer"
|
130
|
+
id="layer1"
|
131
|
+
transform="translate(0,-572.36218)">
|
132
|
+
<rect
|
133
|
+
style="fill:url(#linearGradient6815);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.77499986;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
134
|
+
id="rect4838"
|
135
|
+
width="120"
|
136
|
+
height="600"
|
137
|
+
x="912.36218"
|
138
|
+
y="-620"
|
139
|
+
transform="matrix(0,1,-1,0,0,0)" />
|
140
|
+
<text
|
141
|
+
xml:space="preserve"
|
142
|
+
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
|
143
|
+
x="40"
|
144
|
+
y="952.36218"
|
145
|
+
id="text5348"
|
146
|
+
sodipodi:linespacing="125%"><tspan
|
147
|
+
sodipodi:role="line"
|
148
|
+
id="tspan5350"
|
149
|
+
x="40"
|
150
|
+
y="952.36218"
|
151
|
+
style="font-size:32px;fill:#ffffff">$$NOWPLAYING$$</tspan></text>
|
152
|
+
<rect
|
153
|
+
style="fill:url(#linearGradient6834);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.44928122;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
154
|
+
id="rect4838-2"
|
155
|
+
width="80"
|
156
|
+
height="600"
|
157
|
+
x="592.36218"
|
158
|
+
y="-620"
|
159
|
+
transform="matrix(0,1,-1,0,0,0)" />
|
160
|
+
<text
|
161
|
+
xml:space="preserve"
|
162
|
+
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff8000;fill-opacity:1;stroke:none;font-family:Sans"
|
163
|
+
x="40"
|
164
|
+
y="652.36218"
|
165
|
+
id="text5348-7"
|
166
|
+
sodipodi:linespacing="125%"><tspan
|
167
|
+
sodipodi:role="line"
|
168
|
+
id="tspan5350-8"
|
169
|
+
x="40"
|
170
|
+
y="652.36218"
|
171
|
+
style="font-size:48px;fill:#ff8000;fill-opacity:1">$$STATIONNAME$$</tspan></text>
|
172
|
+
</g>
|
173
|
+
</svg>
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: radiovis-generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- James Harrison
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2012-04-09 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: trollop
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: stomp
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
description: An extendable gem to generate slide images and text for RadioVIS systems and publish them in an intelligent rotation
|
47
|
+
email: james@talkunafraid.co.uk
|
48
|
+
executables:
|
49
|
+
- radiovis-generator
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files: []
|
53
|
+
|
54
|
+
files:
|
55
|
+
- lib/radiovis-generator/slide.rb
|
56
|
+
- lib/radiovis-generator/slides/branding_slide.rb
|
57
|
+
- lib/radiovis-generator/slides/now_playing_slide.rb
|
58
|
+
- lib/radiovis-generator.rb
|
59
|
+
- templates/empty-slide.svg
|
60
|
+
- templates/now-playing-slide.svg
|
61
|
+
- templates/branding-slide.svg
|
62
|
+
- README.md
|
63
|
+
- bin/radiovis-generator
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: http://jamesharrison.github.com/radiovis-generator
|
66
|
+
licenses:
|
67
|
+
- Modified BSD
|
68
|
+
post_install_message: Thanks for installing! Please do visit http://jamesharrison.github.com/radiovis-generator and carefully read the documentation.
|
69
|
+
rdoc_options: []
|
70
|
+
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
requirements:
|
90
|
+
- ImageMagick v6 or better, Inkscape
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 1.3.7
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: A RadioVIS slide generator
|
96
|
+
test_files: []
|
97
|
+
|