tzispa_experts 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86527db555738e69667b3aa79ff1d7a965d1cf69
4
- data.tar.gz: beba9788bd4b2043076415e1d6ae5fbe721b2ace
3
+ metadata.gz: bd6b61a100ec04be26bc745e6bb4eb0cf8cc2ce3
4
+ data.tar.gz: 1bc9191b4f57ac8a339d5c28dcdf9fe2cf563866
5
5
  SHA512:
6
- metadata.gz: 0b85e577b5d5b781323f3183a78f608883f193320eb249119528dad1cca4a3dea7e6ab8cb49e3dfaa57e02b11bc289f3c6764b3433138dabcd3a404adb9e44d3
7
- data.tar.gz: d0bf0ee5ec8f4ed8bc43b6ac2d607fe08b37971bd40329db5c2a2319e6cd20f4f91a691a86e3acd41e5e976c19f936e093d7ca775fc4368e8e8a547974a52e53
6
+ metadata.gz: 5a7ef936cc4d7efa289d1c83a67e6cc9cd7dec3554b0242354c3f7302a673fa0989800cecd5bee66b3add193c8788a184399dd132a3dcbe9a879de6ab822252a
7
+ data.tar.gz: 20d3034767652706871f91716f46b5ae17e7d1d5658bc59ac35aec868726dfe0bb2924ffc26bce323d763f58a34659139b29f743b9edd13b04791d29132d50f6
data/CHANGELOG.md CHANGED
@@ -1,4 +1,7 @@
1
1
  Tzispa Experts
2
2
 
3
+ ## v0.1.0
4
+ - code reorganization: new modules moved from tzispa_helpers
5
+
3
6
  ## v0.0.1
4
7
  - Initial release
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open-uri'
4
+ require 'nokogiri'
5
+ require 'htmlentities'
6
+ require 'reverse_markdown'
7
+ require 'unicode_utils'
8
+ require 'redcarpet'
9
+ require 'tzispa/helpers/hash_trans'
10
+
11
+ module Tzispa
12
+ module Experts
13
+ module Crawler
14
+
15
+ include Tzispa::Helpers::HashTrans
16
+
17
+ class CrawlerError < StandardError; end
18
+
19
+
20
+ def crawler_save_file(url, dest_file, accept_schemes = ['http', 'https', 'ftp'])
21
+ begin
22
+ uri = URI(url)
23
+ raise ArgumentError.new "Inavlid url: #{url}" unless accept_schemes.include?(uri.scheme) && uri.host
24
+ File.delete(dest_file) if File.exist?(dest_file)
25
+ File.open("#{dest_file}", 'wb') do |fo|
26
+ fo.write open(url).read
27
+ end
28
+ rescue => ex
29
+ raise CrawlerError.new "Error in crawler_save_file '#{url}': #{ex.message}"
30
+ end
31
+ end
32
+
33
+ def crawler_to_markdown(source)
34
+ begin
35
+ source = source.read if source.respond_to? :read
36
+ htmee = HTMLEntities.new
37
+ ReverseMarkdown.convert(htmee.decode(source).strip, unknown_tags: :bypass)
38
+ rescue Encoding::UndefinedConversionError
39
+ end
40
+ end
41
+
42
+ def crawler_table_to_dl(noko, table_path, columns, excluded_terms: [], fussion_terms:{})
43
+ String.new.tap { |content|
44
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new)
45
+ sections = crawler_table(noko, table_path, columns)
46
+ hash_fussion! sections, fussion_terms
47
+ unless sections.empty?
48
+ content << '<dl>'
49
+ sections.sort.each { |key, value|
50
+ unless key.empty? || value.empty? || excluded_terms.include?(UnicodeUtils.downcase key)
51
+ content << "<dt>#{key}</dt>"
52
+ if value.is_a?(Array) && value.count > 1
53
+ content << '<ul>' << value.map { |item| "<li>#{markdown.render item}</li>"}.join("\n") << '</ul>'
54
+ elsif value.is_a?(Array) && value.count == 1
55
+ content << "<dd>#{markdown.render value.first}</dd>"
56
+ else
57
+ content << "<dd>#{markdown.render value}</dd>"
58
+ end
59
+ end
60
+ }
61
+ content << "</dl>"
62
+ end
63
+ }
64
+ end
65
+
66
+ def crawler_table(noko, table_path, columns)
67
+ Hash.new.tap { |sections|
68
+ htmee = HTMLEntities.new(:expanded)
69
+ noko = noko.xpath(table_path)
70
+ colspans = "td[@colspan=\"#{columns}\"]"
71
+ if noko.xpath(colspans).count == 0
72
+ noko.collect { |row|
73
+ dterm = htmee.decode(row.at_xpath('td[1]')&.content).gsub(/\n|\r|\t/,' ').strip
74
+ unless dterm.empty?
75
+ sections[dterm] ||= Array.new
76
+ sections[dterm] << (2..columns).map { |i|
77
+ ReverseMarkdown.convert(
78
+ htmee.decode(row.at_xpath("td[#{i}]")&.children&.to_s || row.at_xpath("td[#{i}]")&.to_s).strip, unknown_tags: :bypass
79
+ ).gsub(/\r|\t/,' ').strip
80
+ }.join('\n')
81
+ end
82
+ }
83
+ else
84
+ current_section = nil
85
+ noko.collect { |row|
86
+ unless row.xpath(colspans)&.text.strip.empty?
87
+ current_section = htmee.decode(row.xpath("td[@colspan=\"#{columns}\"]").text).gsub(/\n|\r|\t/,' ').strip
88
+ sections[current_section] ||= Array.new
89
+ else
90
+ if current_section
91
+ sections[current_section] << (1..columns).map { |i|
92
+ ReverseMarkdown.convert(
93
+ htmee.decode(row.at_xpath("td[#{i}]")&.children&.to_s.strip || row.at_xpath("td[#{i}]")&.to_s.strip), unknown_tags: :bypass
94
+ ).strip
95
+ }.join(': ')
96
+ end
97
+ end
98
+ }
99
+ end
100
+ }
101
+ end
102
+
103
+ def crawler_table_to_list(noko, table_path, excluded_terms: [])
104
+ htmee = HTMLEntities.new(:expanded)
105
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new)
106
+ String.new.tap { |list|
107
+ list << '<ul>'
108
+ list << Array.new.tap { |lines|
109
+ noko.xpath(table_path).collect { |td|
110
+ line = if td.xpath('table/tr/td').count > 0
111
+ crawler_table(td, 'table/tr', 2)
112
+ else
113
+ raw_ln = ReverseMarkdown.convert(td&.children&.to_s.strip, unknown_tags: :bypass)
114
+ raw_ln unless raw_ln.empty? || excluded_terms.include?(raw_ln)
115
+ end
116
+ if line&.is_a? String
117
+ lines << "<li>#{htmee.decode(markdown.render line)}</li>"
118
+ elsif line.is_a? Hash
119
+ line&.map { |key, value|
120
+ lines << "<li><strong>#{key}</strong>: #{value} </li>" unless excluded_terms.include?(key) || excluded_terms.include?(value)
121
+ }.join("\n")
122
+ else
123
+ line&.map { |v|
124
+ lines << "<li>#{v}</li>" unless excluded_terms.include?(v)
125
+ }.join("\n")
126
+ end
127
+ }
128
+ }.join("\n")
129
+ list << '</ul>'
130
+ }
131
+ end
132
+
133
+
134
+ end
135
+ end
136
+ end
@@ -1,27 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'mini_magick'
4
+ require 'fileutils'
4
5
 
5
6
  module Tzispa
6
7
  module Experts
7
8
  module Image
8
9
 
9
- def resize_crop_image(source:, image_size: nil, dest_file: nil, qualiy: 90, crop: false)
10
- image_file = dest_file || source
11
- if image_size && MiniMagick::Tool::Convert.new do |convert|
12
- convert.merge! [source, '-resize', image_size, "-quality", "#{qualiy}", image_file]
10
+ class ImageError < StandardError; end
11
+
12
+ def save_image(url, dest_file)
13
+ begin
14
+ File.open("#{dest_file}", 'wb') do |fo|
15
+ fo.write open(url).read
16
+ end
17
+ unless image_valid?(dest_file)
18
+ FileUtils.rm dest_file, :force => true
13
19
  end
20
+ rescue Exception => ex
21
+ raise ImageError.new "Error in crawler_save_file '#{url}': #{ex.class} #{ex.message}"
14
22
  end
15
- if crop
16
- crop_info = MiniMagick::Tool::Convert.new do |convert|
17
- convert.merge! [image_file, "-virtual-pixel", " edge", "-blur", "0x15", "-fuzz", "15%", "-trim", "-format", "'%[fx:w+72]x%[fx:h+72]+%[fx:page.x-10]+%[fx:page.y-10]'", "info:" ]
18
- end if crop
19
- MiniMagick::Tool::Convert.new do |convert|
20
- convert.merge! [ image_file, "-crop", "#{crop_info.delete("'")}", "+repage", "-strip", "-interlace", "Plane", "-gaussian-blur", "0.05", image_file ]
23
+ end
24
+
25
+
26
+ def resize_crop_image(source:, image_size: nil, dest_file: nil, qualiy: 90, crop: false)
27
+ begin
28
+ image_file = dest_file || source
29
+ if image_size && MiniMagick::Tool::Convert.new do |convert|
30
+ convert.merge! [source, '-resize', image_size, "-quality", "#{qualiy}", image_file]
31
+ end
32
+ end
33
+ if crop
34
+ crop_info = MiniMagick::Tool::Convert.new do |convert|
35
+ convert.merge! [image_file, "-virtual-pixel", " edge", "-blur", "0x15", "-fuzz", "15%", "-trim", "-format", "'%[fx:w+72]x%[fx:h+72]+%[fx:page.x-10]+%[fx:page.y-10]'", "info:" ]
36
+ end if crop
37
+ MiniMagick::Tool::Convert.new do |convert|
38
+ convert.merge! [ image_file, "-crop", "#{crop_info.delete("'")}", "+repage", "-strip", "-interlace", "Plane", "-gaussian-blur", "0.05", image_file ]
39
+ end
21
40
  end
41
+ rescue Exception => ex
42
+ raise ImageError.new "Error in resize_crop_image '#{source}': #{ex.class} #{ex.message}"
22
43
  end
23
44
  end
24
45
 
46
+ def image_valid?(source)
47
+ File.exist?(source) && MiniMagick::Image.new(source).valid?
48
+ end
49
+
25
50
  def request_upload_image(param:, path:, save_as: nil, keep_ext: true, crop: false, size: nil)
26
51
  if result = request_upload_file( param: param, path: path, save_as: save_as, keep_ext: keep_ext )
27
52
  resize_crop_image( source: result[:path], image_size: size ) if crop
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mail'
4
+
5
+ module Tzispa
6
+ module Experts
7
+ module Mail
8
+
9
+ def send_smtp_mail(from:, to:, subject:, body:, config:, cc: nil, html: false, debug: false, charset: 'UTF-8')
10
+ begin
11
+ smtp_configuration config
12
+ mail = ::Mail.new
13
+ mail.from = from
14
+ if !to.empty?
15
+ to_addrs = to.split(';')
16
+ mail.to = to_addrs.pop
17
+ to_addrs.each { |email|
18
+ mail.to << email
19
+ }
20
+ if cc
21
+ cc_addrs = cc.split(';')
22
+ mail.cc = cc_addrs.pop
23
+ cc_addrs.each { |email|
24
+ mail.cc << email
25
+ }
26
+ end
27
+ mail.subject = subject
28
+ if html
29
+ mail.html_part do
30
+ content_type "text/html; charset=#{charset}"
31
+ body = body
32
+ end
33
+ else
34
+ mail.body = body
35
+ end
36
+ mail.charset = charset
37
+ mail.deliver
38
+ else
39
+ nil
40
+ end
41
+ rescue
42
+ raise if debug
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def smtp_configuration(config)
49
+ if config.smtp_auth
50
+ ::Mail.defaults do
51
+ delivery_method :smtp, address: config.host, domain: config.domain,
52
+ port: config.port, authentication: config.authentication,
53
+ openssl_verify_mode: config.openssl_verify, enable_starttls_auto: config.starttls_auto,
54
+ user_name: config.user_name, password: config.password
55
+ end
56
+ else
57
+ ::Mail.defaults do
58
+ delivery_method :smtp, address: config.host, domain: config.domain,
59
+ port: config.port, openssl_verify_mode: config.openssl_verify,
60
+ enable_starttls_auto: config.starttls_auto
61
+ end
62
+ end
63
+ end
64
+
65
+
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,30 @@
1
+ require 'net/http'
2
+
3
+ module Tzispa
4
+ module Experts
5
+ module Recaptcha
6
+
7
+ RECAPTCHA_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify'
8
+ RECAPTCHA_RESPONSE_FIELD = 'g-recaptcha-response'
9
+
10
+ def verify(secret, response, ip)
11
+ params = {
12
+ 'secret': secret,
13
+ 'response': response,
14
+ 'remoteip': ip
15
+ }
16
+
17
+ uri = URI.parse(RECAPTCHA_VERIFY_URL)
18
+ http = Net::HTTP.start(uri.host, uri.port)
19
+
20
+ request = Net::HTTP::Post.new(uri.path)
21
+ request.form_data = params
22
+ response = http.request(request)
23
+
24
+ JSON.parse response.body
25
+ end
26
+
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ require 'redcarpet'
2
+
3
+ module Tzispa
4
+ module Helpers
5
+ module Text
6
+
7
+ def mime_formatter(text, mime)
8
+ case mime
9
+ when 'text/x-markdown'
10
+ Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render(text) if text
11
+ else
12
+ text
13
+ end
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -1,7 +1,7 @@
1
1
  module Tzispa
2
2
  module Experts
3
3
 
4
- VERSION = '0.0.1'.freeze
4
+ VERSION = '0.1.0'.freeze
5
5
  NAME = 'Tzispa Experts'.freeze
6
6
  GEM_NAME = 'tzispa_experts'.freeze
7
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tzispa_experts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Antonio Piñero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-24 00:00:00.000000000 Z
11
+ date: 2016-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_magick
@@ -16,14 +16,70 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.3'
19
+ version: '4.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.3'
26
+ version: '4.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: reverse_markdown
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: redcarpet
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mail
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.6'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.6'
27
83
  description: Experts for Tzispa
28
84
  email:
29
85
  - japinero@area-integral.com
@@ -34,10 +90,14 @@ files:
34
90
  - CHANGELOG.md
35
91
  - README.md
36
92
  - lib/tzispa/experts.rb
93
+ - lib/tzispa/experts/crawler.rb
37
94
  - lib/tzispa/experts/image.rb
95
+ - lib/tzispa/experts/mail.rb
96
+ - lib/tzispa/experts/recaptcha.rb
97
+ - lib/tzispa/experts/text.rb
38
98
  - lib/tzispa/experts/version.rb
39
99
  - lib/tzispa_experts.rb
40
- homepage: https://www.area-integral.com
100
+ homepage: https://github.com/japiber/tzispa_experts
41
101
  licenses:
42
102
  - MIT
43
103
  metadata: {}
@@ -49,12 +109,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
49
109
  requirements:
50
110
  - - "~>"
51
111
  - !ruby/object:Gem::Version
52
- version: '2.0'
112
+ version: '2.3'
53
113
  required_rubygems_version: !ruby/object:Gem::Requirement
54
114
  requirements:
55
- - - "~>"
115
+ - - ">="
56
116
  - !ruby/object:Gem::Version
57
- version: '2.0'
117
+ version: '0'
58
118
  requirements: []
59
119
  rubyforge_project:
60
120
  rubygems_version: 2.5.1