Merge branch 'master' of github.com:neocities/neocities

This commit is contained in:
Victoria Wang 2015-02-06 14:00:28 -06:00
commit 6a59cb65cf
35 changed files with 357 additions and 232 deletions

1
.gitignore vendored
View file

@ -31,3 +31,4 @@ files/map.txt
files/sslsites.zip
.tm_properties
./black_box.rb
.vagrant

View file

@ -1,4 +1,3 @@
source 'https://code.stripe.com'
source 'https://rubygems.org'
gem 'sinatra'
@ -16,7 +15,7 @@ gem 'mail'
gem 'google-api-client', require: 'google/api_client'
gem 'tilt'
gem 'erubis'
gem 'stripe'
gem 'stripe', source: 'https://code.stripe.com/'
gem 'screencap'
gem 'cocaine'
gem 'zipruby'
@ -63,7 +62,6 @@ group :test do
gem 'mocha', require: nil
gem 'rake', require: nil
gem 'poltergeist'
gem 'phantomjs', require: 'phantomjs/poltergeist'
gem 'capybara_minitest_spec'
gem 'rack_session_access', require: nil
gem 'webmock', require: nil

View file

@ -1,6 +1,6 @@
GEM
remote: https://code.stripe.com/
remote: https://rubygems.org/
remote: https://code.stripe.com/
specs:
activesupport (4.1.4)
i18n (~> 0.6, >= 0.6.9)
@ -154,7 +154,7 @@ GEM
netrc (~> 0.7)
retriable (1.4.1)
rmagick (2.13.3)
safe_yaml (1.0.1)
safe_yaml (1.0.4)
sass (3.3.8)
screencap (0.1.1)
phantomjs
@ -246,7 +246,6 @@ DEPENDENCIES
minitest-reporters
mocha
pg
phantomjs
poltergeist
pry
pry-byebug
@ -271,7 +270,7 @@ DEPENDENCIES
sinatra
sinatra-flash
sinatra-xsendfile
stripe
stripe!
stripe-ruby-mock (~> 2.0.1)
thread
tilt

View file

@ -4,42 +4,23 @@
The web site for NeoCities! It's open source. Want a feature on the site? Send a pull request!
## Installation (OSX)
## Getting Started
Install homebrew:
```
ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
```
Install deps:
```
$ brew install redis postgresql phantomjs libmagic imagemagick
```
Fork the repository on Github.
Clone the forked repo to your local machine: git clone git@github.com:YOURUSERNAME/neocities.git
Install deps:
Neocities can be quickly launched in development mode with (Vagrant)[https://www.vagrantup.com]. Vagrant builds a virtual machine that automatically installs everything you need to run Neocities as a developer. Install Vagrant, then from the command line:
```
$ cd neocities
$ gem install bundler
$ bundle install
vagrant up --provision
```
Create postgres databases:
![Vagrant takes a while, make a pizza while waiting](http://i.imgur.com/vfIJPXP.png)
```
createdb neocities_test
createdb neocities_dev
vagrant ssh
cd /vagrant
bundle exec rackup
```
Copy config.yml.template to config.yml.
Run the tests to see if they work:
```
bundle exec rake test
```
Now you can access the running site from your browser: http://127.0.0.1:9292
## Want to contribute?

12
Vagrantfile vendored Normal file
View file

@ -0,0 +1,12 @@
VAGRANTFILE_API_VERSION = '2'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = 'ubuntu/trusty64'
config.vm.provision :shell, path: './vagrant/development.sh'
config.vm.network :forwarded_port, guest: 9292, host: 9292
config.vm.provider :virtualbox do |vb|
vb.customize ['modifyvm', :id, '--memory', '1536']
vb.name = 'neocities'
end
end

View file

@ -28,16 +28,21 @@ def browse_sites_dataset
case params[:sort_by]
when 'hits'
site_dataset.where!{views > 100}
site_dataset.order!(:hits.desc, :site_updated_at.desc)
when 'views'
site_dataset.where!{views > 100}
site_dataset.order!(:views.desc, :site_updated_at.desc)
when 'newest'
site_dataset.order!(:created_at.desc, :views.desc)
when 'oldest'
site_dataset.where!{views > 100}
site_dataset.order!(:created_at, :views.desc)
when 'random'
site_dataset.where!{views > 100}
site_dataset.where! 'random() < 0.01'
when 'last_updated'
site_dataset.where!{views > 100}
params[:sort_by] = 'last_updated'
site_dataset.order!(:site_updated_at.desc, :views.desc)
else
@ -46,6 +51,7 @@ def browse_sites_dataset
site_dataset.order!(:views.desc, :site_updated_at.desc)
else
params[:sort_by] = 'last_updated'
site_dataset.where!{views > 100}
site_dataset.order!(:site_updated_at.desc, :views.desc)
end
end

View file

@ -4,6 +4,12 @@ get '/plan/?' do
if parent_site && parent_site.unconverted_legacy_supporter?
customer = Stripe::Customer.retrieve(parent_site.stripe_customer_id)
subscription = customer.subscriptions.first
# Subscription was deleted, add to free plan.
if subscription.nil?
subscription = customer.subscriptions.create plan: 'free'
end
parent_site.stripe_subscription_id = subscription.id
parent_site.plan_type = subscription.plan.id
parent_site.save_changes

View file

@ -23,7 +23,7 @@ get '/stats/?' do
now = Date.today
while runner.to_time < now.to_time
while Date.new(runner.year, runner.month, 1) <= Date.new(now.year, now.month, 1)
monthly_stats.push(
date: runner,
sites_created: Site.where(created_at: runner..runner.next_month).count,

View file

@ -1,24 +1,24 @@
development:
database: 'postgres://neocities@127.0.0.1/neocities'
database: 'postgres://neocities@localhost/neocities'
database_pool: 1
session_secret: SECRET GOES HERE
recaptcha_public_key: ENTER PUBLIC KEY HERE
recaptcha_private_key: ENTER PRIVATE KEY HERE
sidekiq_user: ENTER USER HERE
sidekiq_pass: ENTER PASS HERE
stripe_publishable_key: fillout
stripe_api_key: fillout
session_secret: "SECRET GOES HERE"
recaptcha_public_key: "ENTER PUBLIC KEY HERE"
recaptcha_private_key: "ENTER PRIVATE KEY HERE"
sidekiq_user: "ENTER USER HERE"
sidekiq_pass: "ENTER PASS HERE"
stripe_publishable_key: "ENTER KEY HERE"
stripe_api_key: "ENTER KEY HERE"
ip_hash_salt: "400$8$1$fc21863da5d531c1"
proxy_pass: 'somethinglongandrandom'
test:
database: 'postgres://neocities@127.0.0.1/neocities_test'
database: 'postgres://neocities@localhost/neocities_test'
database_pool: 1
session_secret: SECRET GOES HERE
recaptcha_public_key: ENTER PUBLIC KEY HERE
recaptcha_private_key: ENTER PRIVATE KEY HERE
sidekiq_user: ENTER USER HERE
sidekiq_pass: ENTER PASS HERE
stripe_publishable_key: fillout
stripe_api_key: fillout
session_secret: "SECRET GOES HERE"
recaptcha_public_key: "ENTER PUBLIC KEY HERE"
recaptcha_private_key: "ENTER PRIVATE KEY HERE"
sidekiq_user: "ENTER USER HERE"
sidekiq_pass: "ENTER PASS HERE"
stripe_publishable_key: "ENTER KEY HERE"
stripe_api_key: "ENTER KEY HERE"
ip_hash_salt: "400$8$1$fc21863da5d531c1"
proxy_pass: 'somethinglongandrandom'

View file

@ -6,3 +6,4 @@ recaptcha_private_key: '5678'
phantomjs_url:
- http://localhost:8910
ip_hash_salt: "400$8$1$fc21863da5d531c1"
email_unsubscribe_token: "somethingrandomderrrrp"

6
ext/phantomjs.rb Normal file
View file

@ -0,0 +1,6 @@
module Phantomjs
# Workaround for vagrant bug.
def self.path
'/usr/local/bin/phantomjs'
end
end

View file

@ -509,7 +509,7 @@ class Site < Sequel::Model
# clamdscan doesn't work on travis for testing
return true if ENV['TRAVIS'] == 'true'
File.chmod 0640, uploaded_file[:tempfile].path
File.chmod 0666, uploaded_file[:tempfile].path
line = Cocaine::CommandLine.new(
"clamdscan", "-i --remove=no --no-summary --stdout :path",
expected_outcodes: [0, 1]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View file

@ -104,6 +104,21 @@
padding: 4% 2%;
}
}
.admin {
font-size: 80%;
form {
display: inline;
padding-right: 10px;
}
button {
background:none!important;
border:none;
padding:0!important;
cursor: pointer;
}
}
}
.neo-SS, .z{

View file

@ -38,10 +38,8 @@ describe 'signup' do
click_signup_button
site_created?.must_equal true
assert_equal(
true,
File.exist?(File.join(Site::SITE_FILES_ROOT, @site[:username], 'index.html'))
)
index_file_path = File.join Site::SITE_FILES_ROOT, @site[:username], 'index.html'
File.exist?(index_file_path).must_equal true
site = Site[username: @site[:username]]
site.site_files.length.must_equal 4

View file

@ -170,6 +170,7 @@ describe 'api upload' do
post '/api/upload', {
'' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
res[:error_type].must_equal 'missing_files'
end

23
vagrant/common.sh Normal file
View file

@ -0,0 +1,23 @@
# Quiets the TTY error message
#sed -i 's/^mesg n$/tty -s \&\& mesg n/g' /root/.profile
DEBIAN_FRONTEND=noninteractive
apt-get -y update
apt-get -y upgrade
apt-get install -y openntpd htop autossh sshfs vim
echo 'UTC' | tee /etc/timezone
dpkg-reconfigure -f noninteractive tzdata
update-alternatives --set editor /usr/bin/vim.basic
ufw allow ssh
ufw --force enable
ufw logging off
sed -i 's|[#]*PasswordAuthentication yes|PasswordAuthentication no|g' /etc/ssh/sshd_config
sed -i 's|UsePAM yes|UsePAM no|g' /etc/ssh/sshd_config
#sed -i 's|[#]*PermitRootLogin yes|PermitRootLogin no|g' /etc/ssh/sshd_config
service ssh restart

5
vagrant/database.sh Normal file
View file

@ -0,0 +1,5 @@
#!/bin/bash
DEBIAN_FRONTEND=noninteractive
apt-get -y install postgresql postgresql-contrib libpq-dev

13
vagrant/development.sh Normal file
View file

@ -0,0 +1,13 @@
#!/bin/bash
DEBIAN_FRONTEND=noninteractive
. /vagrant/vagrant/common.sh
. /vagrant/vagrant/database.sh
. /vagrant/vagrant/ruby.sh
. /vagrant/vagrant/webapp.sh
ufw allow 9292
sudo su postgres -c "createuser -d vagrant"
sudo su vagrant -c "createdb neocities"
sudo su vagrant -c "createdb neocities_test"

7
vagrant/phantomjs.sh Normal file
View file

@ -0,0 +1,7 @@
#!/bin/bash
DEBIAN_FRONTEND=noninteractive
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.8-linux-x86_64.tar.bz2
bzip2 -dc phantomjs-1.9.8-linux-x86_64.tar.bz2 | tar xf -
cp phantomjs-1.9.8-linux-x86_64/bin/phantomjs /usr/local/bin/

6
vagrant/redis.sh Normal file
View file

@ -0,0 +1,6 @@
apt-get install -y redis-server
#sed -i 's|[#]*appendfsync everysec|appendfsync always|g' /etc/redis/redis.conf
sed -i 's|[#]*appendonly no|appendonly yes|g' /etc/redis/redis.conf
service redis-server restart

7
vagrant/ruby.sh Normal file
View file

@ -0,0 +1,7 @@
#!/bin/bash
apt-get -y install python-software-properties
apt-add-repository -y ppa:brightbox/ruby-ng
apt-get -y update
apt-get -y install ruby2.2 ruby2.2-dev
gem install bundler --no-rdoc --no-ri

19
vagrant/webapp.sh Normal file
View file

@ -0,0 +1,19 @@
#!/bin/bash
DEBIAN_FRONTEND=noninteractive
. /vagrant/vagrant/phantomjs.sh
. /vagrant/vagrant/redis.sh
apt-get install -y git curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev libffi-dev libpq-dev libmagickwand-dev imagemagick libmagickwand-dev libmagic-dev file clamav-daemon
sed -i 's|[#]*DetectPUA false|DetectPUA true|g' /etc/clamav/clamd.conf
freshclam
service clamav-freshclam start
service clamav-daemon start
usermod -G vagrant clamav
cd /vagrant
bundle install

View file

@ -1,12 +1,12 @@
<div class="header-Outro">
<div class="row content single-Col">
<h1>About Neocities</h1>
<h3 class="subtitle">Your free web page is waiting&#8230; once again.</h3>
<h2 class="subtitle">Your free web page is waiting&#8230; once again.</h2>
</div>
</div>
<div class="content single-Col misc-page">
<article>
<article role="article">
<h1>Neocities is bringing back the fun, creativity and independence that made the web great.</h1>
<p>

View file

@ -1,7 +1,7 @@
<div class="header-Outro">
<div class="row content single-Col">
<h1>Administration</h1>
<h3 class="subtitle">Freedom Ain't Free</h3>
<h2 class="subtitle">Freedom Ain't Free</h2>
</div>
</div>

View file

@ -44,7 +44,7 @@
<form method="GET" action="browse">
<fieldset class="grouping">
<label class="text-Label" for="tag">Search by tag:</label>
<input class="input-Area typeahead" name="tag" type="text" placeholder="pokemon" value="<%= params[:tag] %>" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" dir="auto">
<input class="input-Area typeahead" id="tag" name="tag" type="text" placeholder="pokemon" value="<%= params[:tag] %>" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" dir="auto">
<input style="vertical-align: -4px;margin-left: 4px;" type="submit" class="btn-Action" value="Search">
</fieldset>
</div>
@ -94,6 +94,21 @@
<% end %>
<% end %>
</div>
<% if signed_in? && current_site.is_admin %>
<div class="admin">
<form action="/admin/banhammer" target="_blank" method="POST" onsubmit="return confirm('Confirm ban of <%= site.username %>');">
<%== csrf_token_input_html %>
<input type="hidden" name="username" value="<%= site.username %>">
<button>Ban</button>
</form>
<form action="/admin/mark_nsfw" target="_blank" method="POST" onsubmit="return confirm('Confirm NSFW marking of <%= site.username %>');">
<%== csrf_token_input_html %>
<input type="hidden" name="username" value="<%= site.username %>">
<button>Mark NSFW</button>
</form>
</div>
<% end %>
</div>
</li>
<% end %>

View file

@ -7,7 +7,6 @@
<div class="header-Outro">
<div class="row content single-Col">
<h1>Contact Us</h1>
<h3 class="subtitle"></h3>
</div>
</div>
@ -34,14 +33,14 @@
<form action="/contact" method="POST" class="content">
<input name="csrf_token" type="hidden" value="<%= csrf_token %>">
<fieldset>
<label>Email address</label>
<input type="email" name="email" placeholder="Your Email" style="width: 300px" value="<%= params[:email] %>">
<label for="your_email">Email address</label>
<input type="email" id="your_email" name="email" placeholder="Your Email" style="width: 300px" value="<%= params[:email] %>">
<label>Subject</label>
<input type="text" name="subject" placeholder="Subject" style="width: 400px" value="<%= params[:subject] %>">
<label for="email_subject">Subject</label>
<input type="text" id="email_subject" name="subject" placeholder="Subject" style="width: 400px" value="<%= params[:subject] %>">
<label>Comments</label>
<textarea name="body" style="width: 600px" rows="10"><%= params[:body] %></textarea>
<label for="your_comments">Comments</label>
<textarea name="body" id="your_comments" style="width: 600px" rows="10"><%= params[:body] %></textarea>
<label>Fill out captcha so we know you're not a robot:</label>
<div class="recaptcha">

View file

@ -44,7 +44,7 @@
</div> <!-- end .row -->
</div> <!-- end .header-Outro -->
<main class="content-Base">
<main class="content-Base" role="main">
<div class="content wide">
@ -115,12 +115,12 @@
<div class="file filehover">
<% if file[:is_html] && current_site.screenshot_exists?(file[:path], '210x158') %>
<div class="html-thumbnail html fileimagehover">
<img src="<%= current_site.screenshot_url(file[:path], '210x158') %>">
<img src="<%= current_site.screenshot_url(file[:path], '210x158') %>" alt="">
<div class="overlay"></div>
</div>
<% elsif file[:is_image] && current_site.thumbnail_exists?(file[:path], '210x158') %>
<div class="html-thumbnail image fileimagehover">
<img src="<%= current_site.thumbnail_url(file[:path], '210x158') %>">
<img src="<%= current_site.thumbnail_url(file[:path], '210x158') %>" alt="">
<div class="overlay"></div>
</div>
<% elsif file[:is_directory] %>
@ -150,7 +150,7 @@
<a href="?dir=<%= Rack::Utils.escape file[:path] %>"><i class="fa fa-edit" title="Manage"></i> Manage</a>
<% end %>
<% if !file[:is_root_index] %>
<a href="#" onclick="confirmFileDelete('<%= file[:path] %>')"><i class="fa fa-trash" title="Delete"></i> Delete</a>
<a href="#" onclick="confirmFileDelete('<%= file[:path].gsub("'", '&apos;') %>')"><i class="fa fa-trash" title="Delete"></i> Delete</a>
<% end %>
<% if file[:is_directory] %>
<a class="link-overlay" href="?dir=<%= Rack::Utils.escape file[:path] %>" title="View <%= file[:path] %>"></a>
@ -178,8 +178,8 @@
<p>You are about to delete <strong><span id="deleteFileName"></span></strong>. Are you sure?</p>
</div>
<div class="modal-footer">
<button class="btn cancel" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button class="btn btn-Action btn-danger" onclick="fileDelete()"><i class="fa fa-trash" title="Delete"></i>Delete</button>
<button class="btn cancel" data-dismiss="modal" aria-hidden="true" type="button">Cancel</button>
<button class="btn btn-Action btn-danger" type="button" onclick="fileDelete()"><i class="fa fa-trash" title="Delete"></i>Delete</button>
</div>
</div>
@ -202,7 +202,7 @@
</form>
<script src="/js/dropzone.min.js"></script>
<script type="text/javascript">
<script>
function confirmFileDelete(name) {
$('#deleteFileName').html(name.replace('/',''));
@ -255,7 +255,7 @@
</script>
<div class="modal hide fade" id="createDir" tabindex="-1" role="dialog" aria-labelledby="createDirLabel" aria-hidden="true">
<form method="POST" action="/site/create_directory">
<form method="post" action="/site/create_directory">
<input type="hidden" value="<%= csrf_token %>" name="csrf_token">
<input type="hidden" value="<%= @dir %>" name="dir">
<div class="modal-header">
@ -266,7 +266,7 @@
<input name="name" type="text" placeholder="folder_name">
</div>
<div class="modal-footer">
<button class="btn cancel" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button type="button" class="btn cancel" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button type="submit" class="btn btn-Action">Create</button>
</div>
</form>

View file

@ -5,13 +5,12 @@
<div class="header-Outro">
<div class="row content single-Col">
<h1>Donate to Neocities</h1>
<h3 class="subtitle">Help us keep the creative, independent internet alive!</h3>
<h2 class="subtitle">Help us keep the creative, independent internet alive!</h2>
</div>
</div>
<div class="content single-Col misc-page txt-Center">
<article>
<section>
<article role="article">
<h2>How to Donate</h2>
<p>If you send a donation and want to become a supporter, send us an email and we'll take care of it. Thanks!</p>
@ -40,6 +39,5 @@
<h3>Flattr</h3>
<script id='flattrbtn'>(function(i){var f,s=document.getElementById(i);f=document.createElement('iframe');f.src='//api.flattr.com/button/view/?uid=kyledrake&url='+encodeURIComponent(document.URL);f.title='Flattr';f.height=100;f.width=100;f.style.borderWidth=0;s.parentNode.insertBefore(f,s);})('flattrbtn');</script>
<h4 style="margin-top: 30px; margin-bottom: 30px">Thanks. You are great! <a href="/#new">Now go and make an awesome web site!</a></h4>
</section>
</article>
</div> <!-- end .content -->

View file

@ -6,7 +6,7 @@
</div>
<div class="content single-Col misc-page">
<article>
<article role="article">
<h3>We have automatically been notified of the problem.</h3>
<p>
If you need to add any special information or if this error has not been resolved after a few days, <a href="/contact" title="contact us">contact us</a> and report the problem. Thank you, and our apologies for the inconvenience.

View file

@ -23,7 +23,7 @@
<div class="site-suggestion">
<div class="site-portrait">
<a href="http://dragonquest.neocities.org">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg" alt="">
<span class="caption">dragonquest</span>
</a>
</div>
@ -36,7 +36,7 @@
<div class="site-suggestion">
<div class="site-portrait">
<a href="http://dragonquest.neocities.org">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg" alt="">
<span class="caption">dragonquest</span>
</a>
</div>
@ -48,7 +48,7 @@
<div class="site-suggestion">
<div class="site-portrait">
<a href="http://dragonquest.neocities.org">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg" alt="">
<span class="caption">dragonquest</span>
</a>
</div>
@ -59,7 +59,7 @@
<div class="site-suggestion">
<div class="site-portrait">
<a href="http://dragonquest.neocities.org">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg" alt="">
<span class="caption">dragonquest</span>
</a>
</div>
@ -69,7 +69,7 @@
<div class="site-suggestion">
<div class="site-portrait">
<a href="http://dragonquest.neocities.org">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg" alt="">
<span class="caption">dragonquest</span>
</a>
</div>
@ -80,7 +80,7 @@
<div class="site-suggestion">
<div class="site-portrait">
<a href="http://dragonquest.neocities.org">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg">
<img src="http://neocities.org/site_screenshots/dragonquest.jpg" alt="">
<span class="caption">dragonquest</span>
</a>
</div>

View file

@ -40,16 +40,17 @@
<script src='https://www.google.com/recaptcha/api.js'></script>
</head>
<body class="hp"><a id="new"></a>
<body class="hp">
<a id="new"></a>
<div class="page">
<header class="header-Base">
<header class="header-Base" role="banner">
<nav class="header-Nav clearfix" role="navigation">
<a href="#!" title="show small screen nav" class="small-Nav">
<img src="/img/nav-Icon.png" alt="navigation icon" />
</a>
<ul class="h-Nav constant-Nav">
<ul class="h-Nav constant-Nav" role="presentation">
<li>
<a href="/">Neocities</a>
</li>
@ -84,7 +85,7 @@
<a href="/settings" class="sign-In">Settings</a>
</li>
<li>
<a href="/signout" class="sign-In">Signout</a>
<a href="/signout" class="sign-In">Sign Out</a>
</li>
<% end %>
</ul>
@ -124,14 +125,14 @@
<ul class="intro-List">
<li class="intro-Social">
<span class="intro-Icon"></span>
<h2 class="delta">Share your web creation with the world</h2>
<h3 class="delta">Share your web creation with the world</h3>
<p class="base">
Follow your favorite Neocities sites to keep up with all their latest updates. Discover new websites related to your interests using tags, comment on them, and share them. Unlimited creativity, zero ads.
</p>
</li>
<li class="intro-Tools">
<span class="intro-Icon"></span>
<h2 class="delta">Powerful new features to help you build</h2>
<h3 class="delta">Powerful new features to help you build</h3>
<p class="base">
Weve made it easier to build your website and explore other sites. Neocities features an in-browser HTML editor, custom domain support, faster site loading, easy file uploading, RSS feeds, folder support, and much more.
</li>
@ -143,7 +144,7 @@
<div class="signup-Form">
<div class="content">
<h2 class="gamma txt-Center">Build your Website!</h2>
<h3 class="gamma txt-Center">Build your Website!</h3>
</div>
<p class="txt-Center">
Go to your dashboard to<br> start editing your website!
@ -160,7 +161,7 @@
<h2 class="gamma">Sign up for free</h2>
<hr />
<div class="siteCreateInputs">
<label for="create-Input">Username</label>
<label for="create-Input">User Name</label>
<input type="text" name="prevent_autofill_username" id="prevent_autofill_username" value="" style="position:absolute; top:-2000px; left:-2000px;" />
<input type="password" name="prevent_autofill_password" id="prevent_autofill_password" value="" style="position:absolute; top:-2000px; left:-2000px;" />
<input type="text" class="input-Area" id="create-Input" name="username" placeholder="my-site-name" data-placement="left" data-trigger="manual" autocapitalize="off" autocorrect="off" autocomplete="off" />
@ -170,18 +171,34 @@
<input type="text" class="input-Area" id="tags-input" name="new_tags_string" placeholder="art, videogames, food, music, programming, gardening, cats" data-placement="left" data-trigger="manual" autocapitalize="off" autocorrect="off" autocomplete="off" />
<div class="col col-50" style="padding-left:0;">
<label for="password-input">Password</label>
<input type="password" class="input-Area" id="password-input" name="password" placeholder="password" data-placement="left" data-trigger="manual" autocapitalize="off" autocorrect="off" autocomplete="off" />
<label for="password-input">
Password
</label>
<input type="password" class="input-Area" id="password-input"
name="password" placeholder="password"
data-placement="left" data-trigger="manual"
autocapitalize="off" autocorrect="off" autocomplete="off" />
</div>
<div class="col col-50">
<label for="email-input">Email</label>
<input type="text" class="input-Area" id="email-input" name="email" placeholder="me@example.com" data-placement="left" data-trigger="manual" autocapitalize="off" autocorrect="off" autocomplete="off" />
<label for="email-input">
Email
</label>
<input type="email" class="input-Area"
id="email-input" name="email"
placeholder="me@example.com" data-placement="left"
data-trigger="manual" autocapitalize="off"
autocorrect="off" autocomplete="off" />
</div>
<div class="col col-50" style="padding-left:0;">
<label for="g-recaptcha">Confirm you are human</label>
<div id="captcha-input" class="g-recaptcha" data-sitekey="<%= $config['recaptcha_public_key'] %>" data-theme="dark" data-placement="left" data-trigger="manual"></div>
<label>
Confirm you are human
</label>
<div id="captcha-input" class="g-recaptcha"
data-sitekey="<%= $config['recaptcha_public_key'] %>"
data-theme="dark" data-placement="left" data-trigger="manual">
</div>
</div>
<div class="col col-50">
@ -278,12 +295,20 @@
-->
<section class="section features">
<h2 class="delta">Our mission: To make the web fun again by giving you back control of how you express yourself online.</h2>
<h2 class="delta"><img style="margin-top: .5em;" src="/img/front-editor-screenshot.png"></h2>
<h2 class="delta">
Our mission: To make the web fun again by giving you back control of how you express yourself online.
</h2>
<img style="margin-top: .5em; max-width: 80%;" src="/img/front-editor-screenshot.png" alt="screen shot of neocities code editor" />
<div class="row">
<div class="col col-50">
<h3><i class="fa fa-eye-slash"></i>Zero advertising</h3>
<p>Neocities will never sell your personal data or embed advertising on your site. Instead, we are funded directly by our community through <a href="/plan">supporter plans</a> and <a href="/donate">donations</a>. This allows us to base all our decisions on making the best possible web building experience for you, rather than on appeasing ad companies.</p>
<h3>
<i class="fa fa-eye-slash"></i>Zero advertising
</h3>
<p>
Neocities will never sell your personal data or embed advertising on your site. Instead, we are funded directly by our community through <a href="/plan">supporter plans</a> and <a href="/donate">donations</a>. This allows us to base all our decisions on making the best possible web building experience for you, rather than on appeasing ad companies.
</p>
</div>
@ -319,7 +344,7 @@
<h3>
"Designed as a 21st century reincarnation of GeoCities, Neocities lets you make your own site for free. <strong>And it just might spark a renaissance of creativity online.</strong>"
<br />
Matthew Guay, <a href="http://web.appstorm.net/reviews/web-dev/neocities-the-free-place-to-code-your-own-site-from-scratch" target="_blank">AppStorm</a>. <a href="/press">View All Press »</a>
<cite>— Matthew Guay, <a href="http://web.appstorm.net/reviews/web-dev/neocities-the-free-place-to-code-your-own-site-from-scratch" target="_blank">AppStorm</a>. <a href="/press">View All Press »</a></cite>
</h3>
</div>
</div>
@ -332,8 +357,8 @@
</section>
</main>
<footer class="footer-Base">
<section class="footer-Intro">
<footer class="footer-Base" role="contentinfo">
<div class="footer-Intro">
<div class="footer-Content">
<div class="row">
<div class="col col-33">
@ -369,7 +394,7 @@
</div>
</div>
</div>
</section>
</div>
<%== erb :'_footer', layout: false%>
</footer>

View file

@ -1,13 +1,14 @@
<div class="header-Outro">
<div class="row content single-Col">
<h1>Page Not Found (404)</h1>
<h3 class="subtitle"></h3>
</div>
</div>
<div class="content single-Col misc-page">
<article>
<div class="txt-Center"><img src="/img/cat-larger.png"></div>
<article role="article">
<div class="txt-Center">
<img src="/img/neocitieslogo.svg" style="width:100px; margin: -5px 0;" alt="I can't find what you're looking for!">
</div>
<p>
Penelope the Neocities Cat tried very hard to locate the page you were looking for, but she couldn't find it. She's an awesome sysadmin. If she couldn't find it, it's probably not there.
</p>

View file

@ -10,7 +10,7 @@
Note: If you provided your e-mail, you can reset your password. If you didn't, you will not be able to reset your password, and instead should create a new account. We cannot change a password without an entered email for security reasons.
</p>
<form method="POST" action="/send_password_reset" class="content">
<form method="post" action="/send_password_reset" class="content">
<fieldset>
<input name="csrf_token" type="hidden" value="<%= csrf_token %>">
<input name="email" type="email" class="input-Area" placeholder="Your email" style="width: 300px">

View file

@ -75,23 +75,6 @@
Cancelled: <strong><%= @stats[:cancelled_subscriptions] %></strong>
</h3>
<!--
<table class="table">
<tr>
<th>Status</th>
<th>Amount</th>
<th>Date Subscribed</th>
</tr>
<% @stats[:subscriptions].each do |sub| %>
<tr>
<td><%= sub[:status] %></td>
<td><%= sub[:amount].nil? ? '$0.00' : format("$%.2f", sub[:amount]) %></td>
<td><%= sub[:created_at].strftime('%Y %B') %></td>
</tr>
<% end %>
</table>
-->
<h2>Burn Rate</h2>
<p>
Approximate server expenses (burn rate): <strong><%= format("$%.2f", @stats[:expenses]) %>/mo</strong>