diff --git a/app/assets/javascripts/bulk_update_requests.js.coffee b/app/assets/javascripts/bulk_update_requests.js.coffee
new file mode 100644
index 000000000..24f83d18b
--- /dev/null
+++ b/app/assets/javascripts/bulk_update_requests.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/stylesheets/bulk_update_requests.css.scss b/app/assets/stylesheets/bulk_update_requests.css.scss
new file mode 100644
index 000000000..7f119bd70
--- /dev/null
+++ b/app/assets/stylesheets/bulk_update_requests.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the BulkUpdateRequests controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/controllers/bulk_update_requests_controller.rb b/app/controllers/bulk_update_requests_controller.rb
new file mode 100644
index 000000000..8e3c6c015
--- /dev/null
+++ b/app/controllers/bulk_update_requests_controller.rb
@@ -0,0 +1,31 @@
+class BulkUpdateRequestsController < ApplicationController
+ respond_to :html
+ before_filter :member_only
+ before_filter :admin_only, :only => [:update]
+
+ def new
+ @bulk_update_request = BulkUpdateRequest.new(:user_id => CurrentUser.user.id)
+ respond_with(@bulk_update_request)
+ end
+
+ def create
+ @bulk_update_request = BulkUpdateRequest.create(params[:bulk_update_request])
+ respond_with(@bulk_update_request, :location => bulk_update_requests_path)
+ end
+
+ def update
+ @bulk_update_request = BulkUpdateRequest.find(params[:id])
+ if params[:status] == "approved"
+ @bulk_update_request.approve!
+ else
+ @bulk_update_request.reject!
+ end
+ flash[:notice] = "Bulk update request updated"
+ respond_with(@bulk_update_request, :location => bulk_update_requests_path)
+ end
+
+ def index
+ @bulk_update_requests = BulkUpdateRequest.paginate(params[:page])
+ respond_with(@bulk_update_requests)
+ end
+end
diff --git a/app/helpers/bulk_update_requests_helper.rb b/app/helpers/bulk_update_requests_helper.rb
new file mode 100644
index 000000000..c84b6163a
--- /dev/null
+++ b/app/helpers/bulk_update_requests_helper.rb
@@ -0,0 +1,2 @@
+module BulkUpdateRequestsHelper
+end
diff --git a/app/models/bulk_update_request.rb b/app/models/bulk_update_request.rb
new file mode 100644
index 000000000..066ee95d4
--- /dev/null
+++ b/app/models/bulk_update_request.rb
@@ -0,0 +1,24 @@
+class BulkUpdateRequest < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :forum_topic
+
+ validates_presence_of :user
+ validates_inclusion_of :status, :in => %w(pending approved rejected)
+ attr_accessible :user_id, :forum_topic_id, :script
+ attr_accessible :status, :as => [:admin]
+ before_validation :initialize_attributes, :on => :create
+
+ def approve!
+ AliasAndImplicationImporter.new(script, forum_topic_id, "1").process!
+ update_attribute(:status, "approved")
+ end
+
+ def reject!
+ update_attribute(:status, "rejected")
+ end
+
+ def initialize_attributes
+ self.user_id = CurrentUser.user.id unless self.user_id
+ self.status = "pending"
+ end
+end
diff --git a/app/views/admin/alias_and_implication_imports/new.html.erb b/app/views/admin/alias_and_implication_imports/new.html.erb
index a1076a451..9d354b8f7 100644
--- a/app/views/admin/alias_and_implication_imports/new.html.erb
+++ b/app/views/admin/alias_and_implication_imports/new.html.erb
@@ -10,6 +10,7 @@ remove alias aaa -> bbb
remove implication aaa -> bbb
create alias aaa -> bbb
create implication aaa -> bbb
+mass update aaa -> bbb
diff --git a/config/deploy/development.rb b/config/deploy/development.rb
new file mode 100644
index 000000000..729153f71
--- /dev/null
+++ b/config/deploy/development.rb
@@ -0,0 +1 @@
+server "localhost", :web, :app, :db, :primary => true
diff --git a/config/routes.rb b/config/routes.rb
index 0c28cfc3e..8fbec391d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -78,6 +78,7 @@ Rails.application.routes.draw do
end
end
resources :bans
+ resources :bulk_update_requests
resources :comments do
resources :votes, :controller => "comment_votes", :only => [:create, :destroy]
collection do
@@ -121,6 +122,7 @@ Rails.application.routes.draw do
end
end
resources :ip_bans
+ resources :iqdb_queries, :only => [:create]
resources :janitor_trials do
collection do
get :test
@@ -257,7 +259,6 @@ Rails.application.routes.draw do
get :diff
end
end
- resources :iqdb_queries, :only => [:create]
# aliases
resources :wpages, :controller => "wiki_pages"
diff --git a/db/migrate/20140613004559_create_bulk_update_requests.rb b/db/migrate/20140613004559_create_bulk_update_requests.rb
new file mode 100644
index 000000000..25fd5ec96
--- /dev/null
+++ b/db/migrate/20140613004559_create_bulk_update_requests.rb
@@ -0,0 +1,12 @@
+class CreateBulkUpdateRequests < ActiveRecord::Migration
+ def change
+ create_table :bulk_update_requests do |t|
+ t.integer :user_id, :null => false
+ t.integer :forum_topic_id
+ t.text :script, :null => false
+ t.string :status, :null => false, :default => "pending"
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 173b15d9a..d87ae08e3 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -3,7 +3,6 @@
--
SET statement_timeout = 0;
-SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
@@ -730,6 +729,40 @@ CREATE SEQUENCE bans_id_seq
ALTER SEQUENCE bans_id_seq OWNED BY bans.id;
+--
+-- Name: bulk_update_requests; Type: TABLE; Schema: public; Owner: -; Tablespace:
+--
+
+CREATE TABLE bulk_update_requests (
+ id integer NOT NULL,
+ user_id integer NOT NULL,
+ forum_topic_id integer,
+ script text NOT NULL,
+ status character varying(255) DEFAULT 'pending'::character varying NOT NULL,
+ created_at timestamp without time zone,
+ updated_at timestamp without time zone
+);
+
+
+--
+-- Name: bulk_update_requests_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE bulk_update_requests_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: bulk_update_requests_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE bulk_update_requests_id_seq OWNED BY bulk_update_requests.id;
+
+
--
-- Name: comment_votes; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@@ -3076,6 +3109,13 @@ ALTER TABLE ONLY artists ALTER COLUMN id SET DEFAULT nextval('artists_id_seq'::r
ALTER TABLE ONLY bans ALTER COLUMN id SET DEFAULT nextval('bans_id_seq'::regclass);
+--
+-- Name: id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY bulk_update_requests ALTER COLUMN id SET DEFAULT nextval('bulk_update_requests_id_seq'::regclass);
+
+
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -4086,6 +4126,14 @@ ALTER TABLE ONLY bans
ADD CONSTRAINT bans_pkey PRIMARY KEY (id);
+--
+-- Name: bulk_update_requests_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
+--
+
+ALTER TABLE ONLY bulk_update_requests
+ ADD CONSTRAINT bulk_update_requests_pkey PRIMARY KEY (id);
+
+
--
-- Name: comment_votes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@@ -6751,3 +6799,5 @@ INSERT INTO schema_migrations (version) VALUES ('20140428015134');
INSERT INTO schema_migrations (version) VALUES ('20140505000956');
+INSERT INTO schema_migrations (version) VALUES ('20140613004559');
+
diff --git a/test/controllers/bulk_update_requests_controller_test.rb b/test/controllers/bulk_update_requests_controller_test.rb
new file mode 100644
index 000000000..875175ef1
--- /dev/null
+++ b/test/controllers/bulk_update_requests_controller_test.rb
@@ -0,0 +1,58 @@
+require 'test_helper'
+
+class BulkUpdateRequestsControllerTest < ActionController::TestCase
+ context "BulkUpdateRequestsController" do
+ setup do
+ @user = FactoryGirl.create(:user)
+ @admin = FactoryGirl.create(:admin_user)
+ end
+
+ context "#new" do
+ should "render" do
+ get :new, {}, {:user_id => @user.id}
+ assert_response :success
+ end
+ end
+
+ context "#create" do
+ should "succeed" do
+ assert_difference("BulkUpdateRequest.count", 1) do
+ post :create, {:bulk_update_request => {:script => "create alias aaa -> bbb"}}, {:user_id => @user.id}
+ end
+ end
+ end
+
+ context "#index" do
+ setup do
+ @bulk_update_request = FactoryGirl.create(:bulk_update_request, :user_id => @admin.id)
+ end
+
+ should "render" do
+ get :index, {}, {:user_id => @user.id}
+ assert_response :success
+ end
+ end
+
+ context "#update" do
+ setup do
+ @bulk_update_request = FactoryGirl.create(:bulk_update_request, :user_id => @admin.id)
+ end
+
+ context "for a member" do
+ should "fail" do
+ post :update, {:status => "approved", :id => @bulk_update_request.id}, {:user_id => @user.id}
+ @bulk_update_request.reload
+ assert_equal("pending", @bulk_update_request.status)
+ end
+ end
+
+ context "for an admin" do
+ should "succeed" do
+ post :update, {:status => "approved", :id => @bulk_update_request.id}, {:user_id => @admin.id}
+ @bulk_update_request.reload
+ assert_equal("approved", @bulk_update_request.status)
+ end
+ end
+ end
+ end
+end
diff --git a/test/factories/bulk_update_request.rb b/test/factories/bulk_update_request.rb
new file mode 100644
index 000000000..1e3cb56bc
--- /dev/null
+++ b/test/factories/bulk_update_request.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory(:bulk_update_request) do |f|
+ script "create alias aaa -> bbb"
+ end
+end
diff --git a/test/helpers/bulk_update_requests_helper_test.rb b/test/helpers/bulk_update_requests_helper_test.rb
new file mode 100644
index 000000000..2b140827b
--- /dev/null
+++ b/test/helpers/bulk_update_requests_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class BulkUpdateRequestsHelperTest < ActionView::TestCase
+end
diff --git a/test/models/bulk_update_request_test.rb b/test/models/bulk_update_request_test.rb
new file mode 100644
index 000000000..8b7748903
--- /dev/null
+++ b/test/models/bulk_update_request_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class BulkUpdateRequestTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end