Remove views and replace redis with sequel
This commit is contained in:
		
							parent
							
								
									46179cd27b
								
							
						
					
					
						commit
						eef60a8420
					
				
							
								
								
									
										17
									
								
								db/migrations/0001_create_database.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								db/migrations/0001_create_database.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| Sequel.migration do | ||||
|   change do | ||||
|     create_table(:genres) do | ||||
|       primary_key :id | ||||
|       String :name, null: false | ||||
|     end | ||||
| 
 | ||||
|     create_table(:movies) do | ||||
|       primary_key :id | ||||
|       String :data, text: true, null: false | ||||
|       FalseClass :viewed, null: false, default: false | ||||
|       FalseClass :downloaded, null: false, default: false | ||||
|     end | ||||
| 
 | ||||
|     create_join_table(movie_id: :movies, genre_id: :genres) | ||||
|   end | ||||
| end | ||||
| @ -1,15 +1,11 @@ | ||||
| require 'librarix/version' | ||||
| require 'librarix/redis' | ||||
| require 'librarix/redis/movie' | ||||
| 
 | ||||
| require 'sequel' | ||||
| require 'sqlite3' | ||||
| require 'json' | ||||
| 
 | ||||
| Sequel::Model.plugin :json_serializer | ||||
| Sequel::Model.db = Sequel.sqlite('librarix.sqlite') | ||||
| 
 | ||||
| require 'librarix/models' | ||||
| require 'librarix/application' | ||||
| 
 | ||||
| module Librarix | ||||
|   def self.redis | ||||
|     @redis ||= Librarix::Redis.new(::Redis.new) | ||||
|   end | ||||
| 
 | ||||
|   def self.redis=(connection, namespace: 'librarix') | ||||
|     @redis = Librarix::Redis.new(connection, namespace: namespace) | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -1,31 +1,17 @@ | ||||
| require 'librarix/filter' | ||||
| require 'librarix/menu' | ||||
| require 'librarix/the_movie_db' | ||||
| require 'librarix/helpers' | ||||
| 
 | ||||
| require 'sinatra/base' | ||||
| require 'sinatra/content_for' | ||||
| require 'sinatra/json' | ||||
| require 'sinatra/namespace' | ||||
| 
 | ||||
| require 'yaml' | ||||
| require 'slim' | ||||
| require 'themoviedb' | ||||
| 
 | ||||
| module Librarix | ||||
|   class Application < Sinatra::Application | ||||
|     def initialize(app = nil) | ||||
|       super | ||||
| 
 | ||||
|       Librarix::Menu.menu.add 'Home', '/' | ||||
|       Librarix::Menu.menu.add 'Add a movie', '/search' | ||||
|     end | ||||
| 
 | ||||
|     helpers Librarix::TheMovieDB | ||||
|     helpers Librarix::Menu::Helper | ||||
|     helpers Librarix::Helpers | ||||
| 
 | ||||
|     namespace '/api/v1' do | ||||
|       not_found do | ||||
|         {error: :not_found}.to_json | ||||
|       end | ||||
| 
 | ||||
|       helpers do | ||||
|         def base_url | ||||
|           @base_url ||= "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}" | ||||
| @ -44,101 +30,48 @@ module Librarix | ||||
|         content_type 'application/json' | ||||
|       end | ||||
| 
 | ||||
|       get '/movies' do | ||||
|         Librarix::Filter.new(params).movies.to_json | ||||
|       end | ||||
| 
 | ||||
|       post '/movies' do | ||||
|         id = json_params['tmdb_id'].to_i | ||||
|         movie = Tmdb::Movie.detail(id) | ||||
| 
 | ||||
|         if movie['status_code'] != 34 && !Librarix::Redis::Movie.new(id).added? | ||||
|           Librarix::Redis::Movie.new(id).add.to_json | ||||
|       namespace '/genres' do | ||||
|         get '' do | ||||
|           Librarix::Models::Genre.fetch.to_json | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       get '/movies/:id' do |id| | ||||
|         Librarix::Redis::Movie.new(id).fetch.to_json | ||||
|       end | ||||
|       namespace '/movies' do | ||||
|         get '' do | ||||
|           Librarix::Filter.new(params).movies.to_json | ||||
|         end | ||||
| 
 | ||||
|       get '/movies/:id/fetch' do |id| | ||||
|         Librarix::Redis::Movie.new(id).update | ||||
|       end | ||||
|         post '' do | ||||
|           id = json_params['tmdb_id'].to_i | ||||
|           movie = Tmdb::Movie.detail(id) | ||||
| 
 | ||||
|       patch '/movies/:id/view' do |id| | ||||
|         Librarix::Redis::Movie.new(params[:id]).view | ||||
|       end | ||||
|           if movie['status_code'] != 34 && !Librarix::Redis::Movie.new(id).added? | ||||
|             Librarix::Redis::Movie.new(id).add.to_json | ||||
|           end | ||||
|         end | ||||
| 
 | ||||
|       delete '/movies/:id' do |id| | ||||
|         Librarix::Redis::Movie.new(params[:id]).remove | ||||
|       end | ||||
|     end | ||||
|         get '/:id' do |id| | ||||
|           Librarix::Models::Movie.find(id: id).to_json | ||||
|         end | ||||
| 
 | ||||
|     get '/' do | ||||
|       slim :index, locals: {filter: Librarix::Filter.new(params)} | ||||
|     end | ||||
|         get '/:id/fetch' do |id| | ||||
|           Librarix::Models::Movie.fetch(85).to_json | ||||
|         end | ||||
| 
 | ||||
|     get '/movie/:id' do |id| | ||||
|       movie = Librarix::Redis::Movie.new(id).fetch | ||||
|         patch '/:id/view' do |id| | ||||
|           Librarix::Models::Movie.find(id: id).view! | ||||
|           {success: true}.to_json | ||||
|         end | ||||
| 
 | ||||
|       if request.xhr? | ||||
|         slim :'partials/movie', layout: false, locals: {movie: movie} | ||||
|       else | ||||
|         slim :movie, locals: {movie: movie} | ||||
|       end | ||||
|     end | ||||
|         patch '/:id/download' do |id| | ||||
|           Librarix::Models::Movie.find(id: id).download! | ||||
|           {success: true}.to_json | ||||
|         end | ||||
| 
 | ||||
|     get '/search' do | ||||
|       movies = if params['search'].nil? | ||||
|         Tmdb::Movie.popular.map { |m| Tmdb::Movie.new(m) } | ||||
|       elsif params['search'] == '' | ||||
|         [] | ||||
|       else | ||||
|         Tmdb::Movie.find(params['search']) | ||||
|       end | ||||
| 
 | ||||
|       slim :search, locals: {movies: movies} | ||||
|     end | ||||
| 
 | ||||
|     post '/add' do | ||||
|       id = params[:id].to_i | ||||
|       movie = Tmdb::Movie.detail(id) | ||||
| 
 | ||||
|       if movie['status_code'] == 34 | ||||
|       elsif Librarix::Redis::Movie.new(id).added? | ||||
|       else | ||||
|         Librarix::Redis::Movie.new(id).add | ||||
|       end | ||||
|       redirect to('/') | ||||
|     end | ||||
| 
 | ||||
|     post '/update' do | ||||
|       movie = Librarix::Redis::Movie.new(params[:id]).update | ||||
| 
 | ||||
|       if request.xhr? | ||||
|         slim :'partials/movie', layout: false, locals: {movie: movie} | ||||
|       else | ||||
|         redirect to('/') | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     post '/remove' do | ||||
|       Librarix::Redis::Movie.new(params[:id]).remove | ||||
| 
 | ||||
|       if request.xhr? | ||||
|         "" | ||||
|       else | ||||
|         redirect to('/') | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     post '/view' do | ||||
|       Librarix::Redis::Movie.new(params[:id]).view | ||||
| 
 | ||||
|       if request.xhr? | ||||
|         "" | ||||
|       else | ||||
|         redirect to('/') | ||||
|         delete '/:id' do |id| | ||||
|           Librarix::Models::Movie.find(id: id).destroy | ||||
|           {success: true}.to_json | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  | ||||
| @ -1,117 +0,0 @@ | ||||
| body { | ||||
|   margin: 10px; | ||||
| } | ||||
| 
 | ||||
| a { | ||||
|   text-decoration: none; | ||||
|   color: #666; | ||||
| 
 | ||||
|   &:hover { | ||||
|     color: #888; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| h2 { | ||||
|   margin-top: 0; | ||||
|   overflow: hidden; | ||||
|   text-overflow: ellipsis; | ||||
| 
 | ||||
|   font-size: 1.2em; | ||||
|   font-family: Verdana,Arial,sans-serif; | ||||
| } | ||||
| 
 | ||||
| ul { | ||||
|   list-style-type: none; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| ul#menu { | ||||
|   display: flex; | ||||
|   flex-flow: row wrap; | ||||
|   justify-content: flex-end; | ||||
| 
 | ||||
|   li { | ||||
|     margin: 5px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #search-genres ul { | ||||
|   display: flex; | ||||
|   flex-flow: row wrap; | ||||
| 
 | ||||
|   li { | ||||
|     margin-right: 0.5em; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| ul.genres { | ||||
|   display: flex; | ||||
| 
 | ||||
|   li { | ||||
|     margin-right: 0.4em; | ||||
|   } | ||||
| 
 | ||||
|   li:last-child::after { | ||||
|     content: ''; | ||||
|   } | ||||
| 
 | ||||
|   li::after { | ||||
|     content: ','; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| form #search-main { | ||||
|   display: flex; | ||||
| 
 | ||||
|   input { | ||||
|     border-radius: 0.4em; | ||||
|     border: solid 3px #f4f4f4; | ||||
|   } | ||||
| 
 | ||||
|   input[type="submit"] { | ||||
|     background-color: #f4f4f4; | ||||
|   } | ||||
| 
 | ||||
|   input[type="text"] { | ||||
|     flex-grow: 1; | ||||
|     min-width: 50px; | ||||
|     font-size: 1.4em; | ||||
|     padding: 5px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .default, .compact { | ||||
|   & > li { | ||||
|     padding: 10px 0; | ||||
|   } | ||||
| 
 | ||||
|   & > li:nth-child(even) { | ||||
|     background-color: #f4f4f4; | ||||
|   } | ||||
| 
 | ||||
|   .movie { | ||||
|     display: flex; | ||||
|     flex-flow: row wrap; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
| 
 | ||||
|     .poster { | ||||
|       margin-right: 10px; | ||||
|     } | ||||
| 
 | ||||
|     .informations { | ||||
|       align-self: flex-start; | ||||
|       flex: 1 1 300px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .poster { | ||||
|   display: flex; | ||||
|   flex-flow: row wrap; | ||||
| 
 | ||||
|   .movie { | ||||
|     width: 160px; | ||||
|   } | ||||
| } | ||||
| @ -1,90 +0,0 @@ | ||||
| module Librarix | ||||
|   class Filter | ||||
|     def self.filter_by_genre(movies, genres) | ||||
|       return movies if genres.empty? | ||||
|       movies.reject do |movie| | ||||
|         (movie.genres.map { |genre| genre['name'] } & genres).empty? | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def self.filter_by_title(movies, title) | ||||
|       return movies unless title | ||||
|       movies.select { |movie| movie.title.downcase.include?(title) } | ||||
|     end | ||||
| 
 | ||||
|     def self.filter_by_view_state(movies, view_state) | ||||
|       if view_state == 'viewed' | ||||
|         movies.select(&:viewed?) | ||||
|       elsif view_state == 'not_viewed' | ||||
|         movies.reject(&:viewed?) | ||||
|       else | ||||
|         movies | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def self.sort(movies, sort) | ||||
|       if sort == 'date' | ||||
|         movies.sort_by(&:release_date).reverse | ||||
|       else | ||||
|         movies.sort_by(&:title) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def self.group(movies, group, sort) | ||||
|       return {all: movies} unless group | ||||
| 
 | ||||
|       if sort == 'date' | ||||
|         movies.group_by { |movie| movie.release_date.year } | ||||
|       else | ||||
|         movies.group_by { |movie| movie.title[0].upcase } | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     attr_reader :movies, :params | ||||
| 
 | ||||
|     def initialize(params) | ||||
|       @params = params | ||||
|     end | ||||
| 
 | ||||
|     def movies | ||||
|       @movies ||= begin | ||||
|         movies = Librarix::Redis::Movie.all | ||||
| 
 | ||||
|         movies = self.class.filter_by_genre(movies, genres) | ||||
|         movies = self.class.filter_by_title(movies, params['title']) | ||||
|         movies = self.class.filter_by_view_state(movies, params['view_state']) | ||||
| 
 | ||||
|         movies = self.class.sort(movies, sort) | ||||
|         movies = self.class.group(movies, group, sort) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def group | ||||
|       @group ||= params.key?('group') && params['group'] | ||||
|     end | ||||
| 
 | ||||
|     def genres | ||||
|       @genres ||= params.key?('genres') ? params['genres'].keys : [] | ||||
|     end | ||||
| 
 | ||||
|     def view_state | ||||
|       @view_state ||= if %w{all viewed not_viewed}.include?(params['view_state']) | ||||
|         params['view_state'] | ||||
|       else | ||||
|         'all' | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def sort | ||||
|       @sort ||= if %w{alphabetical date}.include?(params['sort']) | ||||
|         params['sort'] | ||||
|       else | ||||
|         'date' | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def maybe_search? | ||||
|       movies.all? { |k,v| v.empty? } && params.key?('title') | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -1,11 +0,0 @@ | ||||
| module Librarix | ||||
|   module Helpers | ||||
|     def template | ||||
|       if %w{default compact poster}.include?(params['template']) | ||||
|         params['template'] | ||||
|       else | ||||
|         'default' | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -1,56 +0,0 @@ | ||||
| module Librarix | ||||
|   class Menu | ||||
|     module Helper | ||||
|       def menu | ||||
|         Librarix::Menu.menu.render request.path_info | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def self.menu | ||||
|       @menu ||= new | ||||
|     end | ||||
| 
 | ||||
|     attr_accessor :menu | ||||
| 
 | ||||
|     def initialize | ||||
|       self.menu = [] | ||||
|     end | ||||
| 
 | ||||
|     def add(name, url) | ||||
|       self.menu << Element.new(name, url) | ||||
|     end | ||||
| 
 | ||||
|     def render(path = nil) | ||||
|       around menu.map { |elem| elem.render path }.join | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def around(content) | ||||
|       "<ul id=\"menu\">#{content}</ul>" | ||||
|     end | ||||
| 
 | ||||
|     class Element | ||||
|       attr_accessor :name, :url | ||||
| 
 | ||||
|       def initialize(name, url) | ||||
|         self.name = name | ||||
|         self.url = url | ||||
|       end | ||||
| 
 | ||||
|       def render(path = nil) | ||||
|         around "<a href=\"#{url}\">#{name}</a>", path: path | ||||
|       end | ||||
| 
 | ||||
|       def current?(path) | ||||
|         path == url | ||||
|       end | ||||
| 
 | ||||
|       private | ||||
| 
 | ||||
|       def around(element, path: nil) | ||||
|         "<li#{current?(path) ? ' class="active"' : ''}>#{element}</li>" | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
							
								
								
									
										5
									
								
								lib/librarix/models.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								lib/librarix/models.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| module Librarix::Models | ||||
| end | ||||
| 
 | ||||
| require 'librarix/models/genre' | ||||
| require 'librarix/models/movie' | ||||
							
								
								
									
										15
									
								
								lib/librarix/models/genre.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lib/librarix/models/genre.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| class Librarix::Models::Genre < Sequel::Model | ||||
|   def self.fetch | ||||
|     unrestrict_primary_key | ||||
| 
 | ||||
|     genres = Tmdb::Genre.list['genres'] | ||||
|     genres.each do |genre| | ||||
|       find_or_create(id: genre['id']) { |g| g.name = genre['name'] } | ||||
|     end | ||||
| 
 | ||||
|     genres | ||||
|   end | ||||
| 
 | ||||
|   many_to_many :movies | ||||
|   plugin :association_dependencies, movies: :nullify | ||||
| end | ||||
							
								
								
									
										37
									
								
								lib/librarix/models/movie.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/librarix/models/movie.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| class Librarix::Models::Movie < Sequel::Model | ||||
|   def self.fetch(id) | ||||
|     unrestrict_primary_key | ||||
| 
 | ||||
|     movie = find(id: id) || new(id: id) | ||||
|     movie.fetch! | ||||
|   end | ||||
| 
 | ||||
|   plugin :serialization | ||||
|   serialize_attributes :json, :data | ||||
| 
 | ||||
|   many_to_many :genres | ||||
|   plugin :association_dependencies, genres: :nullify | ||||
| 
 | ||||
|   def fetch! | ||||
|     tmdb_data = Tmdb::Movie.detail(id) | ||||
|     self.data = tmdb_data | ||||
|     save | ||||
| 
 | ||||
|     genres_id = data['genres'].map { |g| g['id'] } | ||||
|     Librarix::Models::Genre.where(id: genres_id).all.each do |genre| | ||||
|       add_genre(genre) unless genres.include?(genre) | ||||
|     end | ||||
| 
 | ||||
|     self | ||||
|   end | ||||
| 
 | ||||
|   def download! | ||||
|     self.downloaded = !downloaded | ||||
|     save | ||||
|   end | ||||
| 
 | ||||
|   def view! | ||||
|     self.viewed = !viewed | ||||
|     save | ||||
|   end | ||||
| end | ||||
| @ -1 +0,0 @@ | ||||
| body{margin:10px}a{text-decoration:none;color:#666}a:hover{color:#888}h2{margin-top:0;overflow:hidden;text-overflow:ellipsis;font-size:1.2em;font-family:Verdana,Arial,sans-serif}ul{list-style-type:none;margin:0;padding:0}ul#menu{display:flex;flex-flow:row wrap;justify-content:flex-end}ul#menu li{margin:5px}#search-genres ul{display:flex;flex-flow:row wrap}#search-genres ul li{margin-right:0.5em}ul.genres{display:flex}ul.genres li{margin-right:0.4em}ul.genres li:last-child::after{content:''}ul.genres li::after{content:','}form #search-main{display:flex}form #search-main input{border-radius:0.4em;border:solid 3px #f4f4f4}form #search-main input[type="submit"]{background-color:#f4f4f4}form #search-main input[type="text"]{flex-grow:1;min-width:50px;font-size:1.4em;padding:5px}.default>li,.compact>li{padding:10px 0}.default>li:nth-child(even),.compact>li:nth-child(even){background-color:#f4f4f4}.default .movie,.compact .movie{display:flex;flex-flow:row wrap;align-items:center;justify-content:center}.default .movie .poster,.compact .movie .poster{margin-right:10px}.default .movie .informations,.compact .movie .informations{align-self:flex-start;flex:1 1 300px}.poster{display:flex;flex-flow:row wrap}.poster .movie{width:160px} | ||||
| @ -1,82 +0,0 @@ | ||||
| function request(method, url, data, loadevent) { | ||||
|   var req = new XMLHttpRequest(); | ||||
|   req.open(method, url); | ||||
|   req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); | ||||
| 
 | ||||
|   req.addEventListener('load', loadevent); | ||||
| 
 | ||||
|   req.send(data) | ||||
| } | ||||
| 
 | ||||
| function init() { | ||||
|   var movies = document.querySelectorAll('.movie'); | ||||
|   for (var i = 0; i < movies.length; i++) { | ||||
|     new Movie(movies[i].dataset.id); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| var Movie = function(id) { | ||||
|   this.id = parseInt(id); | ||||
|   this.element = document.querySelector('.movie[data-id="'+id+'"]'); | ||||
| 
 | ||||
|   var remove_button = this.element.querySelector('button[data-action="remove-movie"]'); | ||||
|   var update_button = this.element.querySelector('button[data-action="update-movie"]'); | ||||
|   var view_button = this.element.querySelector('button[data-action="view-movie"]'); | ||||
| 
 | ||||
|   if (remove_button) { | ||||
|     remove_button.addEventListener('click', function(e) { | ||||
|       e.preventDefault(); | ||||
|       this.remove(); | ||||
|     }.bind(this)); | ||||
|   } | ||||
| 
 | ||||
|   if (update_button) { | ||||
|     update_button.addEventListener('click', function(e) { | ||||
|       e.preventDefault(); | ||||
|       this.update(); | ||||
|     }.bind(this)); | ||||
|   } | ||||
| 
 | ||||
|   if (view_button) { | ||||
|     view_button.addEventListener('click', function(e) { | ||||
|       e.preventDefault(); | ||||
|       this.view(); | ||||
|     }.bind(this)); | ||||
|   } | ||||
| 
 | ||||
|   this.formData = function() { | ||||
|     var data = new FormData(); | ||||
|     data.append('id', this.id); | ||||
| 
 | ||||
|     return data; | ||||
|   } | ||||
| 
 | ||||
|   this.update = function() { | ||||
|     request('POST', '/update', this.formData(), function(e) { | ||||
|       oldelem = this.element; | ||||
| 
 | ||||
|       tmp_elem = document.createElement('div'); | ||||
|       tmp_elem.innerHTML = e.target.response; | ||||
| 
 | ||||
|       this.element = tmp_elem.firstChild; | ||||
| 
 | ||||
|       oldelem.parentNode.replaceChild(this.element, oldelem); | ||||
|     }.bind(this)); | ||||
|   }; | ||||
| 
 | ||||
|   this.remove = function() { | ||||
|     request('POST', '/remove', this.formData(), function(e) { | ||||
|       this.element.parentNode.remove(); | ||||
|     }.bind(this)); | ||||
|   }; | ||||
| 
 | ||||
|   this.view = function() { | ||||
|     request('POST', '/view', this.formData(), function(e) { | ||||
|       this.element.querySelector('button[data-action="view-movie"]').parentNode.remove(); | ||||
|     }.bind(this)); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| document.addEventListener('DOMContentLoaded', function(event) { | ||||
|   init(); | ||||
| }); | ||||
| @ -1,49 +0,0 @@ | ||||
| require 'redis' | ||||
| 
 | ||||
| module Librarix | ||||
|   class Redis | ||||
|     TTL = 10800 | ||||
| 
 | ||||
|     attr_reader :connection, :namespace | ||||
| 
 | ||||
|     def initialize(connection, namespace:) | ||||
|       @connection = connection | ||||
|       @namespace = namespace | ||||
|     end | ||||
| 
 | ||||
|     def exist?(key) | ||||
|       exists key | ||||
|     end | ||||
| 
 | ||||
|     def keys(pattern) | ||||
|       @connection.keys("#{prefix}#{pattern}").map { |key| key.sub(prefix, '') } | ||||
|     end | ||||
| 
 | ||||
|     def fetch(key, options = {}) | ||||
|       if options[:force] || (!exist?(key) && block_given?) | ||||
|         value = yield | ||||
|         set key, value | ||||
|         expire key, TTL if options.key?(:ttl) && options[:ttl] | ||||
| 
 | ||||
|         value | ||||
|       else | ||||
|         get key | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def respond_to?(name, include_all = false) | ||||
|       super || @connection.respond_to?(name, include_all) | ||||
|     end | ||||
| 
 | ||||
|     def method_missing(name, *args, &block) | ||||
|       return super unless @connection.respond_to?(name) | ||||
|       @connection.send(name, "#{prefix}#{args.shift}", *args) | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def prefix | ||||
|       "#{namespace}:" | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -1,64 +0,0 @@ | ||||
| module Librarix | ||||
|   class Redis | ||||
|     class Movie | ||||
|       attr_reader :id | ||||
| 
 | ||||
|       def self.all | ||||
|         Array(Librarix.redis.smembers('movies_id')).map { |id| new(id).fetch } | ||||
|       end | ||||
| 
 | ||||
|       def self.genres | ||||
|         fetch_genres unless Librarix.redis.exists('genres') | ||||
|         Librarix.redis.smembers('genres').sort | ||||
|       end | ||||
| 
 | ||||
|       def self.fetch_genres | ||||
|         Tmdb::Genre.list['genres'].each do |genre| | ||||
|           Librarix.redis.sadd('genres', genre['name']) | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       def initialize(id) | ||||
|         @id = id.to_i | ||||
|       end | ||||
| 
 | ||||
|       def movie | ||||
|         @movie ||= fetch | ||||
|       end | ||||
| 
 | ||||
|       def add | ||||
|         Librarix.redis.sadd('movies_id', id) | ||||
|         movie | ||||
|       end | ||||
| 
 | ||||
|       def added? | ||||
|         Librarix.redis.sismember('movies_id', id) | ||||
|       end | ||||
| 
 | ||||
|       def fetch(force = false) | ||||
|         data = JSON.parse(Librarix.redis.fetch("movie:#{id}", force: force) do | ||||
|           Tmdb::Movie.detail(id).to_json | ||||
|         end) | ||||
| 
 | ||||
|         Tmdb::Movie.new(data) | ||||
|       end | ||||
| 
 | ||||
|       def update | ||||
|         fetch(true) | ||||
|       end | ||||
| 
 | ||||
|       def remove | ||||
|         Librarix.redis.del("movie:#{id}") | ||||
|         Librarix.redis.srem('movies_id', id) | ||||
|       end | ||||
| 
 | ||||
|       def view | ||||
|         Librarix.redis.sadd('viewed_movies_id', id) | ||||
|       end | ||||
| 
 | ||||
|       def viewed? | ||||
|         Librarix.redis.sismember('viewed_movies_id', id) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -1,41 +0,0 @@ | ||||
| require 'themoviedb' | ||||
| 
 | ||||
| module Librarix | ||||
|   module TheMovieDB | ||||
|     def poster_url(path, size = 'w92') | ||||
|       base_url = Librarix.redis.fetch('base_url', ttl: true) do | ||||
|         Tmdb::Configuration.new.base_url | ||||
|       end | ||||
| 
 | ||||
|       "#{base_url}#{size}#{path}" | ||||
|     end | ||||
| 
 | ||||
|     def movie(id) | ||||
|       Librarix::Redis::Movie.new(id).fetch | ||||
|     end | ||||
| 
 | ||||
|     module Movie | ||||
|       def genres | ||||
|         super || [] | ||||
|       end | ||||
| 
 | ||||
|       def release_date | ||||
|         @_release_date ||= Date.parse(super) unless super.nil? || super.empty? | ||||
|       end | ||||
| 
 | ||||
|       def release_year | ||||
|         release_date.year unless release_date.nil? | ||||
|       end | ||||
| 
 | ||||
|       def added? | ||||
|         Librarix::Redis::Movie.new(id).added? | ||||
|       end | ||||
| 
 | ||||
|       def viewed? | ||||
|         Librarix::Redis::Movie.new(id).viewed? | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Tmdb::Movie.prepend Librarix::TheMovieDB::Movie | ||||
| @ -1,39 +0,0 @@ | ||||
| - content_for :title do | ||||
|   | Movies | ||||
| 
 | ||||
| form method="get" action="/" id="filter" | ||||
|   div id="search-main" | ||||
|     input type="text" name="title" value="#{params['title']}" autocomplete="off" | ||||
|     input type="submit" value="Filter" | ||||
|   div id="search-more" | ||||
|     select name="view_state" | ||||
|       option value="all" selected=(filter.view_state == 'all') All movies | ||||
|       option value="viewed" selected=(filter.view_state == 'viewed') Only viewed | ||||
|       option value="not_viewed" selected=(filter.view_state == 'not_viewed') Not viewed | ||||
|     select name="sort" | ||||
|       option value="alphabetical" selected=(filter.sort == 'alphabetical') Alphabetical | ||||
|       option value="date" selected=(filter.sort == 'date') Release date | ||||
|     input type="checkbox" name="group" id="group" checked=(filter.group) | ||||
|     label for="group" Group by sort | ||||
|     select name="template" | ||||
|       option value="default" selected=(template == 'default') Default | ||||
|       option value="compact" selected=(template == 'compact') Compact | ||||
|       option value="poster" selected=(template == 'poster') Poster | ||||
|   div id="search-genres" | ||||
|     ul | ||||
|       - Librarix::Redis::Movie.genres.each do |genre| | ||||
|         li | ||||
|           input type="checkbox" name="genres[#{genre}]" id="#{genre}" checked=(filter.genres.include?(genre)) | ||||
|           label for="#{genre}" = genre | ||||
| 
 | ||||
| 
 | ||||
| - filter.movies.each do |group, movies| | ||||
|   - unless group == :all | ||||
|     h1 = group | ||||
|   == slim :'partials/list', locals: {movies: movies} | ||||
| - if filter.maybe_search? | ||||
|   p | ||||
|     | Search for | ||||
|     strong | ||||
|       a<> href="#{url("/search?search=#{params['title']}")}" = params['title'] | ||||
|     | ? | ||||
| @ -1,13 +0,0 @@ | ||||
| doctype html | ||||
| html | ||||
|   head | ||||
|     title | ||||
|       = yield_content :title | ||||
|       |  - Librarix | ||||
|     meta charset="utf-8" | ||||
|     meta name="viewport" content="initial-scale=1.0, user-scalable=yes" | ||||
|     link rel="stylesheet" media="all" href="/application.css" | ||||
|     script type="text/javascript" src="/application.js" | ||||
|   body | ||||
|     == menu | ||||
|     == yield | ||||
| @ -1,27 +0,0 @@ | ||||
| - content_for :title do | ||||
|   = movie.title | ||||
| 
 | ||||
| .movie data-id="#{movie.id}" | ||||
|   h1 = movie.title | ||||
|   .poster | ||||
|     - if movie.poster_path | ||||
|       img src="#{poster_url(movie.poster_path, 'w154')}" | ||||
|   .informations | ||||
|     p = movie.release_date | ||||
|     p = movie.overview | ||||
|     p | ||||
|       a> href="https://www.themoviedb.org/movie/#{movie.id}" The Movie DB | ||||
|       | (#{movie.vote_average}/10, #{movie.vote_count} votes) | ||||
|   .actions | ||||
|     - if movie.added? | ||||
|       - unless movie.viewed? | ||||
|         form method="post" action="/view" | ||||
|           input type="hidden" name="id" value="#{movie.id}" | ||||
|           button type="submit" data-action="view-movie" View | ||||
|       form method="post" action="/remove" | ||||
|         input type="hidden" name="id" value="#{movie.id}" | ||||
|         button type="submit" data-action="remove-movie" Remove | ||||
|     - else | ||||
|       form method="post" action="/add" | ||||
|         input type="hidden" name="id" value="#{movie.id}" | ||||
|         button type="submit" data-action="add-movie" Add | ||||
| @ -1,4 +0,0 @@ | ||||
| ul.movies class="#{template}" | ||||
|   - movies.each do |movie| | ||||
|     li | ||||
|       == slim :'partials/movie', locals: {movie: movie} | ||||
| @ -1,2 +0,0 @@ | ||||
| .movie data-id="#{movie.id}" | ||||
|   == slim :"partials/movie/#{template}", locals: {movie: movie} | ||||
| @ -1,19 +0,0 @@ | ||||
| .poster | ||||
|   - if movie.poster_path | ||||
|     img src="#{poster_url(movie.poster_path, 'w92')}" | ||||
| .informations | ||||
|   h2 | ||||
|     a href="#{url("/movie/#{movie.id}")}" #{movie.title} | ||||
| .actions | ||||
|   - if movie.added? | ||||
|     - unless movie.viewed? | ||||
|       form method="post" action="/view" | ||||
|         input type="hidden" name="id" value="#{movie.id}" | ||||
|         button type="submit" data-action="view-movie" View | ||||
|     form method="post" action="/remove" | ||||
|       input type="hidden" name="id" value="#{movie.id}" | ||||
|       button type="submit" data-action="remove-movie" Remove | ||||
|   - else | ||||
|     form method="post" action="/add" | ||||
|       input type="hidden" name="id" value="#{movie.id}" | ||||
|       button type="submit" data-action="add-movie" Add | ||||
| @ -1,27 +0,0 @@ | ||||
| .poster | ||||
|   - if movie.poster_path | ||||
|     img src="#{poster_url(movie.poster_path, 'w154')}" | ||||
| .informations | ||||
|   h2 | ||||
|     a href="#{url("/movie/#{movie.id}")}" #{movie.title} | ||||
|   p = movie.release_date | ||||
|   p = movie.overview | ||||
|   ul.genres | ||||
|     - movie.genres.each do |genre| | ||||
|       li = genre['name'] | ||||
| .actions | ||||
|   - if movie.added? | ||||
|     - unless movie.viewed? | ||||
|       form method="post" action="/view" | ||||
|         input type="hidden" name="id" value="#{movie.id}" | ||||
|         button type="submit" data-action="view-movie" View | ||||
|     form method="post" action="/update" | ||||
|       input type="hidden" name="id" value="#{movie.id}" | ||||
|       button type="submit" data-action="update-movie" Update | ||||
|     form method="post" action="/remove" | ||||
|       input type="hidden" name="id" value="#{movie.id}" | ||||
|       button type="submit" data-action="remove-movie" Remove | ||||
|   - else | ||||
|     form method="post" action="/add" | ||||
|       input type="hidden" name="id" value="#{movie.id}" | ||||
|       button type="submit" data-action="add-movie" Add | ||||
| @ -1,7 +0,0 @@ | ||||
| .poster | ||||
|   - if movie.poster_path | ||||
|     a href="#{url("/movie/#{movie.id}")}" | ||||
|       img src="#{poster_url(movie.poster_path, 'w154')}" | ||||
| .informations | ||||
|   h2 | ||||
|     a href="#{url("/movie/#{movie.id}")}" #{movie.title} | ||||
| @ -1,10 +0,0 @@ | ||||
| - content_for :title do | ||||
|   | Search | ||||
| 
 | ||||
| form method="get" action="/search" id="search" | ||||
|   div id="search-main" | ||||
|     input type="text" name="search" value="#{params['search']}" autocomplete="off" autofocus="on" | ||||
|     input type="submit" value="Search" | ||||
| 
 | ||||
| div | ||||
|   == slim :'partials/list', locals: {movies: movies} | ||||
| @ -20,11 +20,11 @@ Gem::Specification.new do |spec| | ||||
| 
 | ||||
|   spec.add_dependency "sinatra", '~> 2.0' | ||||
|   spec.add_dependency "sinatra-contrib", '~> 2.0' | ||||
|   spec.add_dependency "slim", '~> 3.0' | ||||
|   spec.add_dependency "redis", '~> 3.2' | ||||
|   spec.add_dependency "themoviedb", '~> 0.1' | ||||
|   spec.add_dependency "sequel", '~> 5.21' | ||||
|   spec.add_dependency "sqlite3", '~> 1.4' | ||||
|   spec.add_dependency "themoviedb", '~> 1.0' | ||||
| 
 | ||||
|   spec.add_development_dependency "bundler", "~> 2.0" | ||||
|   spec.add_development_dependency "rake", "~> 10.0" | ||||
|   spec.add_development_dependency "sass", "~> 3.4" | ||||
|   spec.add_development_dependency "irb" | ||||
| end | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user