Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
a48ab93b08 | |||
daa41ac8e4 | |||
0927a00960 | |||
39ce636c0a | |||
f361e47e75 | |||
46e4e5c079 | |||
39ebf6a535 | |||
0d854b026a | |||
a9c4b29935 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -59,6 +59,9 @@ build-iPhoneSimulator/
|
||||
# Local database storage
|
||||
data/stgm.db
|
||||
|
||||
# Local configuration
|
||||
config/config.yaml
|
||||
|
||||
# Node modules for Grunt.js
|
||||
node_modules/
|
||||
|
||||
|
3
Gemfile
3
Gemfile
@ -12,5 +12,6 @@ gem 'kramdown', '~> 2.4'
|
||||
gem 'pandoc-ruby', '~> 2.1'
|
||||
|
||||
# Use rerun gem to auto-reload app
|
||||
gem 'rerun'
|
||||
gem 'guard-rack'
|
||||
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
||||
|
||||
|
35
Gemfile.lock
35
Gemfile.lock
@ -1,17 +1,42 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
coderay (1.1.3)
|
||||
ffi (1.15.5)
|
||||
ffi (1.15.5-x64-mingw-ucrt)
|
||||
formatador (1.1.0)
|
||||
guard (2.18.0)
|
||||
formatador (>= 0.2.4)
|
||||
listen (>= 2.7, < 4.0)
|
||||
lumberjack (>= 1.0.12, < 2.0)
|
||||
nenv (~> 0.1)
|
||||
notiffany (~> 0.0)
|
||||
pry (>= 0.13.0)
|
||||
shellany (~> 0.0)
|
||||
thor (>= 0.18.1)
|
||||
guard-rack (2.2.1)
|
||||
ffi
|
||||
guard (~> 2.3)
|
||||
spoon
|
||||
kramdown (2.4.0)
|
||||
rexml
|
||||
listen (3.8.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
lumberjack (1.2.8)
|
||||
method_source (1.0.0)
|
||||
multi_json (1.15.0)
|
||||
mustermann (3.0.0)
|
||||
ruby2_keywords (~> 0.0.1)
|
||||
nenv (0.3.0)
|
||||
nio4r (2.5.8)
|
||||
notiffany (0.1.3)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
pandoc-ruby (2.1.7)
|
||||
pry (0.14.2)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
puma (6.1.1)
|
||||
nio4r (~> 2.0)
|
||||
rack (2.2.6.2)
|
||||
@ -20,11 +45,10 @@ GEM
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rerun (0.14.0)
|
||||
listen (~> 3.0)
|
||||
rexml (3.2.5)
|
||||
ruby2_keywords (0.0.5)
|
||||
sequel (5.66.0)
|
||||
shellany (0.0.1)
|
||||
sinatra (3.0.5)
|
||||
mustermann (~> 3.0)
|
||||
rack (~> 2.2, >= 2.2.4)
|
||||
@ -36,17 +60,22 @@ GEM
|
||||
rack-protection (= 3.0.5)
|
||||
sinatra (= 3.0.5)
|
||||
tilt (~> 2.0)
|
||||
spoon (0.0.6)
|
||||
ffi
|
||||
sqlite3 (1.6.1-x64-mingw-ucrt)
|
||||
sqlite3 (1.6.1-x86_64-linux)
|
||||
thor (1.2.1)
|
||||
tilt (2.1.0)
|
||||
|
||||
PLATFORMS
|
||||
x64-mingw-ucrt
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
guard-rack
|
||||
kramdown (~> 2.4)
|
||||
pandoc-ruby (~> 2.1)
|
||||
puma (~> 6.1)
|
||||
rerun
|
||||
sequel (~> 5.66)
|
||||
sinatra (~> 3.0)
|
||||
sinatra-contrib (~> 3.0)
|
||||
|
6
Guardfile
Normal file
6
Guardfile
Normal file
@ -0,0 +1,6 @@
|
||||
guard 'rack' do
|
||||
watch('Gemfile.lock')
|
||||
watch('config.ru')
|
||||
watch('server.rb')
|
||||
watch(%r{^(app)/.*})
|
||||
end
|
6
Rakefile
6
Rakefile
@ -15,11 +15,11 @@ namespace :db do
|
||||
end
|
||||
|
||||
namespace :server do
|
||||
task :dev do
|
||||
%x{ruby server.rb}
|
||||
task :start do
|
||||
system("bundle exec puma -C config/puma.rb")
|
||||
end
|
||||
|
||||
task :reload do
|
||||
%x{rerun --ignore 'assets/*' --ignore 'public/*' --no-notify 'ruby server.rb'}
|
||||
%x{guard}
|
||||
end
|
||||
end
|
||||
|
@ -2,8 +2,14 @@ require 'yaml'
|
||||
|
||||
class Config
|
||||
|
||||
DEFAULT_CONFIG = 'config/defaults.yaml'
|
||||
|
||||
def initialize(config_path)
|
||||
@data = YAML::load_file(config_path)
|
||||
@data = YAML::load_file(DEFAULT_CONFIG)
|
||||
|
||||
if File.exists?(config_path)
|
||||
@data.merge!(YAML::load_file(config_path))
|
||||
end
|
||||
end
|
||||
|
||||
def get(key, depth = 0)
|
@ -1,4 +1,4 @@
|
||||
helpers do
|
||||
module Helpers
|
||||
|
||||
def nullable(value)
|
||||
if (value) and (value != '')
|
@ -16,7 +16,7 @@ class Channel < Sequel::Model
|
||||
end
|
||||
|
||||
def openProjects()
|
||||
return 0
|
||||
return self.videos_dataset.exclude(status: 'published').exclude(archived: true).all()
|
||||
end
|
||||
|
||||
end
|
19
app/routes/api_v1.rb
Normal file
19
app/routes/api_v1.rb
Normal file
@ -0,0 +1,19 @@
|
||||
class StageManager
|
||||
class ApiV1Controller
|
||||
|
||||
get '/health' do
|
||||
json :status => 'success'
|
||||
end
|
||||
|
||||
get '/channels' do
|
||||
channels = Channel.all().map!(&:to_hash)
|
||||
json channels
|
||||
end
|
||||
|
||||
get '/videos' do
|
||||
videos = Video.all().map!(&:to_hash)
|
||||
json videos
|
||||
end
|
||||
|
||||
end
|
||||
end
|
97
app/routes/channel.rb
Normal file
97
app/routes/channel.rb
Normal file
@ -0,0 +1,97 @@
|
||||
class StageManager
|
||||
class ChannelController
|
||||
|
||||
get '/' do
|
||||
redirect '/channel/list'
|
||||
end
|
||||
get '/list' do
|
||||
channels = Channel.reverse(:updated_at).all()
|
||||
erb :'channel/list', :locals => {
|
||||
:title => 'List of channels',
|
||||
:channels => channels
|
||||
}
|
||||
end
|
||||
|
||||
get '/create' do
|
||||
erb :'channel/create', :locals => {
|
||||
:title => 'Create new channel',
|
||||
:base_directory => $conf.get('stgm.base_directory')
|
||||
}
|
||||
end
|
||||
post '/create' do
|
||||
channel = Channel.create(
|
||||
name: params[:channel_name],
|
||||
directory_path: params[:channel_dir],
|
||||
description: params[:channel_description]
|
||||
)
|
||||
|
||||
# create supporting directory structure
|
||||
Dir.mkdir(channel.directory_path)
|
||||
channel.ensureDirectoryStructure()
|
||||
|
||||
redirect "/channel/#{channel.id}"
|
||||
end
|
||||
|
||||
get '/:channel_id' do
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
channel_videos = channel.videos_dataset.reverse(:updated_at).limit(10).all()
|
||||
erb :'channel/view', :locals => {
|
||||
:title => channel.name,
|
||||
:channel => channel,
|
||||
:channel_videos => channel_videos
|
||||
}
|
||||
end
|
||||
|
||||
get '/:channel_id/edit' do
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
erb :'channel/edit', :locals => {
|
||||
:title => "Editing: #{channel.name}",
|
||||
:channel => channel
|
||||
}
|
||||
end
|
||||
post '/:channel_id/edit' do
|
||||
# get channel model and save old directory path
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
old_path = channel.directory_path
|
||||
|
||||
# edit channel model
|
||||
channel.update(
|
||||
name: params[:channel_name],
|
||||
directory_path: params[:channel_dir],
|
||||
description: params[:channel_description]
|
||||
)
|
||||
|
||||
# edit associate videos' directory paths
|
||||
channel.videos.each do |v|
|
||||
video_path = v.directory_path.sub(old_path, channel.directory_path)
|
||||
v.update(directory_path: video_path)
|
||||
end
|
||||
|
||||
# rename channel directory
|
||||
File.rename(old_path, channel.directory_path)
|
||||
|
||||
# redirect user
|
||||
redirect "/channel/#{channel.id}"
|
||||
end
|
||||
|
||||
post '/:channel_id/edit/:attr' do
|
||||
# find channel and temporarily save the old channel path
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
attrToEdit = params[:attr]
|
||||
|
||||
if attrToEdit == 'directory_path'
|
||||
File.rename(channel.directory_path, params[:value])
|
||||
channel.videos.each do |v|
|
||||
video_path = v.directory_path.sub(channel.directory_path, params[:value])
|
||||
v.update(directory_path: video_path)
|
||||
end
|
||||
end
|
||||
|
||||
channel[attrToEdit.to_sym] = params[:value]
|
||||
channel.save()
|
||||
|
||||
return "success"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
15
app/routes/index.rb
Normal file
15
app/routes/index.rb
Normal file
@ -0,0 +1,15 @@
|
||||
class StageManager
|
||||
class IndexController
|
||||
|
||||
get '/' do
|
||||
channels = Channel.reverse(:updated_at).limit(10).all()
|
||||
videos = Video.reverse(:updated_at).limit(10).all()
|
||||
erb :index, :locals => {
|
||||
:title => 'Dashboard',
|
||||
:channels => channels,
|
||||
:videos => videos
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
193
app/routes/video.rb
Normal file
193
app/routes/video.rb
Normal file
@ -0,0 +1,193 @@
|
||||
require 'fileutils'
|
||||
|
||||
class StageManager
|
||||
class VideoController
|
||||
|
||||
get '/' do
|
||||
redirect '/video/list'
|
||||
end
|
||||
get '/list' do
|
||||
videos = Video.reverse(:updated_at).all()
|
||||
erb :'video/list', :locals => {
|
||||
:title => 'List of videos',
|
||||
:videos => videos
|
||||
}
|
||||
end
|
||||
|
||||
get '/create' do
|
||||
# check if there's a channel specified
|
||||
selected_channel = false
|
||||
if params.has_key?(:channel)
|
||||
selected_channel = params[:channel].to_i()
|
||||
end
|
||||
|
||||
channels = Channel.all()
|
||||
erb :'video/create', :locals => {
|
||||
:title => 'Create new video',
|
||||
:channels => channels,
|
||||
:selected_channel => selected_channel
|
||||
}
|
||||
end
|
||||
post '/create' do
|
||||
channel = Channel.where(id: params[:video_channel]).first()
|
||||
video_serial = params[:video_serial].to_s.rjust(4, '0')
|
||||
video_path = File.join(
|
||||
channel.directory_path,
|
||||
'Main',
|
||||
"##{video_serial} - #{params[:video_name]}"
|
||||
)
|
||||
|
||||
video = Video.create(
|
||||
serial: params[:video_serial],
|
||||
name: params[:video_name],
|
||||
channel_id: params[:video_channel],
|
||||
directory_path: video_path,
|
||||
description: params[:video_description],
|
||||
script: "# Introduction\n\n# Body\n\n# Conclusions"
|
||||
)
|
||||
|
||||
# create supporting directory structure
|
||||
Dir.mkdir(video_path)
|
||||
video.ensureDirectoryStructure()
|
||||
|
||||
redirect "/video/#{video.id}"
|
||||
end
|
||||
|
||||
get '/:video_id' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
erb :'video/view', :locals => {
|
||||
:title => video.name,
|
||||
:video => video
|
||||
}
|
||||
end
|
||||
|
||||
get '/:video_id/script' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
erb :'video/script', :locals => {
|
||||
:title => "Script: #{video.name}",
|
||||
:video => video
|
||||
}
|
||||
end
|
||||
|
||||
get '/:video_id/edit' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
channels = Channel.all()
|
||||
erb :'video/edit', :locals => {
|
||||
:title => "Editing: #{video.name}",
|
||||
:video => video,
|
||||
:channels => channels
|
||||
}
|
||||
end
|
||||
post '/:video_id/edit' do
|
||||
channel = Channel.where(id: params[:video_channel]).first()
|
||||
video_serial = params[:video_serial].to_s.rjust(4, '0')
|
||||
video_path = File.join(
|
||||
channel.directory_path,
|
||||
'Main',
|
||||
"##{video_serial} - #{params[:video_name]}"
|
||||
)
|
||||
|
||||
# find video and temporarily save the old video path
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
old_path = video.directory_path
|
||||
|
||||
# edit video attributes
|
||||
video.update(
|
||||
name: params[:video_name],
|
||||
serial: params[:video_serial],
|
||||
channel_id: params[:video_channel],
|
||||
directory_path: video_path,
|
||||
description: params[:video_description]
|
||||
)
|
||||
|
||||
# rename the video project directory
|
||||
File.rename(old_path, video_path)
|
||||
|
||||
# redirect the user
|
||||
redirect "/video/#{video.id}"
|
||||
end
|
||||
|
||||
post '/:video_id/edit/:attr' do
|
||||
# find video and temporarily save the old video path
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
attrToEdit = params[:attr]
|
||||
|
||||
# if we update the video's serial, we need to also update the directory path
|
||||
if attrToEdit == 'serial'
|
||||
old_path = video.directory_path
|
||||
new_path = video.directory_path.sub("##{video.serial}", "##{params[:value]}")
|
||||
File.rename(old_path, new_path)
|
||||
video[:directory_path] = new_path
|
||||
end
|
||||
|
||||
video[attrToEdit.to_sym] = params[:value]
|
||||
video.save()
|
||||
|
||||
return "success"
|
||||
end
|
||||
|
||||
get '/:video_id/archive' do
|
||||
# find the video
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
video_base = File.basename(video.directory_path)
|
||||
|
||||
# move project to channel's archive
|
||||
archive_dir = File.join(
|
||||
video.channel.directory_path,
|
||||
'Archive',
|
||||
video_base
|
||||
)
|
||||
FileUtils.mv(video.directory_path, archive_dir)
|
||||
|
||||
# mark the video as archived and update directory
|
||||
video.update(
|
||||
directory_path: archive_dir,
|
||||
archived: true
|
||||
)
|
||||
|
||||
redirect '/video/' + video.id.to_s()
|
||||
end
|
||||
get '/:video_id/unarchive' do
|
||||
# find the video
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
video_base = File.basename(video.directory_path)
|
||||
|
||||
# move project to channel's archive
|
||||
active_dir = File.join(
|
||||
video.channel.directory_path,
|
||||
'Main',
|
||||
video_base
|
||||
)
|
||||
FileUtils.mv(video.directory_path, active_dir)
|
||||
|
||||
# mark the video as archived and update directory
|
||||
video.update(
|
||||
directory_path: active_dir,
|
||||
archived: false
|
||||
)
|
||||
|
||||
redirect '/video/' + video.id.to_s()
|
||||
end
|
||||
|
||||
get '/:video_id/edit/script' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
erb :'video/edit-script', :locals => {
|
||||
:title => "Editing script: #{video.name}",
|
||||
:video => video
|
||||
}
|
||||
end
|
||||
post '/:video_id/edit/script' do
|
||||
# find video and temporarily save the old video path
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
|
||||
# edit video attributes
|
||||
video.update(
|
||||
script: params[:video_script]
|
||||
)
|
||||
|
||||
# redirect the user
|
||||
redirect "/video/#{video.id}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -1,41 +1,31 @@
|
||||
$(document).ready(() ->
|
||||
$('.channel-path').click((e) ->
|
||||
newPath = prompt('New channel directory path', $(this).find('span').text())
|
||||
if newPath
|
||||
payload =
|
||||
directory_path: newPath
|
||||
channelId = $('#channel-id').val()
|
||||
$.post('/channel/' + channelId + '/edit/directory_path', payload, (data) ->
|
||||
if data == 'success'
|
||||
$('.channel-path span').text(newPath)
|
||||
)
|
||||
)
|
||||
$('.channel-path').click(updateAttribute)
|
||||
|
||||
$('.video-status').click((e) ->
|
||||
newStatus = prompt('New video status', $(this).find('span').text())
|
||||
if newStatus
|
||||
newStatus = newStatus.toLowerCase()
|
||||
payload =
|
||||
status: newStatus
|
||||
videoId = $('#video-id').val()
|
||||
$.post('/video/' + videoId + '/edit/status', payload, (data) ->
|
||||
if data == 'success'
|
||||
$('.video-status span').text(capitalizeWord(newStatus))
|
||||
)
|
||||
)
|
||||
$('.video-status').click(updateAttribute)
|
||||
|
||||
$('.video-serial').click((e) ->
|
||||
newSerial = prompt('New video serial number', $(this).find('span').text())
|
||||
if newSerial
|
||||
payload =
|
||||
serial: newSerial
|
||||
videoId = $('#video-id').val()
|
||||
$.post('/video/' + videoId + '/edit/serial', payload, (data) ->
|
||||
if data == 'success'
|
||||
$('.video-serial span').text(newSerial)
|
||||
)
|
||||
)
|
||||
$('.video-serial').click(updateAttribute)
|
||||
)
|
||||
|
||||
updateAttribute = (e) ->
|
||||
elem = $(this)
|
||||
type = elem.data('type')
|
||||
attr = elem.data('attribute')
|
||||
newValue = prompt('Enter new ' + type + ' ' + attr + ':', elem.find('span').text())
|
||||
if newValue
|
||||
if attr == 'status'
|
||||
newValue = newValue.toLowerCase()
|
||||
payload =
|
||||
value: newValue
|
||||
objectId = $('#' + type + '-id').val()
|
||||
url = '/' + type + '/' + objectId + '/edit/' + attr
|
||||
$.post(url, payload, (data) ->
|
||||
if data == 'success'
|
||||
if attr == 'status'
|
||||
newValue = capitalizeWord(newValue)
|
||||
elem.find('span').text(newValue)
|
||||
)
|
||||
else
|
||||
console.log('User canceled attribute "' + attr + '" update.')
|
||||
|
||||
capitalizeWord = (str) ->
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
|
9
config.ru
Normal file
9
config.ru
Normal file
@ -0,0 +1,9 @@
|
||||
# Load application config
|
||||
require_relative 'app/config.rb'
|
||||
$conf = Config.new(File.join(__dir__, 'config/config.yaml'))
|
||||
|
||||
# Load Sinatra server
|
||||
require_relative './server.rb'
|
||||
|
||||
# Run application
|
||||
run StageManager
|
@ -1,6 +1,10 @@
|
||||
stgm:
|
||||
base_directory: '/srv/videos'
|
||||
|
||||
server:
|
||||
address: '127.0.0.1'
|
||||
port: 4567
|
||||
|
||||
database:
|
||||
adapter: 'sqlite'
|
||||
database: 'data/stgm.db'
|
6
config/puma.rb
Normal file
6
config/puma.rb
Normal file
@ -0,0 +1,6 @@
|
||||
# Load application config
|
||||
require './app/config.rb'
|
||||
$conf = Config.new(File.join(__dir__, 'config/config.yaml'))
|
||||
|
||||
bind_address = "tcp://#{$conf.get('server.address')}:#{$conf.get('server.port')}"
|
||||
bind bind_address
|
@ -1,95 +0,0 @@
|
||||
namespace '/channel' do
|
||||
|
||||
get '' do
|
||||
redirect '/channel/list'
|
||||
end
|
||||
get '/list' do
|
||||
channels = Channel.reverse(:updated_at).all()
|
||||
erb :'channel/list', :locals => {
|
||||
:title => 'List of channels',
|
||||
:channels => channels
|
||||
}
|
||||
end
|
||||
|
||||
get '/create' do
|
||||
erb :'channel/create', :locals => {
|
||||
:title => 'Create new channel',
|
||||
:base_directory => $conf.get('stgm.base_directory')
|
||||
}
|
||||
end
|
||||
post '/create' do
|
||||
channel = Channel.create(
|
||||
name: params[:channel_name],
|
||||
directory_path: params[:channel_dir],
|
||||
description: params[:channel_description]
|
||||
)
|
||||
|
||||
# create supporting directory structure
|
||||
Dir.mkdir(channel.directory_path)
|
||||
channel.ensureDirectoryStructure()
|
||||
|
||||
redirect "/channel/#{channel.id}"
|
||||
end
|
||||
|
||||
get '/:channel_id' do
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
channel_videos = channel.videos_dataset.reverse(:updated_at).limit(10).all()
|
||||
erb :'channel/view', :locals => {
|
||||
:title => channel.name,
|
||||
:channel => channel,
|
||||
:channel_videos => channel_videos
|
||||
}
|
||||
end
|
||||
|
||||
get '/:channel_id/edit' do
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
erb :'channel/edit', :locals => {
|
||||
:title => "Editing: #{channel.name}",
|
||||
:channel => channel
|
||||
}
|
||||
end
|
||||
post '/:channel_id/edit' do
|
||||
# get channel model and save old directory path
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
old_path = channel.directory_path
|
||||
|
||||
# edit channel model
|
||||
channel.update(
|
||||
name: params[:channel_name],
|
||||
directory_path: params[:channel_dir],
|
||||
description: params[:channel_description]
|
||||
)
|
||||
|
||||
# edit associate videos' directory paths
|
||||
channel.videos.each do |v|
|
||||
video_path = v.directory_path.sub(old_path, channel.directory_path)
|
||||
v.update(directory_path: video_path)
|
||||
end
|
||||
|
||||
# rename channel directory
|
||||
File.rename(old_path, channel.directory_path)
|
||||
|
||||
# redirect user
|
||||
redirect "/channel/#{channel.id}"
|
||||
end
|
||||
|
||||
post '/:channel_id/edit/:attr' do
|
||||
# find channel and temporarily save the old channel path
|
||||
channel = Channel.where(id: params[:channel_id]).first()
|
||||
attrToEdit = params[:attr]
|
||||
|
||||
if attrToEdit == 'directory_path'
|
||||
File.rename(channel.directory_path, params[attrToEdit])
|
||||
channel.videos.each do |v|
|
||||
video_path = v.directory_path.sub(channel.directory_path, params[attrToEdit])
|
||||
v.update(directory_path: video_path)
|
||||
end
|
||||
end
|
||||
|
||||
channel[attrToEdit.to_sym] = params[attrToEdit]
|
||||
channel.save()
|
||||
|
||||
return "success"
|
||||
end
|
||||
|
||||
end
|
@ -1,14 +0,0 @@
|
||||
namespace '/' do
|
||||
|
||||
get '' do
|
||||
channels = Channel.reverse(:updated_at).limit(10).all()
|
||||
videos = Video.reverse(:updated_at).limit(10).all()
|
||||
erb :index, :locals => {
|
||||
:title => 'Dashboard',
|
||||
:channels => channels,
|
||||
:videos => videos
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,183 +0,0 @@
|
||||
require 'fileutils'
|
||||
|
||||
namespace '/video' do
|
||||
|
||||
get '' do
|
||||
redirect '/video/list'
|
||||
end
|
||||
get '/list' do
|
||||
videos = Video.reverse(:updated_at).all()
|
||||
erb :'video/list', :locals => {
|
||||
:title => 'List of videos',
|
||||
:videos => videos
|
||||
}
|
||||
end
|
||||
|
||||
get '/create' do
|
||||
# check if there's a channel specified
|
||||
selected_channel = false
|
||||
if params.has_key?(:channel)
|
||||
selected_channel = params[:channel].to_i()
|
||||
end
|
||||
|
||||
channels = Channel.all()
|
||||
erb :'video/create', :locals => {
|
||||
:title => 'Create new video',
|
||||
:channels => channels,
|
||||
:selected_channel => selected_channel
|
||||
}
|
||||
end
|
||||
post '/create' do
|
||||
channel = Channel.where(id: params[:video_channel]).first()
|
||||
video_serial = params[:video_serial].to_s.rjust(4, '0')
|
||||
video_path = File.join(
|
||||
channel.directory_path,
|
||||
'Main',
|
||||
"##{video_serial} - #{params[:video_name]}"
|
||||
)
|
||||
|
||||
video = Video.create(
|
||||
serial: params[:video_serial],
|
||||
name: params[:video_name],
|
||||
channel_id: params[:video_channel],
|
||||
directory_path: video_path,
|
||||
description: params[:video_description],
|
||||
script: "# Introduction\n\n# Body\n\n# Conclusions"
|
||||
)
|
||||
|
||||
# create supporting directory structure
|
||||
Dir.mkdir(video_path)
|
||||
video.ensureDirectoryStructure()
|
||||
|
||||
redirect "/video/#{video.id}"
|
||||
end
|
||||
|
||||
get '/:video_id' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
erb :'video/view', :locals => {
|
||||
:title => video.name,
|
||||
:video => video
|
||||
}
|
||||
end
|
||||
|
||||
get '/:video_id/script' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
erb :'video/script', :locals => {
|
||||
:title => "Script: #{video.name}",
|
||||
:video => video
|
||||
}
|
||||
end
|
||||
|
||||
get '/:video_id/edit' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
channels = Channel.all()
|
||||
erb :'video/edit', :locals => {
|
||||
:title => "Editing: #{video.name}",
|
||||
:video => video,
|
||||
:channels => channels
|
||||
}
|
||||
end
|
||||
post '/:video_id/edit' do
|
||||
channel = Channel.where(id: params[:video_channel]).first()
|
||||
video_serial = params[:video_serial].to_s.rjust(4, '0')
|
||||
video_path = File.join(
|
||||
channel.directory_path,
|
||||
'Main',
|
||||
"##{video_serial} - #{params[:video_name]}"
|
||||
)
|
||||
|
||||
# find video and temporarily save the old video path
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
old_path = video.directory_path
|
||||
|
||||
# edit video attributes
|
||||
video.update(
|
||||
name: params[:video_name],
|
||||
serial: params[:video_serial],
|
||||
channel_id: params[:video_channel],
|
||||
directory_path: video_path,
|
||||
description: params[:video_description]
|
||||
)
|
||||
|
||||
# rename the video project directory
|
||||
File.rename(old_path, video_path)
|
||||
|
||||
# redirect the user
|
||||
redirect "/video/#{video.id}"
|
||||
end
|
||||
|
||||
post '/:video_id/edit/:attr' do
|
||||
# find video and temporarily save the old video path
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
attrToEdit = params[:attr]
|
||||
|
||||
video[attrToEdit.to_sym] = params[attrToEdit]
|
||||
video.save()
|
||||
|
||||
return "success"
|
||||
end
|
||||
|
||||
get '/:video_id/archive' do
|
||||
# find the video
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
video_base = File.basename(video.directory_path)
|
||||
|
||||
# move project to channel's archive
|
||||
archive_dir = File.join(
|
||||
video.channel.directory_path,
|
||||
'Archive',
|
||||
video_base
|
||||
)
|
||||
FileUtils.mv(video.directory_path, archive_dir)
|
||||
|
||||
# mark the video as archived and update directory
|
||||
video.update(
|
||||
directory_path: archive_dir,
|
||||
archived: true
|
||||
)
|
||||
|
||||
redirect '/video/' + video.id.to_s()
|
||||
end
|
||||
get '/:video_id/unarchive' do
|
||||
# find the video
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
video_base = File.basename(video.directory_path)
|
||||
|
||||
# move project to channel's archive
|
||||
active_dir = File.join(
|
||||
video.channel.directory_path,
|
||||
'Main',
|
||||
video_base
|
||||
)
|
||||
FileUtils.mv(video.directory_path, active_dir)
|
||||
|
||||
# mark the video as archived and update directory
|
||||
video.update(
|
||||
directory_path: active_dir,
|
||||
archived: false
|
||||
)
|
||||
|
||||
redirect '/video/' + video.id.to_s()
|
||||
end
|
||||
|
||||
get '/:video_id/edit/script' do
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
erb :'video/edit-script', :locals => {
|
||||
:title => "Editing script: #{video.name}",
|
||||
:video => video
|
||||
}
|
||||
end
|
||||
post '/:video_id/edit/script' do
|
||||
# find video and temporarily save the old video path
|
||||
video = Video.where(id: params[:video_id]).first()
|
||||
|
||||
# edit video attributes
|
||||
video.update(
|
||||
script: params[:video_script]
|
||||
)
|
||||
|
||||
# redirect the user
|
||||
redirect "/video/#{video.id}"
|
||||
end
|
||||
|
||||
end
|
68
server.rb
68
server.rb
@ -1,32 +1,58 @@
|
||||
require 'logger'
|
||||
require 'sequel'
|
||||
require 'sqlite3'
|
||||
require 'sinatra'
|
||||
require 'sinatra/namespace'
|
||||
|
||||
require_relative 'lib/config.rb'
|
||||
|
||||
set :public_folder, __dir__ + '/public'
|
||||
|
||||
set :views, settings.root + '/views'
|
||||
|
||||
# Load configuration file
|
||||
$conf = Config.new(File.join(__dir__, 'data/defaults.yaml'))
|
||||
|
||||
# Initialize logging
|
||||
logger = Logger.new(STDOUT)
|
||||
logger.level = Logger::INFO
|
||||
require 'sinatra/base'
|
||||
require 'sinatra/json'
|
||||
require 'rack/protection'
|
||||
|
||||
# Load the Sequel timestamps plugin
|
||||
Sequel::Model.plugin :timestamps
|
||||
# Initialize Sequel gem for database actions
|
||||
DB = Sequel.connect(adapter: $conf.get('database.adapter'), database: $conf.get('database.database'))
|
||||
# Load models
|
||||
require_relative 'lib/models/channel.rb'
|
||||
require_relative 'lib/models/video.rb'
|
||||
Dir.glob('./app/models/*.rb').each { |f| require f }
|
||||
|
||||
# Load helper functions
|
||||
require_relative 'lib/helpers.rb'
|
||||
class StageManager < Sinatra::Base
|
||||
@@my_app = {}
|
||||
def self.new(*) self < StageManager ? super : Rack::URLMap.new(@@my_app) end
|
||||
def self.map(url) @@my_app[url] = self end
|
||||
|
||||
# Register route handlers
|
||||
require_relative 'lib/routes.rb'
|
||||
# Enable and configure sessions
|
||||
enable :sessions
|
||||
|
||||
# Enable rack protection middleware
|
||||
use Rack::Protection
|
||||
|
||||
# Set up static file serving
|
||||
enable :static
|
||||
set :public_folder, __dir__ + '/public'
|
||||
|
||||
# Set up our view engine
|
||||
set :views, settings.root + '/views'
|
||||
|
||||
# Initialize logging
|
||||
logger = Logger.new(STDOUT)
|
||||
logger.level = Logger::INFO
|
||||
|
||||
# Load helper functions
|
||||
require_relative 'app/helpers.rb'
|
||||
helpers Helpers
|
||||
|
||||
# Map controllers
|
||||
class IndexController < StageManager
|
||||
map '/'
|
||||
end
|
||||
class ChannelController < StageManager
|
||||
map '/channel'
|
||||
end
|
||||
class VideoController < StageManager
|
||||
map '/video'
|
||||
end
|
||||
# API controllers
|
||||
class ApiV1Controller < StageManager
|
||||
map '/api/v1'
|
||||
end
|
||||
end
|
||||
|
||||
# Load controllers
|
||||
Dir.glob('./app/routes/*.rb').each { |f| require f }
|
||||
|
@ -16,11 +16,11 @@
|
||||
<span><a href="/channel/<%= channel.id %>/edit">Edit <i class="fa-solid fa-pen-to-square"></i></a></span><span>
|
||||
<a href="/channel/<%= channel.id %>/delete">Delete <i class="fa-solid fa-trash"></i></a></span>
|
||||
</div>
|
||||
<div class="channel-path">
|
||||
<div class="channel-path" data-attribute="directory_path" data-type="channel">
|
||||
<p><span><%= channel.directory_path %></span></p>
|
||||
</div>
|
||||
<div class="channel-open">
|
||||
<p>Open projects: <span><%= channel.openProjects() %></span></p>
|
||||
<p>Open projects: <span><%= channel.openProjects().length %></span></p>
|
||||
</div>
|
||||
<div class="channel-videos">
|
||||
<p>Total videos: <span><%= channel.videos.length %></span></p>
|
||||
|
@ -42,7 +42,7 @@
|
||||
<% channels.each do |c| %>
|
||||
<tr>
|
||||
<td><a href="/channel/<%= c.id %>"><%= c.name %></a></td>
|
||||
<td><%= nullable(c.openProjects) %></td>
|
||||
<td><%= nullable(c.openProjects().length) %></td>
|
||||
<td><%= nullable(c.videos.length) %></td>
|
||||
<td><%= date_format(c.updated_at) %></td>
|
||||
</tr>
|
||||
|
@ -18,10 +18,10 @@
|
||||
<div class="video-channel">
|
||||
<p>Channel: <a href="/channel/<%= video.channel.id %>"><span><%= video.channel.name %></span></a></p>
|
||||
</div>
|
||||
<div class="video-serial">
|
||||
<div class="video-serial" data-attribute="serial" data-type="video">
|
||||
<p>Serial: <span><%= serialize(video.serial) %></span></p>
|
||||
</div>
|
||||
<div class="video-status">
|
||||
<div class="video-status" data-attribute="status" data-type="video">
|
||||
<p>Status: <span><%= video.status.capitalize() %></span></p>
|
||||
</div>
|
||||
<div class="script-controls">
|
||||
|
Reference in New Issue
Block a user