From f361e47e759e9caedca41da8f1385e64810c74f5 Mon Sep 17 00:00:00 2001 From: Gregory Ballantine Date: Thu, 9 Mar 2023 21:37:33 -0500 Subject: [PATCH] Migrated to a modular Sinatra application --- Gemfile.lock | 2 - Guardfile | 1 + config.ru | 7 +- lib/helpers.rb | 2 +- lib/routes/channel.rb | 164 ++++++++++---------- lib/routes/index.rb | 23 +-- lib/routes/video.rb | 346 +++++++++++++++++++++--------------------- server.rb | 47 ++++-- 8 files changed, 309 insertions(+), 283 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6da35e5..0008e01 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,7 +66,6 @@ GEM sqlite3 (1.6.1-x86_64-linux) thor (1.2.1) tilt (2.1.0) - wdm (0.1.1) PLATFORMS x64-mingw-ucrt @@ -81,7 +80,6 @@ DEPENDENCIES sinatra (~> 3.0) sinatra-contrib (~> 3.0) sqlite3 (~> 1.6) - wdm (>= 0.1.0) BUNDLED WITH 2.3.5 diff --git a/Guardfile b/Guardfile index d1111a6..af5d78c 100644 --- a/Guardfile +++ b/Guardfile @@ -1,5 +1,6 @@ guard 'rack' do watch('Gemfile.lock') + watch('config.ru') watch('server.rb') watch(%r{^(lib)/.*}) end \ No newline at end of file diff --git a/config.ru b/config.ru index 21e2b15..14a0874 100644 --- a/config.ru +++ b/config.ru @@ -1,2 +1,5 @@ -require_relative './server' -run Sinatra::Application +# Load Sinatra server +require_relative './server.rb' + +# Run application +run StageManager diff --git a/lib/helpers.rb b/lib/helpers.rb index 9f9f137..c8291bf 100644 --- a/lib/helpers.rb +++ b/lib/helpers.rb @@ -1,4 +1,4 @@ -helpers do +module Helpers def nullable(value) if (value) and (value != '') diff --git a/lib/routes/channel.rb b/lib/routes/channel.rb index 33dbfad..d04fa00 100644 --- a/lib/routes/channel.rb +++ b/lib/routes/channel.rb @@ -1,95 +1,97 @@ -namespace '/channel' do +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) + 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 - # rename channel directory - File.rename(old_path, channel.directory_path) + 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] + ) - # redirect user - redirect "/channel/#{channel.id}" - end + # create supporting directory structure + Dir.mkdir(channel.directory_path) + channel.ensureDirectoryStructure() - 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] + redirect "/channel/#{channel.id}" + end - if attrToEdit == 'directory_path' - File.rename(channel.directory_path, params[:value]) + 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(channel.directory_path, params[:value]) + 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 - channel[attrToEdit.to_sym] = params[:value] - channel.save() + 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 - return "success" end - end diff --git a/lib/routes/index.rb b/lib/routes/index.rb index f486dbd..8eb3c06 100644 --- a/lib/routes/index.rb +++ b/lib/routes/index.rb @@ -1,14 +1,15 @@ -namespace '/' do +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 - 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 - diff --git a/lib/routes/video.rb b/lib/routes/video.rb index 49ffe5e..e7ab7eb 100644 --- a/lib/routes/video.rb +++ b/lib/routes/video.rb @@ -1,191 +1,193 @@ require 'fileutils' -namespace '/video' do +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() + 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 - 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]}" - ) + 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 - 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" - ) + 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]}" + ) - # create supporting directory structure - Dir.mkdir(video_path) - video.ensureDirectoryStructure() + 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" + ) - redirect "/video/#{video.id}" - end + # create supporting directory structure + Dir.mkdir(video_path) + video.ensureDirectoryStructure() - get '/:video_id' do - video = Video.where(id: params[:video_id]).first() - erb :'video/view', :locals => { - :title => video.name, - :video => video - } - end + redirect "/video/#{video.id}" + 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' do + video = Video.where(id: params[:video_id]).first() + erb :'video/view', :locals => { + :title => 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]}" - ) + get '/:video_id/script' do + video = Video.where(id: params[:video_id]).first() + erb :'video/script', :locals => { + :title => "Script: #{video.name}", + :video => video + } + end - # find video and temporarily save the old video path - video = Video.where(id: params[:video_id]).first() - old_path = video.directory_path + 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]}" + ) - # 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' + # find video and temporarily save the old video path + video = Video.where(id: params[:video_id]).first() 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 + + # 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 - video[attrToEdit.to_sym] = params[:value] - video.save() + 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 - 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 diff --git a/server.rb b/server.rb index 43d0743..64c4371 100644 --- a/server.rb +++ b/server.rb @@ -1,22 +1,13 @@ require 'logger' require 'sequel' require 'sqlite3' -require 'sinatra' -require 'sinatra/namespace' +require 'sinatra/base' 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/config.yaml')) -# Initialize logging -logger = Logger.new(STDOUT) -logger.level = Logger::INFO - # Load the Sequel timestamps plugin Sequel::Model.plugin :timestamps # Initialize Sequel gem for database actions @@ -25,8 +16,36 @@ DB = Sequel.connect(adapter: $conf.get('database.adapter'), database: $conf.get( require_relative 'lib/models/channel.rb' require_relative 'lib/models/video.rb' -# 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 :sessions + + enable :static + set :public_folder, __dir__ + '/public' + + set :views, settings.root + '/views' + + # Initialize logging + logger = Logger.new(STDOUT) + logger.level = Logger::INFO + + # Load helper functions + require_relative 'lib/helpers.rb' + helpers Helpers + + # Map controllers + class IndexController < StageManager + map '/' + end + class ChannelController < StageManager + map '/channel' + end + class VideoController < StageManager + map '/video' + end +end + +Dir.glob('./lib/routes/*.rb').each { |f| require f }