tb_redirects 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5c08fd185fa92c73e68ea44979aa6fe3e0984a41
4
+ data.tar.gz: 7a3713cc31a038e24c141252093af03aa96dd9c6
5
+ SHA512:
6
+ metadata.gz: 74b120125a4444632c803f795d68cfe9d14e559666021bf6dae1d43d18939102e8695cf3a22fd6c35a66590b43afaee393aee39f443224d244d780d94453346f
7
+ data.tar.gz: c5be1b08dacf4caf5b391f71f965ce3694887cf0749e6ff310676bf6c9de4635d0006ee133514ba0c616f14508d1aa324a7c26558fe4da1c9826e3f499a32020
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 Greg Woods
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'TbRedirects'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task default: :test
@@ -0,0 +1,19 @@
1
+ // Tb Redirects
2
+
3
+ (function(){
4
+
5
+ app.admin.tb_redirects = {
6
+ index: function(){
7
+
8
+ },
9
+
10
+ show: function(){
11
+
12
+ },
13
+
14
+ edit: function(){
15
+
16
+ }
17
+ };
18
+
19
+ })();
@@ -0,0 +1,15 @@
1
+ // Tb Redirects
2
+
3
+ (function(){
4
+
5
+ app.tb_redirects = {
6
+ index: function(){
7
+
8
+ },
9
+
10
+ show: function(){
11
+
12
+ }
13
+ };
14
+
15
+ })();
@@ -0,0 +1,2 @@
1
+ // Place tb_redirects admin styles here
2
+
@@ -0,0 +1,2 @@
1
+ // Place tb_redirects styles here
2
+
@@ -0,0 +1,57 @@
1
+ class Admin::TbRedirectsController < Admin::ApplicationController
2
+
3
+ belongs_to_app :tb_redirects
4
+ add_breadcrumb "Redirects", :admin_tb_redirects_path
5
+ before_action :load_tb_redirect, :only => [:show, :edit, :update, :destroy]
6
+
7
+ def index
8
+ @tb_redirects = TbRedirect.ordered.paginate(:page => params[:page])
9
+ if params[:search]
10
+ @tb_redirects = @tb_redirects.search(params[:search])
11
+ end
12
+ respond_with @tb_redirects
13
+ end
14
+
15
+ def show
16
+ respond_with @tb_redirect
17
+ end
18
+
19
+ def new
20
+ @tb_redirect = TbRedirect.new
21
+ respond_with @tb_redirect
22
+ end
23
+
24
+ def create
25
+ if @tb_redirect = TbRedirect.create_smart(tb_redirect_params.merge(:created_by => 'user'))
26
+ flash[:notice] = 'Redirect created successfully'
27
+ end
28
+ respond_with @tb_redirect, :location => admin_tb_redirects_path
29
+ end
30
+
31
+ def edit
32
+ respond_with @tb_redirect
33
+ end
34
+
35
+ def update
36
+ if @tb_redirect.update_attributes(tb_redirect_params)
37
+ flash[:notice] = 'Redirect updated successfully'
38
+ end
39
+ respond_with @tb_redirect, :location => admin_tb_redirects_path
40
+ end
41
+
42
+ def destroy
43
+ flash[:notice] = 'Redirect deleted successfully' if @tb_redirect.destroy
44
+ respond_with @tb_redirect, :location => admin_tb_redirects_path
45
+ end
46
+
47
+ private
48
+
49
+ def load_tb_redirect
50
+ @tb_redirect = TbRedirect.find_by!(:id => params[:id])
51
+ end
52
+
53
+ def tb_redirect_params
54
+ params.require(:tb_redirect).permit(:source, :destination)
55
+ end
56
+
57
+ end
@@ -0,0 +1,16 @@
1
+ module TbRedirects::HandleRedirects
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ rescue_from Spud::NotFoundError, :with => :check_for_applicable_redirect
6
+ end
7
+
8
+ def check_for_applicable_redirect(error)
9
+ if redirect = TbRedirect.find_by_uri(request.original_url)
10
+ redirect_to redirect.destination, :status => :moved_permanently
11
+ else
12
+ handle_request_error(error)
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,11 @@
1
+ module Admin::TbRedirectsHelper
2
+
3
+ def created_by_for_tb_redirect(created_by)
4
+ if created_by == 'user'
5
+ content_tag :span, created_by.titleize, :class => 'label label-info'
6
+ else
7
+ content_tag :span, created_by.titleize, :class => 'label label-default'
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,34 @@
1
+ class TbRedirects::DetectRedirectLoopJob < ActiveJob::Base
2
+ queue_as :default
3
+
4
+ attr_reader :attempts
5
+ MAX_ATTEMPTS = 100
6
+
7
+ def initialize(*arguments)
8
+ super(*arguments)
9
+ @attempts = 0
10
+ end
11
+
12
+ def perform(redirect)
13
+ parents = TbRedirect.where(:destination => redirect.source)
14
+ parents.each{ |p| search_parent(p, redirect.destination) }
15
+ end
16
+
17
+ private
18
+
19
+ class AttemptsExceeded < StandardError
20
+ end
21
+
22
+ def search_parent(parent, destination_to_check)
23
+ @attempts += 1
24
+ raise AttemptsExceeded, "Exceeded #{MAX_ATTEMPTS} max attempts" if @attempts > MAX_ATTEMPTS
25
+
26
+ if parent.source == destination_to_check
27
+ parent.destroy
28
+ else
29
+ parents = TbRedirect.where(:destination => parent.source)
30
+ parents.each{ |p| search_parent(p, destination_to_check) }
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,8 @@
1
+ module TbRedirects::HasRedirects
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many :tb_redirects, :dependent => :destroy, :as => :owner
6
+ end
7
+
8
+ end
@@ -0,0 +1,57 @@
1
+ class TbRedirect < ActiveRecord::Base
2
+ scope :ordered, ->{ order('source desc') }
3
+ scope :search, ->(term){ where('source LIKE ?', "%#{term}%") }
4
+
5
+ belongs_to :owner, :polymorphic => true, :inverse_of => :tb_redirects
6
+
7
+ validates :source, :destination, :presence => true
8
+ validates :source, :uniqueness => true
9
+ validate :source_not_equals_destination
10
+ after_save :destroy_opposite_redirect
11
+ after_save :schedule_loop_detection
12
+
13
+ def self.find_by_uri(uri)
14
+ path = URI(uri).path
15
+ uri_without_params = uri.split('?').first
16
+ find_by(
17
+ arel_table[:source].eq(path)
18
+ .or(arel_table[:source].eq(uri_without_params))
19
+ )
20
+ rescue URI::InvalidURIError => e
21
+ logger.debug e.message
22
+ return nil
23
+ end
24
+
25
+ def self.create_smart(params)
26
+ redirect = find_or_initialize_by(:source => params.delete(:source))
27
+ redirect.assign_attributes(params)
28
+ redirect.save()
29
+ return redirect
30
+ end
31
+
32
+ private
33
+
34
+ def source_not_equals_destination
35
+ if self.source == self.destination
36
+ errors.add(:destination, 'cannot be the same as the source')
37
+ end
38
+ return true
39
+ end
40
+
41
+ def destroy_opposite_redirect
42
+ opposite = TbRedirect.find_by({
43
+ :source => self.destination,
44
+ :destination => self.source
45
+ })
46
+ opposite.destroy if opposite.present?
47
+ return true
48
+ end
49
+
50
+ def schedule_loop_detection
51
+ if TbRedirect.where(:destination => source).count > 0
52
+ TbRedirects::DetectRedirectLoopJob.perform_later(self)
53
+ end
54
+ return true
55
+ end
56
+
57
+ end
@@ -0,0 +1,15 @@
1
+ <%= tb_form_for [:admin, @tb_redirect], :remote => true, :data => {:errors => :inline, :success => admin_tb_redirects_path} do |f| %>
2
+
3
+ <%= tb_form_errors(f.object, :base) %>
4
+
5
+ <%= f.tb_text_field :source %>
6
+
7
+ <%= f.tb_text_field :destination %>
8
+
9
+ <%= f.tb_save_buttons('Redirect', admin_tb_redirects_path) %>
10
+
11
+ <% end %>
12
+
13
+ <script>
14
+ $(document).ready(app.admin.tb_redirects.edit);
15
+ </script>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,39 @@
1
+ <% content_for :data_controls do %>
2
+ <%= render :partial => '/layouts/admin/search', :locals => {:search_path => admin_tb_redirects_path } %>
3
+ <%= link_to "New Redirect", new_admin_tb_redirect_path, :class => "btn btn-primary", :title => "New Redirect" %>
4
+ <% end %>
5
+
6
+ <% content_for :detail do %>
7
+ <div class="table-responsive">
8
+ <table class="table table-striped table-hover">
9
+ <thead>
10
+ <tr>
11
+ <th>Source</th>
12
+ <th>Destination</th>
13
+ <th>Created By</th>
14
+ <th>&nbsp;</th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <% @tb_redirects.each do |tb_redirect| %>
19
+ <tr>
20
+ <td><%= link_to tb_redirect.source, tb_redirect.source, :target => :blank %></td>
21
+ <td><%= link_to tb_redirect.destination, tb_redirect.destination, :target => :blank %></td>
22
+ <td><%= created_by_for_tb_redirect(tb_redirect.created_by) %></td>
23
+ <td class="table-actions">
24
+ <%= link_to 'Details', admin_tb_redirect_path(tb_redirect), :class => 'btn btn-default btn-sm' %>
25
+ <%= link_to 'Edit', edit_admin_tb_redirect_path(tb_redirect), :class => 'btn btn-default btn-sm' %>
26
+ <%= link_to 'Delete', admin_tb_redirect_path(tb_redirect), :method => :delete, :class => 'btn btn-danger btn-sm' %>
27
+ </td>
28
+ </tr>
29
+ <% end %>
30
+ </tbody>
31
+ </table>
32
+ </div>
33
+ <%= will_paginate @tb_redirects, :renderer => BootstrapPagination::Rails %>
34
+
35
+ <script>
36
+ $(document).ready(app.admin.tb_redirects.index);
37
+ </script>
38
+
39
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,21 @@
1
+ <% content_for :data_controls do %>
2
+ <%= link_to 'Edit', edit_admin_tb_redirect_path(@tb_redirect), :class => 'btn btn-default' %>
3
+ <%= link_to "Back", admin_tb_redirects_path, :class => "btn btn-default" %>
4
+ <% end %>
5
+
6
+ <dl class="dl-horizontal">
7
+ <dt>Owner Type:</dt>
8
+ <dd><%= @tb_redirect.owner_type %></dd>
9
+ <dt>Owner:</dt>
10
+ <dd><%= @tb_redirect.owner_id %></dd>
11
+ <dt>Source:</dt>
12
+ <dd><%= @tb_redirect.source %></dd>
13
+ <dt>Destination:</dt>
14
+ <dd><%= @tb_redirect.destination %></dd>
15
+ <dt>Created By:</dt>
16
+ <dd><%= @tb_redirect.created_by %></dd>
17
+ </dl>
18
+
19
+ <script>
20
+ $(document).ready(app.admin.tb_redirects.show);
21
+ </script>
File without changes
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Rails.application.routes.draw do
2
+ namespace :admin do
3
+ resources :tb_redirects, :path => 'redirects'
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ class CreateTbRedirects < ActiveRecord::Migration
2
+ def change
3
+ create_table :tb_redirects do |t|
4
+ t.string :owner_type
5
+ t.integer :owner_id
6
+ t.string :source, :null => false
7
+ t.string :destination, :null => false
8
+ t.string :created_by
9
+ t.timestamps null: false
10
+ end
11
+ add_index :tb_redirects, [:owner_type, :owner_id]
12
+ add_index :tb_redirects, :source, :unique => true
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :tb_redirects do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,28 @@
1
+ require 'tb_core'
2
+
3
+ module TbRedirects
4
+ class Engine < ::Rails::Engine
5
+ engine_name 'tb_redirects'
6
+ config.autoload_paths += Dir["#{config.root}/lib/**/"]
7
+
8
+ config.generators do |g|
9
+ g.test_framework :rspec, :fixture => false
10
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
11
+ g.assets false
12
+ g.helper true
13
+ end
14
+
15
+ initializer 'tb_redirects.admin', :before => 'tb_core.admin' do |config|
16
+ Spud::Core.admin_applications += [
17
+ {:name => 'Redirects', :key => :tb_redirects, :thumbnail => "admin/module_icon.png", :url => '/admin/redirects'},
18
+ ]
19
+ end
20
+
21
+ initializer 'tb_redirects.controllers' do |config|
22
+ ActiveSupport.on_load(:action_controller) do
23
+ Spud::ApplicationController.send :include, TbRedirects::HandleRedirects
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module TbRedirects
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ require "tb_redirects/engine"
2
+
3
+ module TbRedirects
4
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tb_redirects
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Greg Woods
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tb_core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.6
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.6
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 4.2.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 4.2.5
41
+ - !ruby/object:Gem::Dependency
42
+ name: mysql2
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.4.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.4.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: factory_girl_rails
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 4.6.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 4.6.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: database_cleaner
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.5.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.5.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.11.2
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.11.2
111
+ description: TbRedirects provides a tool for creating and managing 301 redirects for
112
+ your website
113
+ email:
114
+ - greg@westlakedesign.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - MIT-LICENSE
120
+ - Rakefile
121
+ - app/assets/javascripts/admin/tb_redirects.js
122
+ - app/assets/javascripts/tb_redirects.js
123
+ - app/assets/stylesheets/admin/tb_redirects.scss
124
+ - app/assets/stylesheets/tb_redirects.scss
125
+ - app/controllers/admin/tb_redirects_controller.rb
126
+ - app/controllers/concerns/tb_redirects/handle_redirects.rb
127
+ - app/helpers/admin/tb_redirects_helper.rb
128
+ - app/jobs/tb_redirects/detect_redirect_loop_job.rb
129
+ - app/models/concerns/tb_redirects/has_redirects.rb
130
+ - app/models/tb_redirect.rb
131
+ - app/views/admin/tb_redirects/_form.html.erb
132
+ - app/views/admin/tb_redirects/edit.html.erb
133
+ - app/views/admin/tb_redirects/index.html.erb
134
+ - app/views/admin/tb_redirects/new.html.erb
135
+ - app/views/admin/tb_redirects/show.html.erb
136
+ - config/application.rb
137
+ - config/routes.rb
138
+ - db/migrate/20160211162513_create_tb_redirects.rb
139
+ - lib/tasks/tb_redirects_tasks.rake
140
+ - lib/tb_redirects.rb
141
+ - lib/tb_redirects/engine.rb
142
+ - lib/tb_redirects/version.rb
143
+ homepage: https://bitbucket.org/westlakedesign/tb_redirects
144
+ licenses:
145
+ - MIT
146
+ metadata: {}
147
+ post_install_message:
148
+ rdoc_options: []
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubyforge_project:
163
+ rubygems_version: 2.4.5.1
164
+ signing_key:
165
+ specification_version: 4
166
+ summary: Simple redirect management for Twice Baked
167
+ test_files: []