cloudpress 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +30 -0
- data/app/assets/cloudpress/cloudpress.css.sass +1 -0
- data/app/assets/cloudpress/code/railscasts.css +70 -0
- data/app/controllers/cloudpress/application_controller.rb +12 -0
- data/app/controllers/cloudpress/archives_controller.rb +34 -0
- data/app/controllers/cloudpress/posts_controller.rb +23 -0
- data/app/controllers/cloudpress/tags_controller.rb +20 -0
- data/app/helpers/cloudpress/renderer_helper.rb +23 -0
- data/app/jobs/cloudpress/update_posts_job.rb +9 -0
- data/app/models/cloudpress/archive.rb +50 -0
- data/app/models/cloudpress/post.rb +65 -0
- data/app/views/cloudpress/archives/_archive.html.slim +3 -0
- data/app/views/cloudpress/archives/_archives.html.slim +2 -0
- data/app/views/cloudpress/archives/_month.html.slim +2 -0
- data/app/views/cloudpress/archives/show.html.slim +1 -0
- data/app/views/cloudpress/posts/_intro.html.slim +9 -0
- data/app/views/cloudpress/posts/_post.html.slim +8 -0
- data/app/views/cloudpress/posts/index.html.slim +1 -0
- data/app/views/cloudpress/posts/show.html.slim +1 -0
- data/app/views/cloudpress/tags/_tag.html.slim +2 -0
- data/app/views/cloudpress/tags/_tags.html.slim +2 -0
- data/app/views/cloudpress/tags/show.html.slim +1 -0
- data/bin/console +14 -0
- data/bin/rails +12 -0
- data/bin/setup +7 -0
- data/cloudpress.gemspec +35 -0
- data/config/initializers/tag_extensions.rb +4 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20150309115639_create_cloudpress_posts.rb +19 -0
- data/db/migrate/20150315192521_create_tags_table.rb +30 -0
- data/db/migrate/20150315193206_create_friendly_id_slugs.rb +15 -0
- data/db/migrate/20150317121651_add_slug_to_tags.rb +6 -0
- data/db/migrate/20150317122608_add_taggings_counter_cache.rb +14 -0
- data/lib/cloudpress.rb +105 -0
- data/lib/cloudpress/dropbox/cleaner.rb +20 -0
- data/lib/cloudpress/dropbox/client.rb +15 -0
- data/lib/cloudpress/dropbox/connector.rb +24 -0
- data/lib/cloudpress/dropbox/directory.rb +57 -0
- data/lib/cloudpress/dropbox/file.rb +57 -0
- data/lib/cloudpress/engine.rb +10 -0
- data/lib/cloudpress/formatters/html_with_pygments.rb +7 -0
- data/lib/cloudpress/renderers/archive.rb +18 -0
- data/lib/cloudpress/renderers/archives.rb +24 -0
- data/lib/cloudpress/renderers/post.rb +39 -0
- data/lib/cloudpress/renderers/posts.rb +38 -0
- data/lib/cloudpress/renderers/tag.rb +18 -0
- data/lib/cloudpress/renderers/tags.rb +24 -0
- data/lib/cloudpress/version.rb +3 -0
- data/lib/generators/cloudpress/initializer/USAGE +8 -0
- data/lib/generators/cloudpress/initializer/initializer_generator.rb +32 -0
- metadata +283 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 66f77b04e4f9ef5b8f64d4f609cb602cbcb958c4
|
4
|
+
data.tar.gz: 85e140b6936fc6cb99e4afeab8568e189b53df31
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a0149d95e94409c77310870b75b825c17e58ec6d54c44b964df7a0095085ee96ce9a7c1ae172f4567c69c7b59dd3d14a079fde2c5c4930e8fbef85e350a062ce
|
7
|
+
data.tar.gz: 83f1f9d14cb774ad0c01b5666ab3643fdeb841d912e6a319478f138f91ae114b2a660b80fc1b4b700fe629691632d57923c705bd01f55b66e23bae54811ce594
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Adam Carlile
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Cloudpress
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/cloudpress`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'cloudpress'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install cloudpress
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it ( https://github.com/[my-github-username]/cloudpress/fork )
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Blorgh'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
Bundler::GemHelper.install_tasks
|
19
|
+
|
20
|
+
require 'rake/testtask'
|
21
|
+
|
22
|
+
Rake::TestTask.new(:test) do |t|
|
23
|
+
t.libs << 'lib'
|
24
|
+
t.libs << 'test'
|
25
|
+
t.pattern = 'test/**/*_test.rb'
|
26
|
+
t.verbose = false
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
task default: :test
|
@@ -0,0 +1 @@
|
|
1
|
+
@import "code/railscasts"
|
@@ -0,0 +1,70 @@
|
|
1
|
+
.highlight { background: #2B2B2B; color: #E6E1DC}
|
2
|
+
.highlight .hll { background-color: #ffffcc }
|
3
|
+
.highlight .c { color: #BC9458; font-style: italic} /* Comment */
|
4
|
+
.highlight .err { color: #E6E1DC} /* Error */
|
5
|
+
.highlight .g { color: #E6E1DC} /* Generic */
|
6
|
+
.highlight .k { color: #CC7833} /* Keyword */
|
7
|
+
.highlight .l { color: #E6E1DC} /* Literal */
|
8
|
+
.highlight .n { color: #E6E1DC} /* Name */
|
9
|
+
.highlight .o { color: #E6E1DC} /* Operator */
|
10
|
+
.highlight .x { color: #E6E1DC} /* Other */
|
11
|
+
.highlight .p { color: #E6E1DC} /* Punctuation */
|
12
|
+
.highlight .cm { color: #BC9458; font-style: italic} /* Comment.Multiline */
|
13
|
+
.highlight .cp { color: #CC7833} /* Comment.Preproc */
|
14
|
+
.highlight .c1 { color: #BC9458; font-style: italic} /* Comment.Single */
|
15
|
+
.highlight .cs { color: #BC9458; font-style: italic} /* Comment.Special */
|
16
|
+
.highlight .gd { color: #E6E1DC; background-color: #660000 } /* Generic.Deleted */
|
17
|
+
.highlight .ge { color: #E6E1DC} /* Generic.Emph */
|
18
|
+
.highlight .gr { color: #FFFFFF; background-color: #990000 } /* Generic.Error */
|
19
|
+
.highlight .gh { color: #FFFFFF} /* Generic.Heading */
|
20
|
+
.highlight .gi { color: #E6E1DC; background-color: #144212 } /* Generic.Inserted */
|
21
|
+
.highlight .go { color: #E6E1DC} /* Generic.Output */
|
22
|
+
.highlight .gp { color: #E6E1DC} /* Generic.Prompt */
|
23
|
+
.highlight .gs { color: #E6E1DC} /* Generic.Strong */
|
24
|
+
.highlight .gu { color: #FFFFFF} /* Generic.Subheading */
|
25
|
+
.highlight .gt { color: #E6E1DC} /* Generic.Traceback */
|
26
|
+
.highlight .kc { color: #CC7833} /* Keyword.Constant */
|
27
|
+
.highlight .kd { color: #CC7833} /* Keyword.Declaration */
|
28
|
+
.highlight .kn { color: #CC7833} /* Keyword.Namespace */
|
29
|
+
.highlight .kp { color: #CC7833} /* Keyword.Pseudo */
|
30
|
+
.highlight .kr { color: #CC7833} /* Keyword.Reserved */
|
31
|
+
.highlight .kt { color: #DA4939} /* Keyword.Type */
|
32
|
+
.highlight .ld { color: #E6E1DC} /* Literal.Date */
|
33
|
+
.highlight .m { color: #A5C261} /* Literal.Number */
|
34
|
+
.highlight .s { color: #A5C261} /* Literal.String */
|
35
|
+
.highlight .na { color: #FFC66D} /* Name.Attribute */
|
36
|
+
.highlight .nb { color: #E6E1DC} /* Name.Builtin */
|
37
|
+
.highlight .nc { color: #E6E1DC} /* Name.Class */
|
38
|
+
.highlight .no { color: #6D9CBE} /* Name.Constant */
|
39
|
+
.highlight .nd { color: #E6E1DC} /* Name.Decorator */
|
40
|
+
.highlight .ni { color: #E6E1DC} /* Name.Entity */
|
41
|
+
.highlight .ne { color: #E6E1DC} /* Name.Exception */
|
42
|
+
.highlight .nf { color: #FFC66D} /* Name.Function */
|
43
|
+
.highlight .nl { color: #E6E1DC} /* Name.Label */
|
44
|
+
.highlight .nn { color: #E6E1DC} /* Name.Namespace */
|
45
|
+
.highlight .nx { color: #E6E1DC} /* Name.Other */
|
46
|
+
.highlight .py { color: #E6E1DC} /* Name.Property */
|
47
|
+
.highlight .nt { color: #CC7833} /* Name.Tag */
|
48
|
+
.highlight .nv { color: #D0D0FF} /* Name.Variable */
|
49
|
+
.highlight .ow { color: #E6E1DC} /* Operator.Word */
|
50
|
+
.highlight .w { color: #E6E1DC} /* Text.Whitespace */
|
51
|
+
.highlight .mf { color: #A5C261} /* Literal.Number.Float */
|
52
|
+
.highlight .mh { color: #A5C261} /* Literal.Number.Hex */
|
53
|
+
.highlight .mi { color: #A5C261} /* Literal.Number.Integer */
|
54
|
+
.highlight .mo { color: #A5C261} /* Literal.Number.Oct */
|
55
|
+
.highlight .sb { color: #A5C261} /* Literal.String.Backtick */
|
56
|
+
.highlight .sc { color: #A5C261} /* Literal.String.Char */
|
57
|
+
.highlight .sd { color: #A5C261} /* Literal.String.Doc */
|
58
|
+
.highlight .s2 { color: #A5C261} /* Literal.String.Double */
|
59
|
+
.highlight .se { color: #A5C261} /* Literal.String.Escape */
|
60
|
+
.highlight .sh { color: #A5C261} /* Literal.String.Heredoc */
|
61
|
+
.highlight .si { color: #A5C261} /* Literal.String.Interpol */
|
62
|
+
.highlight .sx { color: #A5C261} /* Literal.String.Other */
|
63
|
+
.highlight .sr { color: #A5C261} /* Literal.String.Regex */
|
64
|
+
.highlight .s1 { color: #A5C261} /* Literal.String.Single */
|
65
|
+
.highlight .ss { color: #A5C261} /* Literal.String.Symbol */
|
66
|
+
.highlight .bp { color: #E6E1DC} /* Name.Builtin.Pseudo */
|
67
|
+
.highlight .vc { color: #D0D0FF} /* Name.Variable.Class */
|
68
|
+
.highlight .vg { color: #D0D0FF} /* Name.Variable.Global */
|
69
|
+
.highlight .vi { color: #D0D0FF} /* Name.Variable.Instance */
|
70
|
+
.highlight .il { color: #A5C261} /* Literal.Number.Integer.Long */
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Cloudpress
|
2
|
+
class ArchivesController < Cloudpress::ApplicationController
|
3
|
+
|
4
|
+
def show
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def archive
|
10
|
+
@archive ||= begin
|
11
|
+
out = nil
|
12
|
+
date = Date.new *[params[:year], params[:month]].compact.map(&:to_i)
|
13
|
+
out = Cloudpress::Archive.year(date) if year?
|
14
|
+
out = Cloudpress::Archive.find(date) if year? && month?
|
15
|
+
out
|
16
|
+
end
|
17
|
+
end
|
18
|
+
helper_method :archive
|
19
|
+
|
20
|
+
def posts
|
21
|
+
@posts ||= archive.posts
|
22
|
+
end
|
23
|
+
helper_method :posts
|
24
|
+
|
25
|
+
def year?
|
26
|
+
params[:year].present?
|
27
|
+
end
|
28
|
+
|
29
|
+
def month?
|
30
|
+
params[:month].present?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cloudpress
|
2
|
+
class PostsController < Cloudpress::ApplicationController
|
3
|
+
|
4
|
+
def index
|
5
|
+
end
|
6
|
+
|
7
|
+
def show
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def posts
|
13
|
+
@posts ||= Cloudpress::Post.published.page(params[:page])
|
14
|
+
end
|
15
|
+
helper_method :posts
|
16
|
+
|
17
|
+
def post
|
18
|
+
@post ||= Cloudpress::Post.find_by(slug: params[:slug])
|
19
|
+
end
|
20
|
+
helper_method :post
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Cloudpress
|
2
|
+
class TagsController < Cloudpress::ApplicationController
|
3
|
+
|
4
|
+
def show
|
5
|
+
end
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def tagging
|
10
|
+
@tagging ||= ActsAsTaggableOn::Tag.find(params[:id])
|
11
|
+
end
|
12
|
+
helper_method :tagging
|
13
|
+
|
14
|
+
def posts
|
15
|
+
@posts ||= Cloudpress::Post.tagged_with(tagging.name)
|
16
|
+
end
|
17
|
+
helper_method :posts
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cloudpress
|
2
|
+
module RendererHelper
|
3
|
+
|
4
|
+
def render_cloudpress_posts(posts, options={}, &block)
|
5
|
+
Cloudpress::Renderers::Posts.new(self, posts, options).render
|
6
|
+
end
|
7
|
+
|
8
|
+
def render_cloudpress_post(post, options={}, &block)
|
9
|
+
renderer = Cloudpress::Renderers::Post.new(self, post, options)
|
10
|
+
renderer.content = capture(&block) if block_given?
|
11
|
+
renderer.render
|
12
|
+
end
|
13
|
+
|
14
|
+
def render_cloudpress_tags(tags)
|
15
|
+
Cloudpress::Renderers::Tags.new(self, tags).render
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_cloudpress_archives(archives)
|
19
|
+
Cloudpress::Renderers::Archives.new(self, archives).render
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Cloudpress
|
2
|
+
class Archive
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def all
|
6
|
+
wrap(Cloudpress::Post.unscoped.published.group_by_month(:publish_date).count.keys.group_by {|x| x.year})
|
7
|
+
end
|
8
|
+
|
9
|
+
def year(date)
|
10
|
+
raise ArgumentError unless date.respond_to?(:year)
|
11
|
+
new(date_range(date.beginning_of_year..date.end_of_year))
|
12
|
+
end
|
13
|
+
|
14
|
+
def find(date)
|
15
|
+
raise ArgumentError unless date.respond_to?(:year)
|
16
|
+
new(date_range(date.beginning_of_month..date.end_of_month))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def wrap(hash)
|
22
|
+
hash.map { |k, v| new(date_range(v)) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def date_range(range)
|
26
|
+
range.first.to_time.beginning_of_month.in_time_zone..range.last.to_time.end_of_month.in_time_zone
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :range
|
32
|
+
|
33
|
+
def initialize(range)
|
34
|
+
@range = range
|
35
|
+
end
|
36
|
+
|
37
|
+
def year
|
38
|
+
range.first.year
|
39
|
+
end
|
40
|
+
|
41
|
+
def months
|
42
|
+
@months ||= (range.first.to_date..range.last.to_date).map {|x| x.beginning_of_month}.uniq
|
43
|
+
end
|
44
|
+
|
45
|
+
def posts
|
46
|
+
@posts ||= Cloudpress::Post.published.between(@range)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Cloudpress
|
2
|
+
class Post < ActiveRecord::Base
|
3
|
+
acts_as_taggable
|
4
|
+
|
5
|
+
default_scope -> { order(publish_date: :desc) }
|
6
|
+
scope :published, -> { where(state: 'live') }
|
7
|
+
scope :draft, -> { where(state: 'draft') }
|
8
|
+
|
9
|
+
scope :between, ->(date_range) { where(:publish_date => date_range) }
|
10
|
+
|
11
|
+
paginates_per 10
|
12
|
+
|
13
|
+
def update_from_dropbox(dropbox_file)
|
14
|
+
self.revision = dropbox_file.revision
|
15
|
+
self.body = dropbox_file.body
|
16
|
+
self.metadata = dropbox_file.metadata
|
17
|
+
self.title = metadata[:title] || titleized_file_name
|
18
|
+
self.publish_date = created_at || Time.now
|
19
|
+
self.publish_date = Time.parse(metadata[:publish_date]) if metadata[:publish_date]
|
20
|
+
self.slug = metadata[:slug] || generate_slug
|
21
|
+
self.tag_list = metadata_tags.map(&:downcase)
|
22
|
+
self.state = dropbox_file.state
|
23
|
+
save!
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_param
|
27
|
+
slug
|
28
|
+
end
|
29
|
+
|
30
|
+
def layout
|
31
|
+
metadata[:layout]
|
32
|
+
end
|
33
|
+
|
34
|
+
def metadata
|
35
|
+
super.with_indifferent_access
|
36
|
+
end
|
37
|
+
|
38
|
+
def summary
|
39
|
+
@summary ||= Nokogiri::HTML(body).at_css('p').text
|
40
|
+
end
|
41
|
+
|
42
|
+
def wordcount
|
43
|
+
@wordcount ||= Nokogiri::HTML(body).inner_text.split(' ').size
|
44
|
+
end
|
45
|
+
|
46
|
+
def time_to_read
|
47
|
+
@time_to_read ||= ((wordcount.to_f / 200.0) * 60).to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def generate_slug
|
53
|
+
slug_parts = []
|
54
|
+
slug_parts << publish_date.year
|
55
|
+
slug_parts << publish_date.month
|
56
|
+
slug_parts << title.parameterize
|
57
|
+
slug_parts.join('/')
|
58
|
+
end
|
59
|
+
|
60
|
+
def metadata_tags
|
61
|
+
[metadata[:tags]].flatten.compact
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|