lgtm_hd 0.1.3 → 0.1.4

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: 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: