This commit is contained in:
randuin
2011-09-02 17:52:18 -07:00
145 changed files with 2631 additions and 1334 deletions

4
Capfile Normal file
View File

@@ -0,0 +1,4 @@
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
load 'config/deploy' # remove this line to skip loading any of the default tasks

10
Gemfile
View File

@@ -9,10 +9,12 @@ group :test do
end end
group :assets do group :assets do
gem "uglifier"
gem "uglifier-rails"
gem "therubyracer"
end end
gem "rails", "3.1.0.rc5" gem "rails", "3.1.0.rc8"
gem "pg" gem "pg"
gem "memcache-client", :require => "memcache" gem "memcache-client", :require => "memcache"
gem "imagesize", :require => "image_size" gem "imagesize", :require => "image_size"
@@ -24,4 +26,4 @@ gem "mechanize"
gem "nokogiri" gem "nokogiri"
gem "meta_search", :git => "git://github.com/ernie/meta_search.git" gem "meta_search", :git => "git://github.com/ernie/meta_search.git"
gem "silent-postgres" gem "silent-postgres"
gem "whenever", :require => false gem "whenever", :require => false

View File

@@ -17,48 +17,51 @@ GEM
remote: http://gemcutter.org/ remote: http://gemcutter.org/
specs: specs:
aaronh-chronic (0.3.9) aaronh-chronic (0.3.9)
actionmailer (3.1.0.rc5) actionmailer (3.1.0.rc8)
actionpack (= 3.1.0.rc5) actionpack (= 3.1.0.rc8)
mail (~> 2.3.0) mail (~> 2.3.0)
actionpack (3.1.0.rc5) actionpack (3.1.0.rc8)
activemodel (= 3.1.0.rc5) activemodel (= 3.1.0.rc8)
activesupport (= 3.1.0.rc5) activesupport (= 3.1.0.rc8)
builder (~> 3.0.0) builder (~> 3.0.0)
erubis (~> 2.7.0) erubis (~> 2.7.0)
i18n (~> 0.6) i18n (~> 0.6)
rack (~> 1.3.1) rack (~> 1.3.2)
rack-cache (~> 1.0.2) rack-cache (~> 1.0.3)
rack-mount (~> 0.8.1) rack-mount (~> 0.8.2)
rack-test (~> 0.6.0) rack-test (~> 0.6.1)
sprockets (~> 2.0.0.beta.12) sprockets (~> 2.0.0.beta.15)
activemodel (3.1.0.rc5) activemodel (3.1.0.rc8)
activesupport (= 3.1.0.rc5) activesupport (= 3.1.0.rc8)
bcrypt-ruby (~> 2.1.4) bcrypt-ruby (~> 3.0.0)
builder (~> 3.0.0) builder (~> 3.0.0)
i18n (~> 0.6) i18n (~> 0.6)
activerecord (3.1.0.rc5) activerecord (3.1.0.rc8)
activemodel (= 3.1.0.rc5) activemodel (= 3.1.0.rc8)
activesupport (= 3.1.0.rc5) activesupport (= 3.1.0.rc8)
arel (~> 2.1.4) arel (~> 2.2.1)
tzinfo (~> 0.3.29) tzinfo (~> 0.3.29)
activeresource (3.1.0.rc5) activeresource (3.1.0.rc8)
activemodel (= 3.1.0.rc5) activemodel (= 3.1.0.rc8)
activesupport (= 3.1.0.rc5) activesupport (= 3.1.0.rc8)
activesupport (3.1.0.rc5) activesupport (3.1.0.rc8)
multi_json (~> 1.0) multi_json (~> 1.0)
arel (2.1.4) arel (2.2.1)
bcrypt-ruby (2.1.4) bcrypt-ruby (3.0.0)
builder (3.0.0) builder (3.0.0)
daemons (1.1.4) daemons (1.1.4)
delayed_job (2.1.4) delayed_job (2.1.4)
activesupport (~> 3.0) activesupport (~> 3.0)
daemons daemons
erubis (2.7.0) erubis (2.7.0)
factory_girl (2.0.3) execjs (1.2.4)
multi_json (~> 1.0)
factory_girl (2.0.5)
haml (3.1.2) haml (3.1.2)
hike (1.2.0) hike (1.2.1)
i18n (0.6.0) i18n (0.6.0)
imagesize (0.1.1) imagesize (0.1.1)
libv8 (3.3.10.2)
mail (2.3.0) mail (2.3.0)
i18n (>= 0.4.0) i18n (>= 0.4.0)
mime-types (~> 1.16) mime-types (~> 1.16)
@@ -73,58 +76,66 @@ GEM
mocha (0.9.12) mocha (0.9.12)
multi_json (1.0.3) multi_json (1.0.3)
net-http-digest_auth (1.1.1) net-http-digest_auth (1.1.1)
net-http-persistent (1.8) net-http-persistent (1.9)
nokogiri (1.5.0) nokogiri (1.5.0)
pg (0.11.0) pg (0.11.0)
polyglot (0.3.2) polyglot (0.3.2)
rack (1.3.2) rack (1.3.2)
rack-cache (1.0.2) rack-cache (1.0.3)
rack (>= 0.4) rack (>= 0.4)
rack-mount (0.8.1) rack-mount (0.8.2)
rack (>= 1.0.0) rack (>= 1.0.0)
rack-ssl (1.3.2) rack-ssl (1.3.2)
rack rack
rack-test (0.6.1) rack-test (0.6.1)
rack (>= 1.0) rack (>= 1.0)
rails (3.1.0.rc5) rails (3.1.0.rc8)
actionmailer (= 3.1.0.rc5) actionmailer (= 3.1.0.rc8)
actionpack (= 3.1.0.rc5) actionpack (= 3.1.0.rc8)
activerecord (= 3.1.0.rc5) activerecord (= 3.1.0.rc8)
activeresource (= 3.1.0.rc5) activeresource (= 3.1.0.rc8)
activesupport (= 3.1.0.rc5) activesupport (= 3.1.0.rc8)
bundler (~> 1.0) bundler (~> 1.0)
railties (= 3.1.0.rc5) railties (= 3.1.0.rc8)
railties (3.1.0.rc5) railties (3.1.0.rc8)
actionpack (= 3.1.0.rc5) actionpack (= 3.1.0.rc8)
activesupport (= 3.1.0.rc5) activesupport (= 3.1.0.rc8)
rack-ssl (~> 1.3.2) rack-ssl (~> 1.3.2)
rake (>= 0.8.7) rake (>= 0.8.7)
rdoc (~> 3.4) rdoc (~> 3.4)
thor (~> 0.14.6) thor (~> 0.14.6)
rake (0.9.2) rake (0.9.2)
rdoc (3.9.1) rdoc (3.9.4)
shoulda (2.11.3) shoulda (2.11.3)
silent-postgres (0.0.8) silent-postgres (0.1.1)
simple_form (1.4.2) simple_form (1.4.2)
actionpack (~> 3.0) actionpack (~> 3.0)
activemodel (~> 3.0) activemodel (~> 3.0)
simplecov (0.4.2) simplecov (0.4.2)
simplecov-html (~> 0.4.4) simplecov-html (~> 0.4.4)
simplecov-html (0.4.5) simplecov-html (0.4.5)
sprockets (2.0.0.beta.13) sprockets (2.0.0)
hike (~> 1.2) hike (~> 1.2)
rack (~> 1.0) rack (~> 1.0)
tilt (!= 1.3.0, ~> 1.1) tilt (~> 1.1, != 1.3.0)
super_exception_notifier (3.0.13) super_exception_notifier (3.0.13)
actionmailer actionmailer
rake rake
therubyracer (0.9.4)
libv8 (~> 3.3.10)
thor (0.14.6) thor (0.14.6)
tilt (1.3.2) tilt (1.3.3)
treetop (1.4.10) treetop (1.4.10)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
tzinfo (0.3.29) tzinfo (0.3.29)
webrobots (0.0.10) uglifier (1.0.2)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)
uglifier-rails (3.1.0.rc.2)
railties (~> 3.1.0.rc1)
uglifier (>= 1.0.0)
webrobots (0.0.11)
nokogiri (>= 1.4.4) nokogiri (>= 1.4.4)
whenever (0.6.8) whenever (0.6.8)
aaronh-chronic (>= 0.3.9) aaronh-chronic (>= 0.3.9)
@@ -145,10 +156,13 @@ DEPENDENCIES
mocha mocha
nokogiri nokogiri
pg pg
rails (= 3.1.0.rc5) rails (= 3.1.0.rc8)
shoulda shoulda
silent-postgres silent-postgres
simple_form simple_form
simplecov simplecov
super_exception_notifier super_exception_notifier
therubyracer
uglifier
uglifier-rails
whenever whenever

View File

@@ -1,9 +1,8 @@
#!/bin/bash #!/bin/bash
echo "This script is out of date; please read the INSTALL document" # Run: curl -s https://raw.github.com/r888888888/danbooru/master/INSTALL.debian > install.sh ; chmod +x install.sh ; ./install.sh
exit 1
if [ $USER != root ] ; then if [[ "$(whoami)" != "root" ]] ; then
echo "You must run this script as root" echo "You must run this script as root"
exit 1 exit 1
fi fi
@@ -13,120 +12,131 @@ echo "This script will install Ruby, Rails, PostgreSQL, and Nginx. By the end,"
echo "you should be able to connect to the server and create an account." echo "you should be able to connect to the server and create an account."
echo echo
echo "It will create a new user called danbooru which will run the Danbooru" echo "It will create a new user called danbooru which will run the Danbooru"
echo "processes. It will download the latest trunk copy and install it in" echo "processes. It will download the latest copy and install it in"
echo "/var/www/danbooru. It will run three Mongrel processes, starting on port" echo "/var/www/danbooru."
echo "8050." echo
echo "It is mostly automated but you will receive some prompts when installing"
echo "Passenger towards the end of the script."
echo echo
echo -n "Enter the hostname for this server (ex: danbooru.donmai.us): " echo -n "Enter the hostname for this server (ex: danbooru.donmai.us): "
read hostname read HOSTNAME
if [ -z $hostname ] ; then if [[ -z "$HOSTNAME" ]] ; then
echo "Must enter a hostname" echo "Must enter a hostname"
exit 1 exit 1
fi fi
echo -n "Enter a name for the site (default: Danbooru): " echo -n "Enter a name for the site (default: Danbooru): "
read sitename read SITENAME
if [ -z $sitename ] ; then if [[ -z "$SITENAME" ]] ; then
sitename=Danbooru SITENAME=Danbooru
fi fi
# Install packages # Install packages
apt-get -y install sudo gcc g++ make libreadline5-dev zlib1g-dev flex bison libgd2-noxpm libgd2-noxpm-dev bzip2 postgresql-8.3 postgresql-contrib-8.3 libpq-dev ruby ruby1.8-dev ri irb rdoc rubygems ragel memcached libmemcache-dev subversion nginx rake libopenssl-ruby mongrel echo "Installing packages..."
apt-get -y install build-essential automake openssl libssl-dev libyaml-dev libxml2-dev libxslt-dev autoconf ncurses-dev sudo gcc g++ libreadline-dev zlib1g-dev flex bison libgd2-noxpm libgd2-noxpm-dev bzip2 ragel memcached libmemcache-dev git curl libcurl4-openssl-dev emacs-nox
# Install Ruby gems # Install PostgreSQL 9.1
for i in postgres diff-lcs html5 mongrel mongrel_cluster memcache-client aws-s3 json ; do gem install $i ; done apt-get -y install python-software-properties
gem install rails --version=2.1.0 add-apt-repository ppa:pitti/postgresql
gem install acts_as_versioned apt-get update
apt-get install -y postgresql-9.1 postgresql-contrib-9.1 libpq-dev
if [ $? -ne 0 ]; then
exit 1
fi
# Install RVM
echo "Installing RVM..."
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
echo "source /usr/local/rvm/scripts/rvm" >> /etc/bash.bashrc
echo "source /usr/local/rvm/scripts/rvm" >> /etc/profile
source /usr/local/rvm/scripts/rvm
rvm install ruby-1.9.2-p290 --with-openssl-dir=/usr/local
rvm 1.9.2 --default
# Install gems
gem install --no-ri --no-rdoc capistrano
gem install --no-ri --no-rdoc capistrano-ext
gem install --no-ri --no-rdoc bundler
# Install Passenger
gem install --no-ri --no-rdoc -v 3.0.8 passenger
rvm exec passenger-install-nginx-module
rm /opt/nginx/conf/*.default
if [ $? -ne 0 ]; then
exit 1
fi
# Create user account # Create user account
useradd -m danbooru useradd -m danbooru
PG_HBA_FILE="/etc/postgresql/8.3/main/pg_hba.conf" chsh -s /bin/bash danbooru
echo "source /usr/local/rvm/scripts/rvm" > /home/danbooru/.bashrc
chmod g-wx,o-wx /home/danbooru/.bashrc
chown danbooru:danbooru /home/danbooru/.bashrc
echo "export rvm_path=/usr/local/rvm" > /etc/rvmrc
addgroup wheel
usermod -G root,wheel root
usermod -G danbooru,wheel danbooru
# Update PostgreSQL
PG_HBA_FILE="/etc/postgresql/9.1/main/pg_hba.conf"
echo "local all postgres,danbooru trust" > $PG_HBA_FILE echo "local all postgres,danbooru trust" > $PG_HBA_FILE
echo "host all postgres,danbooru 127.0.0.1/32 trust" >> $PG_HBA_FILE echo "host all postgres,danbooru 127.0.0.1/32 trust" >> $PG_HBA_FILE
/etc/init.d/postgresql-8.3 restart
# Install Danbooru /etc/init.d/postgresql restart
cd /var/www
svn export svn://donmai.us/danbooru/trunk danbooru
chown -R danbooru:danbooru danbooru
cd danbooru
mkdir -p public/data/sample
cd config
cp database.yml.example database.yml
cp local_config.rb.example local_config.rb
sed -i -e "s/DAN_HOSTNAME/$hostname/g" local_config.rb
sed -i -e "s/DAN_SITENAME/$sitename/g" local_config.rb
echo "--- " > mongrel_cluster.yml
echo "cwd: /var/www/danbooru" >> mongrel_cluster.yml
echo "port: \"8050\"" >> mongrel_cluster.yml
echo "environment: production" >> mongrel_cluster.yml
echo "address: 127.0.0.1" >> mongrel_cluster.yml
echo "servers: 3" >> mongrel_cluster.yml
echo "num_processors: 10" >> mongrel_cluster.yml
cd ../lib/danbooru_image_resizer
ruby extconf.rb
make
cd ../..
sudo -u postgres createuser -s danbooru sudo -u postgres createuser -s danbooru
sudo -u danbooru createdb danbooru
sudo -u danbooru psql danbooru < db/postgres.sql
sudo -u danbooru rake db:migrate RAILS_ENV=production
script/donmai/upbooru
# Set up nginx mkdir -p /var/log/www
DANBOORU_CONF_FILE="/etc/nginx/sites-enabled/danbooru.conf"
echo "upstream mongrel {" > $DANBOORU_CONF_FILE # Setup nginx
echo " server 127.0.0.1:8050;" >> $DANBOORU_CONF_FILE curl -s https://raw.github.com/r888888888/danbooru/master/script/install/init_d.templ > /etc/init.d/nginx
echo " server 127.0.0.1:8051;" >> $DANBOORU_CONF_FILE chmod +x,g-w /etc/init.d/nginx
echo " server 127.0.0.1:8052;" >> $DANBOORU_CONF_FILE update-rc.d -f nginx defaults
echo "}" >> $DANBOORU_CONF_FILE mkdir -p /opt/nginx/conf/sites
echo "server {" >> $DANBOORU_CONF_FILE curl -s https://raw.github.com/r888888888/danbooru/master/script/install/nginx.conf > /opt/nginx/conf/nginx.conf
echo " listen 80;" >> $DANBOORU_CONF_FILE curl -s https://raw.github.com/r888888888/danbooru/master/script/install/nginx.danbooru.conf > /opt/nginx/conf/sites/danbooru.conf
echo " server_name $hostname;" >> $DANBOORU_CONF_FILE sed -i -e 's/\$hostname/$HOSTNAME/g' /opt/nginx/conf/sites/danbooru.conf
echo " root /var/www/danbooru/public;" >> $DANBOORU_CONF_FILE /etc/init.d/nginx start
echo " index index.html;" >> $DANBOORU_CONF_FILE
echo " access_log /var/www/danbooru/log/server.access.log;" >> $DANBOORU_CONF_FILE echo "%wheel ALL=(ALL) ALL" >> /etc/sudoers
echo " error_log /var/www/danbooru/log/server.error.log;" >> $DANBOORU_CONF_FILE
echo " client_max_body_size 30m;" >> $DANBOORU_CONF_FILE # Setup logrotate
echo " location /stylesheets {" >> $DANBOORU_CONF_FILE LOGROTATE_CONF_FILE="/etc/logrotate.conf"
echo " expires max;" >> $DANBOORU_CONF_FILE echo >> $LOGROTATE_CONF_FILE
echo " break;" >> $DANBOORU_CONF_FILE echo "/var/log/www/danbooru.access.log" >> $LOGROTATE_CONF_FILE
echo " }" >> $DANBOORU_CONF_FILE echo "/var/log/www/danbooru.error.log">> $LOGROTATE_CONF_FILE
echo " location /javascripts {" >> $DANBOORU_CONF_FILE echo "/var/www/danbooru/current/log/production.log {" >> $LOGROTATE_CONF_FILE
echo " expires max;" >> $DANBOORU_CONF_FILE echo " daily" >> $LOGROTATE_CONF_FILE
echo " break;" >> $DANBOORU_CONF_FILE echo " rotate 3" >> $LOGROTATE_CONF_FILE
echo " }" >> $DANBOORU_CONF_FILE echo " copytruncate" >> $LOGROTATE_CONF_FILE
echo " location /data {" >> $DANBOORU_CONF_FILE echo "}" >> $LOGROTATE_CONF_FILE
echo " valid_referers none $hostname;" >> $DANBOORU_CONF_FILE
echo " if (\$invalid_referer) {" >> $DANBOORU_CONF_FILE # Setup danbooru account
echo " return 403;" >> $DANBOORU_CONF_FILE echo "*************************************************"
echo " }" >> $DANBOORU_CONF_FILE echo "* Enter a new password for the danbooru account *"
echo " expires max;" >> $DANBOORU_CONF_FILE echo "*************************************************"
echo " break;" >> $DANBOORU_CONF_FILE passwd danbooru
echo " }" >> $DANBOORU_CONF_FILE
echo " location /maintenance.html {" >> $DANBOORU_CONF_FILE sudo -u danbooru createdb danbooru2
echo " expires 10;" >> $DANBOORU_CONF_FILE cd /home/danbooru
echo " }" >> $DANBOORU_CONF_FILE sudo -u danbooru mkdir /home/danbooru/apps
echo " if (-f \$document_root/maintenance.html) {" >> $DANBOORU_CONF_FILE git clone git://github.com/r888888888/danbooru.git danbooru
echo " rewrite ^(.*)\$ /maintenance.html last;" >> $DANBOORU_CONF_FILE chown -R danbooru:danbooru danbooru
echo " break;" >> $DANBOORU_CONF_FILE cap deploy:setup
echo " }" >> $DANBOORU_CONF_FILE cap deploy:update_code
echo " location / {" >> $DANBOORU_CONF_FILE cap deploy:migrate
echo " proxy_set_header X-Real-IP \$remote_addr;" >> $DANBOORU_CONF_FILE chown danbooru:danbooru /var/www/danbooru/shared/log/development.log
echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;" >> $DANBOORU_CONF_FILE
echo " proxy_set_header Host \$http_host;" >> $DANBOORU_CONF_FILE
echo " proxy_redirect false;" >> $DANBOORU_CONF_FILE
echo " if (!-f \$request_filename) {" >> $DANBOORU_CONF_FILE
echo " proxy_pass http://mongrel;" >> $DANBOORU_CONF_FILE
echo " }" >> $DANBOORU_CONF_FILE
echo " }" >> $DANBOORU_CONF_FILE
echo " error_page 404 /404.html;" >> $DANBOORU_CONF_FILE
echo " error_page 500 502 503 504 /500.html;" >> $DANBOORU_CONF_FILE
echo "}" >> $DANBOORU_CONF_FILE
/etc/init.d/nginx restart
echo echo
echo "I'm done!" echo
echo "You should probably set the password for the danbooru account (run passwd danbooru)." echo "**************************************************************"
echo "* Danbooru has now been setup on this computer and should be *"
echo "* accessible from the web. Go ahead and create an account. *"
echo "* The first account will automatically be made an admin. You *"
echo "* can edit the configuration files by editing *"
echo "* /var/www/danbooru/shared/config/local_config and *"
echo "* /var/www/danbooru/shared/config/database.yml *"
echo "**************************************************************"

View File

@@ -1,138 +0,0 @@
Danbooru Installation guide on FreeBSD (6.2)
Provided by Shuugo
Cleanup of dovac's guide: http://uruchai.com/2007/12/24/in-depth-guide-on-installing-danbooru-on-freebsd
A minimal FreeBSD profile installation is encouraged. You can use VMWare to test how things work before trying on an actual machine.
1)) Updating ports:
You can find how fully work here: http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/ports-using.html but basically you will only need:
1. portsnap fetch
2. portsnap extract
2)) Install the following things through ports
1. cd /usr/ports/devel/mkmf/ && make install clean
2. cd /usr/ports/ftp/wget/ && make install clean
3. cd /usr/ports/editors/nano/ && make install clean
4. cd /usr/ports/devel/subversion/ && make install clean (May ask for configuration: Choose "libiconv", "python25", enable "huge stack size", and disable "ipv6"
5. cd /usr/ports/databases/memcached/ && make install clean
6. cd /usr/ports/graphics/gd/ && make install clean (Make sure you enable iconv support)
7. cd /usr/ports/databases/postgresql83-client/ && make install clean (config defaults are ok)
8. cd /usr/ports/databases/postgresql83-server/ && make install clean (config defaults are ok)
3)) Editing rc.conf for starting postgres and memcached at boot.
1. nano /etc/rc.conf
2. Add the following at the end of the file:
postgresql_enable="YES"
memcached_enable="yes"
memacached_flags="-l 127.0.0.1 -d m 100"
3. Press Control + X to save.
4. We run "/usr/local/etc/rc.d/postgresql initdb" to get ready to initialize postgres for first time.
5. Use "/usr/local/etc/rc.d/postgresql start", to start the postgresql server.
4)) Ruby on rails installation
1. cd /usr/ports/lang/ruby18/ && make install clean (Disable ipv6)
2. rubygem-rails port is broken, download it from rubyforge
2a wget http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz
2b tar xvf rubygems-1.0.1.tgz
2c cd rubygems-1.0.1
2d ruby setup.rb
3. cd /usr/ports/www/rubygem-rails/ && make install clean (Be sure it's rubygem-rails-1.2.6. Rails 2.0 isn't compatible yet)
4. cd /usr/ports/www/rubygem-redcloth/ && make install clean
5. cd /usr/ports/www/rubygem-mongrel/ && make install clean
Some gems are not available through ports
6a wget http://rubyforge.org/frs/download.php/29624/postgres-0.7.9.2007.12.22.gem
6b /usr/bin/gem18 install --no-ri --install-dir /usr/local/lib/ruby/gems/1.8 ./postgres-0.7.9.2007.12.22.gem (There's a chance that it's not gem18, but gem I'll assume it's the correct path, if not, replace it on the following steps too)
7. /usr/bin/gem18 aws-s3 diff-lcs acts_as_versioned html5 (Accept all dependencies)
5)) Danbooru installation
1. Create the danbooru user, -> adduser (danbooru, and choose a password)
2. cd /home/danbooru
3. svn co svn://danbooru.donmai.us/danbooru/trunk (This will get you the latest trunk)
4. cd trunk/
5. mv * ..
6. cd ..
7. rm -r trunk/
8. Database creation:
8a su pgsql
8b CREATE DATABASE danbooru;
8c \q
8d psql -d danbooru -f /home/danbooru/db/postgres.sql
8e exit
6)) Danbooru configuration
1. cd /home/danbooru/config
2. mv database.yml.example database.yml
3. nano database.yml
3a Change all users to pgsql (Control+X to save and exit)
4. mv local_config.rb.example local_config.rb
5. nano local_config.rb
NOTE: You can check for additional configuration parameters and a brief explanation in default_config.rb
5a. Change the parameters needed an add these parameters
CONFIG["password_salt"] = “choujin-steinerr” (replace the salt with something else)
CONFIG["image_store"] = :local_flat (replace with :local_hierarchy if you want scaled folders for example /01/23/fullhash.ext, leave :local_falt to leave all the images in one same folder)
CONFIG["enable_caching"] = false (change to true to enable memcache, this will speed up things)
CONFIG["memcache_servers"] = ["localhost:4000"] (change to "localhost:11211")
5b Control + X to save and exit.
6. Compiling the resizer
6a You can rather choose between using "ruby extconf.rb" or "ruby extconf.rb --with-gd-dir=/usr/local/gd", if you are using this last option you can ignore the 6b 6c and 6d steps. Using the first method will give you always the same gd version while the second command, the gd version will be updated when you update it through ports.
6b cp /usr/local/include/gd.h gd.h
6c cp /usr/local/include/gd_io.h gd_io.h
6d cp /usr/local/include/gdfx.h gdfx.h
6e make
6f make install
7. cd /home/danbooru
7b /usr/local/bin/rake db:migrate
7)) Basic webserver
- Now you can run "mongrel_rails start", this will make danbooru public on your hostname:3000. You will see debug information in the console
- For running it with mongrel and serving it "normally" you can use "mongrel_rails start -p 80 -d" This will tell mongrel to run on port 80 and as a daemon (not displaying anything in the console)
8)) Advanced webserver
Is encouraged that you rather configure Apache or lighttpd to proxy (or vhosting) the rails app. However this last method requries advanced configuration files and server modules.
If you plan only on running danbooru here's a good configuration for lighttpd usage (you can install it through ports)
Mongrel running as a daemon (4 threads) You might want to add this to the rc.conf if you want to start it automatically
1. cd /home/danbooru
2a mongrel_rails start -d -p 8001 -e production -P log/mongrel-1.pid
2b mongrel_rails start -d -p 8002 -e production -P log/mongrel-2.pid
2c mongrel_rails start -d -p 8003 -e production -P log/mongrel-3.pid
2d mongrel_rails start -d -p 8004 -e production -P log/mongrel-4.pid
Then on lighttpd.conf be sure to have the following mods enabled (Remove # before its names if not):
-mod_rewrite
-mod_redirect
-mod_access
-mod_accesslog
-mod_compress
-mod_proxy
3. Add this to your lighttpd.conf:
proxy.balance = "fair"
proxy.server = ( "/" =>
( ( "host" => "127.0.0.1", "port" => 8001 ),
( "host" => "127.0.0.1", "port" => 8002 ),
( "host" => "127.0.0.1", "port" => 8003 ),
( "host" => "127.0.0.1", "port" => 8004 ) ) )
4. Restart lighttpd: "/usr/local/etc/rc.d/lighttpd restart"

View File

@@ -50,17 +50,7 @@
location.href = domain + "/static/terms_of_service?url=" + location.href; location.href = domain + "/static/terms_of_service?url=" + location.href;
return; return;
} }
if (this.get("hide-news-ticker") == "1") {
$("#news-ticker").hide();
} else {
$("#close-news-ticker-link").click(function(e) {
$("#news-ticker").hide();
Danbooru.Cookie.put("hide-news-ticker", "1", 1);
return false;
});
}
if (this.get("hide-upgrade-account") != "1") { if (this.get("hide-upgrade-account") != "1") {
$("#upgrade-account").show(); $("#upgrade-account").show();
} }

View File

@@ -20,6 +20,36 @@
$("a#remove-from-favorites").hide(); $("a#remove-from-favorites").hide();
} }
} }
Danbooru.Favorite.create = function(post_id) {
Danbooru.Post.notice_update("inc");
$.ajax({
type: "POST",
url: "/favorites",
data: {
post_id: post_id
},
complete: function() {
Danbooru.Post.notice_update("dec");
},
error: function(data, status, xhr) {
Danbooru.j_alert("Error: " + data.reason);
}
});
}
Danbooru.Favorite.destroy = function(post_id) {
Danbooru.Post.notice_update("inc");
$.ajax({
type: "DELETE",
url: "/favorites/" + post_id,
complete: function() {
Danbooru.Post.notice_update("dec");
}
});
}
})(); })();
$(document).ready(function() { $(document).ready(function() {

View File

@@ -5,6 +5,19 @@
$("#c-forum-topics #preview").hide(); $("#c-forum-topics #preview").hide();
this.initialize_preview_link(); this.initialize_preview_link();
this.initialize_last_forum_read_at();
}
Danbooru.ForumPost.initialize_last_forum_read_at = function() {
var last_forum_read_at = Date.parse(Danbooru.meta("last-forum-read-at"));
$("#c-forum-topics #a-index time").each(function(i, x) {
var $x = $(x);
var $date = Date.parse($x.attr("datetime"));
if (Date.parse($x.attr("datetime")) > last_forum_read_at) {
$x.closest("tr").addClass("new-topic");
}
});
} }
Danbooru.ForumPost.initialize_preview_link = function() { Danbooru.ForumPost.initialize_preview_link = function() {

View File

@@ -0,0 +1,21 @@
(function() {
Danbooru.News = {};
Danbooru.News.initialize = function() {
var key = $("#news-ticker").data("updated-at");
if (Danbooru.Cookie.get("news-ticker") === key) {
$("#news-ticker").hide();
} else {
$("#close-news-ticker-link").click(function(e) {
$("#news-ticker").hide();
Danbooru.Cookie.put("news-ticker", key);
return false;
});
}
}
$(function() {
Danbooru.News.initialize();
});
})();

View File

@@ -0,0 +1,83 @@
(function() {
Danbooru.PostModeMenu = {};
Danbooru.PostModeMenu.initialize = function() {
this.initialize_selector();
this.initialize_preview_link();
}
Danbooru.PostModeMenu.initialize_selector = function() {
if (Danbooru.Cookie.get("mode") === "") {
Danbooru.Cookie.put("mode", "view");
$("#mode-box select").val("view");
} else {
$("#mode-box select").val(Danbooru.Cookie.get("mode"));
}
$("#mode-box select").click(Danbooru.PostModeMenu.change);
}
Danbooru.PostModeMenu.initialize_preview_link = function() {
$(".post-preview a").click(Danbooru.PostModeMenu.click);
}
Danbooru.PostModeMenu.change = function() {
var s = $("#mode-box select").val();
var $body = $(document.body);
$body.removeClass();
$body.addClass("mode-" + s);
Danbooru.Cookie.put("mode", s, 7);
if (s === "edit-tag-script") {
var script = Danbooru.Cookie.get("tag-script");
script = prompt("Enter a tag script", script);
if (script) {
Cookie.put("tag-script", script);
$("#mode-box select").val("apply-tag-script");
} else {
$("#mode-box select").val("view");
}
this.change();
}
}
Danbooru.PostModeMenu.click = function(e) {
var s = $("#mode-box select").val();
var post_id = $(e.target).closest("article").data("id");
if (s === "add-fav") {
Danbooru.Favorite.create(post_id);
} else if (s === "remove-fav") {
Danbooru.Favorite.destroy(post_id);
} else if (s === "edit") {
// TODO
} else if (s === 'vote-down') {
Danbooru.Post.vote("down", post_id);
} else if (s === 'vote-up') {
Danbooru.Post.vote("up", post_id);
} else if (s === 'rating-q') {
Danbooru.Post.update(post_id, {"post[rating]": "q"});
} else if (s === 'rating-s') {
Danbooru.Post.update(post_id, {"post[rating]": "s"});
} else if (s === 'rating-e') {
Danbooru.Post.update(post_id, {"post[rating]": "e"});
} else if (s === 'lock-rating') {
Danbooru.Post.update(post_id, {"post[is_rating_locked]": "1"});
} else if (s === 'lock-note') {
Danbooru.Post.update(post_id, {"post[is_note_locked]": "1"});
} else if (s === "apply-tag-script") {
var tag_script = Danbooru.Cookie.get("tag-script");
Danbooru.TagScript.run(post_id, tag_script);
} else {
return;
}
e.preventDefault();
}
})();
$(function() {
Danbooru.PostModeMenu.initialize();
});

View File

@@ -1,170 +1,8 @@
// PostModeMenu = {
// init: function() {
// this.original_background_color = $(document.body).css("background-color")
//
// if (Cookie.get("mode") == "") {
// Cookie.put("mode", "view");
// $("#mode-box select").val("view");
// } else {
// $("#mode-box select").val(Cookie.get("mode"));
// }
//
// // this.change();
// },
//
// change: function() {
// var s = $("#mode-box select").val();
// Cookie.put("mode", s, 7);
//
// if (s == "view") {
// $(document.body).css({"background-color": this.original_background_color});
// } else if (s == "edit") {
// $(document.body).css({"background-color": "#3A3"});
// } else if (s == "add-fav") {
// $(document.body).css({"background-color": "#FFA"});
// } else if (s == "remove-fav") {
// $(document.body).css({"background-color": "#FFA"});
// } else if (s == "rating-q") {
// $(document.body).css({"background-color": "#AAA"});
// } else if (s == "rating-s") {
// $(document.body).css({"background-color": "#6F6"});
// } else if (s == "rating-e") {
// $(document.body).css({"background-color": "#F66"});
// } else if (s == "vote-down") {
// $(document.body).css({"background-color": "#FAA"});
// } else if (s == "vote-up") {
// $(document.body).css({"background-color": "#AFA"});
// } else if (s == "lock-rating") {
// $(document.body).css({"background-color": "#AA3"});
// } else if (s == "lock-note") {
// $(document.body).css({"background-color": "#3AA"});
// } else if (s == "approve") {
// $(document.body).css({"background-color": "#26A"});
// } else if (s == "unapprove") {
// $(document.body).css({"background-color": "#F66"});
// } else if (s == "add-to-pool") {
// $(document.body).css({"background-color": "#26A"});
// } else if (s == "apply-tag-script") {
// $(document.body).css({"background-color": "#A3A"});
// } else if (s == "edit-tag-script") {
// $(document.body).css({"background-color": "#FFF"});
//
// var script = Cookie.get("tag-script");
// script = prompt("Enter a tag script", script);
//
// if (script) {
// Cookie.put("tag-script", script);
// $("#mode-box select").val("apply-tag-script");
// } else {
// $("#mode-box select").val("view");
// }
//
// this.change();
// } else {
// $(document.body).css({"background-color": "#AFA"});
// }
// },
//
// click: function(post_id) {
// var s = $("#mode-box select").val();
//
// if (s.value == "view") {
// return true;
// } else if (s.value == "add-fav") {
// Favorite.create(post_id);
// } else if (s.value == "remove-fav") {
// Favorite.destroy(post_id);
// } else if (s.value == "edit") {
// // TODO
// } else if (s.value == 'vote-down') {
// PostVote.create("down", post_id);
// } else if (s.value == 'vote-up') {
// PostVote.create("up", post_id);
// } else if (s.value == 'rating-q') {
// Post.update(post_id, {"post[rating]": "questionable"});
// } else if (s.value == 'rating-s') {
// Post.update(post_id, {"post[rating]": "safe"});
// } else if (s.value == 'rating-e') {
// Post.update(post_id, {"post[rating]": "explicit"});
// } else if (s.value == 'lock-rating') {
// Post.update(post_id, {"post[is_rating_locked]": "1"});
// } else if (s.value == 'lock-note') {
// Post.update(post_id, {"post[is_note_locked]": "1"});
// } else if (s.value == 'unapprove') {
// Unapproval.create(post_id);
// } else if (s.value == "approve") {
// Post.update(post_id, {"post[is_pending]": "0"});
// } else if (s.value == 'add-to-pool') {
// Pool.add_post(post_id, 0);
// } else if (s.value == "apply-tag-script") {
// var tag_script = Cookie.get("tag-script");
// TagScript.run(post_id, tag_script);
// }
//
// return false;
// }
// }
//
// TagScript = {
// parse: function(script) {
// return script.match(/\[.+?\]|\S+/g);
// },
//
// test: function(tags, predicate) {
// var split_pred = predicate.match(/\S+/g);
// var is_true = true;
//
// split_pred.each(function(x) {
// if (x[0] == "-") {
// if (tags.include(x.substr(1, 100))) {
// is_true = false;
// throw $break;
// }
// } else {
// if (!tags.include(x)) {
// is_true = false;
// throw $break;
// }
// }
// })
//
// return is_true
// },
//
// process: function(tags, command) {
// if (command.match(/^\[if/)) {
// var match = command.match(/\[if\s+(.+?)\s*,\s*(.+?)\]/)
// if (TagScript.test(tags, match[1])) {
// return TagScript.process(tags, match[2]);
// } else {
// return tags;
// }
// } else if (command == "[reset]") {
// return [];
// } else if (command[0] == "-") {
// return tags.reject(function(x) {return x == command.substr(1, 100)})
// } else {
// tags.push(command)
// return tags;
// }
// },
//
// run: function(post_id, tag_script) {
// var commands = TagScript.parse(tag_script);
// var post = Post.posts.get(post_id);
// var old_tags = post.tags.join(" ");
//
// commands.each(function(x) {
// post.tags = TagScript.process(post.tags, x);
// })
//
// Post.update(post_id, {"post[old_tags]": old_tags, "post[tags]": post.tags.join(" ")});
// }
// }
(function() { (function() {
Danbooru.Post = {}; Danbooru.Post = {};
Danbooru.Post.pending_update_count = 0;
Danbooru.Post.initialize_all = function() { Danbooru.Post.initialize_all = function() {
this.initialize_post_sections(); this.initialize_post_sections();
this.initialize_wiki_page_excerpt(); this.initialize_wiki_page_excerpt();
@@ -192,7 +30,7 @@
Danbooru.Cookie.put("hide-wiki-page-excerpt", "0"); Danbooru.Cookie.put("hide-wiki-page-excerpt", "0");
}); });
} }
Danbooru.Post.initialize_post_sections = function() { Danbooru.Post.initialize_post_sections = function() {
$("#post-sections li a").click(function(e) { $("#post-sections li a").click(function(e) {
$("#comments").hide(); $("#comments").hide();
@@ -209,11 +47,68 @@
$("#notes").hide(); $("#notes").hide();
$("#edit").hide(); $("#edit").hide();
} }
Danbooru.Post.notice_update = function(x) {
if (x === "inc") {
Danbooru.Post.pending_update_count += 1;
Danbooru.notice("Updating posts (" + Danbooru.Post.pending_update_count + " pending)...");
} else {
Danbooru.Post.pending_update_count -= 1;
if (Danbooru.Post.pending_update_count < 1) {
Danbooru.notice("Posts updated");
} else {
Danbooru.notice("Updating posts (" + Post.pending_update_count + " pending)...");
}
}
}
Danbooru.Post.update_data = function(data) {
var $post = $("#post_" + data.id);
$post.data("tags", data.tags);
}
Danbooru.Post.vote = function(score, id) {
Danbooru.Post.notice_update("inc");
$.ajax({
type: "POST",
url: "/posts/" + id + "/votes",
data: {
score: score
},
complete: function() {
Danbooru.Post.notice_update("dec");
},
success: function(data, status, xhr) {
$("post-score-" + data.post_id).html(data.score);
},
error: function(data, status, xhr) {
Danbooru.notice("Error: " + data.reason);
}
});
}
Danbooru.Post.update = function(post_id, params) {
Danbooru.Post.notice_update("inc");
$.ajax({
type: "PUT",
url: "/posts/" + post_id + ".json",
data: params,
complete: function() {
Danbooru.Post.notice_update("dec");
},
success: function(data, status, xhr) {
Danbooru.Post.update_data(data);
},
error: function(data, status, xhr) {
Danbooru.j_alert("Error: " + data.reason);
}
});
}
})(); })();
$(document).ready(function() { $(document).ready(function() {
// $("#mode-box select").click(PostModeMenu.change);
// PostModeMenu.init();
Danbooru.Post.initialize_all(); Danbooru.Post.initialize_all();
}); });

View File

@@ -0,0 +1,56 @@
(function() {
Danbooru.TagScript = {};
Danbooru.TagScript.parse = function(script) {
return script.match(/\[.+?\]|\S+/g);
}
Danbooru.TagScript.test = function(tags, predicate) {
var split_pred = predicate.match(/\S+/g);
var is_true = true;
$.each(split_pred, function(i, x) {
if (x[0] === "-") {
if (tags.include(x.substr(1, 100))) {
is_true = false;
}
} else {
if (!tags.include(x)) {
is_true = false;
}
}
});
return is_true;
}
Danbooru.TagScript.process = function(tags, command) {
if (command.match(/^\[if/)) {
var match = command.match(/\[if\s+(.+?)\s*,\s*(.+?)\]/)
if (this.test(tags, match[1])) {
return this.process(tags, match[2]);
} else {
return tags;
}
} else if (command === "[reset]") {
return [];
} else if (command[0] === "-") {
return Danbooru.reject(tags, function(x) {return x === command.substr(1, 100)});
} else {
tags.push(command)
return tags;
}
}
Danbooru.TagScript.run = function(post_id, tag_script) {
var commands = this.parse(tag_script);
var post = $("#p_" + post_id);
var old_tags = post.data("tags");
$.each(commands, function(i, x) {
post.data("tags", Danbooru.TagScript.process(post.data("tags"), x));
})
Danbooru.Post.update(post_id, {"post[old_tags]": old_tags, "post[tags]": post.data("tags")});
}
})();

View File

@@ -1,4 +1,4 @@
$(document).ready(function() { $(function() {
var img = $("#image-preview img"); var img = $("#image-preview img");
if (img) { if (img) {
var height = img.attr("height"); var height = img.attr("height");
@@ -7,7 +7,7 @@ $(document).ready(function() {
var ratio = 400.0 / height; var ratio = 400.0 / height;
img.attr("height", height * ratio); img.attr("height", height * ratio);
img.attr("width", width * ratio); img.attr("width", width * ratio);
$("#scale").val("Scaled " + parseInt(100 * ratio) + "%"); $("#scale").html("Scaled " + parseInt(100 * ratio) + "%");
} }
} }
}); });

View File

@@ -3,6 +3,10 @@
return $("meta[name=" + key + "]").attr("content"); return $("meta[name=" + key + "]").attr("content");
} }
Danbooru.notice = function(msg) {
$('#notice').html(msg).show();
}
Danbooru.j_alert = function(title, msg) { Danbooru.j_alert = function(title, msg) {
$('<div title="' + title + '"></div>').html(msg).dialog(); $('<div title="' + title + '"></div>').html(msg).dialog();
} }
@@ -30,4 +34,14 @@
return all; return all;
} }
Danbooru.reject = function(array, f) {
var filtered = [];
$.each(array, function(i, x) {
if (!f(x)) {
filtered.push(x);
}
});
return filtered;
}
})(); })();

View File

@@ -896,6 +896,10 @@ div#c-forum-topics {
color: #AAA; color: #AAA;
} }
tr.new-topic {
font-weight: bold;
}
div#form-content { div#form-content {
float: left; float: left;
width: 450px; width: 450px;
@@ -1079,7 +1083,7 @@ footer#page-footer {
margin: 1em; margin: 1em;
text-align: center; text-align: center;
padding-top: 1em; padding-top: 1em;
border-top: 2px solid #CCC; border-top: 1px solid #EEE;
} }
/*** news ticker ***/ /*** news ticker ***/
@@ -1108,3 +1112,69 @@ div#news-ticker {
float: right; float: right;
} }
} }
/*** post mode menus ***/
body#mode-view {
background-color: "#FFF";
}
body#mode-edit {
background-color: "#3A3";
}
body#mode-add-fav {
background-color: "#FFA";
}
body#mode-remove-fav {
background-color: "#FFA";
}
body#mode-rating-q {
background-color: "#AAA";
}
body#mode-rating-s {
background-color: "#6F6";
}
body#mode-rating-e {
background-color: "#F66";
}
body#mode-vote-down {
background-color: "#FAA";
}
body#mode-vote-up {
background-color: "#AFA";
}
body#mode-lock-rating {
background-color: "#AA3";
}
body#mode-lock-note {
background-color: "#3AA";
}
body#mode-approve {
background-color: "#26A";
}
body#mode-unapprove {
background-color: "#F66";
}
body#mode-add-to-pool {
background-color: "#26A";
}
body#mode-apply-tag-script {
background-color: "#A3A";
}
body#mode-edit-tag-script {
background-color: "#FFF";
}

View File

@@ -12,6 +12,11 @@ class ArtistsController < ApplicationController
respond_with(@artist) respond_with(@artist)
end end
def banned
@artists = Artist.where("is_banned = ?", true).order("name")
respond_with(@artists)
end
def index def index
@search = Artist.search(params[:search]) @search = Artist.search(params[:search])
@artists = @search.paginate(params[:page]) @artists = @search.paginate(params[:page])

View File

@@ -2,6 +2,7 @@ class ForumTopicsController < ApplicationController
respond_to :html, :xml, :json respond_to :html, :xml, :json
before_filter :member_only, :except => [:index, :show] before_filter :member_only, :except => [:index, :show]
before_filter :normalize_search, :only => :index before_filter :normalize_search, :only => :index
before_filter :update_last_forum_read_at, :only => [:index, :show]
rescue_from User::PrivilegeError, :with => "static/access_denied" rescue_from User::PrivilegeError, :with => "static/access_denied"
def new def new
@@ -56,6 +57,12 @@ private
forum_topic.is_sticky = params[:forum_topic][:is_sticky] forum_topic.is_sticky = params[:forum_topic][:is_sticky]
end end
def update_last_forum_read_at
return if CurrentUser.last_forum_read_at.present? && CurrentUser.last_forum_read_at > 1.day.ago
CurrentUser.update_column(:last_forum_read_at, Time.now)
end
def normalize_search def normalize_search
if params[:title_matches] if params[:title_matches]
params[:search] ||= {} params[:search] ||= {}

View File

@@ -6,6 +6,7 @@ class SessionsController < ApplicationController
def create def create
if User.authenticate(params[:name], params[:password]) if User.authenticate(params[:name], params[:password])
@user = User.find_by_name(params[:name]) @user = User.find_by_name(params[:name])
@user.update_column(:last_logged_in_at, Time.now)
session[:user_id] = @user.id session[:user_id] = @user.id
redirect_to(params[:url] || session[:previous_uri] || posts_path, :notice => "You are now logged in.") redirect_to(params[:url] || session[:previous_uri] || posts_path, :notice => "You are now logged in.")
else else

View File

@@ -23,6 +23,7 @@ class UploadsController < ApplicationController
def create def create
@upload = Upload.create(params[:upload]) @upload = Upload.create(params[:upload])
@upload.delay.process!
respond_with(@upload) respond_with(@upload)
end end

View File

@@ -22,6 +22,7 @@ class UsersController < ApplicationController
def show def show
@user = User.find(params[:id]) @user = User.find(params[:id])
@presenter = UserPresenter.new(@user)
respond_with(@user) respond_with(@user)
end end

View File

@@ -22,7 +22,7 @@ module AdvertisementsHelper
def render_rss_advertisement def render_rss_advertisement
if Danbooru.config.can_user_see_ads?(CurrentUser.user) if Danbooru.config.can_user_see_ads?(CurrentUser.user)
render :partial => "static/jlist_rss_ads" render "static/jlist_rss_ads"
end end
end end
end end

View File

@@ -23,13 +23,20 @@ module ApplicationHelper
end end
end end
def time_tag(content = nil, time)
zone = time.strftime("%z")
datetime = time.strftime("%Y-%m-%dT%H:%M" + zone[0, 3] + ":" + zone[3, 2])
content_tag(:time, content || datetime, :datetime => datetime)
end
def compact_time(time) def compact_time(time)
if time > Time.now.beginning_of_day if time > Time.now.beginning_of_day
time.strftime("%H:%M") time_tag(time.strftime("%H:%M"), time)
elsif time > Time.now.beginning_of_year elsif time > Time.now.beginning_of_year
time.strftime("%b %e") time_tag(time.strftime("%b %e"), time)
else else
time.strftime("%b %e, %Y") time_tag(time.strftime("%b %e, %Y"), time)
end end
end end
@@ -62,7 +69,7 @@ protected
when "uploads" when "uploads"
/^\/post/ /^\/post/
when "post_versions" when "post_versions", "explore/posts"
/^\/post/ /^\/post/
when "pool_versions" when "pool_versions"

View File

@@ -112,6 +112,13 @@ class AnonymousUser
[] []
end end
def last_forum_read_at
Time.now
end
def update_column(*params)
end
%w(member banned privileged contributor janitor moderator admin).each do |name| %w(member banned privileged contributor janitor moderator admin).each do |name|
define_method("is_#{name}?") do define_method("is_#{name}?") do
false false

View File

@@ -0,0 +1,23 @@
class RemoteFileManager
attr_reader :path
def initialize(path)
@path = path
end
def distribute
Danbooru.config.other_server_hosts.each do |hostname|
Net::SFTP.start(hostname, Danbooru.config.remote_server_login) do |ftp|
ftp.upload!(path, path)
end
end
end
def delete
Danbooru.config.other_server_hosts.each do |hostname|
Net::SFTP.start(hostname, Danbooru.config.remote_server_login) do |ftp|
ftp.remove(path)
end
end
end
end

View File

@@ -0,0 +1,44 @@
require 'base64'
require 'digest/md5'
class AmazonBackup < ActiveRecord::Base
def self.last_id
first.last_id
end
def self.update_id(new_id)
first.update_column(:last_id, new_id)
end
def self.execute
last_id = AmazonBackup.last_id
Post.where("id > ?", last_id).limit(200).order("id").each do |post|
AWS::S3::Base.establish_connection!(
:access_key_id => Danbooru.config.amazon_s3_access_key_id,
:secret_access_key => Danbooru.config.amazon_s3_secret_access_key
)
if File.exists?(post.file_path)
base64_md5 = Base64.encode64(Digest::MD5.digest(File.read(post.file_path)))
AWS::S3::S3Object.store(post.file_name, open(post.file_path, "rb"), Danbooru.config.amazon_s3_bucket_name, "Content-MD5" => base64_md5)
end
if post.image? && File.exists?(post.preview_file_path)
AWS::S3::S3Object.store("preview/#{post.md5}.jpg", open(post.preview_file_path, "rb"), Danbooru.config.amazon_s3_bucket_name)
end
if File.exists?(post.medium_file_path)
AWS::S3::S3Object.store("medium/#{post.md5}.jpg", open(post.medium_file_path, "rb"), Danbooru.config.amazon_s3_bucket_name)
end
if File.exists?(post.large_file_path)
AWS::S3::S3Object.store("large/#{post.md5}.jpg", open(post.large_file_path, "rb"), Danbooru.config.amazon_s3_bucket_name)
end
AmazonBackup.update_id(last_id)
end
rescue Exception => x
# probably some network error, retry next time
end
end

View File

@@ -166,6 +166,10 @@ class Artist < ActiveRecord::Base
include NoteMethods include NoteMethods
include TagMethods include TagMethods
def ban!
end
def initialize_creator def initialize_creator
self.creator_id = CurrentUser.user.id self.creator_id = CurrentUser.user.id
end end

View File

@@ -1,27 +0,0 @@
module Jobs
class BackupToS3 < Struct.new(:last_id)
def perform
Post.find(:all, :conditions => ["id > ?", last_id], :limit => 200, :order => "id").each do |post|
AWS::S3::Base.establish_connection!(:access_key_id => CONFIG["amazon_s3_access_key_id"], :secret_access_key => CONFIG["amazon_s3_secret_access_key"])
if File.exists?(post.file_path)
base64_md5 = Base64.encode64(Digest::MD5.digest(File.read(post.file_path)))
AWS::S3::S3Object.store(post.file_name, open(post.file_path, "rb"), CONFIG["amazon_s3_bucket_name"], "Content-MD5" => base64_md5)
end
if post.image? && File.exists?(post.preview_path)
AWS::S3::S3Object.store("preview/#{post.md5}.jpg", open(post.preview_path, "rb"), CONFIG["amazon_s3_bucket_name"])
end
if File.exists?(post.sample_path)
AWS::S3::S3Object.store("sample/" + CONFIG["sample_filename_prefix"] + "#{post.md5}.jpg", open(post.sample_path, "rb"), CONFIG["amazon_s3_bucket_name"])
end
self.last_id = post.id
end
Delayed::Job.enqueue(BackupToS3.new(last_id))
rescue Exception => x
# probably some network error, retry next time
end
end
end

View File

@@ -1,7 +0,0 @@
module Jobs
class CalculatePostCount < Struct.new(:tag_name)
def perform
Tag.recalculate_post_count(tag_name)
end
end
end

View File

@@ -1,12 +0,0 @@
module Jobs
class CalculateRelatedTags < Struct.new(:tag_id)
def perform
tag = Tag.find_by_id(tag_id)
if tag
tag.update_related
tag.save
end
end
end
end

View File

@@ -1,13 +0,0 @@
module Jobs
class CalculateUploadedTags < Struct.new(:user_id)
def perform
tags = []
user = User.find(user_id)
CONFIG["tag_types"].values.uniq.each do |tag_type|
tags += user.calculate_uploaded_tags(tag_type)
end
user.update_column(:uploaded_tags, tags.join("\n"))
end
end
end

View File

@@ -1,12 +0,0 @@
module Jobs
class CreateTagAlias < Struct.new(:antecedent_name, :consequent_name, :creator_id, :creator_ip_addr)
def execute
TagAlias.create(
:antecedent_name => antecedent_name,
:consequent_name => consequent_name,
:creator_id => creator_id,
:creator_ip_addr => creator_ip_addr
)
end
end
end

View File

@@ -1,12 +0,0 @@
module Jobs
class CreateTagImplication < Struct.new(:antecedent_name, :consequent_name, :creator_id, :creator_ip_addr)
def perform
TagImplication.create(
:antecedent_name => antecedent_name,
:consequent_name => consequent_name,
:creator_id => creator_id,
:creator_ip_addr => creator_ip_addr
)
end
end
end

View File

@@ -1,13 +0,0 @@
module Jobs
class FixPixivUploads < Struct.new(:last_post_id)
def perform
post_id = nil
Post.find_each(:conditions => ["GREATEST(width, height) IN (150, 600) AND source LIKE ? AND id > ?", "%pixiv%", last_post_id]) do |post|
post_id = post.id
end
update_attributes(:data => {:last_post_id => post_id})
end
end
end

View File

@@ -1,7 +0,0 @@
module Jobs
class MassTagEdit < Struct.new(:start_tags, :result_tags, :updater_id, :updater_ip_addr)
def perform
Tag.mass_edit(start_tags, result_tags, updater_id, updater_ip_addr)
end
end
end

View File

@@ -1,10 +0,0 @@
module Jobs
class ProcessTagSubscriptions < Struct.new(:last_run)
def perform
if last_run.nil? || last_run < 20.minutes.ago
TagSubscription.process_all
Delayed::Job.enqueue(ProcessTagSubscriptions.new(Time.now))
end
end
end
end

View File

@@ -1,9 +0,0 @@
module Jobs
class ProcessUploads
def perform
Upload.find_each(:conditions => ["status = ?", "pending"]) do |upload|
upload.process!
end
end
end
end

View File

@@ -5,6 +5,7 @@ class Post < ActiveRecord::Base
attr_accessor :old_tag_string, :old_parent_id attr_accessor :old_tag_string, :old_parent_id
after_destroy :delete_files after_destroy :delete_files
after_destroy :delete_remote_files
after_save :create_version after_save :create_version
after_save :update_parent_on_save after_save :update_parent_on_save
before_save :merge_old_tags before_save :merge_old_tags
@@ -61,11 +62,28 @@ class Post < ActiveRecord::Base
} }
module FileMethods module FileMethods
def distribute_files
RemoteFileManager.new(file_path).distribute
RemoteFileManager.new(real_preview_file_path).distribute
RemoteFileManager.new(ssd_preview_file_path).distribute if Danbooru.config.ssd_path
RemoteFileManager.new(medium_file_path).distribute if has_medium?
RemoteFileManager.new(large_file_path).distribute if has_large?
end
def delete_remote_files
RemoteFileManager.new(file_path).delete
RemoteFileManager.new(real_preview_file_path).delete
RemoteFileManager.new(ssd_preview_file_path).delete if Danbooru.config.ssd_path
RemoteFileManager.new(medium_file_path).delete if has_medium?
RemoteFileManager.new(large_file_path).delete if has_large?
end
def delete_files def delete_files
FileUtils.rm_f(file_path) FileUtils.rm_f(file_path)
FileUtils.rm_f(medium_file_path) FileUtils.rm_f(medium_file_path)
FileUtils.rm_f(large_file_path) FileUtils.rm_f(large_file_path)
FileUtils.rm_f(preview_file_path) FileUtils.rm_f(ssd_preview_file_path) if Danbooru.config.ssd_path
FileUtils.rm_f(real_preview_file_path)
end end
def file_path_prefix def file_path_prefix
@@ -91,9 +109,21 @@ class Post < ActiveRecord::Base
file_path file_path
end end
end end
def real_preview_file_path
"#{Rails.root}/public/data/preview/#{file_path_prefix}#{md5}.jpg"
end
def ssd_preview_file_path
"#{Danbooru.config.ssd_path}/public/data/preview/#{file_path_preview}#{md5}.jpg"
end
def preview_file_path def preview_file_path
"#{Rails.root}/public/data/preview/#{file_path_prefix}#{md5}.jpg" if Danbooru.config.ssd_path
ssd_preview_file_path
else
real_preview_file_path
end
end end
def file_url def file_url
@@ -117,7 +147,11 @@ class Post < ActiveRecord::Base
end end
def preview_file_url def preview_file_url
"/data/preview/#{file_path_prefix}#{md5}.jpg" if Danbooru.config.ssd_path
"/ssd/data/preview/#{file_path_prefix}#{md5}.jpg"
else
"/data/preview/#{file_path_prefix}#{md5}.jpg"
end
end end
def file_url_for(user) def file_url_for(user)

View File

@@ -48,6 +48,8 @@ class Upload < ActiveRecord::Base
module ConversionMethods module ConversionMethods
def process! def process!
return if status =~ /processing|completed|error/
CurrentUser.scoped(uploader, uploader_ip_addr) do CurrentUser.scoped(uploader, uploader_ip_addr) do
update_attribute(:status, "processing") update_attribute(:status, "processing")
if is_downloadable? if is_downloadable?
@@ -64,6 +66,7 @@ class Upload < ActiveRecord::Base
generate_resizes(file_path) generate_resizes(file_path)
move_file move_file
post = convert_to_post post = convert_to_post
post.distribute_files
if post.save if post.save
update_attributes(:status => "completed", :post_id => post.id) update_attributes(:status => "completed", :post_id => post.id)
else else
@@ -231,7 +234,7 @@ class Upload < ActiveRecord::Base
end end
def temp_file_path def temp_file_path
@temp_file_path ||= File.join(Rails.root, "tmp", "upload_#{Time.now.to_f}.#{$PROCESS_ID}") @temp_file_path ||= File.join(Rails.root, "tmp", "upload_#{Time.now.to_f}.#{Process.pid}")
end end
end end
@@ -258,7 +261,7 @@ class Upload < ActiveRecord::Base
self.file_path = temp_file_path self.file_path = temp_file_path
if file.tempfile if file.respond_to?(:tempfile) && file.tempfile
FileUtils.cp(file.tempfile.path, file_path) FileUtils.cp(file.tempfile.path, file_path)
else else
File.open(file_path, 'wb') do |out| File.open(file_path, 'wb') do |out|
@@ -279,6 +282,10 @@ class Upload < ActiveRecord::Base
status == "pending" status == "pending"
end end
def is_processing?
status == "processing"
end
def is_completed? def is_completed?
status == "completed" status == "completed"
end end

View File

@@ -30,7 +30,7 @@ class User < ActiveRecord::Base
has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy
has_many :posts, :foreign_key => "uploader_id" has_many :posts, :foreign_key => "uploader_id"
has_one :ban has_one :ban
has_many :subscriptions, :class_name => "TagSubscription" has_many :subscriptions, :class_name => "TagSubscription", :foreign_key => "creator_id"
has_many :note_versions, :foreign_key => "updater_id" has_many :note_versions, :foreign_key => "updater_id"
belongs_to :inviter, :class_name => "User" belongs_to :inviter, :class_name => "User"
scope :named, lambda {|name| where(["lower(name) = ?", name])} scope :named, lambda {|name| where(["lower(name) = ?", name])}

View File

@@ -5,8 +5,4 @@ class ForumTopicPresenter < Presenter
@forum_posts = forum_posts @forum_posts = forum_posts
@forum_topic = forum_topic @forum_topic = forum_topic
end end
def pagination_html(template)
Paginators::ForumTopic.new(forum_topic, forum_posts).numbered_pagination_html(template)
end
end end

View File

@@ -26,9 +26,9 @@ class PostPresenter < Presenter
return template.content_tag("p", "You need a privileged account to see this image.") if !Danbooru.config.can_user_see_post?(CurrentUser.user, @post) return template.content_tag("p", "You need a privileged account to see this image.") if !Danbooru.config.can_user_see_post?(CurrentUser.user, @post)
if @post.is_flash? if @post.is_flash?
template.render(:partial => "posts/partials/show/flash", :locals => {:post => @post}) template.render("posts/partials/show/flash", :post => @post)
elsif @post.is_image? elsif @post.is_image?
template.render(:partial => "posts/partials/show/image", :locals => {:post => @post}) template.render("posts/partials/show/image", :post => @post)
end end
end end

View File

@@ -18,7 +18,7 @@ class PostSetPresenter < Presenter
html = "<div class='post-previews'>" html = "<div class='post-previews'>"
if posts.empty? if posts.empty?
return template.render(:partial => "post_sets/blank") return template.render("post_sets/blank")
end end
posts.each do |post| posts.each do |post|

View File

@@ -8,7 +8,7 @@ module PostSetPresenters
html = "" html = ""
if posts.empty? if posts.empty?
return template.render(:partial => "post_sets/blank") return template.render("post_sets/blank")
end end
posts.each do |post| posts.each do |post|

View File

@@ -1,7 +1,7 @@
module PostSetPresenters module PostSetPresenters
class Popular < Base class Popular < Base
attr_accessor :post_set, :tag_set_presenter attr_accessor :post_set, :tag_set_presenter
delegate :posts, :date, :to => :post_set delegate :posts, :date, :min_date, :max_date, :to => :post_set
def initialize(post_set) def initialize(post_set)
@post_set = post_set @post_set = post_set
@@ -30,5 +30,15 @@ module PostSetPresenters
def next_month def next_month
1.month.since(date) 1.month.since(date)
end end
def range_text
if min_date == max_date
date.strftime("%B %d, %Y")
elsif max_date - min_date == 6
min_date.strftime("Week of %B %d, %Y")
else
date.strftime("%B %Y")
end
end
end end
end end

View File

@@ -5,6 +5,10 @@ class UserPresenter
@user = user @user = user
end end
def join_date
user.created_at.strftime("%Y-%m-%d")
end
def level def level
user.level_string user.level_string
end end
@@ -26,7 +30,7 @@ class UserPresenter
def upload_limit def upload_limit
deleted_count = Post.for_user(user.id).deleted.count deleted_count = Post.for_user(user.id).deleted.count
pending_count = Post.for_user(user.id).pending.count pending_count = Post.for_user(user.id).pending.count
approved_count = Post.where("is_flagged = false and is_pending = false and user_id = ?", user.id).count approved_count = Post.where("is_flagged = false and is_pending = false and uploader_id = ?", user.id).count
if user.base_upload_limit if user.base_upload_limit
limit = user.base_upload_limit - pending_count limit = user.base_upload_limit - pending_count
@@ -89,7 +93,7 @@ class UserPresenter
if user.inviter_id if user.inviter_id
template.link_to(user.inviter.name, template.user_path(user.inviter_id)) template.link_to(user.inviter.name, template.user_path(user.inviter_id))
else else
nil "None"
end end
end end
@@ -102,6 +106,16 @@ class UserPresenter
neutral = UserFeedback.for_user(user.id).neutral.count neutral = UserFeedback.for_user(user.id).neutral.count
negative = UserFeedback.for_user(user.id).negative.count negative = UserFeedback.for_user(user.id).negative.count
template.link_to("positive:#{positive} neutral:#{neutral} negative:#{negative}", user_feedbacks_path(:search => {:user_id_rq => user.id})) template.link_to("positive:#{positive} neutral:#{neutral} negative:#{negative}", template.user_feedbacks_path(:search => {:user_id_rq => user.id}))
end
def subscriptions(template)
if user.subscriptions.any?
user.subscriptions.map do |subscription|
template.link_to(subscription.name, template.posts_path(:tags => "sub:#{user.name}:#{subscription.name}"))
end.join(", ").html_safe
else
"None"
end
end end
end end

View File

@@ -1,3 +1,9 @@
<%= image_tag(@advertisement.image_url) %> <div id="c-advertisements">
<%= render "form" %> <div id="a-edit">
<h1>Edit Advertisement</h1>
<%= image_tag(@advertisement.image_url) %>
<%= render "form" %>
</div>
</div>
<%= render "secondary_links" %> <%= render "secondary_links" %>

View File

@@ -1,22 +1,26 @@
<h4>Advertisements</h4> <div id="c-advertisements">
<div id="c-index">
<h1>Advertisements</h1>
<table width="100%" class="highlightable"> <table width="100%" class="highlightable">
<thead> <thead>
<tr> <tr>
<th width="5%"></th> <th width="5%"></th>
<th width="5%" style="text-align: right;">Hits</th> <th width="5%" style="text-align: right;">Hits</th>
<th width="90%"></th> <th width="90%"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% @advertisements.each do |advertisement| %> <% @advertisements.each do |advertisement| %>
<tr> <tr>
<td><%= image_tag(advertisement.image_url, :width => advertisement.preview_width, :height => advertisement.preview_height) %></td> <td><%= image_tag(advertisement.image_url, :width => advertisement.preview_width, :height => advertisement.preview_height) %></td>
<td style="text-align: right;"><%= advertisement.hits.between(@start_date, @end_date).count %></td> <td style="text-align: right;"><%= advertisement.hits.between(@start_date, @end_date).count %></td>
<td><%= link_to "Edit", edit_advertisement_path(advertisement) %></td> <td><%= link_to "Edit", edit_advertisement_path(advertisement) %></td>
</tr> </tr>
<% end %> <% end %>
</tbody> </tbody>
</table> </table>
</div>
</div>
<%= render "secondary_links" %> <%= render "secondary_links" %>

View File

@@ -1,3 +1,9 @@
<%= error_messages_for :advertisement %> <div id="c-advertisements">
<%= render "form" %> <div id="a-new">
<h1>New Advertisement</h1>
<%= error_messages_for :advertisement %>
<%= render "form" %>
</div>
</div>
<%= render "secondary_links" %> <%= render "secondary_links" %>

View File

@@ -1,7 +1,14 @@
<div><%= image_tag(@advertisement.image_url, :width => @advertisement.preview_width, :height => @advertisement.preview_height) %></div> <div id="c-advertisements">
<div id="a-show">
<h1>Show Advertisement</h1>
<%= image_tag(@advertisement.image_url, :width => @advertisement.preview_width, :height => @advertisement.preview_height) %>
<ul>
<li>Hits: <%= @advertisement.hits.between(@start_date, @end_date).count %></li>
</ul>
</div>
</div>
<ul>
<li>Hits: <%= @advertisement.hits.between(@start_date, @end_date).count %></li>
</ul>
<%= render "secondary_links" %> <%= render "secondary_links" %>

View File

@@ -0,0 +1,13 @@
<div id="c-artists">
<div id="a-banned">
<h1>Banned Artists</h1>
<p>The following artists have requested they be removed from the site. Please do not upload any works from these artists. These artists all have implications pointing to the <code>banned_artist</code> tag.</p>
<ul>
<% @artists.each do |artist| %>
<li><%= link_to artist.name, artist_path(artist) %></li>
<% end %>
</ul>
</div>
</div>

View File

@@ -1,5 +1,7 @@
<div id="c-artists"> <div id="c-artists">
<div id="a-index"> <div id="a-index">
<h1>Artists</h1>
<table class="striped" width="100%"> <table class="striped" width="100%">
<thead> <thead>
<tr> <tr>

View File

@@ -1,7 +1,7 @@
<div class="bans"> <div class="bans">
<div class="new"> <div class="new">
<h1>Edit Ban</h1> <h1>Edit Ban</h1>
<%= render :partial => "form", :locals => {:ban => @ban} %> <%= render "form", :ban => @ban %>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,7 @@
<div class="bans"> <div class="bans">
<div class="index"> <div class="index">
<h1>Bans</h1>
<table> <table>
<thead> <thead>
<tr> <tr>

View File

@@ -1,7 +1,7 @@
<div class="bans"> <div class="bans">
<div class="new"> <div class="new">
<h1>New Ban</h1> <h1>New Ban</h1>
<%= render :partial => "form", :locals => {:ban => @ban} %> <%= render "form", :ban => @ban %>
</div> </div>
</div> </div>

View File

@@ -0,0 +1 @@
$("div.comments-for-post[data-post-id=<%= @comment.post_id %>] div.list-of-comments").append("<%= escape_javascript(render('comments/partials/show/comment', :comment => @comment)) %>");

View File

@@ -1 +0,0 @@
page.insert_html(:bottom, "div.comments-for-post[data-post-id=#{@comment.post_id}] div.list-of-comments", :partial => "comments/partials/show/comment", :locals => {:comment => @comment})

View File

@@ -1,9 +1,11 @@
<div id="c-comments"> <div id="c-comments">
<div id="a-index"> <div id="a-index">
<h1>Comments</h1>
<div class="comments-for-post"> <div class="comments-for-post">
<div class="list-of-comments"> <div class="list-of-comments">
<% @comments.each do |comment| %> <% @comments.each do |comment| %>
<%= render :partial => "comments/partials/show/comment", :locals => {:post => comment.post, :comment => comment, :show_header => false} %> <%= render "comments/partials/show/comment", :post => comment.post, :comment => comment, :show_header => false %>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@@ -11,7 +11,7 @@
<div class="preview"> <div class="preview">
<%= link_to(image_tag(post.preview_file_url), post_path(post)) %> <%= link_to(image_tag(post.preview_file_url), post_path(post)) %>
</div> </div>
<%= render :partial => "comments/partials/index/list", :locals => {:post => post, :comments => post.comments.recent.reverse, :show_header => true} %> <%= render "comments/partials/index/list", :post => post, :comments => post.comments.recent.reverse, :show_header => true %>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<% end %> <% end %>
@@ -20,4 +20,4 @@
</div> </div>
</div> </div>
<%= render "comments/secondary_links" %> <%= render "comments/secondary_links" %>

View File

@@ -1,6 +1,6 @@
<div class="comments-for-post" data-post-id="<%= post.id %>"> <div class="comments-for-post" data-post-id="<%= post.id %>">
<% if show_header %> <% if show_header %>
<%= render :partial => "comments/partials/index/header", :locals => {:post => post} %> <%= render "comments/partials/index/header", :post => post %>
<% end %> <% end %>
<div class="list-of-comments"> <div class="list-of-comments">
@@ -15,6 +15,6 @@
<div class="new-comment"> <div class="new-comment">
<p><%= link_to "Post comment", new_comment_path, :class => "expand-comment-response" %></p> <p><%= link_to "Post comment", new_comment_path, :class => "expand-comment-response" %></p>
<%= render :partial => "comments/partials/new/form", :locals => {:post => post} %> <%= render "comments/partials/new/form", :post => post %>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,7 @@
<div id="c-comments"> <div id="c-comments">
<div id="a-search"> <div id="a-search">
<h1>Search Comments</h1> <h1>Search Comments</h1>
<%= simple_form_for(@search) do |f| %> <%= simple_form_for(@search) do |f| %>
<%= hidden_field_tag "group_by", "comment" %> <%= hidden_field_tag "group_by", "comment" %>
<%= f.input :body_matches, :label => "Body", :required => false %> <%= f.input :body_matches, :label => "Body", :required => false %>

View File

@@ -1,2 +1,7 @@
<h1>Edit Message</h1> <div id="c-dmails">
<%= render :partial => "form", :locals => {:dmail => @dmail} %> <div id="a-edit">
<h1>Edit Message</h1>
<%= render "form", :dmail => @dmail %>
</div>
</div>

View File

@@ -1,15 +1,19 @@
<h1>Messages</h1> <div id="c-dmails">
<div id="a-index">
<h1>Messages</h1>
<%= render "search" %> <%= render "search" %>
<table> <table>
<tbody> <tbody>
<% @dmails.each do |dmail| %> <% @dmails.each do |dmail| %>
<% if params[:folder] == "sent" %> <% if params[:folder] == "sent" %>
<%= render :partial => "sent", :locals => {:dmail => dmail} %> <%= render "sent", :dmail => dmail %>
<% else %> <% else %>
<%= render :partial => "received", :locals => {:dmail => dmail} %> <%= render "received", :dmail => dmail %>
<% end %> <% end %>
<% end %> <% end %>
</tbody> </tbody>
</table> </table>
</div>
</div>

View File

@@ -1,2 +1,7 @@
<h1>New Message</h1> <div id="c-dmails">
<%= render :partial => "form", :locals => {:dmail => @dmail} %> <div id="a-new">
<h1>New Message</h1>
<%= render "form", :dmail => @dmail %>
</div>
</div>

View File

@@ -1,8 +1,9 @@
<div class="dmails"> <div class="c-dmails">
<div class="show"> <div class="a-show">
<div class="dmail"> <div class="dmail">
<h1><%= @dmail.title %></h1> <h1><%= @dmail.title %></h1>
<%= format_text(@dmail.body) %> <%= format_text(@dmail.body) %>
<p> <p>
<%= link_to "Respond", new_dmail_path(:respond_to_id => @dmail) %> <%= link_to "Respond", new_dmail_path(:respond_to_id => @dmail) %>
| <%= link_to "Forward", new_dmail_path(:respond_to_id => @dmail, :forward => true) %> | <%= link_to "Forward", new_dmail_path(:respond_to_id => @dmail, :forward => true) %>

View File

@@ -1,6 +1,6 @@
<div id="c-explore-posts"> <div id="c-explore-posts">
<div id="a-index"> <div id="a-index">
<h1>Explore: <%= @post_set.min_date %> &ndash; <%= @post_set.max_date %></h1> <h1>Explore: <%= @post_set.presenter.range_text %></h1>
<%= render "date_explore", :post_set => @post_set %> <%= render "date_explore", :post_set => @post_set %>

View File

@@ -1,11 +1,11 @@
<div id="c-favorites"> <div id="c-favorites">
<div id="a-index"> <div id="a-index">
<aside id="sidebar"> <aside id="sidebar">
<%= render :partial => "posts/partials/common/search", :locals => {:path => favorites_path, :tags => @favorite_set.tag_string} %> <%= render "posts/partials/common/search", :path => favorites_path, :tags => @favorite_set.tag_string %>
<% if CurrentUser.is_privileged? %> <% if CurrentUser.is_privileged? %>
<section id="mode-box"> <section id="mode-box">
<%= render :partial => "posts/partials/index/mode_menu" %> <%= render "posts/partials/index/mode_menu" %>
</section> </section>
<% end %> <% end %>
@@ -29,7 +29,7 @@
/fav:<%= CurrentUser.name %> /fav:<%= CurrentUser.name %>
<% end %> <% end %>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,6 @@
<div class="list-of-forum-posts"> <div class="list-of-forum-posts">
<% forum_posts.each do |forum_post| %> <% forum_posts.each do |forum_post| %>
<%= render :partial => "forum_posts/forum_post", :locals => {:forum_post => forum_post} %> <%= render "forum_posts/forum_post", :forum_post => forum_post %>
<% end %> <% end %>
</div> </div>

View File

@@ -1,6 +1,6 @@
<div id="c-forum-topics"> <div id="c-forum-topics">
<div id="a-show" class="single-forum-post list-of-forum-posts"> <div id="a-show" class="single-forum-post list-of-forum-posts">
<%= render :partial => "forum_post", :locals => {:forum_post => @forum_post} %> <%= render "forum_post", :forum_post => @forum_post %>
</div> </div>
</div> </div>

View File

@@ -1 +0,0 @@
<%= @forum_topic.presenter(@forum_posts).pagination_html(self) %>

View File

@@ -1,24 +1,34 @@
<h1>Forum</h1> <div id="c-forum-topics">
<div id="a-index">
<h1>Forum</h1>
<table width="100%" class="striped"> <table width="100%" class="striped">
<thead> <thead>
<tr> <tr>
<th>Title</th> <th>Title</th>
<th>Creator</th> <th>Creator</th>
<th>Updated by</th> <th>Updated by</th>
<th>Updated at</th> <th>Updated at</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% @forum_topics.each do |topic| %> <% @forum_topics.each do |topic| %>
<tr> <tr>
<td><% if topic.is_sticky? %><span class="sticky">Sticky:</span> <% end %><%= link_to topic.title, forum_topic_path(topic) %></td> <td><% if topic.is_sticky? %><span class="sticky">Sticky:</span> <% end %><%= link_to topic.title, forum_topic_path(topic) %></td>
<td><%= topic.creator.name %></td> <td><%= topic.creator.name %></td>
<td><%= topic.updater.name %></td> <td><%= topic.updater.name %></td>
<td><%= compact_time topic.updated_at %></td> <td><%= compact_time topic.updated_at %></td>
</tr> </tr>
<% end %> <% end %>
</tbody> </tbody>
</table> </table>
<%= numbered_paginator(@forum_topics) %>
</div>
</div>
<%= render "secondary_links" %> <%= render "secondary_links" %>
<%= content_for(:html_header) do %>
<meta name="last-forum-read-at" content="<%= CurrentUser.last_forum_read_at.to_date %>">
<% end %>

View File

@@ -6,13 +6,14 @@
</div> </div>
<% end %> <% end %>
<%= render :partial => "forum_posts/listing", :locals => {:forum_posts => @forum_posts} %> <%= render "forum_posts/listing", :forum_posts => @forum_posts %>
<%= render "paginator" %>
<%= numbered_paginator(@forum_posts) %>
</div> </div>
</div> </div>
<%= render "secondary_links" %> <%= render "secondary_links" %>
<%= content_for(:page_title) do %> <%= content_for(:page_title) do %>
forum/<%= @forum_topic.title %> forum/<%= @forum_topic.title %>
<% end %> <% end %>

View File

@@ -1,22 +1,27 @@
<h1>IP Bans</h1> <div id="c-ip-bans">
<div id="a-index">
<h1>IP Bans</h1>
<table>
<thead>
<tr>
<th>IP Address</th>
<th>Banner</th>
<th>Reason</th>
<th></th>
</tr>
</thead>
<tbody>
<% @ip_bans.each do |ip_ban| %>
<tr>
<td><%= ip_ban.ip_addr %></td>
<td><%= ip_ban.creator.name %></td>
<td><%= ip_ban.reason %></td>
<td><%= link_to "Unban", ip_ban_path(ip_ban), :remote => true, :method => :delete, :confirm => "Do your really want to unban #{ip_ban.creator.name}?" %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<table>
<thead>
<tr>
<th>IP Address</th>
<th>Banner</th>
<th>Reason</th>
<th></th>
</tr>
</thead>
<tbody>
<% @ip_bans.each do |ip_ban| %>
<tr>
<td><%= ip_ban.ip_addr %></td>
<td><%= ip_ban.creator.name %></td>
<td><%= ip_ban.reason %></td>
<td><%= link_to "Unban", ip_ban_path(ip_ban), :remote => true, :method => :delete, :confirm => "Do your really want to unban #{ip_ban.creator.name}?" %></td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -1,7 +1,11 @@
<h1>New IP Ban</h1> <div id="c-ip-bans">
<div id="a-new">
<h1>New IP Ban</h1>
<%= simple_form_for(@ip_ban) do |f| %> <%= simple_form_for(@ip_ban) do |f| %>
<%= f.input :ip_addr %> <%= f.input :ip_addr %>
<%= f.input :reason %> <%= f.input :reason %>
<%= f.button :submit %> <%= f.button :submit %>
<% end %> <% end %>
</div>
</div>

View File

@@ -1,23 +1,27 @@
<h1>Janitor Trials</h1> <div id="c-janitor-trials">
<div id="a-index">
<h1>Janitor Trials</h1>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>User</th> <th>User</th>
<th>Duration</th> <th>Duration</th>
<td></td> <td></td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% @janitor_trials.each do |janitor_trial| %> <% @janitor_trials.each do |janitor_trial| %>
<tr> <tr>
<td><%= janitor_trial.user.name %></td> <td><%= janitor_trial.user.name %></td>
<td><%= janitor_trial.created_at %></td> <td><%= janitor_trial.created_at %></td>
<td> <td>
<%= link_to "Promote", promote_janitor_trial_path(janitor_trial), :remote => true, :method => :put %> <%= link_to "Promote", promote_janitor_trial_path(janitor_trial), :remote => true, :method => :put %>
| <%= link_to "Demote", demote_janitor_trial_path(janitor_trial), :remote => true, :method => :put %> | <%= link_to "Demote", demote_janitor_trial_path(janitor_trial), :remote => true, :method => :put %>
</td> </td>
</tr> </tr>
<% end %> <% end %>
</tbody> </tbody>
</table> </table>
</div>
</div>

View File

@@ -1,6 +1,10 @@
<h1>New Janitor Trial</h1> <div id="c-janitor-trials">
<div id="a-new">
<h1>New Janitor Trial</h1>
<%= simple_form_for(@janitor_trial) do |f| %> <%= simple_form_for(@janitor_trial) do |f| %>
<%= f.input :user_id %> <%= f.input :user_id %>
<%= f.button :submit %> <%= f.button :submit %>
<% end %> <% end %>
</div>
</div>

View File

@@ -38,4 +38,4 @@
</div> </div>
</div> </div>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>

View File

@@ -1,4 +1,4 @@
<div id="news-ticker"> <div id="news-ticker" data-updated-at="2011-09-01">
<ul> <ul>
</ul> </ul>

View File

@@ -35,7 +35,7 @@
<%= sequential_paginator(@note_versions) %> <%= sequential_paginator(@note_versions) %>
<%= render :partial => "notes/secondary_links" %> <%= render "notes/secondary_links" %>
</div> </div>
</div> </div>

View File

@@ -17,4 +17,4 @@
</div> </div>
</div> </div>
<%= render :partial => "pools/secondary_links" %> <%= render "pools/secondary_links" %>

View File

@@ -37,4 +37,4 @@
</div> </div>
</div> </div>
<%= render :partial => "pools/secondary_links" %> <%= render "pools/secondary_links" %>

View File

@@ -1,17 +1,21 @@
<p>If this post was automatically deleted, <strong>then it means at least ten janitors all thought it didn't belong on the site</strong>. If you still believe this image was wrongfully deleted, then you can appeal its deletion.</p> <div id="c-post-appeals">
<div id="a-index">
<p>If this post was automatically deleted, <strong>then it means at least ten janitors all thought it didn't belong on the site</strong>. If you still believe this image was wrongfully deleted, then you can appeal its deletion.</p>
<p>Some valid reasons for appealing include:</p> <p>Some valid reasons for appealing include:</p>
<ul> <ul>
<li>Funny</li> <li>Funny</li>
<li>Weird</li> <li>Weird</li>
<li>Translated</li> <li>Translated</li>
<li>Part of a pool</li> <li>Part of a pool</li>
</ul> </ul>
<p>All users are limited to 5 appeals a day. For more details, please read the <%= link_to "wiki", wiki_pages_path(:title => "help:deletion_appeals") %>.</p> <p>All users are limited to 5 appeals a day. For more details, please read the <%= link_to "wiki", wiki_pages_path(:title => "help:deletion_appeals") %>.</p>
<%= simple_form_for(@post_appeal, :remote => true, :format => :js) do |f| %> <%= simple_form_for(@post_appeal, :remote => true, :format => :js) do |f| %>
<%= hidden_field_tag "post_appeal[post_id]", @post_appeal.post_id %> <%= hidden_field_tag "post_appeal[post_id]", @post_appeal.post_id %>
<%= f.text_field :reason, :size => "40x5" %> <%= f.text_field :reason, :size => "40x5" %>
<% end %> <% end %>
</div>
</div>

View File

@@ -1,25 +1,29 @@
<p>If you believe a post does not belong on this site, you can flag for its deletion. As a reminder, the following are some common reasons for flagging a post:</p> <div id="c-post-flags">
<div id="a-index">
<p>If you believe a post does not belong on this site, you can flag for its deletion. As a reminder, the following are some common reasons for flagging a post:</p>
<ul> <ul>
<li>Not anime-related</li> <li>Not anime-related</li>
<li>Furry: a character has body fur or an animal face</li> <li>Furry: a character has body fur or an animal face</li>
<li>Watermark: text or logo inserted by someone besides the original artist</li> <li>Watermark: text or logo inserted by someone besides the original artist</li>
<li>Poor compression: JPEG artifacts</li> <li>Poor compression: JPEG artifacts</li>
<li>Guro: mutilation, extreme bodily distension</li> <li>Guro: mutilation, extreme bodily distension</li>
<li>Bad proportions: extremely large breasts or penises</li> <li>Bad proportions: extremely large breasts or penises</li>
<li>Manga: Multiple pages of a manga, doujinshi, or comic that don't stand up to individual scrutiny</li> <li>Manga: Multiple pages of a manga, doujinshi, or comic that don't stand up to individual scrutiny</li>
<li>Fake translations: Made up translations are banned</li> <li>Fake translations: Made up translations are banned</li>
</ul> </ul>
<p>The following are <strong>NOT</strong> valid reasons for flagging a post:</p> <p>The following are <strong>NOT</strong> valid reasons for flagging a post:</p>
<ul> <ul>
<li>Duplicate: just parent to the original</li> <li>Duplicate: just parent to the original</li>
</ul> </ul>
<p>Enter a reason:</p> <p>Enter a reason:</p>
<%= simple_form_for(@post_flag, :remote => true, :format => :js) do |f| %> <%= simple_form_for(@post_flag, :remote => true, :format => :js) do |f| %>
<%= f.input :post_id, :as => :hidden %> <%= f.input :post_id, :as => :hidden %>
<%= f.text_field :reason %> <%= f.text_field :reason %>
<% end %> <% end %>
</div>
</div>

View File

@@ -11,7 +11,7 @@
<% if @post_versions.empty? %> <% if @post_versions.empty? %>
<%= render "post_sets/blank" %> <%= render "post_sets/blank" %>
<% else %> <% else %>
<%= render :partial => "listing", :locals => {:post_versions => @post_versions} %> <%= render"listing", :post_versions => @post_versions %>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@@ -1,28 +1,28 @@
<div id="c-posts"> <div id="c-posts">
<div id="a-index"> <div id="a-index">
<aside id="sidebar"> <aside id="sidebar">
<%= render :partial => "posts/partials/common/search", :locals => {:path => posts_path, :tags => params[:tags]} %> <%= render "posts/partials/common/search", :path => posts_path, :tags => params[:tags] %>
<%= render :partial => "posts/partials/index/mode_menu" %> <%= render "posts/partials/index/mode_menu" %>
<section id="tag-box"> <section id="tag-box">
<h1>Tags</h1> <h1>Tags</h1>
<%= @post_set.presenter.tag_list_html(self) %> <%= @post_set.presenter.tag_list_html(self) %>
</section> </section>
<%= render :partial => "posts/partials/index/blacklist" %> <%= render "posts/partials/index/blacklist" %>
</aside> </aside>
<section id="content"> <section id="content">
<%= render :partial => "wiki_pages/excerpt", :locals => {:post_set => @post_set} %> <%= render "wiki_pages/excerpt", :post_set => @post_set %>
<%= render :partial => "posts/partials/index/posts", :locals => {:post_set => @post_set} %> <%= render "posts/partials/index/posts", :post_set => @post_set %>
</section> </section>
<% content_for(:page_title) do %> <% content_for(:page_title) do %>
/<%= @post_set.tag_string %> /<%= @post_set.tag_string %>
<% end %> <% end %>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>
</div> </div>
</div> </div>

View File

@@ -16,9 +16,6 @@
<option value="lock-note">Lock notes</option> <option value="lock-note">Lock notes</option>
<option value="edit-tag-script">Edit tag script</option> <option value="edit-tag-script">Edit tag script</option>
<option value="apply-tag-script">Apply tag script</option> <option value="apply-tag-script">Apply tag script</option>
<% if CurrentUser.user.is_janitor? %>
<option value="approve">Approve</option>
<% end %>
</select> </select>
</form> </form>
</section> </section>

View File

@@ -1,12 +1,12 @@
<div id="c-posts"> <div id="c-posts">
<div id="a-show"> <div id="a-show">
<aside id="sidebar"> <aside id="sidebar">
<%= render :partial => "posts/partials/common/search", :locals => {:path => posts_path, :tags => params[:tags]} %> <%= render "posts/partials/common/search", :path => posts_path, :tags => params[:tags] %>
<% if @post.pools.any? %> <% if @post.pools.any? %>
<section id="pool-sidebar"> <section id="pool-sidebar">
<h1>Pools</h1> <h1>Pools</h1>
<%= render :partial => "posts/partials/show/pools", :locals => {:post => @post} %> <%= render "posts/partials/show/pools", :post => @post %>
</section> </section>
<% end %> <% end %>
@@ -17,12 +17,12 @@
<section> <section>
<h1>Information</h1> <h1>Information</h1>
<%= render :partial => "posts/partials/show/information", :locals => {:post => @post} %> <%= render "posts/partials/show/information", :post => @post %>
</section> </section>
<section> <section>
<h1>Options</h1> <h1>Options</h1>
<%= render :partial => "posts/partials/show/options", :locals => {:post => @post} %> <%= render "posts/partials/show/options", :post => @post %>
</section> </section>
<section> <section>
@@ -36,7 +36,7 @@
</aside> </aside>
<section id="content"> <section id="content">
<%= render :partial => "posts/partials/show/notices", :locals => {:post => @post} %> <%= render "posts/partials/show/notices", :post => @post %>
<section id="image-container"> <section id="image-container">
<div id="note-container"></div> <div id="note-container"></div>
@@ -50,7 +50,7 @@
</menu> </menu>
<section id="comments"> <section id="comments">
<%= render :partial => "comments/partials/index/list", :locals => {:comments => @post.comments, :post => @post, :show_header => false} %> <%= render "comments/partials/index/list", :comments => @post.comments, :post => @post, :show_header => false %>
</section> </section>
<section id="notes"> <section id="notes">
@@ -62,7 +62,7 @@
</section> </section>
<section id="edit"> <section id="edit">
<%= render :partial => "posts/partials/show/edit", :locals => {:post => @post} %> <%= render "posts/partials/show/edit", :post => @post %>
</section> </section>
</section> </section>
</div> </div>
@@ -93,4 +93,4 @@
<meta name="post-is-deleted" content="<%= @post.is_deleted? %>"> <meta name="post-is-deleted" content="<%= @post.is_deleted? %>">
<% end %> <% end %>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>

View File

@@ -1,66 +0,0 @@
<h4>Report: <%= @report_title %></h4>
<div>
<div style="margin-bottom: 1em;">
<% form_tag({:action => params[:action]}, :method => :get) do %>
<table width="100%">
<tfoot>
<tr>
<td colspan="2"><%= submit_tag "Search" %></td>
</tr>
</tfoot>
<tbody>
<tr>
<th width="15%"><label for="start_date">Start Date</label></th>
<td width="85%"><%= text_field_tag "start_date", @start_date, :size => 10 %></td>
</tr>
<tr>
<th><label for="end_date">End Date</label></th>
<td><%= text_field_tag "end_date", @end_date, :size => 10 %></td>
</tr>
<tr>
<th><label for="limit">Limit</label></th>
<td><%= text_field_tag "limit", @limit, :size => 5 %></td>
</tr>
<tr>
<td><label for="level">Level</label></td>
<td><%= user_level_select_tag "level", :include_blank => true %></td>
</tr>
</tbody>
</table>
<% end %>
</div>
<div>
<table width="100%" class="highlightable">
<thead>
<tr>
<th width="15%">User</th>
<th width="10%">Changes</th>
<th width="75%">Percentage</th>
</tr>
</thead>
<tfoot>
<td>Total</td>
<td><%= @users[0]["sum"].to_i %></td>
<td></td>
</tfoot>
<tbody>
<% @users.each do |user| %>
<tr class="<%= cycle 'even', 'odd' %>">
<td><%= link_to_unless user["id"].nil?, h(user["name"]), :controller => "user", :action => "show", :id => user["id"] %></td>
<td><%= link_to_unless user["id"].nil?, user["change_count"], @change_params.call(user["id"]) %></td>
<td><%= number_to_percentage 100 * user["change_count"] / user["sum"], :precision => 1 %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<% content_for("subnavbar") do %>
<li><%= link_to "Tags", :action => "tag_updates", :start_date => @start_date, :end_date => @end_date %></li>
<li><%= link_to "Notes", :action => "note_updates", :start_date => @start_date, :end_date => @end_date %></li>
<li><%= link_to "Wiki", :action => "wiki_updates", :start_date => @start_date, :end_date => @end_date %></li>
<li><%= link_to "Uploads", :action => "post_uploads", :start_date => @start_date, :end_date => @end_date %></li>
<% end %>

View File

@@ -1,40 +0,0 @@
<script language="javascript" type="text/javascript" src="/javascripts/flotr-0.2.0-alpha.js"></script>
<% form_tag({:action => "tag_history"}, :method => :get) do %>
<table width="100%">
<tbody>
<tr>
<th width="10%">Tags</th>
<td width="90%"><%= text_field_tag "tag", params[:tag], :size => 50 %></td>
</tr>
<tr>
<th>Start Date</th>
<td><%= text_field_tag "start_date", @start_date %></td>
</tr>
<tr>
<th>End Date</th>
<td><%= text_field_tag "end_date", @end_date %></td>
</tr>
<tr>
<td colspan="2"><%= submit_tag "Search" %></td>
</tr>
</tbody>
</table>
<% end %>
<div id="container" style="width: 100%; height: 400px"></div>
<% if @counts %>
<script type="text/javascript" charset="utf-8">
Flotr.draw(
$("container"), [<%= @counts.map {|x| "{data: #{x[1].to_json}, label: #{x[0].to_json}}"}.join(", ") %>],
{
lines: {show: true},
xaxis: {ticks: <%= @ticks.to_json %>},
yaxis: {noTicks: 10, tickDecimals: 0},
legend: {show: true},
shadowSize: 0
}
)
</script>
<% end %>

View File

@@ -1,5 +1,5 @@
<div id="sessions"> <div id="c-sessions">
<div id="new"> <div id="a-new">
<section> <section>
<h1>Login</h1> <h1>Login</h1>
<%= form_tag(session_path, :class => "simple_form") do %> <%= form_tag(session_path, :class => "simple_form") do %>

View File

@@ -1,11 +1,11 @@
<div id="c-tag-subscriptions"> <div id="c-tag-subscriptions">
<div id="a-posts"> <div id="a-posts">
<aside id="sidebar"> <aside id="sidebar">
<%= render :partial => "posts/partials/common/search", :locals => {:path => posts_tag_subscription_path, :tags => @post_set.tag_string} %> <%= render "posts/partials/common/search", :path => posts_tag_subscription_path, :tags => @post_set.tag_string %>
<%= render :partial => "posts/partials/index/mode_menu" %> <%= render "posts/partials/index/mode_menu" %>
<%= render :partial => "posts/partials/index/blacklist" %> <%= render "posts/partials/index/blacklist" %>
</aside> </aside>
<section id="content"> <section id="content">
@@ -20,7 +20,7 @@
/fav:<%= CurrentUser.name %> /fav:<%= CurrentUser.name %>
<% end %> <% end %>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>
</div> </div>
</div> </div>

View File

@@ -27,4 +27,4 @@
</div> </div>
</div> </div>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>

View File

@@ -59,4 +59,4 @@
/ Upload / Upload
<% end %> <% end %>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>

View File

@@ -10,6 +10,8 @@
<p>This upload has finished processing. <%= link_to "View the post", post_path(@upload.post_id) %>.</p> <p>This upload has finished processing. <%= link_to "View the post", post_path(@upload.post_id) %>.</p>
<% elsif @upload.is_pending? %> <% elsif @upload.is_pending? %>
<p>This upload is waiting to be processed. Please wait a few seconds.</p> <p>This upload is waiting to be processed. Please wait a few seconds.</p>
<% elsif @upload.is_processing? %>
<p>This upload is being processed. Please wait a few seconds.</p>
<% else %> <% else %>
<p>An error occurred: <%= @upload.status %></p> <p>An error occurred: <%= @upload.status %></p>
<% end %> <% end %>
@@ -21,4 +23,4 @@
<% end %> <% end %>
</p> </p>
<%= render :partial => "posts/partials/common/secondary_links" %> <%= render "posts/partials/common/secondary_links" %>

View File

@@ -1,3 +1,54 @@
<h1>Namasté <%= CurrentUser.pretty_name %>!</h1> <div id="c-users">
<div id="a-show">
<h1>Show User: <%= CurrentUser.pretty_name %></h1>
<%= render :partial => "secondary_links" %> <dl>
<dt>Join Date</dt>
<dd><%= @presenter.join_date %></dd>
<dt>Inviter</dt>
<dd><%= @presenter.inviter(self) %></dd>
<dt>Level</dt>
<dd><%= @presenter.level %></dd>
<dt>Upload Limit</dt>
<dd><%= @presenter.upload_limit %></dd>
<dt>Uploads</dt>
<dd><%= @presenter.uploads(self) %></dd>
<dt>Deleted Uploads</dt>
<dd><%= @presenter.deleted_uploads(self) %></dd>
<dt>Favorites</dt>
<dd><%= @presenter.favorites(self) %></dd>
<dt>Subscriptions</dt>
<dd><%= @presenter.subscriptions(self) %></dd>
<dt>Post Changes</dt>
<dd><%= @presenter.post_versions(self) %></dd>
<dt>Note Changes</dt>
<dd><%= @presenter.note_versions(self) %></dd>
<dt>Wiki Page Changes</dt>
<dd><%= @presenter.wiki_page_versions(self) %></dd>
<dt>Pool Changes</dt>
<dd><%= @presenter.pool_versions(self) %></dd>
<dt>Forum Posts</dt>
<dd><%= @presenter.forum_posts(self) %></dd>
<dt>Approvals</dt>
<dd><%= @presenter.approvals(self) %></dd>
<dt>Feedback</dt>
<dd><%= @presenter.feedbacks(self) %></dd>
</dl>
</div>
</div>
<%= render "secondary_links" %>

View File

@@ -1,6 +1,6 @@
<div id="c-wiki-pages"> <div id="c-wiki-pages">
<div id="a-index"> <div id="a-index">
<%= render :partial => "wiki_pages/sidebar" %> <%= render "wiki_pages/sidebar" %>
<section id="content"> <section id="content">
<h1>Wiki Pages</h1> <h1>Wiki Pages</h1>
@@ -37,4 +37,4 @@
</div> </div>
</div> </div>
<%= render :partial => "wiki_pages/secondary_links" %> <%= render "wiki_pages/secondary_links" %>

View File

@@ -1,6 +1,6 @@
<div id="c-wiki-pages"> <div id="c-wiki-pages">
<div id="a-index"> <div id="a-index">
<%= render :partial => "sidebar" %> <%= render "sidebar" %>
<section id="content"> <section id="content">
<h1>Wiki Pages</h1> <h1>Wiki Pages</h1>

View File

@@ -72,6 +72,11 @@ module Danbooru
300 300
end end
# If a solid state drive is availble, cache the thumbnails on the SSD to reduce disk seek times.
def ssd_path
nil
end
# List of memcached servers # List of memcached servers
def memcached_servers def memcached_servers
%w(localhost:11211) %w(localhost:11211)

View File

@@ -1,39 +0,0 @@
module Danbooru
class CustomConfiguration < Configuration
# Define your custom overloads here
def app_name
"Lorem"
end
def posts_per_page
3
end
def is_user_restricted?(user)
!user.is_privileged? || user.name == "ppayne"
end
def is_post_restricted?(post)
post.has_tag?("loli") || post.has_tag?("shota")
end
def custom_html_header_content
%{
<script type="text/javascript">
//var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
//document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
//var pageTracker = _gat._getTracker("UA-86094-4");
//pageTracker._trackPageview();
} catch(err) {}
</script>
}.html_safe
end
def is_user_advertiser?(user)
user.is_admin? || user.name == "ppayne"
end
end
end

118
config/deploy.rb Normal file
View File

@@ -0,0 +1,118 @@
$:.unshift(File.expand_path("./lib", ENV["rvm_path"]))
set :rvm_ruby_string, "ruby-1.9.2"
set :rvm_bin_path, "/usr/local/rvm/bin"
require 'rvm/capistrano'
set :stages, %w(production staging)
set :default_stage, "staging"
require 'capistrano/ext/multistage'
require 'bundler/capistrano'
set :whenever_command, "bundle exec whenever"
set :whenever_environment, defer {stage}
require 'whenever/capistrano'
set :application, "danbooru"
set :repository, "git://github.com/r888888888/danbooru.git"
set :scm, :git
set :user, "danbooru"
set :deploy_to, "/var/www/#{application}"
default_run_options[:pty] = true
namespace :local_config do
desc "Create the shared config directory"
task :setup_shared_directory do
run "mkdir -p #{deploy_to}/shared/config"
end
desc "Initialize local config files"
task :setup_local_files do
run "curl -s https://raw.github.com/r888888888/danbooru/master/script/install/danbooru_local_config.rb.templ > #{deploy_to}/shared/config/danbooru_local_config.rb"
run "curl -s https://raw.github.com/r888888888/danbooru/master/script/install/database.yml.templ > #{deploy_to}/shared/config/database.yml"
end
desc "Link the local config files"
task :link_local_files do
run "ln -s #{deploy_to}/shared/config/danbooru_local_config.rb #{release_path}/config/danbooru_local_config.rb"
run "ln -s #{deploy_to}/shared/config/database.yml #{release_path}/config/database.yml"
end
end
namespace :data do
task :setup_directories do
run "mkdir -p #{deploy_to}/shared/data"
run "mkdir #{deploy_to}/shared/data/preview"
run "mkdir #{deploy_to}/shared/data/small"
run "mkdir #{deploy_to}/shared/data/large"
run "mkdir #{deploy_to}/shared/data/original"
end
task :link_directories do
run "rm -f #{release_path}/public/data"
run "ln -s #{deploy_to}/shared/data #{release_path}/public/data"
end
end
desc "Change ownership of common directory to user"
task :reset_ownership_of_common_directory do
sudo "chown -R #{user}:#{user} /var/www/danbooru"
end
namespace :deploy do
namespace :web do
desc "Present a maintenance page to visitors."
task :disable do
maintenance_html_path = "#{current_path}/public/maintenance.html.bak"
run "if [ -e #{maintenance_html_path} ] ; then mv #{maintenance_html_path} #{current_path}/public/maintenance.html ; fi"
end
desc "Makes the application web-accessible again."
task :enable do
maintenance_html_path = "#{current_path}/public/maintenance.html"
run "if [ -e #{maintenance_html_path} ] ; then mv #{maintenance_html_path} #{current_path}/public/maintenance.html.bak ; fi"
end
end
desc "Restart the application"
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
desc "Compile the image resizer"
task :compile_image_resizer do
run "cd #{release_path}/lib/danbooru_image_resizer ; ruby extconf.rb ; make"
end
end
namespace :delayed_job do
desc "Start delayed_job process"
task :start, :roles => :app do
run "cd #{current_path}; RAILS_ENV=#{rails_env} script/delayed_job start"
end
desc "Stop delayed_job process"
task :stop, :roles => :app do
run "cd #{current_path}; RAILS_ENV=#{rails_env} script/delayed_job stop"
end
desc "Restart delayed_job process"
task :restart, :roles => :app do
run "cd #{current_path}; RAILS_ENV=#{rails_env} script/delayed_job restart"
end
end
after "deploy:setup", "reset_ownership_of_common_directory"
after "deploy:setup", "local_config:setup_shared_directory"
after "deploy:setup", "local_config:setup_local_files"
after "deploy:setup", "data:setup_directories"
after "deploy:symlink", "local_config:link_local_files"
after "deploy:symlink", "data:link_directories"
after "deploy:symlink", "deploy:compile_image_resizer"
after "deploy:start", "delayed_job:start"
after "deploy:stop", "delayed_job:stop"
after "deploy:restart", "delayed_job:restart"
before "deploy:update", "deploy:web:disable"
after "deploy:restart", "deploy:web:enable"

View File

@@ -0,0 +1,2 @@
server "sonohara.donmai.us", :web, :app, :primary => true
server "hijiribe.donmai.us", :web, :app

Some files were not shown because too many files have changed in this diff Show More