chili_videos 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +1 -0
- data/.autotest +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +33 -0
- data/History.txt +4 -0
- data/LICENSE +20 -0
- data/Manifest.txt +63 -0
- data/README.md +169 -0
- data/Rakefile +45 -0
- data/app/controllers/videos_controller.rb +72 -0
- data/app/helpers/videos_helper.rb +34 -0
- data/app/models/assembly.rb +62 -0
- data/app/models/assembly_observer.rb +6 -0
- data/app/models/assembly_processor.rb +16 -0
- data/app/models/video.rb +24 -0
- data/app/views/settings/_settings.html.erb +13 -0
- data/app/views/videos/edit.html.erb +32 -0
- data/app/views/videos/index.html.erb +37 -0
- data/app/views/videos/new.html.erb +41 -0
- data/app/views/videos/plugin_not_configured.html.erb +6 -0
- data/app/views/videos/show.html.erb +40 -0
- data/app/views/videos/upload_complete.html.erb +7 -0
- data/assets/player.swf +0 -0
- data/assets/readme.html +84 -0
- data/assets/stylesheets/forms.css +7 -0
- data/assets/stylesheets/videos.css +76 -0
- data/assets/swfobject.js +8 -0
- data/assets/yt.swf +0 -0
- data/autotest/discover.rb +4 -0
- data/bin/delayed_job +23 -0
- data/config/locales/en.yml +15 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20110301025054_create_videos.rb +15 -0
- data/db/migrate/20110309060901_create_assemblies.rb +14 -0
- data/db/migrate/20110314022354_create_delayed_jobs.rb +21 -0
- data/db/migrate/20110402043115_create_slugs.rb +18 -0
- data/db/migrate/20110402053931_add_slug_cache_to_videos.rb +11 -0
- data/init.rb +63 -0
- data/lang/en.yml +16 -0
- data/lib/chili_videos.rb +18 -0
- data/lib/chili_videos/config.rb +40 -0
- data/lib/chili_videos/error.rb +5 -0
- data/lib/tasks/chili_videos_tasks.rb +112 -0
- data/lib/tasks/contributor_tasks.rb +64 -0
- data/lib/tasks/delayed_job.rake +6 -0
- data/lib/tasks/friendly_id.rake +19 -0
- data/lib/video_project_patch.rb +10 -0
- data/lib/video_user_patch.rb +10 -0
- data/lib/video_version_patch.rb +9 -0
- data/rails/delayed_job +25 -0
- data/rails/init.rb +1 -0
- data/test/fixtures/incomplete_assembly.json +9 -0
- data/test/fixtures/single_video_processed_assembly.json +9 -0
- data/test/fixtures/standard_transloadit_response.json +6 -0
- data/test/functional/videos_controller_test.rb +232 -0
- data/test/integration/project_video_list_test.rb +104 -0
- data/test/integration/project_video_uploading_test.rb +56 -0
- data/test/integration/viewing_project_video_test.rb +74 -0
- data/test/test_helper.rb +77 -0
- data/test/unit/assembly_processor_test.rb +57 -0
- data/test/unit/assembly_test.rb +95 -0
- data/test/unit/chili_video_plugin/config_test.rb +49 -0
- data/test/unit/chili_video_plugin_test.rb +30 -0
- data/test/unit/video_test.rb +26 -0
- metadata +279 -0
- metadata.gz.sig +0 -0
data/assets/swfobject.js
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
/**
|
2
|
+
* SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
|
3
|
+
*
|
4
|
+
* SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
|
5
|
+
* http://www.opensource.org/licenses/mit-license.php
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;
|
data/assets/yt.swf
ADDED
Binary file
|
data/bin/delayed_job
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- ruby -*-
|
3
|
+
require 'rubygems'
|
4
|
+
require 'daemon_spawn'
|
5
|
+
|
6
|
+
class DelayedJobWorker < DaemonSpawn::Base
|
7
|
+
def start(args)
|
8
|
+
ENV['RAILS_ENV'] ||= args.first || 'development'
|
9
|
+
Dir.chdir ENV['RAILS_ROOT']
|
10
|
+
require File.join('config', 'environment')
|
11
|
+
|
12
|
+
Delayed::Worker.new.start
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop
|
16
|
+
system("kill `cat #{ENV['RAILS_ROOT']}/tmp/pids/delayed_job.pid`")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
DelayedJobWorker.spawn!(:log_file => File.join(ENV['RAILS_ROOT'], "log", "delayed_job.log"),
|
21
|
+
:pid_file => File.join(ENV['RAILS_ROOT'], 'tmp', 'pids', 'delayed_job.pid'),
|
22
|
+
:sync_log => true,
|
23
|
+
:working_dir => ENV['RAILS_ROOT'])
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# English strings go here for Rails i18n
|
2
|
+
en:
|
3
|
+
permission_view_video_list: View video list
|
4
|
+
permission_view_specific_video: View specific video
|
5
|
+
permission_modify_videos: Modify videos
|
6
|
+
permission_delete_video: Delete videos
|
7
|
+
permission_add_video: Add videos
|
8
|
+
transloadit_video_directions: Enter the Transload.it API key and the workflow you would like to use below.
|
9
|
+
transloadit_api_key_label: Transload.it API key
|
10
|
+
transloadit_workflow_label: Workflow
|
11
|
+
new_video_label: Add video
|
12
|
+
delete_video_label: Delete this video
|
13
|
+
edit_video_label: Edit this video
|
14
|
+
confirm_video_deletion: Are you sure you want to delete this video?
|
15
|
+
video_deleted_message: "Booyah! The requested video has been deleted."
|
data/config/routes.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateVideos < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :videos do |t|
|
4
|
+
t.column :title, :string
|
5
|
+
t.column :description, :text
|
6
|
+
t.column :url, :text
|
7
|
+
t.integer :project_id, :user_id, :version_id, :duration, :height, :width
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :videos
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateAssemblies < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :assemblies do |t|
|
4
|
+
t.integer :project_id, :unsigned => true
|
5
|
+
t.integer :user_id, :unsigned => true
|
6
|
+
t.string :assembly_id, :assembly_url
|
7
|
+
t.boolean :processed
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
drop_table :assemblies
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateDelayedJobs < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :delayed_jobs, :force => true do |table|
|
4
|
+
table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
|
5
|
+
table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
|
6
|
+
table.text :handler # YAML-encoded string of the object that will do work
|
7
|
+
table.text :last_error # reason for last failure (See Note below)
|
8
|
+
table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
|
9
|
+
table.datetime :locked_at # Set when a client is working on this object
|
10
|
+
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
|
11
|
+
table.string :locked_by # Who is working on this object (if locked)
|
12
|
+
table.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :delayed_jobs
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateSlugs < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :slugs do |t|
|
4
|
+
t.string :name
|
5
|
+
t.integer :sluggable_id
|
6
|
+
t.integer :sequence, :null => false, :default => 1
|
7
|
+
t.string :sluggable_type, :limit => 40
|
8
|
+
t.string :scope
|
9
|
+
t.datetime :created_at
|
10
|
+
end
|
11
|
+
add_index :slugs, :sluggable_id
|
12
|
+
add_index :slugs, [:name, :sluggable_type, :sequence, :scope], :name => "index_slugs_on_n_s_s_and_s", :unique => true
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :slugs
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AddSlugCacheToVideos < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :videos, :cached_slug, :string
|
4
|
+
add_index :videos, :cached_slug, :unique => true
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_index :videos, :column => :cached_slug
|
9
|
+
remove_column :videos, :cached_slug
|
10
|
+
end
|
11
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'redmine'
|
2
|
+
require 'chili_videos'
|
3
|
+
|
4
|
+
# Patches to the Redmine core.
|
5
|
+
require 'dispatcher'
|
6
|
+
require 'videos_helper'
|
7
|
+
|
8
|
+
Dispatcher.to_prepare :question_plugin do
|
9
|
+
require_dependency 'project'
|
10
|
+
Project.send(:include, VideoProjectPatch) unless Project.included_modules.include? VideoProjectPatch
|
11
|
+
|
12
|
+
require_dependency 'user'
|
13
|
+
User.send(:include, VideoUserPatch) unless User.included_modules.include? VideoUserPatch
|
14
|
+
|
15
|
+
require_dependency 'version'
|
16
|
+
Version.send(:include, VideoVersionPatch) unless Version.included_modules.include? VideoVersionPatch
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
Redmine::Plugin.register :chili_videos do
|
21
|
+
name 'Chili Videos plugin'
|
22
|
+
author 'Tom Kersten'
|
23
|
+
description 'Adds support for using the Transload.it service to transcode videos and associate them with projects.'
|
24
|
+
version ChiliVideos::VERSION
|
25
|
+
url 'http://example.com/path/to/plugin'
|
26
|
+
author_url 'http://tomkersten.com/'
|
27
|
+
|
28
|
+
project_module :videos do
|
29
|
+
permission :view_video_list, :videos => :index
|
30
|
+
permission :view_specific_video, :videos => :show
|
31
|
+
permission :modify_videos, :videos => [:edit,:update]
|
32
|
+
permission :delete_video, :videos => :destroy
|
33
|
+
permission :add_video, :videos => [:new, :create, :upload_complete]
|
34
|
+
end
|
35
|
+
|
36
|
+
settings :default => {:transloadit_api_key => '', :transloadit_workflow => ''}, :partial => 'settings/settings'
|
37
|
+
|
38
|
+
menu :project_menu, :videos, { :controller => 'videos', :action => 'index' }, :caption => 'Videos', :param => :project_id
|
39
|
+
|
40
|
+
ActiveRecord::Base.observers << :assembly_observer
|
41
|
+
end
|
42
|
+
|
43
|
+
Redmine::WikiFormatting::Macros.register do
|
44
|
+
desc "Embeds a flv file into flash video player.\n" +
|
45
|
+
"Usage examples:\n\n" +
|
46
|
+
" !{{video(id)}}\n"
|
47
|
+
macro :video do |o, args|
|
48
|
+
video_id = args[0]
|
49
|
+
size = args[1] || :standard
|
50
|
+
|
51
|
+
video = Video.find(video_id)
|
52
|
+
if video
|
53
|
+
file_url = video.url
|
54
|
+
else
|
55
|
+
file_url = "im_not_a_video"
|
56
|
+
end
|
57
|
+
|
58
|
+
<<END
|
59
|
+
<div class="video-cell large" id="video_#{video.to_param}"></div>
|
60
|
+
#{VideosHelper.video_embed_code(video, size)}
|
61
|
+
END
|
62
|
+
end
|
63
|
+
end
|
data/lang/en.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
permission_view_video_list: View video list
|
4
|
+
permission_view_specific_video: View specific video
|
5
|
+
permission_modify_videos: Modify videos
|
6
|
+
permission_delete_video: Delete videos
|
7
|
+
permission_add_video: Add videos
|
8
|
+
transloadit_video_directions: Enter the Transload.it API key and the workflow you would like to use below.
|
9
|
+
transloadit_api_key_label: Transload.it API key
|
10
|
+
transloadit_workflow_label: Workflow
|
11
|
+
default_video_title: (none provided)
|
12
|
+
new_video_label: Add video
|
13
|
+
delete_video_label: Delete this video
|
14
|
+
edit_video_label: Edit this video
|
15
|
+
confirm_video_deletion: Are you sure you want to delete this video?
|
16
|
+
video_deleted_message: "Booyah! The requested video has been deleted."
|
data/lib/chili_videos.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'hashie'
|
3
|
+
require 'friendly_id'
|
4
|
+
|
5
|
+
require 'delayed_job'
|
6
|
+
Delayed::Worker.backend = :active_record
|
7
|
+
|
8
|
+
require 'chili_videos/config'
|
9
|
+
|
10
|
+
module ChiliVideos
|
11
|
+
extend self
|
12
|
+
|
13
|
+
VERSION = '0.1.0' unless defined?(ChiliVideos::VERSION)
|
14
|
+
|
15
|
+
def configured?
|
16
|
+
!Config.api_key.blank? && !Config.workflow.blank?
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ChiliVideos
|
2
|
+
module Config
|
3
|
+
extend self
|
4
|
+
|
5
|
+
PLUGIN_KEYNAME = 'plugin_chili_videos'
|
6
|
+
API_KEY_KEYNAME = 'transloadit_api_key'
|
7
|
+
WORKFLOW_KEYNAME = 'transloadit_workflow'
|
8
|
+
|
9
|
+
def api_key
|
10
|
+
plugin_settings[API_KEY_KEYNAME]
|
11
|
+
end
|
12
|
+
|
13
|
+
def workflow
|
14
|
+
plugin_settings[WORKFLOW_KEYNAME]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Accepts anything which responds to '[]' and '.has_key?' # (Hash-like objects)
|
18
|
+
#
|
19
|
+
# Requires & utilizes the following keys
|
20
|
+
# - :api_key
|
21
|
+
# - :workflow
|
22
|
+
def update(options)
|
23
|
+
unless options.has_key?(:api_key) && options.has_key?(:workflow)
|
24
|
+
raise ArgumentError, "Missing key(s) in: #{options.inspect}"
|
25
|
+
end
|
26
|
+
Setting[PLUGIN_KEYNAME] = formatted_hash(options[:api_key], options[:workflow])
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def plugin_settings
|
32
|
+
Setting[PLUGIN_KEYNAME]
|
33
|
+
end
|
34
|
+
|
35
|
+
def formatted_hash(api_key, workflow)
|
36
|
+
HashWithIndifferentAccess.new({API_KEY_KEYNAME => api_key,
|
37
|
+
WORKFLOW_KEYNAME => workflow})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
class ChiliVideosTasks < Rake::TaskLib
|
5
|
+
VALID_DJ_ACTIONS = %w(start restart stop status)
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
define
|
9
|
+
end
|
10
|
+
|
11
|
+
def define
|
12
|
+
namespace :chili_videos do
|
13
|
+
desc "Install ChiliVideos plugin (migrate database, include assets, etc)"
|
14
|
+
task :install => [:migrate_db, :symlink_assets]
|
15
|
+
|
16
|
+
desc "Uninstalls ChiliVideos plugin (removes database modifications, removes assets, etc)"
|
17
|
+
task :uninstall => [:environment] do
|
18
|
+
puts "Removing ChiliVideos database modifications..."
|
19
|
+
migrate_db(:to_version => 0)
|
20
|
+
|
21
|
+
puts "Removing link to ChiliVideo assets (stylesheets, js, etc)..."
|
22
|
+
remove_symlink asset_destination_dir
|
23
|
+
|
24
|
+
puts post_uninstall_steps
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Manage delayed_job...requires argument [ACTION=(#{VALID_DJ_ACTIONS.join('|')})]"
|
28
|
+
task :delayed_job, :action, :needs => [:environment] do |task, args|
|
29
|
+
unless(args[:action] && VALID_DJ_ACTIONS.include?(args[:action]))
|
30
|
+
puts "'ACTION' is a required parameter. Valid values are: #{VALID_DJ_ACTIONS.join(', ')}"
|
31
|
+
exit(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
shell_command = "RAILS_ROOT='#{application_root}' RAILS_ENV=#{RAILS_ENV} #{File.expand_path(delayed_job_path)} #{args[:action]}"
|
35
|
+
puts "Issuing '#{args[:action]}' command to delayed_job executable (bundled with ChiliVideos)"
|
36
|
+
sh shell_command do |ok, status|
|
37
|
+
ok || fail("Command failed (status: #{status}) (command: '#{shell_command}')")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :migrate_db => [:environment] do
|
42
|
+
puts "Migrating chili_videos-#{ChiliVideos::VERSION}..."
|
43
|
+
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
44
|
+
ActiveRecord::Migrator.migrate(gem_db_migrate_dir, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
45
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
46
|
+
end
|
47
|
+
|
48
|
+
task :symlink_assets => [:environment] do
|
49
|
+
# HACK: Symlinks the files from plugindir/assets to the appropriate place in
|
50
|
+
# the rails application
|
51
|
+
puts "Symlinking assets (stylesheets, etc)..."
|
52
|
+
add_symlink asset_source_dir, asset_destination_dir
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def application_root
|
59
|
+
File.expand_path(RAILS_ROOT)
|
60
|
+
end
|
61
|
+
|
62
|
+
def gem_root
|
63
|
+
@gem_root ||= File.expand_path(File.dirname(__FILE__) + "/../..")
|
64
|
+
end
|
65
|
+
|
66
|
+
def asset_destination_dir
|
67
|
+
@destination_dir ||= File.expand_path("#{application_root}/public/plugin_assets/chili_videos")
|
68
|
+
end
|
69
|
+
|
70
|
+
def asset_source_dir
|
71
|
+
@source_dir ||= File.expand_path(gem_root + "/assets")
|
72
|
+
end
|
73
|
+
|
74
|
+
def gem_db_migrate_dir
|
75
|
+
@gem_db_migrate_dir ||= File.expand_path(gem_root + "/db/migrate")
|
76
|
+
end
|
77
|
+
|
78
|
+
def delayed_job_path
|
79
|
+
@delayed_job_path ||= File.expand_path(gem_root + "/bin/delayed_job")
|
80
|
+
end
|
81
|
+
|
82
|
+
def remove_symlink(symlink_file)
|
83
|
+
system("unlink #{symlink_file}") if File.exists?(symlink_file)
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_symlink(source, destination)
|
87
|
+
remove_symlink destination
|
88
|
+
system("ln -s #{source} #{destination}")
|
89
|
+
end
|
90
|
+
|
91
|
+
def migrate_db(options = {})
|
92
|
+
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
93
|
+
ActiveRecord::Migrator.migrate(gem_db_migrate_dir, options[:to_version])
|
94
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
95
|
+
end
|
96
|
+
|
97
|
+
def post_uninstall_steps
|
98
|
+
[
|
99
|
+
"!!!!! MANUAL STEPS !!!!!",
|
100
|
+
"\t1. In your 'config/environment.rb', remove:",
|
101
|
+
"\t\tconfig.gem 'chili_videos'",
|
102
|
+
"",
|
103
|
+
"\t2. In your 'Rakefile', remove:",
|
104
|
+
"\t\trequire 'chili_videos'",
|
105
|
+
"\t\trequire 'tasks/chili_videos_tasks'",
|
106
|
+
"\t\tChiliVideosTasks.new",
|
107
|
+
"",
|
108
|
+
"\t3. Cycle your application server (mongrel, unicorn, etc)",
|
109
|
+
"\n",
|
110
|
+
].join("\n")
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
class ContributorTasks < Rake::TaskLib
|
5
|
+
def initialize
|
6
|
+
define
|
7
|
+
end
|
8
|
+
|
9
|
+
def define
|
10
|
+
desc "Update contributors list in README"
|
11
|
+
task :update_contributors do
|
12
|
+
if new_contributors?
|
13
|
+
puts "New contributors!"
|
14
|
+
new_contributors.each {|name| puts "- #{name}"}
|
15
|
+
puts ""
|
16
|
+
|
17
|
+
print "Updating the 'Contributors' section of README..."
|
18
|
+
|
19
|
+
File.open("README.md", "w+") do |file|
|
20
|
+
file.puts readme_without_contributors_section
|
21
|
+
file.puts "## Contributors (sorted alphabetically)"
|
22
|
+
file.puts ""
|
23
|
+
committers.each {|name| file.puts "* #{name}"}
|
24
|
+
end
|
25
|
+
puts "done!"
|
26
|
+
else
|
27
|
+
puts "No new contributors."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def all_committers
|
34
|
+
all_names = `git shortlog -s |cut -s -f2`
|
35
|
+
all_names.gsub!(/\sand\s/, "\n").split("\n").uniq!.sort!
|
36
|
+
end
|
37
|
+
|
38
|
+
def committers
|
39
|
+
excluded_committers = ["Tom Kersten"]
|
40
|
+
@committers ||= all_committers - excluded_committers
|
41
|
+
end
|
42
|
+
|
43
|
+
def readme_file_contents
|
44
|
+
@readme_contents ||= `cat README.md`
|
45
|
+
end
|
46
|
+
|
47
|
+
def existing_contributors
|
48
|
+
existing_contributors = readme_file_contents[/## Contributors(.|\n)*/].strip.split("\n* ")
|
49
|
+
existing_contributors.shift # remove "Contributors..." line
|
50
|
+
existing_contributors
|
51
|
+
end
|
52
|
+
|
53
|
+
def new_contributors
|
54
|
+
@new_contributors ||= committers - existing_contributors
|
55
|
+
end
|
56
|
+
|
57
|
+
def new_contributors?
|
58
|
+
!new_contributors.empty?
|
59
|
+
end
|
60
|
+
|
61
|
+
def readme_without_contributors_section
|
62
|
+
readme_file_contents.sub(/## Contributors(.|\n)*/, '')
|
63
|
+
end
|
64
|
+
end
|