lgtm_hd 0.1.3 → 0.1.4

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: 4cb60a766e51ba4e5afa496f4ece6c1ed2178213
4
- data.tar.gz: 32f930d5fd406cb6fcb8530343910a6d7d796e69
3
+ metadata.gz: 690ffa92888775481986a81d37f5283cb85b5736
4
+ data.tar.gz: 9004f97a6135757b9206b11af5189f6af79c5d8e
5
5
  SHA512:
6
- metadata.gz: e55c1aadd8ac434d1bf3223d60dcb0a53520c77996bf6b2a6797f6ebeabb1b7d10cc799cea044fed065a706ee35088c6ede16625c25c9614be943431b9dfc71a
7
- data.tar.gz: f20e482210fa657059447b2cd52f1479be3b2bc13aee251f1b18dc4fa6e636eb59702b2edd9041124f5968cfe490b0d449bce3727542da44c3eadf4b5ab47284
6
+ metadata.gz: 3be3ee8b19592dbcf5be3d03df690a0f24bab103b318ea0953d2c9fa571fe50ed8d03a1536c4141c85ce5b86b115d5a4e646a6a63ca402a4bf36a8a19856464d
7
+ data.tar.gz: 977302599a8bd739e8e7ee0900a7d19542850ee017e0bae2e41484316642844d690b89498ddcf082869b164780e13964a2ae3a6ad2176246c983cda752e4d508
@@ -2,3 +2,9 @@ language: ruby
2
2
  rvm:
3
3
  - 2.2.3
4
4
  before_install: gem install bundler -v 1.10.6
5
+ addons:
6
+ code_climate:
7
+ repo_token: f8de4766221c1d212d7c884d1415314f1c55a24c1a58e16db530efbf155d1ad3
8
+ # regular test configuration
9
+ after_success:
10
+ - bundle exec codeclimate-test-reporter
data/README.md CHANGED
@@ -23,10 +23,14 @@ Source | Happy Taeyeon!
23
23
 
24
24
  ## Usage
25
25
 
26
- $ lgtm_hd [transform] <source> <output> [--clipboard]
26
+ $ lgtm_hd [transform] <source_uri> <output_folder> [--clipboard] [--interactive]
27
27
  $ lgtm_hd http://domain.com/image.jpg /path/lgtm.jpg
28
28
 
29
- # Default command is transform so you can just leave the command empty.
29
+
30
+ --clipboard will let the OS copy content of the file for direct pasting to Github comment box
31
+ --interactive is for lazy people who can\'t bother to type
32
+ Default command is transform so you can just leave the command empty.
33
+
30
34
 
31
35
  ## Features
32
36
 
@@ -1,4 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
- require "lgtm_hd/cli"
3
-
4
- LgtmHD::CLI.new.run #if $0 == __FILE__
2
+ require "lgtm_hd"
3
+ LgtmHD::CLI.new.run
@@ -33,6 +33,8 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency "bundler", "~> 1.10"
34
34
  spec.add_development_dependency "rake", "~> 10.0"
35
35
  spec.add_development_dependency "rspec", "3.6.0"
36
+ spec.add_development_dependency "simplecov"
37
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
36
38
  spec.add_runtime_dependency "commander", "4.4.3"
37
39
  spec.add_runtime_dependency "clipboard", "1.1.1"
38
40
  spec.add_runtime_dependency "os", "1.0.0"
@@ -1,123 +1,5 @@
1
+ require "lgtm_hd/version"
1
2
  require "lgtm_hd/configuration"
2
- require "mini_magick"
3
- require "rubygems"
4
-
5
- module LgtmHD
6
-
7
- class MemeGenerator
8
- attr_accessor :input_image_URI, :output_image_URI
9
-
10
- # TODO make options list for this class
11
- # TODO pass BLOB data into this class instead of paths
12
- def initialize(input_image_URI, output_image_URI)
13
- @input_image_URI = input_image_URI
14
- @output_image_URI = output_image_URI
15
-
16
- @img = MiniMagick::Image.open(@input_image_URI)
17
- @caption_position = :caption_position_bottom
18
- end
19
-
20
- ##
21
- # Used to create a new Image object data-copy. Not used to "paint" or
22
- # that kind of thing.
23
- #
24
- # @param caption_text [String] Specify the caption for your LGTM meme
25
- # @return [MiniMagick::Image] The drawn image
26
- #
27
- def draw (caption_text = "LGTM")
28
- if @img.respond_to? (:combine_options) then
29
- @img.combine_options do |c|
30
- c.gravity captionPosition()
31
- c.draw "text 0,0 " << "#{caption_text}"
32
- c.font captionFont
33
- c.pointsize captionFontSize
34
- c.density imageDensity
35
- c.fill captionColor
36
- c.resize imageMaxSize().reduce() {|w,h| w << 'x' << h} # syntax: convert -resize $wx$h
37
- end
38
- @img.contrast
39
- end
40
- yield @img if block_given?
41
- end
42
-
43
- def export
44
- @img.write(@output_image_URI)
45
- yield @output_image_URI if block_given?
46
- end
47
-
48
-
49
- private
50
-
51
- def imageMaxSize
52
- [Configuration::OUTPUT_MAX_WIDTH.to_s, Configuration::OUTPUT_MAX_HEIGHT.to_s]
53
- end
54
-
55
- ##
56
- # @return [String] the position of image
57
- # Could be either :caption_position_top or :caption_position_bottom
58
- #
59
- def captionPosition ()
60
- if not [:caption_position_top, :caption_position_bottom].include? (@caption_position)
61
- @caption_position = :caption_position_top
62
- end
63
- return {:caption_position_top => "north center",
64
- :caption_position_bottom => "south center"}[@caption_position]
65
- end
66
-
67
- def captionFont
68
- '' << LgtmHD.root << Configuration::FONT_PATH
69
- end
70
-
71
- def captionFontSize
72
- Configuration::CAPTION_FONT_SIZE_DEFAULT
73
- end
74
-
75
- def imageDensity
76
- Configuration::OUTPUT_DENSITY
77
- end
78
-
79
- ##
80
- # Decide foreground color depending on background color
81
- # https://en.wikipedia.org/wiki/Rec._601
82
- #
83
- # We use this method that include magic numbers .241, .691, .068 accroding to
84
- # the provided wikipedia link
85
- # Math.Sqrt(
86
- # c.R * c.R * .241 +
87
- # c.G * c.G * .691 +
88
- # c.B * c.B * .068)
89
- #
90
- # Magic cut off number is 130.
91
- # Under 130 is too dark, so the foreground color is white
92
- # Above is too bright so the foreground color is black
93
- #
94
- # @return [String] the foreground color of caption
95
- #
96
- def captionColor
97
- # Copy current image data instead of working directly on working file
98
- img = MiniMagick::Image.read(@img.to_blob)
99
-
100
- # cutoff's x is always 0 as we only support top or bottom right now
101
- cutoff_y = @caption_position == :caption_position_bottom ? (img.height/2).round : 0
102
- img.crop("#{img.width}x#{img.height/2}+0+#{cutoff_y}")
103
-
104
- # Since we are getting
105
- img = img.resize('1x1')
106
- rgb = img.get_pixels[0][0] # Only 1x1 pixel remember? ^_^
107
- color = {}
108
- ['r','g','b'].zip(rgb) { |k,v| color[k] = v }
109
-
110
- magic_color_value = color['r'] * color['r'] * 0.241
111
- magic_color_value += color['g'] * color['g'] * 0.691
112
- magic_color_value += color['b'] * color['b'] * 0.068
113
- magic_color_value = Math.sqrt(magic_color_value)
114
-
115
- return (magic_color_value.round > 130) ? "#000000" : "#FFFFFF"
116
- end
117
-
118
- end # End of Class
119
-
120
- def self.root
121
- File.expand_path '../..', __FILE__
122
- end
123
- end # End of Module
3
+ require "lgtm_hd/utilities"
4
+ require "lgtm_hd/meme_generator"
5
+ require "lgtm_hd/cli"
@@ -1,15 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'commander'
3
3
  require 'os'
4
- require 'net/http'
5
- require 'tempfile'
6
4
  require 'clipboard'
7
5
  require 'uri'
8
6
 
9
- require 'lgtm_hd'
10
- require 'lgtm_hd/version'
11
- require 'lgtm_hd/configuration'
12
-
13
7
  module LgtmHD
14
8
  class CLI
15
9
  include Commander::Methods
@@ -21,7 +15,7 @@ module LgtmHD
21
15
  default_command :transform
22
16
 
23
17
  command :transform do |c|
24
- c.syntax = 'lgtm_hd transform <source_uri> <output_uri> [options]'
18
+ c.syntax = 'lgtm_hd <source_uri> <output_path> [--clipboard] [--interactive]'
25
19
  c.summary = 'Generate a LGTM image from source_uri (local path or URL) into output folder'
26
20
  c.description = ''
27
21
  c.example '', 'lgtm_hd export http://domain.com/image.png /path/to/lgtm.png'
@@ -32,37 +26,34 @@ module LgtmHD
32
26
  to_clipboard = options.clipboard
33
27
 
34
28
  # ARGS validation!
35
- if args.length == 2 then
29
+ if args.length == 2
36
30
  source_uri = args[0]
37
31
  output_uri = args[1]
38
-
39
32
  elsif options.interactive # Interactive mode!
40
33
  say "-- LGTM Interactive mode --"
41
34
  source_uri = ask('Source (URL or Path/to/file): ')
42
- output_uri = ask('Output Folder (absolute path): ')
43
- # TODO accept relative path "~/.."
35
+ output_uri = ask('Output Folder: ')
44
36
  to_clipboard = agree("Copy to clipboard afterward? [Y/N]")
45
37
  else
46
- raise "Too few or too many arguments provided. Need 2: source and output URIs."
38
+ say "usage: lgtm_hd <source_uri> <output_path> [--clipboard] [--interactive]"
39
+ raise ArgumentError, "Too few or too many arguments provided, need 2: source and output URIs"
47
40
  end
48
41
 
49
42
 
50
43
  # Validate the inputs
51
- unless (source_uri =~ URI::regexp or File.exist?(source_uri)) then
52
- # Part of the reason why I fucking hate #unless. No reason.
53
- raise "Source is not proper URIs (URL or Path/to/file)"
54
- end
44
+ output_folder = File.expand_path(output_uri)
45
+ output_file = File.join(output_folder,
46
+ LgtmHD::Configuration::OUTPUT_PREFIX +
47
+ Time.now.strftime('%Y-%m-%d_%H-%M-%S') +
48
+ File.extname(source_uri))
49
+ raise "Source is not proper URIs (URL or Path/to/file)" unless source_uri =~ URI::regexp || File.exist?(source_uri)
50
+ raise "Output is invalid path or directory" unless File.exist?(output_folder) && File.directory?(output_folder)
55
51
 
56
- unless File.exist?(output_uri) and File.directory?(output_uri) then
57
- raise "Output is not a directory or valid path"
58
- end
59
52
 
60
- file_ext = File.extname(source_uri)
61
- output_uri = File.join(output_uri, "" << LgtmHD::Configuration::OUTPUT_PREFIX << Time.now.strftime('%Y-%m-%d_%H-%M-%S') << file_ext)
62
53
 
63
54
  # Do stuff with our LGTM meme
64
55
  say "- Reading and inspecting source"
65
- meme_generator = MemeGenerator.new(source_uri, output_uri)
56
+ meme_generator = MemeGenerator.new(input_image_uri:source_uri, output_image_uri:output_file)
66
57
  say "- Rendering output"
67
58
  meme_generator.draw
68
59
 
@@ -1,18 +1,18 @@
1
1
  module LgtmHD
2
2
  module Configuration
3
3
  # Program configurations
4
- PROGRAM_NAME = "lgtm_hd"
5
- DESCRIPTION = "Generating images from user input with LGTM text on it, or fetching images from LGTM.in based on user's query. Finally put the image to clipboard."
4
+ PROGRAM_NAME = "lgtm_hd".freeze
5
+ DESCRIPTION = "Generating images from user input with LGTM text on it, or fetching images from LGTM.in based on user's query. Finally put the image to clipboard.".freeze
6
6
 
7
7
  # Output Image configurations
8
- OUTPUT_PREFIX = "lgtm_tmp_"
9
- OUTPUT_MAX_WIDTH = 500
10
- OUTPUT_MAX_HEIGHT = 500
11
- OUTPUT_DENSITY = 90 # or 120 point per inch
8
+ OUTPUT_PREFIX = "lgtm_hd_".freeze
9
+ OUTPUT_MAX_WIDTH = 500.freeze
10
+ OUTPUT_MAX_HEIGHT = 500.freeze
11
+ OUTPUT_DENSITY = 90.freeze # or 120 point per inch
12
12
 
13
13
  # Caption configurations
14
- FONT_PATH = "/fonts/impact.ttf"
15
- CAPTION_FONT_SIZE_DEFAULT = 96
14
+ FONT_PATH = "/fonts/impact.ttf".freeze
15
+ CAPTION_FONT_SIZE_DEFAULT = 96.freeze
16
16
 
17
17
  end
18
18
  end
@@ -0,0 +1,118 @@
1
+ require "mini_magick"
2
+
3
+ module LgtmHD
4
+ class MemeGenerator
5
+
6
+ # TODO make options list for this class
7
+ # TODO pass BLOB data into this class instead of paths
8
+ def initialize(input_image_uri:, output_image_uri:)
9
+ @input_image_uri = input_image_uri
10
+ @output_image_uri = output_image_uri
11
+ end
12
+
13
+ ##
14
+ # Used to create a new Image object data-copy. Not used to "paint" or
15
+ # that kind of thing.
16
+ #
17
+ # @param caption_text [String] Specify the caption for your LGTM meme
18
+ # @return [MiniMagick::Image] The drawn image
19
+ #
20
+ def draw(caption_text = "LGTM")
21
+ img = image
22
+ img.combine_options do |c|
23
+ c.gravity caption_position
24
+ c.draw "text 0,0 " << caption_text
25
+ c.font caption_font
26
+ c.pointsize caption_font_size
27
+ c.density image_density
28
+ c.fill caption_color
29
+ c.resize image_max_size().reduce() {|w,h| "#{w}x#{h}"} # syntax: convert -resize $wx$h
30
+ img.contrast
31
+ end
32
+ yield img if block_given?
33
+ end
34
+
35
+ def export
36
+ image.write(@output_image_uri)
37
+ yield @output_image_uri if block_given?
38
+ end
39
+
40
+
41
+ private
42
+
43
+ def image
44
+ @image ||= MiniMagick::Image.open(@input_image_uri)
45
+ end
46
+
47
+ def image_max_size
48
+ [Configuration::OUTPUT_MAX_WIDTH, Configuration::OUTPUT_MAX_HEIGHT]
49
+ end
50
+
51
+ ##
52
+ # @return [String] the position of image
53
+ # Could be either :caption_position_top or :caption_position_bottom
54
+ # Default value is top
55
+ #
56
+ def caption_position
57
+ if not [:caption_position_top, :caption_position_bottom].include? (@caption_position)
58
+ @caption_position = :caption_position_bottom
59
+ end
60
+ return {:caption_position_top => "north center",
61
+ :caption_position_bottom => "south center"}[@caption_position]
62
+ end
63
+
64
+ def caption_font
65
+ File.join(LgtmHD::gem_root, Configuration::FONT_PATH)
66
+ end
67
+
68
+ def caption_font_size
69
+ Configuration::CAPTION_FONT_SIZE_DEFAULT
70
+ end
71
+
72
+ def image_density
73
+ Configuration::OUTPUT_DENSITY
74
+ end
75
+
76
+ ##
77
+ # Decide foreground color depending on background color
78
+ # https://en.wikipedia.org/wiki/Rec._601
79
+ #
80
+ # We use this method that include magic numbers .241, .691, .068 accroding to
81
+ # the provided wikipedia link
82
+ # Math.Sqrt(
83
+ # c.R * c.R * .241 +
84
+ # c.G * c.G * .691 +
85
+ # c.B * c.B * .068)
86
+ #
87
+ # Magic cut off number is 130.
88
+ # Under 130 is too dark, so the foreground color is white
89
+ # Above is too bright so the foreground color is black
90
+ #
91
+ # @return [String] the foreground color of caption
92
+ #
93
+ def caption_color
94
+ # Copy current image data instead of working directly on working file
95
+ # because ImageMagick apply change directly to the temporary working file instead of keep changes in memory
96
+ # Might need to invest a bit further to ensure this, as for now, lazy..
97
+ temp_img = MiniMagick::Image.read(image.to_blob)
98
+
99
+ # cutoff's x is always 0 as we only support top or bottom right now
100
+ cutoff_y = @caption_position == :caption_position_bottom ? (temp_img.height/2).round : 0
101
+ temp_img.crop("#{temp_img.width}x#{temp_img.height/2}+0+#{cutoff_y}")
102
+
103
+ # Since we are getting
104
+ temp_img = temp_img.resize('1x1')
105
+ rgb = temp_img.get_pixels[0][0] # Only 1x1 pixel remember? ^_^
106
+ color = {}
107
+ ['r','g','b'].zip(rgb) { |k,v| color[k] = v }
108
+
109
+ magic_color_value = color['r'] * color['r'] * 0.241
110
+ magic_color_value += color['g'] * color['g'] * 0.691
111
+ magic_color_value += color['b'] * color['b'] * 0.068
112
+ magic_color_value = Math.sqrt(magic_color_value)
113
+
114
+ (magic_color_value.round > 130) ? "#000000" : "#FFFFFF"
115
+ end
116
+
117
+ end # End of Class
118
+ end # End of module
@@ -0,0 +1,5 @@
1
+ module LgtmHD
2
+ def self.gem_root
3
+ File.expand_path '../../..', __FILE__
4
+ end
5
+ end # End of Module
@@ -1,3 +1,3 @@
1
1
  module LgtmHD
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lgtm_hd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Huy Dinh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-24 00:00:00.000000000 Z
11
+ date: 2017-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.6.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: codeclimate-test-reporter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.0.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.0.0
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: commander
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +162,8 @@ files:
134
162
  - lib/lgtm_hd.rb
135
163
  - lib/lgtm_hd/cli.rb
136
164
  - lib/lgtm_hd/configuration.rb
165
+ - lib/lgtm_hd/meme_generator.rb
166
+ - lib/lgtm_hd/utilities.rb
137
167
  - lib/lgtm_hd/version.rb
138
168
  homepage: http://github.com/phradion/lgtm_hd
139
169
  licenses: