added all files that I have found
This commit is contained in:
parent
65419473ee
commit
d0534f2b83
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.gitignore export-ignore
|
||||
.gitattributes export-ignore
|
10
Gemfile
Normal file
10
Gemfile
Normal file
@ -0,0 +1,10 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
ruby '2.3.2'
|
||||
|
||||
gem 'tilt', '<2.0'
|
||||
gem 'camping'
|
||||
gem 'activerecord'
|
||||
gem 'sqlite3'
|
||||
gem 'markaby'
|
||||
gem 'thin'
|
115
app/controllers.rb
Executable file
115
app/controllers.rb
Executable file
@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
module Drugstore::Controllers
|
||||
class Index < R '/'
|
||||
def get
|
||||
@cart = 0
|
||||
unless @state.cart.blank?
|
||||
@state.cart.each do |product_id, quantity|
|
||||
@cart = @cart + quantity.to_i
|
||||
end
|
||||
end
|
||||
@products = Product.all
|
||||
render :index
|
||||
end
|
||||
|
||||
def post
|
||||
if( ( @input.has_key?( "product_id" ) ) && ( @input.has_key?( "quantity" ) ) )
|
||||
@state.cart ||= {}
|
||||
if @state.cart.has_key?( @input.product_id )
|
||||
@state.cart[ @input.product_id.to_i ] = @state.cart[ @input.product_id.to_i ].to_i + @input.quantity.to_i
|
||||
else
|
||||
@state.cart[ @input.product_id.to_i ] = @input.quantity.to_i
|
||||
end
|
||||
@state.cart[ @input.product_id.to_i ] = 10 if @state.cart[ @input.product_id.to_i ] > 10
|
||||
@state.info = ' <= Product successfully added.'
|
||||
end
|
||||
redirect Index
|
||||
end
|
||||
end
|
||||
|
||||
class Cart < R '/cart'
|
||||
def get
|
||||
unless @state.cart.blank?
|
||||
@products = []
|
||||
@sum = 0
|
||||
@state.cart.each do |product_id, quantity|
|
||||
product = Product.find_by_id( product_id )
|
||||
subtotal = ( product.price * quantity.to_f ).round(6)
|
||||
line = { "quantity" => quantity,
|
||||
"title" => product.title,
|
||||
"price" => product.price,
|
||||
"subtotal" => subtotal,
|
||||
"id" => product_id }
|
||||
@products << line
|
||||
@sum = ( @sum + subtotal ).round(6)
|
||||
end
|
||||
render :card
|
||||
else
|
||||
redirect Index
|
||||
end
|
||||
end
|
||||
|
||||
def post
|
||||
if @input.has_key?( "cleanup" )
|
||||
if @input.cleanup == "all"
|
||||
@state.cart = nil
|
||||
redirect Index
|
||||
elsif @input.cleanup =~ /\A\d+\Z/
|
||||
@state.cart = @state.cart.select{ |x| x != @input.cleanup.to_i }
|
||||
redirect Cart
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Checkout < R '/checkout'
|
||||
def get
|
||||
unless @state.cart.blank?
|
||||
render :checkout
|
||||
else
|
||||
redirect Index
|
||||
end
|
||||
end
|
||||
|
||||
def post
|
||||
order = Order.create( :fullname => @input.fullname,
|
||||
:addrline1 => @input.addrline1,
|
||||
:zippostalcode => @input.zippostalcode,
|
||||
:city => @input.city,
|
||||
:country => @input.country,
|
||||
:cart => @state.cart.to_s,
|
||||
:bitcoinaddress => "15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf",
|
||||
:addrline2 => @input.addrline2,
|
||||
:stateprovinceregion => @input.stateprovinceregion,
|
||||
:email => @input.email,
|
||||
:orderdate => Time.now.strftime( "%Y-%m-%dT%H:%M:%S" ) )
|
||||
if order.errors.any?
|
||||
@error = 'ERROR: Creation of order failed! Please check the form and try again.'
|
||||
render :checkout, @input
|
||||
else
|
||||
@state.order = "done"
|
||||
# We skip autocreation of bitcoin addresses here!
|
||||
redirect Bitcoin
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Bitcoin < R '/bitcoin'
|
||||
def get
|
||||
unless @state.cart.blank?
|
||||
if @state.has_key?( "order" )
|
||||
if @state.order == "done"
|
||||
@state.order = nil
|
||||
@state.cart = nil
|
||||
render :bitcoin
|
||||
end
|
||||
else
|
||||
redirect Checkout
|
||||
end
|
||||
else
|
||||
redirect Index
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
16
app/models.rb
Executable file
16
app/models.rb
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
module Drugstore::Models
|
||||
class Product < Base
|
||||
after_find do
|
||||
ActiveRecord::Base.clear_active_connections!
|
||||
end
|
||||
end
|
||||
|
||||
class Order < Base
|
||||
validates :fullname, :addrline1, :zippostalcode, :city, :country, :cart, :bitcoinaddress, presence: true
|
||||
after_create do
|
||||
ActiveRecord::Base.clear_active_connections!
|
||||
end
|
||||
end
|
||||
end
|
26
app/root.rb
Executable file
26
app/root.rb
Executable file
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
HeadTitle = "Drugstore"
|
||||
HeaderH1 = "Hidden drugstore"
|
||||
|
||||
module Drugstore
|
||||
include Camping::Session
|
||||
set :secret, '48be8eda8ea970a3f621974822091127895784c0'
|
||||
def service(*)
|
||||
@headers['Content-Type'] = 'text/html; charset=utf-8'
|
||||
super
|
||||
end
|
||||
|
||||
def r404( path )
|
||||
"Sorry, but Magento Community Edition can't find #{path}."
|
||||
end
|
||||
|
||||
def r501( method )
|
||||
"Sorry, but Magento Community Edition can't respond to #{method}."
|
||||
end
|
||||
|
||||
def r500( klass, method, ex )
|
||||
"Sorry, but #{klass}##{method} failed with #{ex}."
|
||||
end
|
||||
|
||||
end
|
205
app/views.rb
Executable file
205
app/views.rb
Executable file
@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
module Drugstore::Views
|
||||
# Layout for all sites
|
||||
def layout
|
||||
html do
|
||||
head do
|
||||
title HeadTitle
|
||||
style do
|
||||
text 'h1{background-color:grey;color:white;padding-left:8px;margin-left:-8px;margin-right:-8px;}'
|
||||
text '.greenbutton{background-color:green;font-weight:bold;color:white;}'
|
||||
text 'table,th,td{border:1px dotted;border-collapse:collapse;padding:8px;}'
|
||||
text 'th,td{text-align:center;}'
|
||||
text '.redbutton{background-color:red;font-weight:bold;color:white;}'
|
||||
text '.boldgreen{font-weight:bold;color:green;}'
|
||||
text '.boldred{font-weight:bold;color:red;}'
|
||||
text 'fieldset{width:32em;}'
|
||||
text 'fieldset label{display:inline;float:left;width:12em;}'
|
||||
end
|
||||
end
|
||||
body do
|
||||
center 'This is NOT a real drugstore. This site just exists for educational purpose!', :class => "boldred"
|
||||
h1 HeaderH1
|
||||
self << yield
|
||||
hr
|
||||
p do
|
||||
text '(c) 2016 - '
|
||||
a 'The Onion Root', :href => 'mailto:the-onion-root@riseup.net'
|
||||
end
|
||||
center 'This is NOT a real drugstore. This site just exists for educational purpose!', :class => "boldred"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Index and Catalog
|
||||
def index
|
||||
if @products.empty?
|
||||
h2 'No products found'
|
||||
p do
|
||||
text 'Could not find any products.'
|
||||
br
|
||||
text 'Please try again later.'
|
||||
end
|
||||
else
|
||||
h2 'Products'
|
||||
if @cart == 0
|
||||
p { text 'Items on cart: ' + @cart.to_s }
|
||||
else
|
||||
p do
|
||||
a 'Items on cart: ' + @cart.to_s, :href => "/cart"
|
||||
if @state.info
|
||||
span @state.info, :class => "boldgreen"
|
||||
@state.info = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@products.each do |product|
|
||||
hr
|
||||
_product( product )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Cart
|
||||
def card
|
||||
h2 'Cart'
|
||||
p { a '<- Back to the calalog' + @cart.to_s, :href => "/" }
|
||||
hr
|
||||
unless @products.empty?
|
||||
form :action => "/cart", :method => 'post' do
|
||||
input :name => 'cleanup', :type => 'hidden', :value => "all"
|
||||
input :type => 'submit', :value => 'Delete Cart', :class => "redbutton"
|
||||
end
|
||||
br
|
||||
table do
|
||||
tr do
|
||||
th 'Quantity (Gramm)'
|
||||
th 'Title'
|
||||
th 'Price (Bitcoin)'
|
||||
th 'Subtotal (Bitcoin)'
|
||||
th 'Action'
|
||||
end
|
||||
@products.each do |product|
|
||||
tr do
|
||||
td product[ "quantity" ]
|
||||
td product[ "title" ]
|
||||
td product[ "price" ]
|
||||
td do
|
||||
b product[ "subtotal" ]
|
||||
end
|
||||
td do
|
||||
form :action => "/cart", :method => 'post' do
|
||||
input :name => 'cleanup', :type => 'hidden', :value => product[ "id" ]
|
||||
input :type => 'submit', :value => 'Delete product', :class => "redbutton"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
p do
|
||||
text 'Total: '
|
||||
span @sum.to_s, :class => "boldred"
|
||||
text ' BTC'
|
||||
end
|
||||
form :action => "/checkout" do
|
||||
input :type => "submit", :value => "Checkout", :class => "greenbutton"
|
||||
end
|
||||
p 'Hint: the max of gramms per product per order is set at 10.'
|
||||
else
|
||||
p 'Cart is empty.'
|
||||
end
|
||||
end
|
||||
|
||||
def checkout
|
||||
h2 'Checkout'
|
||||
p { a '<- Back to the cart', :href => "/cart" }
|
||||
hr
|
||||
if @error
|
||||
p @error, :class => "boldred"
|
||||
end
|
||||
form :action => "/checkout", :method => 'post', :id => "shippingaddress" do
|
||||
label 'Shipping Address:', :form => "shippingaddress"
|
||||
fieldset do
|
||||
label 'Full Name:', :for => 'fullname', :class => 'boldred'
|
||||
input :name => 'fullname', :type => 'text', :size => "30", :value => @input.fullname
|
||||
br
|
||||
label 'Address Line 1:', :for => 'addrline1', :class => 'boldred'
|
||||
input :name => 'addrline1', :type => 'text', :size => "30", :value => @input.addrline1
|
||||
br
|
||||
label 'Address Line 2:', :for => 'addrline2'
|
||||
input :name => 'addrline2', :type => 'text', :size => "30", :value => @input.addrline2
|
||||
br
|
||||
label 'City:', :for => 'city', :class => 'boldred'
|
||||
input :name => 'city', :type => 'text', :size => "30", :value => @input.city
|
||||
br
|
||||
label 'State/Province/Region:', :for => 'stateprovinceregion'
|
||||
input :name => 'stateprovinceregion', :type => 'text', :size => "30", :value => @input.stateprovinceregion
|
||||
br
|
||||
label 'ZIP/Postal Code:', :for => 'zippostalcode', :class => 'boldred'
|
||||
input :name => 'zippostalcode', :type => 'text', :size => "30", :value => @input.zippostalcode
|
||||
br
|
||||
label 'Country:', :for => 'country', :class => 'boldred'
|
||||
input :name => 'country', :type => 'text', :size => "30", :value => @input.country
|
||||
br
|
||||
label 'Email:', :for => 'email'
|
||||
input :name => 'email', :type => 'text', :size => "30", :value => @input.email
|
||||
br
|
||||
end
|
||||
br
|
||||
input :type => 'submit', :value => 'Place order', :class => "greenbutton"
|
||||
end
|
||||
p do
|
||||
text 'Some hints:'
|
||||
ul do
|
||||
li { span 'Fields with a bold red label are mandatory fields!', :class => "boldred" }
|
||||
li 'After successfully placing the order you will get a bitcoin address.'
|
||||
li 'Shipping will be done after you have proceeded a transaction to that address.'
|
||||
li 'Unpayed orders will be deleted in the database after the request expires (1 day).'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def bitcoin
|
||||
h2 'Bitcoin'
|
||||
p { a '<- Back to the calalog' + @cart.to_s, :href => "/" }
|
||||
hr
|
||||
br
|
||||
br
|
||||
br
|
||||
center do
|
||||
p '15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf'
|
||||
img :src => "img/15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf.png", :alt => 'QR code'
|
||||
end
|
||||
br
|
||||
br
|
||||
br
|
||||
p do
|
||||
text 'Hint: '
|
||||
span "This bitcoin address has expired. DON'T use it!", :class => "boldred"
|
||||
end
|
||||
end
|
||||
|
||||
# Partials
|
||||
def _product( product )
|
||||
img :src => product.image_url, :alt => product.title
|
||||
h3 product.title
|
||||
p do
|
||||
b 'Description'
|
||||
text ': ' + product.description
|
||||
br
|
||||
br
|
||||
b 'Price per gramm'
|
||||
text ': ' + product.price.to_s + ' Bitcoin(s)'
|
||||
end
|
||||
form :action => "/", :method => 'post' do
|
||||
input :name => 'product_id', :type => 'hidden', :value => product.id
|
||||
tag! :select, :name => 'quantity' do
|
||||
(1..10).each do |q|
|
||||
tag! :option, q
|
||||
end
|
||||
end
|
||||
input :type => 'submit', :value => 'Add to card', :class => "greenbutton"
|
||||
end
|
||||
end
|
||||
end
|
6
cnf/db.yml
Normal file
6
cnf/db.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
production:
|
||||
adapter: sqlite3
|
||||
database: /home/dealer/drugstore/db/drugstore.sqlite
|
||||
pool: 15
|
||||
timeout: 5000
|
21
cnf/thin.yml
Normal file
21
cnf/thin.yml
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
chdir: /home/dealer/drugstore
|
||||
environment: production
|
||||
address: 127.0.0.1
|
||||
port: 3000
|
||||
timeout: 30
|
||||
log: log/thin.log
|
||||
pid: tmp/pids/thin.pid
|
||||
max_conns: 1024
|
||||
max_persistent_conns: 512
|
||||
require: []
|
||||
wait: 30
|
||||
threadpool_size: 20
|
||||
servers: 3
|
||||
rackup: config.ru
|
||||
daemonize: true
|
||||
user: neupat75
|
||||
group: staff
|
||||
threaded: true
|
||||
no-epoll: true # linux only!
|
||||
tag: Drugstore
|
17
config.ru
Executable file
17
config.ru
Executable file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'camping'
|
||||
require 'camping/ar'
|
||||
require 'camping/session'
|
||||
|
||||
db = YAML.load( File.read( 'cnf/db.yml' ) )
|
||||
ActiveRecord::Base.establish_connection( db['production'] )
|
||||
|
||||
Camping.goes :Drugstore
|
||||
|
||||
require_relative 'app/root'
|
||||
require_relative 'app/models'
|
||||
require_relative 'app/views'
|
||||
require_relative 'app/controllers'
|
||||
|
||||
run Drugstore
|
BIN
db/drugstore.sqlite
Normal file
BIN
db/drugstore.sqlite
Normal file
Binary file not shown.
21
drugstore
Executable file
21
drugstore
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
usage() {
|
||||
printf "\nUsage: ${0} start|restart|stop\n\n"
|
||||
}
|
||||
|
||||
if [ "${#}" -ne 1 ] ; then
|
||||
printf "\nError: less or more then one command are given.\n"
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! [[ "${1}" =~ start|restart|stop ]] ; then
|
||||
printf "\nError: only start, restart or stop are allowed.\n"
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
thin "${1}" -C cnf/thin.yml
|
||||
|
||||
exit 0
|
27
lighttpd.conf.sample.conf
Normal file
27
lighttpd.conf.sample.conf
Normal file
@ -0,0 +1,27 @@
|
||||
# Debian GNU/Linux "Jessie" defaults:
|
||||
server.modules = ( "mod_access", "mod_compress", "mod_proxy" )
|
||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||
server.errorlog = "/var/log/lighttpd/error.log"
|
||||
server.pid-file = "/var/run/lighttpd.pid"
|
||||
server.username = "www-data"
|
||||
server.groupname = "www-data"
|
||||
server.port = 80
|
||||
url.access-deny = ( "~" )
|
||||
compress.cache-dir = "/var/cache/lighttpd/compress/"
|
||||
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
|
||||
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
||||
|
||||
# Hidden Drugstore modifications/additions:
|
||||
#index-file.names = ( "index.html", "index.lighttpd.html" )
|
||||
compress.filetype = ( "text/plain", "text/html" )
|
||||
server.document-root = "/home/dealer/drugstore/pub"
|
||||
server.bind = "127.0.0.1"
|
||||
server.tag = "Microsoft-IIS/8.0"
|
||||
proxy.balance = "fair"
|
||||
$HTTP["url"] !~ "\.(txt|html|ico|jpg|png)$" {
|
||||
proxy.server = ( "" => (
|
||||
( "host" => "127.0.0.1", "port" => 3000 ),
|
||||
( "host" => "127.0.0.1", "port" => 3001 ),
|
||||
( "host" => "127.0.0.1", "port" => 3002 ),
|
||||
) )
|
||||
}
|
0
log/thin.3000.log
Normal file
0
log/thin.3000.log
Normal file
0
log/thin.3001.log
Normal file
0
log/thin.3001.log
Normal file
0
log/thin.3002.log
Normal file
0
log/thin.3002.log
Normal file
BIN
pub/favicon.ico
Normal file
BIN
pub/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
pub/img/15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf.png
Executable file
BIN
pub/img/15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
BIN
pub/img/broken_cookies.jpg
Normal file
BIN
pub/img/broken_cookies.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
pub/img/dark_chocolate.jpg
Normal file
BIN
pub/img/dark_chocolate.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
BIN
pub/img/salt_crystal.jpg
Normal file
BIN
pub/img/salt_crystal.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
2
pub/robots.txt
Normal file
2
pub/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-Agent: *
|
||||
Disallow: /
|
0
tmp/pids/.placeholder
Normal file
0
tmp/pids/.placeholder
Normal file
Loading…
x
Reference in New Issue
Block a user