jekyll-mail-comments 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4ebed81f1e8338d62ed7b4260a85053cebba168a7ad734785ba90ba4e2358a4f
4
+ data.tar.gz: 8a06546dd5307ca7c0142fd9dcca55542510c419edd62d93fb8898a12fb9b65e
5
+ SHA512:
6
+ metadata.gz: b1261991ca3b7f61b1b9f2f81a7ad5517f7ba50d2cb4801cc57c4b9a40412e569e15e80c3d803df7952750ed498652b4ba3c3051b78eb335dbf24356f6b08c12
7
+ data.tar.gz: 5291b56543dc5b8fb8fe97275a942c40500327380d3d877bb6d2fff112845097b9694c19687d8ceed8631c07e8795b685475bcd7a50ee48c5be6144dc39d86ec
data/.env.dist ADDED
@@ -0,0 +1,5 @@
1
+ export MC_LOGIN="username@mailhost.com"
2
+ export MC_PASSWORD=p4ss0rd
3
+ export MC_HOST="imap.mailhost.com"
4
+ export MC_PORT=993
5
+ export MC_SUBJECT_SUFFIX="Jekyll"
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle
2
+ /.rbenv-vars
3
+ /.ruby-version
4
+ /.rvmrc
5
+ /corpus
6
+ /coverage
7
+ /Gemfile.lock
8
+ /gems
9
+ /mail-*.gem
10
+ /rdoc
11
+ *~
12
+ .env
13
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+ gemspec
4
+ gem 'mail'
5
+ gem 'jekyll'
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # Jekyll Mail comments
2
+
3
+ This gem fetches email from your mailbox by filtering with specific suffix, it makes data files which you can use to generate Jekyll comments.
4
+
5
+ ## How it works ?
6
+
7
+ * You've to setup mailbox, on Jekyll pages you will have mailto link which opens native system mail client with pre filled subject.
8
+ * Person who wants to comment message write message to your specific email address.
9
+ * Fetch program watch for special subject suffix to distinct comments from other emails
10
+ * Fetch program generate json based data files which perfectly fits to Jekyll data system https://jekyllrb.com/docs/datafiles/
11
+
12
+
13
+ ## What is the purpose ?
14
+
15
+ * Jekyll static site generator has no comments system
16
+ * Don't want to inject 3rdparty javascript code to work with SaSS comments system
17
+ * Any RDBS for static site generator is overhead
18
+
19
+
20
+ ## How-to Setup
21
+
22
+ * Go to your jekyll site `cd ~/jekull_site`
23
+ * Install gem `gem install mail_comments`
24
+ * Setup credentials
25
+
26
+ There few credentials your have to setup before run:
27
+
28
+ ** MC_LOGIN - Login to imap server
29
+ ** MC_PASSWORD - Password for imap server
30
+ ** MC_HOST - IMAP server hostname
31
+ ** MC_PORT - IMAP server port
32
+ ** MC_SUBJECT_SUFFIX - Suffix to filter comments
33
+
34
+ * You have put this as environment variables `see .env.dist`
35
+ * `jekyll-mail-comments-fetch`
36
+ * After that you will get comments data files inside Jekyll data directory - **_data**
37
+
38
+ After that if new comments are present it will generate data files with comments which you can process with Jekyll with data tag.
39
+ See here. https://jekyllrb.com/docs/datafiles/ or below.
40
+
41
+ Here is how to you can include comments block into your Jekyll post template
42
+
43
+ ```
44
+
45
+ <section>
46
+ {% include comments-count.html replies_to=page.path %}
47
+
48
+ {% if comment_count %}
49
+ <h2>Comments ({{- comment_count -}}) <small class="text-muted">Read carefuly </small> </h2>
50
+ {% include comments.html replies_to=page.path indent_class="ml-auto" title=page.title %}
51
+ {% else %}
52
+ <h2>No comments here yet <small class="text-muted">Write here gently</small></h2>
53
+ {% endif %}
54
+ <div class="mt-3"><a class="btn btn-outline-secondary btn-block" href="mailto:{{site.comments.email}}?subject=RE:{{page.path}}:{{site.comments.subject_suffix}}:{{post.title}}">Write a comment</a> </div>
55
+ </section>
56
+ ```
57
+ Templates can be found inside **templates** directory of this gem.
58
+
59
+
60
+ ## Credits
61
+
62
+ Inspiration while searching for already existing gem for email comments
63
+
64
+ * https://stevescott.ca/2017-04-03-static-site-comments-via-email.html
65
+ * https://github.com/aioobe/dead-simple-jekyll-comments/
66
+
67
+
68
+ ## Example
69
+
70
+ * https://blog.falsetrue.io
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'jekyll-mail-comments'
4
+ Jekyll::MailComments.fetch
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'jekyll-mail-comments'
3
+ s.version = '0.0.2'
4
+ s.date = '2022-01-01'
5
+ s.summary = "Email based comment system for Jekyll static site generator"
6
+ s.description = <<DESC
7
+ Provides html generator of threaded comments pages fetched from an IMAP for Jekyll
8
+ DESC
9
+ s.authors = "Dmitry Rodichev"
10
+ s.email = 'noroot@falsetrue.io'
11
+ s.files = `git ls-files`.split($/)
12
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
14
+
15
+ s.add_dependency 'jekyll'
16
+ s.homepage = 'https://github.com/noroot/jekyll-mail-comments'
17
+ s.license = 'GPL-3.0'
18
+ s.post_install_message = <<MSG
19
+ Don't forget to put credentials inside .env file, see .env.dist inside gem source.
20
+ MSG
21
+ end
@@ -0,0 +1,103 @@
1
+ require 'net/imap'
2
+ require 'mail'
3
+ require 'fileutils'
4
+ require "base64"
5
+ require 'yaml'
6
+ require 'digest'
7
+ require 'jekyll'
8
+
9
+ module Jekyll
10
+
11
+ module MailComments
12
+
13
+ class Configuration
14
+ attr_accessor :login
15
+ attr_accessor :password
16
+ attr_accessor :host
17
+ attr_accessor :port
18
+ attr_accessor :subject_suffix
19
+
20
+ def initialize
21
+ @login = ENV.fetch('MC_LOGIN', '')
22
+ @password = ENV.fetch('MC_PASSWORD', '')
23
+ @host = ENV.fetch('MC_HOST', '')
24
+ @port = ENV.fetch('MC_PORT', '')
25
+ @subject_suffix = ENV.fetch('MC_SUBJECT_SUFFIX', '')
26
+ end
27
+ end
28
+
29
+
30
+ class << self
31
+ attr_writer :configuration
32
+ end
33
+
34
+ def self.configuration
35
+ @configuration ||= Configuration.new
36
+ end
37
+
38
+ def self.configure
39
+ yield(configuration)
40
+ end
41
+
42
+ def self.fetch
43
+
44
+ login = MailComments.configuration.login
45
+ password = MailComments.configuration.password
46
+ host = MailComments.configuration.host
47
+ port = MailComments.configuration.port
48
+ subject_suffix = MailComments.configuration.subject_suffix
49
+
50
+ imap = Net::IMAP.new(host, 993, true)
51
+ imap.login(login, password)
52
+ imap.select("INBOX")
53
+ cx = imap.search(["SUBJECT", subject_suffix, "UNSEEN"])
54
+ if !cx.nil? && cx.length > 0
55
+ puts "Comments found CX=#{cx.length}"
56
+ comments = {}
57
+ cx.each do |message_id|
58
+ msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
59
+ mail = Mail.read_from_string(msg)
60
+ if mail.multipart?
61
+ body = mail.multipart?? mail.text_part.body.decoded : mail.html_part.body.decoded
62
+ else
63
+ body = mail.body.decoded
64
+ end
65
+
66
+ author = mail.header['From'].field.addrs.first.display_name
67
+
68
+ begin
69
+ tmp = mail.subject.split(":")
70
+ if tmp.length == 4
71
+ reply_id = mail.subject.split(":")[1].strip()
72
+ post_title = mail.subject.split(":")[3].strip()
73
+
74
+ message_id = Digest::SHA1.hexdigest(mail['Message-ID'].value)
75
+ comment = {
76
+ title: post_title,
77
+ reply_to: reply_id,
78
+ id: message_id,
79
+ author: author,
80
+ from: mail.from.first,
81
+ date: mail.date,
82
+ text: body
83
+ }
84
+ file_name = "#{mail.date.strftime("%s").to_s}-#{message_id}.yaml"
85
+ File.open("_data/comments/#{file_name}", "w") do |f|
86
+ f.write(comment.transform_keys(&:to_s).to_yaml)
87
+ end
88
+ puts "Comment from #{comment[:author]} - <#{comment[:from]}> on \"#{comment[:title]}\" at #{comment[:date]}"
89
+ else
90
+ puts "Wrong subject for #{msg}"
91
+ end
92
+
93
+ rescue => e
94
+ puts e
95
+ end
96
+ end
97
+ else
98
+ puts "No messages found."
99
+ end
100
+
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,100 @@
1
+ require 'net/imap'
2
+ require 'mail'
3
+ require 'fileutils'
4
+ require "base64"
5
+ require 'yaml'
6
+ require 'digest'
7
+
8
+
9
+ module MailComments
10
+
11
+ class Configuration
12
+ attr_accessor :login
13
+ attr_accessor :password
14
+ attr_accessor :host
15
+ attr_accessor :port
16
+ attr_accessor :subject_suffix
17
+
18
+ def initialize
19
+ @login = ENV.fetch('MC_LOGIN', '')
20
+ @password = ENV.fetch('MC_PASSWORD', '')
21
+ @host = ENV.fetch('MC_HOST', '')
22
+ @port = ENV.fetch('MC_PORT', '')
23
+ @subject_suffix = ENV.fetch('MC_SUBJECT_SUFFIX', '')
24
+ end
25
+ end
26
+
27
+
28
+ class << self
29
+ attr_writer :configuration
30
+ end
31
+
32
+ def self.configuration
33
+ @configuration ||= Configuration.new
34
+ end
35
+
36
+ def self.configure
37
+ yield(configuration)
38
+ end
39
+
40
+ def self.fetch
41
+
42
+ login = MailComments.configuration.login
43
+ password = MailComments.configuration.password
44
+ host = MailComments.configuration.host
45
+ port = MailComments.configuration.port
46
+ subject_suffix = MailComments.configuration.subject_suffix
47
+
48
+ imap = Net::IMAP.new(host, 993, true)
49
+ imap.login(login, password)
50
+ imap.select("INBOX")
51
+ cx = imap.search(["SUBJECT", subject_suffix, "UNSEEN"])
52
+ if !cx.nil? && cx.length > 0
53
+ puts "Comments found CX=#{cx.length}"
54
+ comments = {}
55
+ cx.each do |message_id|
56
+ msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
57
+ mail = Mail.read_from_string(msg)
58
+ if mail.multipart?
59
+ body = mail.multipart?? mail.text_part.body.decoded : mail.html_part.body.decoded
60
+ else
61
+ body = mail.body.decoded
62
+ end
63
+
64
+ author = mail.header['From'].field.addrs.first.display_name
65
+
66
+ begin
67
+ tmp = mail.subject.split(":")
68
+ if tmp.length == 4
69
+ reply_id = mail.subject.split(":")[1].strip()
70
+ post_title = mail.subject.split(":")[3].strip()
71
+
72
+ message_id = Digest::SHA1.hexdigest(mail['Message-ID'].value)
73
+ comment = {
74
+ title: post_title,
75
+ reply_to: reply_id,
76
+ id: message_id,
77
+ author: author,
78
+ from: mail.from.first,
79
+ date: mail.date,
80
+ text: body
81
+ }
82
+ file_name = "#{mail.date.strftime("%s").to_s}-#{message_id}.yaml"
83
+ File.open("_data/comments/#{file_name}", "w") do |f|
84
+ f.write(comment.transform_keys(&:to_s).to_yaml)
85
+ end
86
+ puts "Comment from #{comment[:author]} - <#{comment[:from]}> on \"#{comment[:title]}\" at #{comment[:date]}"
87
+ else
88
+ puts "Wrong subject for #{msg}"
89
+ end
90
+
91
+ rescue => e
92
+ puts e
93
+ end
94
+ end
95
+ else
96
+ puts "No messages found."
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,7 @@
1
+ {%- for entry in site.data.comments -%}
2
+ {%- if entry[1].reply_to == include.replies_to -%}
3
+ {%- assign comment_count = comment_count | plus: 1 -%}
4
+ {%- assign com_id = entry[0] -%}
5
+ {%- include comments-count.html replies_to=com_id -%}
6
+ {%- endif -%}
7
+ {%- endfor -%}
@@ -0,0 +1,30 @@
1
+ {% assign sorted = site.data.comments | sort %}
2
+ {%- for entry in sorted -%}
3
+
4
+ {%- assign cid = entry[0] -%}
5
+ {%- assign com = entry[1] -%}
6
+ {%- assign indent_class = include.indent_class %}
7
+ {%- assign title = include.title %}
8
+ {%- if com.reply_to != include.replies_to -%}
9
+ {%- continue -%}
10
+ {%- endif -%}
11
+
12
+ <div class="{{ indent_class }} comment" id="{{ cid }}">
13
+ <div class="d-flex">
14
+ <div><a href="" class="comment-author">{{ com.author | escape | strip_newlines }}</a> - <span class="comment-date"> {{ com.date | date_to_rfc822 }}</span></div>
15
+ <!-- <div class="ml-auto">at {{ com.date | date_to_rfc822 }}</div> -->
16
+ </div>
17
+ <div>
18
+ {{ com.text | escape | newline_to_br | strip_newlines | markdownify | replace: "&amp;#39;", "'" | replace: "&amp;quot;", '"' }}
19
+
20
+ <!-- <div class="comment-controls">
21
+ <a href="#{{cid}}">Permalink</a> | <a href="mailto:{{site.comments.email}}?subject=RE:{{cid}}:{{site.comments.subject_suffix}}:{{ page.path}}">Reply</a>
22
+ </div> -->
23
+ </div>
24
+ <div class="d-flex">
25
+ <div class="ml-auto"><a href="#{{cid}}">Permalink</a> | <a href="mailto:{{site.comments.email}}?subject=RE:{{cid}}:{{site.comments.subject_suffix}}:{{title}}">Reply</a> </div>
26
+ </div>
27
+ {%- include comments.html replies_to=cid indent_class="ml-3 comment-indent" title=title -%}
28
+ </div>
29
+
30
+ {%- endfor -%}
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-mail-comments
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Dmitry Rodichev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: 'Provides html generator of threaded comments pages fetched from an IMAP
28
+ for Jekyll
29
+
30
+ '
31
+ email: noroot@falsetrue.io
32
+ executables:
33
+ - jekyll-mail-comments-fetch
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - ".env.dist"
38
+ - ".gitignore"
39
+ - Gemfile
40
+ - README.md
41
+ - bin/jekyll-mail-comments-fetch
42
+ - jekyll-mail-comments.gemspec
43
+ - lib/jekyll-mail-comments.rb
44
+ - lib/jekyll_mail_comments.rb
45
+ - templates/comments-count.html
46
+ - templates/comments.html
47
+ homepage: https://github.com/noroot/jekyll-mail-comments
48
+ licenses:
49
+ - GPL-3.0
50
+ metadata: {}
51
+ post_install_message: 'Don''t forget to put credentials inside .env file, see .env.dist
52
+ inside gem source.
53
+
54
+ '
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubygems_version: 3.0.6
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Email based comment system for Jekyll static site generator
73
+ test_files: []