ecm_blog 1.0.2 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de632ffe27ad033f830a1959baf29d7a78d99ab4
4
- data.tar.gz: 389d767abee60c6d20f4bb42cb6da3f3fd40e589
3
+ metadata.gz: 843e5ebb68cbbe18d01e5a23cdf95e7baca769fb
4
+ data.tar.gz: 823084d2f9afe1478db9a69437e1ed0c9b0b4142
5
5
  SHA512:
6
- metadata.gz: 593e54f330468a25548c635155144b41d189b9101060105b22be0dc72c36a50b6c85fb1889e2f826e9704b79339318c09383195e3bf4d72264a7e14c67759b8f
7
- data.tar.gz: 90d9832e83a280efefd21ca37324be37a041d4125cc5d82557fbb1626747a730d052fa97e8ca0c64a06ff9c97746ccaa231a799a8ef86687a0af4812ea427859
6
+ metadata.gz: 04062aaf40066b9bdc681b9f334783c80254e8932a30abaaa277a7d4a414ea93c804ce155e852aa065452c556b767c6a1210ae1d9024ccc40eddfee8656bc2e4
7
+ data.tar.gz: a78b270146ff4129e97b8f992b090ad151f134d46984d6306b543c07cf04861880a731612268a74e0a7292c395d1c3d387d5976048d8f8da26f783e667995b5e
@@ -6,6 +6,7 @@ module Ecm
6
6
  include ResourcesController::RestResourceUrls
7
7
  include ResourcesController::RestActions
8
8
  include ResourcesController::Kaminari
9
+ include ResourcesController::LocationHistory
9
10
 
10
11
  helper Ecm::Comments::ApplicationHelper
11
12
 
@@ -16,7 +17,7 @@ module Ecm
16
17
  private
17
18
 
18
19
  def load_collection_scope
19
- super.published.friendly.order(updated_at: :desc)
20
+ super.published.friendly.order(created_at: :desc)
20
21
  end
21
22
 
22
23
  def load_resource_scope
@@ -0,0 +1,8 @@
1
+ module Ecm
2
+ module Blog
3
+ class ApplicationService < Rails::AddOns::Service::Base
4
+ class Result < Rails::AddOns::Service::Result::Base
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,147 @@
1
+ require 'csv'
2
+
3
+ module Ecm
4
+ module Blog
5
+ # Example:
6
+ #
7
+ # You selected joomla posts from your database like this:
8
+ #
9
+ # SELECT joomla_content.title, joomla_content.fulltext, joomla_content.created, joomla_content.modified, joomla_users.email
10
+ # FROM joomla_content, joomla_users
11
+ # where created_by = joomla_users.id;
12
+ #
13
+ # And exported the data into a csv file like this:
14
+ #
15
+ # # tmp/old_posts.csv
16
+ # title;fulltext;created;modified;email
17
+ # "My first Post";"This is the body";"2013-02-12 14:22:23";"2013-02-12 21:58:54";john.doe@example.com
18
+ #
19
+ # You can import this csv file from the rails console:
20
+ #
21
+ # # rails console
22
+ # Ecm::Blog::ImportPostsService.call({ filename: 'tmp/old_posts.csv', column_map: :joomla, body_source_format: :html }, autosave: true)
23
+ #
24
+ class ImportPostsService < ApplicationService
25
+ class Result < ApplicationService::Result
26
+ attr_accessor :filename, :column_map, :body_source_format, :csv_data, :posts
27
+ end
28
+
29
+ COLUMN_MAPS = {
30
+ joomla: {
31
+ title: :title,
32
+ body: :fulltext,
33
+ created_at: :created,
34
+ updated_at: :modified,
35
+ # published_at: ->(row) { Time.zone.now },
36
+ published_at: :created,
37
+ creator_email: :email
38
+ }
39
+ }
40
+
41
+ def self.column_maps
42
+ COLUMN_MAPS
43
+ end
44
+
45
+ BODY_SOURCE_FORMATS = [:markdown, :html]
46
+
47
+ def self.body_source_formats
48
+ BODY_SOURCE_FORMATS
49
+ end
50
+
51
+ attr_accessor :filename, :column_map, :body_source_format
52
+
53
+ validates :filename, presence: true
54
+ validates :column_map, presence: true, inclusion: column_maps.keys
55
+ validates :body_source_format, presence: true, inclusion: body_source_formats
56
+
57
+ private
58
+
59
+ def after_initialize
60
+ @creators = {}
61
+ @body_source_format ||= :markdown
62
+ end
63
+
64
+ def _perform
65
+ @csv_data = load_csv_data!
66
+ @posts = build_posts!
67
+
68
+ ActiveRecord::Base.transaction { @posts.map(&:save!) } if autosave?
69
+
70
+ @result.csv_data = @csv_data
71
+ @result.posts = @posts
72
+ @result.filename = @filename
73
+ @result.column_map = @column_map
74
+ @result.body_source_format = @body_source_format
75
+ end
76
+
77
+ def load_csv_data!
78
+ CSV.read(@filename, csv_options)
79
+ end
80
+
81
+ def csv_options
82
+ { col_sep: ';', headers: true }
83
+ end
84
+
85
+ def build_posts!
86
+ say "Building posts" do
87
+ @csv_data.each_with_index.collect do |row, index|
88
+ build_post(row, index)
89
+ end
90
+ end
91
+ end
92
+
93
+ def build_post(row, index)
94
+ say "Building post [#{index}]" do
95
+ attrs = build_post_attributes(row.to_h)
96
+ Ecm::Blog::Post.new(attrs)
97
+ end
98
+ end
99
+
100
+ def build_post_attributes(row)
101
+ attrs = column_mapping.each_with_object({}) do |(post_attribute_name, value_key_or_proc), result|
102
+ result[post_attribute_name] = case value_key_or_proc
103
+ when Symbol, String
104
+ row[value_key_or_proc.to_s]
105
+ when Proc
106
+ value_key_or_proc.call(row)
107
+ else
108
+ nil
109
+ end
110
+ end
111
+ attrs[:creator] = load_creator(attrs.delete(:creator_email))
112
+ attrs[:body] = transform_body(attrs.delete(:body) || '') unless @body_source_format == :markdown
113
+ attrs
114
+ end
115
+
116
+ def column_maps
117
+ self.class.column_maps
118
+ end
119
+
120
+ def column_mapping
121
+ column_maps[@column_map]
122
+ end
123
+
124
+ def post_attribute_for_imported_key(key)
125
+ column_mapping.invert[key.to_sym]
126
+ end
127
+
128
+ def load_creator(email)
129
+ creator = Ecm::Blog::Configuration.creator_class_name.constantize.where(email: email).first_or_initialize { |u| u.password = u.password_confirmation = SecureRandom.uuid }
130
+ if creator.persisted?
131
+ @creators[email] ||= creator
132
+ else
133
+ creator
134
+ end
135
+ end
136
+
137
+ def transform_body(body)
138
+ case @body_source_format
139
+ when :html
140
+ HTMLPage.new(contents: body).markdown
141
+ else
142
+ body
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -1,8 +1,14 @@
1
1
  %div{ id: dom_id(post), class: dom_class(post) }
2
2
  %h1.post-title
3
- = post.title
4
- %small.post-creation-information.pull-right
3
+ = link_to(post.title, ecm_blog.url_for(post))
4
+ %small
5
+ %span.post-creation-information.text-muted
5
6
  = "#{l(post.created_at)} | #{post.creator.try(:human)}"
6
- %p.post-tags= tag_labels_for(post)
7
+ |
8
+ %span.comments-information
9
+ = link_to(t('ecm.comments.commentable.comments_information', comments_count: post.comments.count), ecm_blog.post_url(post, anchor: 'comments'))
10
+ |
11
+ %span.post-tags
12
+ = tag_labels_for(post)
7
13
 
8
14
  %p.post-body= post.body(format: :html).html_safe
@@ -1,12 +1,14 @@
1
1
  %div{ id: dom_id(post), class: "#{dom_class(post)} bottom-margin-5" }
2
2
  %h2.post-title
3
3
  = link_to(post.title, ecm_blog.url_for(post))
4
- %small.post-creation-information.pull-right
4
+ %small
5
+ %span.post-creation-information.text-muted
5
6
  = "#{l(post.created_at)} | #{post.creator.try(:human)}"
6
- %p
7
- %span.post-tags<= tag_labels_for(post)
8
7
  |
9
8
  %span.comments-information
10
9
  = link_to(t('ecm.comments.commentable.comments_information', comments_count: post.comments.count), ecm_blog.post_url(post, anchor: 'comments'))
10
+ |
11
+ %span.post-tags
12
+ = tag_labels_for(post)
11
13
 
12
14
  %p.post-body= post.body(format: :html).html_safe
@@ -1,6 +1,7 @@
1
- %h1#page-title= resource_class.model_name.human(count: :other)
1
+ %h1#page-title= Ecm::Blog::Configuration.posts_index_page_title_proc.call(self)
2
2
 
3
3
  = render partial: "post_in_index", collection: @collection, as: :post
4
4
 
5
- .col-lg.12.text-center
6
- = bootstrap_paginate(@collection)
5
+ .row
6
+ .col-lg-12.text-center
7
+ = paginate(@collection, Ecm::Blog::Configuration.pagination_options_proc.call(self))
data/config/routes.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  Ecm::Blog::Engine.routes.draw do
2
2
  localized do
3
3
  scope :ecm_blog_engine do
4
- resources :posts, only: [:index, :show]
4
+ resources :posts, only: [:index, :show] do
5
+ get 'page/:page', action: :index, on: :collection
6
+ end
5
7
 
6
8
  root to: 'posts#index'
7
9
  end
@@ -11,6 +11,8 @@ module Ecm
11
11
 
12
12
  mattr_accessor(:base_controller) { '::FrontendController' }
13
13
  mattr_accessor(:creator_class_name) { 'User' }
14
+ mattr_accessor(:posts_index_page_title_proc) { ->(view) { view.resource_class.model_name.human(count: :other) } }
15
+ mattr_accessor(:pagination_options_proc) { ->(view) { { theme: 'twitter-bootstrap-3' } } }
14
16
  end
15
17
  end
16
18
  end
@@ -1,5 +1,5 @@
1
1
  module Ecm
2
2
  module Blog
3
- VERSION = '1.0.2'.freeze
3
+ VERSION = '1.2.0'.freeze
4
4
  end
5
5
  end
data/lib/ecm_blog.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'ecm_comments'
2
2
  require 'acts_as_published'
3
3
  require 'friendly_id'
4
+ require 'html2markdown'
4
5
  require 'kaminari'
5
6
  require 'kramdown'
6
7
 
@@ -4,6 +4,33 @@ Ecm::Blog.configure do |config|
4
4
  # Default: config.base_controller = '<%= base_controller_class_name %>'
5
5
  #
6
6
  config.base_controller = '<%= base_controller_class_name %>'
7
-
7
+
8
+ # Class to use for creators and updaters.
9
+ #
10
+ # default: config.creator_class_name = 'User'
11
+ #
8
12
  config.creator_class_name = 'User'
13
+
14
+ # Set the page title for the posts index page. Useful for when you use
15
+ # the blog posts index as main app root page.
16
+ #
17
+ # example: config.posts_index_page_title_proc = ->(view) { view.t('.welcome') }
18
+ #
19
+ # default: config.posts_index_page_title_proc = ->(view) { view.resource_class.model_name.human(count: :other) }
20
+ #
21
+ config.posts_index_page_title_proc = ->(view) { view.resource_class.model_name.human(count: :other) }
22
+
23
+ # Set options that will be passed to the paginate call.
24
+ #
25
+ # example for bootstrap 3 (You will need to add the bootstrap3-kaminari-views gem to your Gemfile):
26
+ #
27
+ # config.pagination_options_proc = ->(view) { { theme: 'twitter-bootstrap-3' }
28
+ #
29
+ # example for bootstrap 4 (You will need to add the bootstrap4-kaminari-views gem to your Gemfile):
30
+ #
31
+ # config.pagination_options_proc = ->(view) { { theme: 'twitter-bootstrap-4' }
32
+ #
33
+ # default: config.pagination_options_proc = ->(view) { { theme: 'twitter-bootstrap-4', pagination_class: 'justify-content-center' } }
34
+ #
35
+ config.pagination_options_proc = ->(view) { { theme: 'twitter-bootstrap-4', pagination_class: 'justify-content-center' } }
9
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecm_blog
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Vasquez Angel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-10 00:00:00.000000000 Z
11
+ date: 2018-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: html2markdown
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: kaminari
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -102,7 +116,6 @@ extensions: []
102
116
  extra_rdoc_files: []
103
117
  files:
104
118
  - MIT-LICENSE
105
- - README.rdoc
106
119
  - Rakefile
107
120
  - app/assets/javascripts/ecm/blog/application.js
108
121
  - app/assets/stylesheets/ecm/blog/application.css
@@ -110,6 +123,8 @@ files:
110
123
  - app/controllers/ecm/blog/posts_controller.rb
111
124
  - app/helpers/ecm/blog/application_helper.rb
112
125
  - app/models/ecm/blog/post.rb
126
+ - app/services/ecm/blog/application_service.rb
127
+ - app/services/ecm/blog/import_posts_service.rb
113
128
  - app/views/ecm/blog/posts/_post.haml
114
129
  - app/views/ecm/blog/posts/_post_in_index.haml
115
130
  - app/views/ecm/blog/posts/index.haml
data/README.rdoc DELETED
@@ -1,3 +0,0 @@
1
- = Ecm::Blog
2
-
3
- This project rocks and uses MIT-LICENSE.