vesper 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.md +20 -0
- data/Rakefile +1 -0
- data/bin/vesper +12 -0
- data/lib/vesper.rb +5 -0
- data/lib/vesper/template/.gitignore +12 -0
- data/lib/vesper/template/Gemfile +26 -0
- data/lib/vesper/template/Gemfile.lock +102 -0
- data/lib/vesper/template/README.md +0 -0
- data/lib/vesper/template/Rakefile +5 -0
- data/lib/vesper/template/app.rb +14 -0
- data/lib/vesper/template/config.ru +5 -0
- data/lib/vesper/template/config/databases.rb +15 -0
- data/lib/vesper/template/config/email.rb +15 -0
- data/lib/vesper/template/config/mime_types.rb +2 -0
- data/lib/vesper/template/config/schedule.rb +20 -0
- data/lib/vesper/template/config/sessions.rb +5 -0
- data/lib/vesper/template/config/sms.rb +15 -0
- data/lib/vesper/template/data/seeds.rb +7 -0
- data/lib/vesper/template/data/transmogrify.rb +7 -0
- data/lib/vesper/template/ext/date_time.rb +88 -0
- data/lib/vesper/template/ext/helpers.rb +43 -0
- data/lib/vesper/template/ext/log.rb +60 -0
- data/lib/vesper/template/ext/number.rb +60 -0
- data/lib/vesper/template/ext/string.rb +40 -0
- data/lib/vesper/template/lib/hello_world.rb +20 -0
- data/lib/vesper/template/log/messages.log +0 -0
- data/lib/vesper/template/public/css/design.css +17 -0
- data/lib/vesper/template/public/img/fyeah.jpg +0 -0
- data/lib/vesper/template/public/js/hide_addressbar.js +22 -0
- data/lib/vesper/template/public/robots.txt +3 -0
- data/lib/vesper/template/tasks/databases.rb +36 -0
- data/lib/vesper/template/tasks/irb.rb +8 -0
- data/lib/vesper/template/tmp/restart.txt +0 -0
- data/lib/vesper/template/vendor/bundle/.gitkeep +0 -0
- data/lib/vesper/template/views/hello_world.html +8 -0
- data/lib/vesper/template/views/layout.html +34 -0
- data/lib/vesper/version.rb +3 -0
- data/vesper.gemspec +21 -0
- metadata +85 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Vesper is still in alpha, so you'll have to build it from source.
|
2
|
+
|
3
|
+
[Download the repo](https://github.com/jarrodtaylor/vesper/downloads), uncompress and cd into your new directory.
|
4
|
+
|
5
|
+
Install the gem from souce:
|
6
|
+
|
7
|
+
sudo rake install
|
8
|
+
|
9
|
+
Create a new Vesper web app:
|
10
|
+
|
11
|
+
cd ~/Sites
|
12
|
+
vesper create MyApp && cd MyApp
|
13
|
+
|
14
|
+
Run your new web app:
|
15
|
+
|
16
|
+
rackup
|
17
|
+
|
18
|
+
[Visit your web app locally.](http://localhost:9292)
|
19
|
+
|
20
|
+
Don't forget to periodically pull updates and reinstall to get the latest version.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/vesper
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils.rb'
|
4
|
+
|
5
|
+
if ARGV[0]
|
6
|
+
case ARGV[0]
|
7
|
+
when 'create'
|
8
|
+
FileUtils.cp_r File.dirname(__FILE__) + '/../lib/vesper/template', ARGV[1] unless Dir.exists? ARGV[1]
|
9
|
+
end
|
10
|
+
else
|
11
|
+
# Message about what commands to use goes here
|
12
|
+
end
|
data/lib/vesper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Ignore OS X's desktop service files
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
# These files are specific to each machine and should be ignored
|
5
|
+
/.bundle
|
6
|
+
|
7
|
+
# Ignore log files, except for messages
|
8
|
+
/log/*
|
9
|
+
!/log/messages.log
|
10
|
+
|
11
|
+
# Ignore development database
|
12
|
+
/data/*sqlite3
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Use RubyGems to find and download gems
|
2
|
+
source 'http://rubygems.org'
|
3
|
+
|
4
|
+
|
5
|
+
# For date and time parsing
|
6
|
+
gem 'chronic'
|
7
|
+
|
8
|
+
# For databases and model classes
|
9
|
+
gem 'data_mapper'
|
10
|
+
# gem 'dm-mysql-adapter'
|
11
|
+
gem 'dm-sqlite-adapter'
|
12
|
+
|
13
|
+
# For sending email
|
14
|
+
gem 'pony'
|
15
|
+
|
16
|
+
# For Markdown conversions
|
17
|
+
gem 'redcarpet'
|
18
|
+
|
19
|
+
# For route handling
|
20
|
+
gem 'sinatra'
|
21
|
+
|
22
|
+
# For sending text messages
|
23
|
+
gem 'twiliolib'
|
24
|
+
|
25
|
+
# For writing cron jobs in Ruby
|
26
|
+
gem 'whenever', :require => false
|
@@ -0,0 +1,102 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.1.3)
|
5
|
+
multi_json (~> 1.0)
|
6
|
+
addressable (2.2.6)
|
7
|
+
bcrypt-ruby (3.0.1)
|
8
|
+
builder (3.0.0)
|
9
|
+
chronic (0.6.5)
|
10
|
+
data_mapper (1.2.0)
|
11
|
+
dm-aggregates (~> 1.2.0)
|
12
|
+
dm-constraints (~> 1.2.0)
|
13
|
+
dm-core (~> 1.2.0)
|
14
|
+
dm-migrations (~> 1.2.0)
|
15
|
+
dm-serializer (~> 1.2.0)
|
16
|
+
dm-timestamps (~> 1.2.0)
|
17
|
+
dm-transactions (~> 1.2.0)
|
18
|
+
dm-types (~> 1.2.0)
|
19
|
+
dm-validations (~> 1.2.0)
|
20
|
+
data_objects (0.10.7)
|
21
|
+
addressable (~> 2.1)
|
22
|
+
dm-aggregates (1.2.0)
|
23
|
+
dm-core (~> 1.2.0)
|
24
|
+
dm-constraints (1.2.0)
|
25
|
+
dm-core (~> 1.2.0)
|
26
|
+
dm-core (1.2.0)
|
27
|
+
addressable (~> 2.2.6)
|
28
|
+
dm-do-adapter (1.2.0)
|
29
|
+
data_objects (~> 0.10.6)
|
30
|
+
dm-core (~> 1.2.0)
|
31
|
+
dm-migrations (1.2.0)
|
32
|
+
dm-core (~> 1.2.0)
|
33
|
+
dm-serializer (1.2.1)
|
34
|
+
dm-core (~> 1.2.0)
|
35
|
+
fastercsv (~> 1.5.4)
|
36
|
+
json (~> 1.6.1)
|
37
|
+
json_pure (~> 1.6.1)
|
38
|
+
multi_json (~> 1.0.3)
|
39
|
+
dm-sqlite-adapter (1.2.0)
|
40
|
+
dm-do-adapter (~> 1.2.0)
|
41
|
+
do_sqlite3 (~> 0.10.6)
|
42
|
+
dm-timestamps (1.2.0)
|
43
|
+
dm-core (~> 1.2.0)
|
44
|
+
dm-transactions (1.2.0)
|
45
|
+
dm-core (~> 1.2.0)
|
46
|
+
dm-types (1.2.1)
|
47
|
+
bcrypt-ruby (~> 3.0.0)
|
48
|
+
dm-core (~> 1.2.0)
|
49
|
+
fastercsv (~> 1.5.4)
|
50
|
+
json (~> 1.6.1)
|
51
|
+
multi_json (~> 1.0.3)
|
52
|
+
stringex (~> 1.3.0)
|
53
|
+
uuidtools (~> 2.1.2)
|
54
|
+
dm-validations (1.2.0)
|
55
|
+
dm-core (~> 1.2.0)
|
56
|
+
do_sqlite3 (0.10.7)
|
57
|
+
data_objects (= 0.10.7)
|
58
|
+
fastercsv (1.5.4)
|
59
|
+
i18n (0.6.0)
|
60
|
+
json (1.6.3)
|
61
|
+
json_pure (1.6.1)
|
62
|
+
mail (2.3.0)
|
63
|
+
i18n (>= 0.4.0)
|
64
|
+
mime-types (~> 1.16)
|
65
|
+
treetop (~> 1.4.8)
|
66
|
+
mime-types (1.17.2)
|
67
|
+
multi_json (1.0.4)
|
68
|
+
polyglot (0.3.3)
|
69
|
+
pony (1.4)
|
70
|
+
mail (> 2.0)
|
71
|
+
rack (1.3.5)
|
72
|
+
rack-protection (1.1.4)
|
73
|
+
rack
|
74
|
+
redcarpet (1.17.2)
|
75
|
+
sinatra (1.3.1)
|
76
|
+
rack (~> 1.3, >= 1.3.4)
|
77
|
+
rack-protection (~> 1.1, >= 1.1.2)
|
78
|
+
tilt (~> 1.3, >= 1.3.3)
|
79
|
+
stringex (1.3.0)
|
80
|
+
tilt (1.3.3)
|
81
|
+
treetop (1.4.10)
|
82
|
+
polyglot
|
83
|
+
polyglot (>= 0.3.1)
|
84
|
+
twiliolib (2.0.7)
|
85
|
+
builder (>= 2.1.2)
|
86
|
+
uuidtools (2.1.2)
|
87
|
+
whenever (0.7.0)
|
88
|
+
activesupport (>= 2.3.4)
|
89
|
+
chronic (~> 0.6.3)
|
90
|
+
|
91
|
+
PLATFORMS
|
92
|
+
ruby
|
93
|
+
|
94
|
+
DEPENDENCIES
|
95
|
+
chronic
|
96
|
+
data_mapper
|
97
|
+
dm-sqlite-adapter
|
98
|
+
pony
|
99
|
+
redcarpet
|
100
|
+
sinatra
|
101
|
+
twiliolib
|
102
|
+
whenever
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Use the gems in Gemfile
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require
|
4
|
+
|
5
|
+
# Directories to load, in order
|
6
|
+
load_files = [
|
7
|
+
'config',
|
8
|
+
'ext',
|
9
|
+
'lib'
|
10
|
+
]
|
11
|
+
load_files.each {|dir| Dir["./#{dir}/**/*.rb"].each {|file| require file}}
|
12
|
+
|
13
|
+
# Tell DataMapper that all the models are ready
|
14
|
+
DataMapper.finalize
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Shows DataMapper queries alongside page requests:
|
2
|
+
# DataMapper::Logger.new $stdout, :debug
|
3
|
+
|
4
|
+
# Setup a SQLite database for development
|
5
|
+
DataMapper.setup(:default, "sqlite://#{Dir.pwd}/data/development.sqlite3")
|
6
|
+
|
7
|
+
# Optionally set up a MySQL database for production
|
8
|
+
# configure :production do
|
9
|
+
# DataMapper.setup(:default, {
|
10
|
+
# adapter: 'mysql',
|
11
|
+
# host: '',
|
12
|
+
# username: '' ,
|
13
|
+
# password: '',
|
14
|
+
# database: ''})
|
15
|
+
# end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
set :mail_server, {
|
2
|
+
address: 'smtp.gmail.com',
|
3
|
+
port: '587',
|
4
|
+
enable_starttls_auto: true,
|
5
|
+
user_name: '',
|
6
|
+
password: '',
|
7
|
+
authentication: :plain
|
8
|
+
}
|
9
|
+
|
10
|
+
# To send email via GMail:
|
11
|
+
# Pony.mail(via: :smtp, via_options: settings.mail_server,
|
12
|
+
# to: 'you@example.com',
|
13
|
+
# subject:'This is a sample email',
|
14
|
+
# body: 'Can you read me now?'
|
15
|
+
# )
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Use this file to easily define all of your cron jobs.
|
2
|
+
#
|
3
|
+
# It's helpful, but not entirely necessary to understand cron before proceeding.
|
4
|
+
# http://en.wikipedia.org/wiki/Cron
|
5
|
+
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# set :output, "/path/to/my/cron_log.log"
|
9
|
+
#
|
10
|
+
# every 2.hours do
|
11
|
+
# command "/usr/bin/some_great_command"
|
12
|
+
# runner "MyModel.some_method"
|
13
|
+
# rake "some:great:rake:task"
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# every 4.days do
|
17
|
+
# runner "AnotherModel.prune_old_records"
|
18
|
+
# end
|
19
|
+
|
20
|
+
# Learn more: http://github.com/javan/whenever
|
@@ -0,0 +1,15 @@
|
|
1
|
+
set :sms_server, {
|
2
|
+
account_number: '',
|
3
|
+
account_sid: '',
|
4
|
+
account_token: '',
|
5
|
+
api_version: ''
|
6
|
+
}
|
7
|
+
|
8
|
+
# To send an sms via Twilio:
|
9
|
+
# account = Twilio::RestAccount.new(settings.sms_server[:account_sid], settings.sms_server[:account_token])
|
10
|
+
# msg = {
|
11
|
+
# 'From' => settings.sms[:account_number],
|
12
|
+
# 'To' => 'xxxxxxxxxxx',
|
13
|
+
# 'Body' => 'Can you read me now?'
|
14
|
+
# }
|
15
|
+
# account.request("/#{settings.sms_server[:api_version]}/Accounts/#{settings.sms_server[:account_sid]}/SMS/Messages", 'POST', msg)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Timepiece
|
2
|
+
|
3
|
+
# Adds the below ClassMethods module methods as class methods to the including class
|
4
|
+
def self.included base
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
# Convert date form fields into a DB compatible date
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# >> Date.from_fields 2010, 6, 26
|
14
|
+
# => 2010-06-26 12:00:00 -0400
|
15
|
+
#
|
16
|
+
# Arguments:
|
17
|
+
# year, month, day
|
18
|
+
#
|
19
|
+
def from_fields year, month, day
|
20
|
+
Chronic.parse("#{year}-#{month}-#{day}")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
# Convert date to human readable string
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
# >> DateTime.now.display :date
|
29
|
+
# => "Friday Dec 09, 2011"
|
30
|
+
#
|
31
|
+
# Arguments:
|
32
|
+
# format (options: date, day, day_with_time, american_day)
|
33
|
+
#
|
34
|
+
def display format = :date
|
35
|
+
case format
|
36
|
+
when :date
|
37
|
+
string = "%A %b %d, %Y"
|
38
|
+
when :day
|
39
|
+
string = "%b %d, %Y"
|
40
|
+
when :day_with_time
|
41
|
+
string = "%b %d, %Y at %I:%M%P"
|
42
|
+
when :american_day
|
43
|
+
string = "%m/%d/%y"
|
44
|
+
else
|
45
|
+
string = "%A %b %d, %Y"
|
46
|
+
end
|
47
|
+
self.strftime string
|
48
|
+
end
|
49
|
+
|
50
|
+
# Convert date form fields
|
51
|
+
#
|
52
|
+
# Example:
|
53
|
+
# >> DateTime.now.to_fields
|
54
|
+
# => (Entirely to long to show)
|
55
|
+
#
|
56
|
+
# Arguments:
|
57
|
+
# field (to reference the fields by name later)
|
58
|
+
#
|
59
|
+
def to_fields field
|
60
|
+
date_field = ""
|
61
|
+
|
62
|
+
date_field << "<select name='#{field}_month' id='#{field}_month'>"
|
63
|
+
(1..12).each do |m|
|
64
|
+
date_field << "<option value='#{m}' #{'selected' if m == self.strftime('%m').to_i}>#{m}</option>"
|
65
|
+
end
|
66
|
+
date_field << "</select>"
|
67
|
+
|
68
|
+
date_field << "<select name='#{field}_day' id='#{field}_day'>"
|
69
|
+
(1..31).each do |d|
|
70
|
+
date_field << "<option value='#{d}' #{'selected' if d == self.strftime('%d').to_i}>#{d}</option>"
|
71
|
+
end
|
72
|
+
date_field << "</select>"
|
73
|
+
|
74
|
+
date_field << "<select name='#{field}_year' id='#{field}_year'>"
|
75
|
+
(2007..Chronic.parse('3 years from now').strftime('%Y').to_i).each do |y|
|
76
|
+
date_field << "<option value='#{y}' #{'selected' if y == self.strftime('%Y').to_i}>#{y}</option>"
|
77
|
+
end
|
78
|
+
date_field << "</select>"
|
79
|
+
|
80
|
+
date_field
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
# Include the above module in Date, DateTime and Time classes
|
86
|
+
Date.class_eval { include Timepiece }
|
87
|
+
DateTime.class_eval { include Timepiece }
|
88
|
+
Time.class_eval { include Timepiece }
|
@@ -0,0 +1,43 @@
|
|
1
|
+
helpers do
|
2
|
+
|
3
|
+
# Adds a class of 'active' to an element that matches the page url
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# <a href="#" class="<%= active '/home' %>">Home</a>
|
7
|
+
#
|
8
|
+
# Arguemnts:
|
9
|
+
# path (to match against the current url)
|
10
|
+
#
|
11
|
+
def active path
|
12
|
+
'active' if request.path_info.include? "/#{path}"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Displays an alert message div
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
# session[:flash] = 'Your message here.'
|
19
|
+
#
|
20
|
+
# Notes:
|
21
|
+
# Will only display on the next page load
|
22
|
+
#
|
23
|
+
def alert
|
24
|
+
unless session[:alert].nil?
|
25
|
+
msg = session[:alert]
|
26
|
+
session[:alert] = nil
|
27
|
+
"<div id='alert'>#{msg}</div>"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Hides an element
|
32
|
+
#
|
33
|
+
# Example:
|
34
|
+
# <div style="<%= hidden %>">Content to hide</div>
|
35
|
+
#
|
36
|
+
# Notes:
|
37
|
+
# Works will with if/unless (hidden unless @var.empty?)
|
38
|
+
#
|
39
|
+
def hidden
|
40
|
+
'display: none;'
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Log
|
2
|
+
|
3
|
+
# Writes a message to /log/messages.log
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# >> Log.message 'This is a message'
|
7
|
+
#
|
8
|
+
# Arguments:
|
9
|
+
# msg
|
10
|
+
#
|
11
|
+
def self.message msg
|
12
|
+
File.open('log/messages.log', 'a+') { |f| f.write("\n#{msg}\n") }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Writes errors to a log file
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
# >> Log.write_errors request.env, request
|
19
|
+
#
|
20
|
+
# Arguments:
|
21
|
+
# env (also the name of the log file, ex: development.log), request (used to parse errors)
|
22
|
+
#
|
23
|
+
def self.write_errors env, request
|
24
|
+
if env['sinatra.error']
|
25
|
+
File.open("log/#{settings.environment}.log", 'a+') do |f|
|
26
|
+
f.write("\n#{env['sinatra.error']}\n")
|
27
|
+
f.write(" #{Time.now} #{env['SERVER_PROTOCOL']} #{request.port} #{request.request_method} #{request.url}\n\n")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Writes errors and requests to a log file
|
33
|
+
#
|
34
|
+
# Example:
|
35
|
+
# >> Log.write_requests_and_errors request.env, request
|
36
|
+
#
|
37
|
+
# Arguments:
|
38
|
+
# env (also the name of the log file, ex: development.log), request (used to parse errors and requests)
|
39
|
+
#
|
40
|
+
def self.write_requests_and_errors env, request
|
41
|
+
File.open("log/#{settings.environment}.log", 'a+') do |f|
|
42
|
+
f.write("\n#{env['sinatra.error']}\n") if env['sinatra.error']
|
43
|
+
f.write(" #{Time.now} #{env['SERVER_PROTOCOL']} #{request.port} #{request.request_method} #{request.url}\n")
|
44
|
+
f.write("\n") if env['sinatra.error']
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Clears a log file
|
49
|
+
#
|
50
|
+
# Example:
|
51
|
+
# >> Log.clear 'messages'
|
52
|
+
#
|
53
|
+
# Arguments:
|
54
|
+
# file (name of log file to clear)
|
55
|
+
#
|
56
|
+
def self.clear file
|
57
|
+
File.open("log/#{file}.log", 'w+') if File::exists?("log/#{file}.log")
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Number
|
2
|
+
|
3
|
+
# Converts a number to a dollar
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# >> 1.dollarize
|
7
|
+
# => '$1.00'
|
8
|
+
#
|
9
|
+
# Note:
|
10
|
+
# This isn't a currency conversion, it's only a string
|
11
|
+
#
|
12
|
+
def dollarize
|
13
|
+
num = self
|
14
|
+
"$%.2f" % num.to_f
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns true if a number is even
|
18
|
+
#
|
19
|
+
# Example:
|
20
|
+
# >> 2.even?
|
21
|
+
# => true
|
22
|
+
#
|
23
|
+
def even?
|
24
|
+
self%2 == 0
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns true if a number is odd
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
# >> 2.even?
|
31
|
+
# => false
|
32
|
+
#
|
33
|
+
def odd?
|
34
|
+
self%2 != 0
|
35
|
+
end
|
36
|
+
|
37
|
+
# Truncates a number to a float
|
38
|
+
#
|
39
|
+
# Example:
|
40
|
+
# >> 1.234.truncate_to_decimal 2
|
41
|
+
# => 1.23
|
42
|
+
#
|
43
|
+
# Arguments:
|
44
|
+
# dec (number of digits after the decimal, defaults to 1)
|
45
|
+
#
|
46
|
+
# Note:
|
47
|
+
# The standard truncate methods returns an integer
|
48
|
+
#
|
49
|
+
def truncate_to_decimal dec = 1
|
50
|
+
num = self
|
51
|
+
rounded = "%.#{dec}f" % num.to_f
|
52
|
+
rounded = rounded.to_s.split('.').first if rounded.to_s.end_with?('0')
|
53
|
+
rounded.to_f
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
# Include the above module in Fixnum and Float classes
|
59
|
+
Fixnum.class_eval { include Number }
|
60
|
+
Float.class_eval { include Number }
|
@@ -0,0 +1,40 @@
|
|
1
|
+
String.class_eval do
|
2
|
+
|
3
|
+
# Coverts markdown text to html
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# >> '# Header'.markdown
|
7
|
+
# => '<h1>Header</h1>'
|
8
|
+
#
|
9
|
+
def markdown
|
10
|
+
Redcarpet.new(self).to_html
|
11
|
+
end
|
12
|
+
|
13
|
+
# Capitalizes the first letter of each word in a string
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
# >> 'This is a title'.titleize
|
17
|
+
# => 'This Is A Title'
|
18
|
+
#
|
19
|
+
def titleize
|
20
|
+
title = ''
|
21
|
+
self.split(' ').each {|s| title << s.capitalize + ' ' }
|
22
|
+
title
|
23
|
+
end
|
24
|
+
|
25
|
+
# Truncates by word count, not letter
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
# >> 'One Two Three Four Five'.truncate 3
|
29
|
+
# => 'One Two Three...'
|
30
|
+
#
|
31
|
+
# Arguments:
|
32
|
+
# length (word count), end_string (attached to the end of a truncated string)
|
33
|
+
#
|
34
|
+
def truncate length = 100, end_string = '...'
|
35
|
+
return if self == nil
|
36
|
+
words = self.split()
|
37
|
+
words[0..(length-1)].join(' ') + (words.length > length ? end_string : '')
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Sinatra route
|
2
|
+
# For more info: http://www.sinatrarb.com/
|
3
|
+
#
|
4
|
+
get '/?' do
|
5
|
+
erb :hello_world
|
6
|
+
end
|
7
|
+
|
8
|
+
# DataMapper model class
|
9
|
+
# For more info: http://datamapper.org/
|
10
|
+
#
|
11
|
+
# class User
|
12
|
+
# include DataMapper::Resource
|
13
|
+
#
|
14
|
+
# property :id, Serial
|
15
|
+
# property :deleted_at, ParanoidDateTime
|
16
|
+
# timestamps :at
|
17
|
+
#
|
18
|
+
# property :email, String
|
19
|
+
#
|
20
|
+
# end
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/* Import fonts from Google */
|
2
|
+
@import url(http://fonts.googleapis.com/css?family=Vollkorn:700italic,400italic,400,700);
|
3
|
+
@import url(http://fonts.googleapis.com/css?family=Cabin+Condensed:400,700);
|
4
|
+
|
5
|
+
body {
|
6
|
+
color: #333;
|
7
|
+
font-family: 'Vollkorn', serif;
|
8
|
+
font-size: 16px;
|
9
|
+
line-height: 1.5em;
|
10
|
+
padding-top: 5%;
|
11
|
+
text-align: center;
|
12
|
+
}
|
13
|
+
|
14
|
+
h1 {
|
15
|
+
color: black;
|
16
|
+
font-family: 'Cabin Condensed', sans-serif;
|
17
|
+
}
|
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
// Hide the iPhone Safari address bar
|
2
|
+
// Works on load and on device rotation
|
3
|
+
// Has no effect is the content doesn't fill the height
|
4
|
+
//
|
5
|
+
// Example: <script src="/js/hide_addressbar.js"></script>
|
6
|
+
|
7
|
+
function hideAddressBar() { window.scrollTo(0, 0); }
|
8
|
+
|
9
|
+
addEventListener('load', function() { setTimeout(hideAddressBar, 0); }, false);
|
10
|
+
|
11
|
+
window.onorientationchange = function() {
|
12
|
+
switch(window.orientation) {
|
13
|
+
case 0:
|
14
|
+
case 180:
|
15
|
+
hideAddressBar();
|
16
|
+
break;
|
17
|
+
case -90:
|
18
|
+
case 90:
|
19
|
+
hideAddressBar();
|
20
|
+
break;
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Example:
|
2
|
+
# >> rake build
|
3
|
+
desc 'Builds the app from scratch'
|
4
|
+
task :build => ['db:setup'] do
|
5
|
+
exec 'rackup'
|
6
|
+
end
|
7
|
+
|
8
|
+
# Database specific tasks
|
9
|
+
namespace :db do
|
10
|
+
|
11
|
+
# Example:
|
12
|
+
# >> rake db:setup
|
13
|
+
desc 'Creates a new seeded database'
|
14
|
+
task :setup => ['db:migrate', 'db:seed']
|
15
|
+
|
16
|
+
# Example:
|
17
|
+
# >> rake db:upgrade
|
18
|
+
desc 'Auto upgrades the database, non-descructive'
|
19
|
+
task(:upgrade) { DataMapper.auto_upgrade }
|
20
|
+
|
21
|
+
# Example:
|
22
|
+
# >> rake db:migrate
|
23
|
+
desc 'Auto migrates the database, destructive'
|
24
|
+
task(:migrate) { DataMapper.auto_migrate! }
|
25
|
+
|
26
|
+
# Example:
|
27
|
+
# >> rake db:seed
|
28
|
+
desc 'Seeds the database'
|
29
|
+
task(:seed) { require "#{Dir.pwd}/data/seeds.rb" }
|
30
|
+
|
31
|
+
# Example
|
32
|
+
# >> rake db:transmogrify
|
33
|
+
desc 'Alters the data'
|
34
|
+
task(:transmogrify) { require "#{Dir.pwd}/data/transmogrify.rb" }
|
35
|
+
|
36
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
|
6
|
+
<meta charset="utf-8">
|
7
|
+
|
8
|
+
<title>Your Name Here</title>
|
9
|
+
|
10
|
+
<!-- Mobile viewport settings -->
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="/css/design.css">
|
14
|
+
|
15
|
+
<!-- Hide address bar in Safari on iPhone -->
|
16
|
+
<script src="/js/hide_addressbar.js"></script>
|
17
|
+
|
18
|
+
<!-- Use jQuery hosted by Google -->
|
19
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
|
20
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
|
21
|
+
|
22
|
+
</head>
|
23
|
+
|
24
|
+
<body>
|
25
|
+
|
26
|
+
<!-- Show alert messages -->
|
27
|
+
<%= alert %>
|
28
|
+
|
29
|
+
<!-- Show content -->
|
30
|
+
<%= yield %>
|
31
|
+
|
32
|
+
</body>
|
33
|
+
|
34
|
+
</html>
|
data/vesper.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "vesper/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "vesper"
|
7
|
+
s.version = Vesper::VERSION
|
8
|
+
s.author = "Jarrod Taylor"
|
9
|
+
s.email = "jarrodtaylor@me.com"
|
10
|
+
s.homepage = "http://jarrodtaylor.github.com/vesper/"
|
11
|
+
s.summary = "A web framework with a focus on transparency."
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
# specify any dependencies here; for example:
|
19
|
+
# s.add_development_dependency "rspec"
|
20
|
+
# s.add_runtime_dependency "rest-client"
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vesper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jarrod Taylor
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-10 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: jarrodtaylor@me.com
|
16
|
+
executables:
|
17
|
+
- vesper
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- README.md
|
24
|
+
- Rakefile
|
25
|
+
- bin/vesper
|
26
|
+
- lib/vesper.rb
|
27
|
+
- lib/vesper/template/.gitignore
|
28
|
+
- lib/vesper/template/Gemfile
|
29
|
+
- lib/vesper/template/Gemfile.lock
|
30
|
+
- lib/vesper/template/README.md
|
31
|
+
- lib/vesper/template/Rakefile
|
32
|
+
- lib/vesper/template/app.rb
|
33
|
+
- lib/vesper/template/config.ru
|
34
|
+
- lib/vesper/template/config/databases.rb
|
35
|
+
- lib/vesper/template/config/email.rb
|
36
|
+
- lib/vesper/template/config/mime_types.rb
|
37
|
+
- lib/vesper/template/config/schedule.rb
|
38
|
+
- lib/vesper/template/config/sessions.rb
|
39
|
+
- lib/vesper/template/config/sms.rb
|
40
|
+
- lib/vesper/template/data/seeds.rb
|
41
|
+
- lib/vesper/template/data/transmogrify.rb
|
42
|
+
- lib/vesper/template/ext/date_time.rb
|
43
|
+
- lib/vesper/template/ext/helpers.rb
|
44
|
+
- lib/vesper/template/ext/log.rb
|
45
|
+
- lib/vesper/template/ext/number.rb
|
46
|
+
- lib/vesper/template/ext/string.rb
|
47
|
+
- lib/vesper/template/lib/hello_world.rb
|
48
|
+
- lib/vesper/template/log/messages.log
|
49
|
+
- lib/vesper/template/public/css/design.css
|
50
|
+
- lib/vesper/template/public/img/fyeah.jpg
|
51
|
+
- lib/vesper/template/public/js/hide_addressbar.js
|
52
|
+
- lib/vesper/template/public/robots.txt
|
53
|
+
- lib/vesper/template/tasks/databases.rb
|
54
|
+
- lib/vesper/template/tasks/irb.rb
|
55
|
+
- lib/vesper/template/tmp/restart.txt
|
56
|
+
- lib/vesper/template/vendor/bundle/.gitkeep
|
57
|
+
- lib/vesper/template/views/hello_world.html
|
58
|
+
- lib/vesper/template/views/layout.html
|
59
|
+
- lib/vesper/version.rb
|
60
|
+
- vesper.gemspec
|
61
|
+
homepage: http://jarrodtaylor.github.com/vesper/
|
62
|
+
licenses: []
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.8.11
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: A web framework with a focus on transparency.
|
85
|
+
test_files: []
|