clipster 0.4.0 → 0.4.1
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/MIT-LICENSE +20 -20
- data/README.md +76 -72
- data/Rakefile +34 -34
- data/app/assets/javascripts/clipster/application.js +15 -15
- data/app/assets/javascripts/clipster/bootstrap.js +2026 -2026
- data/app/assets/javascripts/clipster/bootstrap.min.js +5 -5
- data/app/assets/javascripts/clipster/clip.js +2 -2
- data/app/assets/javascripts/clipster/clips.js +6 -6
- data/app/assets/javascripts/clipster/users.js +2 -2
- data/app/assets/stylesheets/clipster/application.css +27 -27
- data/app/assets/stylesheets/clipster/bootstrap.css +5774 -5774
- data/app/assets/stylesheets/clipster/clip.css +31 -31
- data/app/assets/stylesheets/clipster/clips.css +4 -4
- data/app/assets/stylesheets/clipster/users.css +4 -4
- data/app/controllers/clipster/application_controller.rb +14 -14
- data/app/controllers/clipster/clips_controller.rb +86 -86
- data/app/controllers/clipster/users_controller.rb +17 -17
- data/app/helpers/clipster/application_helper.rb +19 -19
- data/app/helpers/clipster/clip_helper.rb +4 -4
- data/app/helpers/clipster/clips_helper.rb +4 -4
- data/app/helpers/clipster/users_helper.rb +4 -4
- data/app/models/clipster/clip.rb +97 -99
- data/app/views/clipster/clips/about.html.erb +14 -14
- data/app/views/clipster/clips/create.html.erb +56 -56
- data/app/views/clipster/clips/list.atom.builder +21 -21
- data/app/views/clipster/clips/list.html.erb +60 -60
- data/app/views/clipster/clips/show.html.erb +8 -8
- data/app/views/clipster/users/index.html.erb +2 -2
- data/app/views/clipster/users/show.html.erb +45 -45
- data/app/views/kaminari/_first_page.html.erb +3 -3
- data/app/views/kaminari/_gap.html.erb +3 -3
- data/app/views/kaminari/_last_page.html.erb +3 -3
- data/app/views/kaminari/_next_page.html.erb +3 -3
- data/app/views/kaminari/_page.html.erb +3 -3
- data/app/views/kaminari/_paginator.html.erb +17 -17
- data/app/views/kaminari/_prev_page.html.erb +3 -3
- data/app/views/layouts/clipster/application.html.erb +62 -62
- data/config/initializers/clipster.rb +12 -0
- data/config/routes.rb +16 -16
- data/config/schedule.rb +10 -10
- data/db/migrate/20121126185058_create_clipster_clips.rb +18 -0
- data/lib/clipster.rb +5 -5
- data/lib/clipster/configuration.rb +22 -22
- data/lib/clipster/engine.rb +23 -23
- data/lib/clipster/version.rb +3 -3
- data/lib/generators/clipster/install_generator.rb +19 -19
- data/lib/generators/templates/clipster.rb +12 -12
- data/lib/tasks/clipster_tasks.rake +4 -4
- metadata +5 -11
- data/db/migrate/20121004010757_create_clipster_clips.rb +0 -16
- data/db/migrate/20121007154400_add_hash_index_to_clips.rb +0 -13
- data/db/migrate/20121007155125_populate_clip_defaults.rb +0 -21
- data/db/migrate/20121007162741_rename_hash_to_url_hash.rb +0 -9
- data/db/migrate/20121007223358_remove_default_from_language.rb +0 -9
- data/db/migrate/20121007223631_set_default_title_to_untitled.rb +0 -9
- data/db/migrate/20121105212724_add_lifespan_to_clips.rb +0 -9
- data/db/migrate/20121114175749_add_user_id_to_clips.rb +0 -9
@@ -1,32 +1,32 @@
|
|
1
|
-
/*
|
2
|
-
Place all the styles related to the matching controller here.
|
3
|
-
They will automatically be included in application.css.
|
4
|
-
*/
|
5
|
-
|
6
|
-
.bordered {
|
7
|
-
border: 1px solid #dddddd;
|
8
|
-
border-collapse: separate;
|
9
|
-
*border-collapse: collapse;
|
10
|
-
/*border-left: 0;*/
|
11
|
-
-webkit-border-radius: 4px;
|
12
|
-
-moz-border-radius: 4px;
|
13
|
-
border-radius: 4px;
|
14
|
-
}
|
15
|
-
|
16
|
-
.bordered div {
|
17
|
-
margin: 5px;
|
18
|
-
}
|
19
|
-
|
20
|
-
.title {
|
21
|
-
border-bottom: 1px solid #ddd;
|
22
|
-
}
|
23
|
-
|
24
|
-
.help-tip label{
|
25
|
-
display: inline;
|
26
|
-
}
|
27
|
-
|
28
|
-
.image-feed {
|
29
|
-
width: 14px;
|
30
|
-
height: 14px;
|
31
|
-
background:url("../
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
5
|
+
|
6
|
+
.bordered {
|
7
|
+
border: 1px solid #dddddd;
|
8
|
+
border-collapse: separate;
|
9
|
+
*border-collapse: collapse;
|
10
|
+
/*border-left: 0;*/
|
11
|
+
-webkit-border-radius: 4px;
|
12
|
+
-moz-border-radius: 4px;
|
13
|
+
border-radius: 4px;
|
14
|
+
}
|
15
|
+
|
16
|
+
.bordered div {
|
17
|
+
margin: 5px;
|
18
|
+
}
|
19
|
+
|
20
|
+
.title {
|
21
|
+
border-bottom: 1px solid #ddd;
|
22
|
+
}
|
23
|
+
|
24
|
+
.help-tip label{
|
25
|
+
display: inline;
|
26
|
+
}
|
27
|
+
|
28
|
+
.image-feed {
|
29
|
+
width: 14px;
|
30
|
+
height: 14px;
|
31
|
+
background:url("../clipster/rss_logo_small.png");
|
32
32
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*
|
2
|
-
Place all the styles related to the matching controller here.
|
3
|
-
They will automatically be included in application.css.
|
4
|
-
*/
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*
|
2
|
-
Place all the styles related to the matching controller here.
|
3
|
-
They will automatically be included in application.css.
|
4
|
-
*/
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
@@ -1,14 +1,14 @@
|
|
1
|
-
module Clipster
|
2
|
-
class ApplicationController < ActionController::Base
|
3
|
-
before_filter :set_current_user
|
4
|
-
|
5
|
-
private
|
6
|
-
def set_current_user
|
7
|
-
begin
|
8
|
-
Clip.current_user = current_user if Clipster.config.associates_clip_with_user
|
9
|
-
rescue Exception => e
|
10
|
-
raise "If User assocations have been enabled for Clipster, your application should have a current_user helper defined"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
1
|
+
module Clipster
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
before_filter :set_current_user
|
4
|
+
|
5
|
+
private
|
6
|
+
def set_current_user
|
7
|
+
begin
|
8
|
+
Clip.current_user = current_user if Clipster.config.associates_clip_with_user
|
9
|
+
rescue Exception => e
|
10
|
+
raise "If User assocations have been enabled for Clipster, your application should have a current_user helper defined"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,86 +1,86 @@
|
|
1
|
-
require_dependency "clipster/application_controller"
|
2
|
-
|
3
|
-
module Clipster
|
4
|
-
class ClipsController < ApplicationController
|
5
|
-
def index
|
6
|
-
create
|
7
|
-
render 'create'
|
8
|
-
end
|
9
|
-
|
10
|
-
def list
|
11
|
-
# get all clips, with the newest clip first
|
12
|
-
if params[:lang].nil?
|
13
|
-
@clips = Clip.public.order('created_at DESC').page(params[:page])
|
14
|
-
else
|
15
|
-
@clips = Clip.language_for_public(params[:lang]).order('created_at DESC').page(params[:page])
|
16
|
-
end
|
17
|
-
|
18
|
-
@languages = Clip.public.select("language, count(*) as count").group(:language)
|
19
|
-
@updated_at = @clips.first.updated_at unless @clips.empty?
|
20
|
-
|
21
|
-
respond_to do |format|
|
22
|
-
format.html
|
23
|
-
format.atom
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# TODO: refactor to do proper RESTful controller
|
28
|
-
def new
|
29
|
-
create
|
30
|
-
render 'create'
|
31
|
-
end
|
32
|
-
|
33
|
-
def create
|
34
|
-
@clip = Clip.new(params[:clip])
|
35
|
-
|
36
|
-
#only do validation if something was actually posted.
|
37
|
-
if !params[:clip].nil? && @clip.valid?
|
38
|
-
@clip.save
|
39
|
-
redirect_to @clip
|
40
|
-
return #early return so we don't have else statement
|
41
|
-
end
|
42
|
-
|
43
|
-
# Get all languages we have syntax for and remove debugging languages.
|
44
|
-
@languages = get_languages
|
45
|
-
end
|
46
|
-
|
47
|
-
def show
|
48
|
-
@clip = Clip.where("
|
49
|
-
:id => params[:id],
|
50
|
-
:now => DateTime.now
|
51
|
-
}).first
|
52
|
-
|
53
|
-
if @clip.nil?
|
54
|
-
# Most likely the clip is expired, take advantage of this time to
|
55
|
-
# clean up all expired clips, then display error page
|
56
|
-
Clip.delete_expired_clips
|
57
|
-
render :expired
|
58
|
-
return
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def search
|
63
|
-
@clips = Clip.search(params[:search_term]).page(params[:page])
|
64
|
-
|
65
|
-
p '\n\n\n\n'
|
66
|
-
p @clips
|
67
|
-
|
68
|
-
@languages = Clip.select("language, count(*) as count").group(:language)
|
69
|
-
|
70
|
-
render 'list' unless @clips.nil?
|
71
|
-
end
|
72
|
-
|
73
|
-
def about
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def get_languages
|
79
|
-
languages = CodeRay::Scanners.all_plugins
|
80
|
-
languages.delete(CodeRay::Scanners::Raydebug)
|
81
|
-
languages.delete(CodeRay::Scanners::Debug)
|
82
|
-
|
83
|
-
languages
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
1
|
+
require_dependency "clipster/application_controller"
|
2
|
+
|
3
|
+
module Clipster
|
4
|
+
class ClipsController < ApplicationController
|
5
|
+
def index
|
6
|
+
create
|
7
|
+
render 'create'
|
8
|
+
end
|
9
|
+
|
10
|
+
def list
|
11
|
+
# get all clips, with the newest clip first
|
12
|
+
if params[:lang].nil?
|
13
|
+
@clips = Clip.public.order('created_at DESC').page(params[:page])
|
14
|
+
else
|
15
|
+
@clips = Clip.language_for_public(params[:lang]).order('created_at DESC').page(params[:page])
|
16
|
+
end
|
17
|
+
|
18
|
+
@languages = Clip.public.select("language, count(*) as count").group(:language)
|
19
|
+
@updated_at = @clips.first.updated_at unless @clips.empty?
|
20
|
+
|
21
|
+
respond_to do |format|
|
22
|
+
format.html
|
23
|
+
format.atom
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO: refactor to do proper RESTful controller
|
28
|
+
def new
|
29
|
+
create
|
30
|
+
render 'create'
|
31
|
+
end
|
32
|
+
|
33
|
+
def create
|
34
|
+
@clip = Clip.new(params[:clip])
|
35
|
+
|
36
|
+
#only do validation if something was actually posted.
|
37
|
+
if !params[:clip].nil? && @clip.valid?
|
38
|
+
@clip.save
|
39
|
+
redirect_to @clip
|
40
|
+
return #early return so we don't have else statement
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get all languages we have syntax for and remove debugging languages.
|
44
|
+
@languages = get_languages
|
45
|
+
end
|
46
|
+
|
47
|
+
def show
|
48
|
+
@clip = Clip.where("id = :id and (expires is null OR expires > :now)",{
|
49
|
+
:id => params[:id],
|
50
|
+
:now => DateTime.now
|
51
|
+
}).first
|
52
|
+
|
53
|
+
if @clip.nil?
|
54
|
+
# Most likely the clip is expired, take advantage of this time to
|
55
|
+
# clean up all expired clips, then display error page
|
56
|
+
Clip.delete_expired_clips
|
57
|
+
render :expired
|
58
|
+
return
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def search
|
63
|
+
@clips = Clip.search(params[:search_term]).page(params[:page])
|
64
|
+
|
65
|
+
p '\n\n\n\n'
|
66
|
+
p @clips
|
67
|
+
|
68
|
+
@languages = Clip.select("language, count(*) as count").group(:language)
|
69
|
+
|
70
|
+
render 'list' unless @clips.nil?
|
71
|
+
end
|
72
|
+
|
73
|
+
def about
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def get_languages
|
79
|
+
languages = CodeRay::Scanners.all_plugins
|
80
|
+
languages.delete(CodeRay::Scanners::Raydebug)
|
81
|
+
languages.delete(CodeRay::Scanners::Debug)
|
82
|
+
|
83
|
+
languages
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
require_dependency "clipster/application_controller"
|
2
|
-
|
3
|
-
module Clipster
|
4
|
-
class UsersController < ApplicationController
|
5
|
-
def index
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
def show
|
10
|
-
@user = Clipster.config.user_class.find(params[:id])
|
11
|
-
|
12
|
-
@clips = Clip.public.where(:user_id => @user.id).page(params[:page])
|
13
|
-
|
14
|
-
@languages = Clip.select("language, count(*) as count").group(:language)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
1
|
+
require_dependency "clipster/application_controller"
|
2
|
+
|
3
|
+
module Clipster
|
4
|
+
class UsersController < ApplicationController
|
5
|
+
def index
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
@user = Clipster.config.user_class.find(params[:id])
|
11
|
+
|
12
|
+
@clips = Clip.public.where(:user_id => @user.id).page(params[:page])
|
13
|
+
|
14
|
+
@languages = Clip.select("language, count(*) as count").group(:language)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
module Clipster
|
2
|
-
module ApplicationHelper
|
3
|
-
def get_languages
|
4
|
-
languages = CodeRay::Scanners.all_plugins
|
5
|
-
languages.delete(CodeRay::Scanners::Raydebug)
|
6
|
-
languages.delete(CodeRay::Scanners::Debug)
|
7
|
-
|
8
|
-
languages
|
9
|
-
end
|
10
|
-
|
11
|
-
def get_language_counts
|
12
|
-
Clip.select("language, count(*) as count").group(:language)
|
13
|
-
end
|
14
|
-
|
15
|
-
def display_user_text(user)
|
16
|
-
user.send(Clipster.config.user_display_attribute)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
1
|
+
module Clipster
|
2
|
+
module ApplicationHelper
|
3
|
+
def get_languages
|
4
|
+
languages = CodeRay::Scanners.all_plugins
|
5
|
+
languages.delete(CodeRay::Scanners::Raydebug)
|
6
|
+
languages.delete(CodeRay::Scanners::Debug)
|
7
|
+
|
8
|
+
languages
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_language_counts
|
12
|
+
Clip.select("language, count(*) as count").group(:language)
|
13
|
+
end
|
14
|
+
|
15
|
+
def display_user_text(user)
|
16
|
+
user.send(Clipster.config.user_display_attribute)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Clipster
|
2
|
-
module ClipHelper
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Clipster
|
2
|
+
module ClipHelper
|
3
|
+
end
|
4
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Clipster
|
2
|
-
module ClipsHelper
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Clipster
|
2
|
+
module ClipsHelper
|
3
|
+
end
|
4
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Clipster
|
2
|
-
module UsersHelper
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Clipster
|
2
|
+
module UsersHelper
|
3
|
+
end
|
4
|
+
end
|
data/app/models/clipster/clip.rb
CHANGED
@@ -1,99 +1,97 @@
|
|
1
|
-
module Clipster
|
2
|
-
class Clip < ActiveRecord::Base
|
3
|
-
include ActionView::Helpers::DateHelper
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
["
|
21
|
-
["A
|
22
|
-
["A
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
:
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
cr_scanner
|
85
|
-
|
86
|
-
|
87
|
-
return cr_scanner.div
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
99
|
-
end
|
1
|
+
module Clipster
|
2
|
+
class Clip < ActiveRecord::Base
|
3
|
+
include ActionView::Helpers::DateHelper
|
4
|
+
|
5
|
+
before_create :default_values
|
6
|
+
|
7
|
+
attr_accessible :clip, :language, :title, :private, :expires, :lifespan
|
8
|
+
cattr_reader :lifespans
|
9
|
+
cattr_accessor :current_user, :lifespan
|
10
|
+
|
11
|
+
belongs_to :user, :class_name => Clipster.config.user_class.to_s unless not Clipster.config.associates_clip_with_user
|
12
|
+
|
13
|
+
validates :clip, :length => {:minimum => 3}
|
14
|
+
validates :title, :length => {:minimum => 1}
|
15
|
+
|
16
|
+
# Define all supported lifespans and their time offset
|
17
|
+
@@lifespans = [["Forever", nil],
|
18
|
+
["An Hour", :hours=>1],
|
19
|
+
["A Week", :days=>7],
|
20
|
+
["A Day", :days=>1],
|
21
|
+
["A Month", :months=>1],
|
22
|
+
["A Year", :years=>1]]
|
23
|
+
|
24
|
+
# TODO: build more powerful search term creation
|
25
|
+
scope :search, lambda {|term|
|
26
|
+
where("(title LIKE :term or language LIKE :term or clip LIKE :term) and (expires is null OR expires > :now)",{
|
27
|
+
:term => term,
|
28
|
+
:now => DateTime.now
|
29
|
+
})
|
30
|
+
}
|
31
|
+
|
32
|
+
# All clips that are public, language specific, and not expired
|
33
|
+
scope :language_for_public, lambda {|lang|
|
34
|
+
where("private = :private AND
|
35
|
+
language = :lang AND
|
36
|
+
(expires is null OR expires > :now)",{
|
37
|
+
:private => false,
|
38
|
+
:lang => lang,
|
39
|
+
:now => DateTime.now
|
40
|
+
})
|
41
|
+
}
|
42
|
+
|
43
|
+
# All clips that are public, and not expired
|
44
|
+
scope :public, lambda {
|
45
|
+
where("private = :private AND
|
46
|
+
(expires is null OR expires > :now)",{
|
47
|
+
:private => false,
|
48
|
+
:now => DateTime.now
|
49
|
+
})
|
50
|
+
}
|
51
|
+
|
52
|
+
# Setter to convert user's choice of 'A Week', etc. to an actual DateTime
|
53
|
+
def lifespan=(lifespan)
|
54
|
+
@lifespan = lifespan
|
55
|
+
@@lifespans.each_with_index do |span, index|
|
56
|
+
if span[0] == lifespan
|
57
|
+
self.expires = DateTime.now.advance(@@lifespans[index][1])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def lifespan
|
63
|
+
@lifespan
|
64
|
+
end
|
65
|
+
|
66
|
+
# Getter to convert an expire date to '1 Month', '1 Year', etc.
|
67
|
+
def expires_in_words
|
68
|
+
unless self.expires.nil?
|
69
|
+
time_ago_in_words(self.expires).humanize
|
70
|
+
else
|
71
|
+
"The end of time"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Utility method called by either cron job or when an expired clip is accessed
|
76
|
+
def Clip.delete_expired_clips
|
77
|
+
Clip.destroy_all(["expires is not null AND expires <= ?", DateTime.now])
|
78
|
+
end
|
79
|
+
|
80
|
+
# Creates the div for the clip
|
81
|
+
def div
|
82
|
+
cr_scanner = CodeRay.scan(self.clip, self.language)
|
83
|
+
# Only show line numbers if its greater than 1
|
84
|
+
if cr_scanner.loc <= 1
|
85
|
+
return cr_scanner.div
|
86
|
+
else
|
87
|
+
return cr_scanner.div(:line_numbers => :table)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
def default_values
|
93
|
+
self.user_id = self.current_user unless not Clipster.config.associates_clip_with_user
|
94
|
+
self.id = Time.now.to_f.to_s.gsub('.','').to_i.to_s(36)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|