tblog_duopack 0.0.51 → 0.0.53

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tblog_duopack.rb +219 -143
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad9d079f87010d2cb76d806d622812ff121b447c50a53281c5405638a4ec8b3c
4
- data.tar.gz: d272c07dac84708c42baf4a2130c3c119ef81cc314ceeb6a0b5f3437db35beb4
3
+ metadata.gz: 5a7bae240113c68c4b89024c456e78eacdc3f64af192ce1bda0d7587229297c6
4
+ data.tar.gz: 997b8630952fe379fd09e480582bd17c4246c94bfe713497461206bc4c5375dd
5
5
  SHA512:
6
- metadata.gz: ebd34ad67bc3c9a4fbf66cb36c111f2f3c9590bfbd0a7e12cbcdde713cfdf96d9e682cc04c4dceea9ab1bcb0ffafd984e262294f8eba574e9ba6ccde21760972
7
- data.tar.gz: aeac5ac03199e03ddc17e0a1c78231f2c429656817e5bfa8cca8aa22ea2e6076f6ceaf278c9f83837703716440ecbb80e4d3261f8952e9ec66d0bd921408ea0d
6
+ metadata.gz: 291fab89eb49561eda99ec5624ebeb1d9c867d73d2db3a0e7a8c393c9db7e2ec71d2035e9e72d54df2d7093ed4ad96f4b10e960a97925252b54023c32b8fa998
7
+ data.tar.gz: c3f235ed4d9d64550b27daf17834042186d1bf6bbe4a146e1f632f63c319eb66148a2b77b485cd8e8a1a8e1e289da3282a06bbbebe4d2948d65a7d7bfaad1840
data/lib/tblog_duopack.rb CHANGED
@@ -245,46 +245,46 @@ class Naver
245
245
  def initialize
246
246
  @seed = 1
247
247
  @cookie = ''
248
- kill_selenium_chrome #기존 창 모두 닫는 명령
249
- sleep(1)
248
+ #kill_selenium_chrome #기존 창 모두 닫는 명령
249
+ #sleep(1)
250
250
  end
251
251
 
252
- def kill_selenium_chrome
253
- wmi = WIN32OLE.connect("winmgmts://")
252
+ #def kill_selenium_chrome
253
+ # wmi = WIN32OLE.connect("winmgmts://")
254
254
 
255
- # chromedriver 프로세스 목록을 Ruby 배열로 변환
256
- chromedrivers_ole = wmi.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'chromedriver.exe'")
257
- chromedrivers = []
258
- chromedrivers_ole.each { |proc| chromedrivers << proc }
259
- chromedriver_pids = chromedrivers.map { |proc| proc.ProcessId }
255
+ # # chromedriver 프로세스 목록을 Ruby 배열로 변환
256
+ # chromedrivers_ole = wmi.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'chromedriver.exe'")
257
+ # chromedrivers = []
258
+ # chromedrivers_ole.each { |proc| chromedrivers << proc }
259
+ # chromedriver_pids = chromedrivers.map { |proc| proc.ProcessId }
260
260
 
261
261
  # chrome.exe 프로세스 목록을 Ruby 배열로 변환
262
- chrome_procs_ole = wmi.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'chrome.exe'")
263
- chrome_procs = []
264
- chrome_procs_ole.each { |proc| chrome_procs << proc }
262
+ # chrome_procs_ole = wmi.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'chrome.exe'")
263
+ # chrome_procs = []
264
+ # chrome_procs_ole.each { |proc| chrome_procs << proc }
265
265
 
266
266
  # chromedriver가 띄운 크롬 종료
267
- chrome_procs.each do |proc|
268
- if chromedriver_pids.include?(proc.ParentProcessId)
269
- puts "→ chromedriver가 띄운 크롬 종료: PID #{proc.ProcessId}"
270
- begin
271
- proc.Terminate
272
- rescue => e
273
- puts "→ 종료 실패: PID #{proc.ProcessId} / 오류: #{e.message}"
274
- end
275
- end
276
- end
267
+ # chrome_procs.each do |proc|
268
+ # if chromedriver_pids.include?(proc.ParentProcessId)
269
+ # puts "→ chromedriver가 띄운 크롬 종료: PID #{proc.ProcessId}"
270
+ # begin
271
+ # proc.Terminate
272
+ # rescue => e
273
+ # puts "→ 종료 실패: PID #{proc.ProcessId} / 오류: #{e.message}"
274
+ # end
275
+ # end
276
+ # end
277
277
 
278
278
  # chromedriver 자체도 종료
279
- chromedrivers.each do |proc|
280
- puts "→ chromedriver 종료: PID #{proc.ProcessId}"
281
- begin
282
- proc.Terminate
283
- rescue => e
284
- puts "→ chromedriver 종료 실패: #{proc.ProcessId} / 오류: #{e.message}"
285
- end
286
- end
287
- end
279
+ # chromedrivers.each do |proc|
280
+ # puts "→ chromedriver 종료: PID #{proc.ProcessId}"
281
+ # begin
282
+ # proc.Terminate
283
+ # rescue => e
284
+ # puts "→ chromedriver 종료 실패: #{proc.ProcessId} / 오류: #{e.message}"
285
+ # end
286
+ # end
287
+ #end
288
288
 
289
289
 
290
290
 
@@ -1756,84 +1756,112 @@ class Wordpress
1756
1756
 
1757
1757
 
1758
1758
 
1759
- def auto_image(keyword = nil)
1760
- keyword ||= @keyword
1761
- puts "키워드: #{keyword}"
1762
-
1763
- client = HTTPClient.new
1764
- client.default_header = {
1765
- 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
1766
- '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
1767
- 'Accept' => 'application/json, text/javascript, */*; q=0.01',
1768
- 'Accept-Language' => 'en-US,en;q=0.9',
1769
- 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
1770
- 'X-Requested-With' => 'XMLHttpRequest'
1771
- }
1759
+ def crop_image_height_under_width(path, min_crop_ratio = 0.625)
1760
+ img = Magick::Image.read(path).first
1761
+ width = img.columns
1762
+ height = img.rows
1772
1763
 
1773
- retry_count = 0
1774
- max_retries = 10
1775
- results = []
1776
1764
 
1777
- begin
1778
- page = rand(1..15)
1779
- url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
1780
- puts "Request URL: #{url}"
1781
- res = client.get(url)
1782
-
1783
- unless res.status == 200
1784
- puts "HTTP Error: #{res.status}"
1785
- raise "HTTP Error"
1786
- end
1787
1765
 
1788
- json = JSON.parse(res.body)
1789
- results = json['results']
1790
- mm = []
1766
+ if height > width
1767
+ min_height = (width * min_crop_ratio).to_i
1768
+ new_height = rand(min_height..width)
1769
+ crop_top = ((height - new_height) / 2.0).round
1791
1770
 
1792
- results.each do |photo|
1793
- full_url = photo.dig('urls', 'full').to_s
1794
- regular_url = photo.dig('urls', 'regular').to_s
1771
+ cropped = img.crop(0, crop_top, width, new_height, true)
1772
+ cropped.write(path)
1795
1773
 
1796
- if full_url.start_with?("https://images.unsplash.com/photo-") &&
1797
- regular_url.include?("1080")
1798
- mm << full_url
1799
- end
1800
- end
1774
+
1775
+ else
1776
+
1777
+ end
1778
+ end
1801
1779
 
1802
- if mm.empty?
1803
- raise "No matching image"
1804
- end
1780
+ def auto_image(keyword = nil)
1781
+ # auto_image 내부에서만 crop 호출
1782
+ keyword ||= @keyword
1783
+ puts "키워드: #{keyword}"
1784
+
1785
+ client = HTTPClient.new
1786
+ client.default_header = {
1787
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
1788
+ '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
1789
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
1790
+ 'Accept-Language' => 'en-US,en;q=0.9',
1791
+ 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
1792
+ 'X-Requested-With' => 'XMLHttpRequest'
1793
+ }
1794
+
1795
+ retry_count = 0
1796
+ max_retries = 10
1797
+ results = []
1798
+
1799
+ begin
1800
+ page = rand(1..15)
1801
+ url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
1802
+ puts "Request URL: #{url}"
1803
+ res = client.get(url)
1804
+
1805
+ unless res.status == 200
1806
+ puts "HTTP Error: #{res.status}"
1807
+ raise "HTTP Error"
1808
+ end
1805
1809
 
1806
- selected_url = mm.sample
1807
- Down.download(selected_url, destination: "./image/memory.png")
1808
- puts "이미지 다운로드 완료: #{selected_url}"
1810
+ json = JSON.parse(res.body)
1811
+ results = json['results']
1812
+ mm = []
1809
1813
 
1810
- rescue => e
1811
- retry_count += 1
1812
- puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
1813
- sleep(3)
1814
- if retry_count < max_retries
1815
- retry
1816
- else
1817
- puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
1818
-
1819
- if results && !results.empty?
1820
- random_photo = results.sample
1821
- fallback_url = random_photo.dig('urls', 'full')
1822
- if fallback_url
1823
- Down.download(fallback_url, destination: "./image/memory.png")
1824
- puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
1825
- else
1826
- puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
1827
- color_image
1828
- end
1814
+ results.each do |photo|
1815
+ full_url = photo.dig('urls', 'full').to_s
1816
+ regular_url = photo.dig('urls', 'regular').to_s
1817
+
1818
+ if full_url.start_with?("https://images.unsplash.com/photo-") &&
1819
+ regular_url.include?("1080")
1820
+ mm << full_url
1821
+ end
1822
+ end
1823
+
1824
+ if mm.empty?
1825
+ raise "No matching image"
1826
+ end
1827
+
1828
+ selected_url = mm.sample
1829
+ destination_path = "./image/memory.png"
1830
+ Down.download(selected_url, destination: destination_path)
1831
+ puts "이미지 다운로드 완료: #{selected_url}"
1832
+
1833
+ # 오직 auto_image에서만 자르기 호출
1834
+ crop_image_height_under_width(destination_path)
1835
+
1836
+ rescue => e
1837
+ retry_count += 1
1838
+ puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
1839
+ sleep(3)
1840
+ if retry_count < max_retries
1841
+ retry
1842
+ else
1843
+ puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
1844
+
1845
+ if results && !results.empty?
1846
+ random_photo = results.sample
1847
+ fallback_url = random_photo.dig('urls', 'full')
1848
+ if fallback_url
1849
+ Down.download(fallback_url, destination: "./image/memory.png")
1850
+ puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
1851
+ crop_image_height_under_width("./image/memory.png")
1829
1852
  else
1830
- puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
1831
- color_image
1832
- end
1853
+ puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
1854
+ color_image
1833
1855
  end
1856
+ else
1857
+ puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
1858
+ color_image
1834
1859
  end
1860
+ end
1861
+ end
1835
1862
  end
1836
1863
 
1864
+
1837
1865
  def color_image
1838
1866
  color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
1839
1867
  image = Magick::Image.new(740, 740) { |k| k.background_color = color.sample }
@@ -1926,57 +1954,104 @@ class Wordpress
1926
1954
  end
1927
1955
 
1928
1956
 
1929
- def image_text(text1, text2)
1957
+ def image_text(text1, text2)
1958
+ begin
1959
+ color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
1960
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
1961
+ font2 = './fonts/' + font_files.sample
1962
+
1963
+ # 랜덤 글자색 선택
1964
+ color2 = color.sample
1965
+
1966
+ # 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
1967
+ def hex_to_rgb(hex)
1968
+ hex = hex.delete('#')
1969
+ [hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
1970
+ end
1971
+
1972
+ # 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
1973
+ def color_distance(c1, c2)
1974
+ Math.sqrt(
1975
+ (c1[0] - c2[0])**2 +
1976
+ (c1[1] - c2[1])**2 +
1977
+ (c1[2] - c2[2])**2
1978
+ )
1979
+ end
1980
+
1981
+ # 대비가 충분히 되는 테두리 색상 선택
1982
+ max_attempts = 10
1983
+ stroke_color = nil
1984
+ base_rgb = hex_to_rgb(color2)
1985
+
1986
+ max_attempts.times do
1987
+ candidate = color.sample
1988
+ candidate_rgb = hex_to_rgb(candidate)
1989
+ dist = color_distance(base_rgb, candidate_rgb)
1990
+
1991
+ # 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
1992
+ if dist > 100
1993
+ stroke_color = candidate
1994
+ break
1995
+ end
1996
+ end
1997
+ stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
1998
+
1999
+ img = Magick::Image.read('./image/memory.png').first
2000
+ draw = Magick::Draw.new
2001
+
2002
+ raw_message = "#{text1}\n#{text2}".strip
2003
+ max_width = img.columns * 0.85
2004
+ max_height = img.rows * 0.6
2005
+
1930
2006
  begin
1931
- color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
1932
- font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
1933
- font2 = './fonts/' + font_files.sample
1934
- color2 = color.sample
1935
-
1936
- img = Magick::Image.read('./image/memory.png').first
1937
- draw = Magick::Draw.new
1938
-
1939
- raw_message = "#{text1}\n#{text2}".strip
1940
- max_width = img.columns * 0.85
1941
- max_height = img.rows * 0.6
1942
-
1943
- begin
1944
- size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
1945
- rescue
1946
- size = 30
1947
- end
1948
-
1949
- wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
1950
-
1951
- if @data['이미지설정']['글자그림자'].checked?
1952
- img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
1953
- draw.gravity = Magick::CenterGravity
1954
- draw.pointsize = adjusted_size
1955
- draw.fill = '#000000'
1956
- draw.font = font2
1957
- end
1958
- end
1959
-
1960
- draw2 = Magick::Draw.new
1961
- img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
1962
- draw2.gravity = Magick::CenterGravity
1963
- draw2.pointsize = adjusted_size
1964
- draw2.fill = color2
1965
- draw2.font = font2
1966
- if @data['이미지설정']['글자테두리'].checked?
1967
- draw2.stroke_width = 2
1968
- draw2.stroke = '#000000'
1969
- end
1970
- end
1971
-
1972
- img.write('./image/memory.png')
2007
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
1973
2008
  rescue
1974
- puts '이미지 폰트 불러오기 오류 재시도...'
1975
- sleep(3)
1976
- retry
2009
+ size = 30
2010
+ end
2011
+
2012
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2013
+
2014
+ if @data['이미지설정']['글자그림자'].checked?
2015
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2016
+ draw.gravity = Magick::CenterGravity
2017
+ draw.pointsize = adjusted_size
2018
+ draw.fill = '#000000'
2019
+ draw.font = font2
2020
+ end
2021
+ end
2022
+
2023
+ if @data['이미지설정']['글자테두리'].checked?
2024
+ draw_stroke = Magick::Draw.new
2025
+ img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
2026
+ draw_stroke.gravity = Magick::CenterGravity
2027
+ draw_stroke.pointsize = adjusted_size
2028
+ draw_stroke.fill = 'none'
2029
+ draw_stroke.stroke = stroke_color
2030
+ draw_stroke.stroke_width = rand(5..10)
2031
+ draw_stroke.font = font2
2032
+ end
1977
2033
  end
2034
+
2035
+ draw2 = Magick::Draw.new
2036
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2037
+ draw2.gravity = Magick::CenterGravity
2038
+ draw2.pointsize = adjusted_size
2039
+ draw2.fill = color2
2040
+ draw2.stroke = 'none'
2041
+ draw2.font = font2
2042
+ end
2043
+
2044
+ img.write('./image/memory.png')
2045
+
2046
+ rescue => e
2047
+ puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
2048
+ sleep(3)
2049
+ retry
2050
+ end
1978
2051
  end
1979
2052
 
2053
+
2054
+
1980
2055
  def border()
1981
2056
  color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
1982
2057
  img = Magick::Image.read('./image/memory.png').first
@@ -2002,7 +2077,7 @@ class Wordpress
2002
2077
  else
2003
2078
  auto_image()
2004
2079
  end
2005
-
2080
+
2006
2081
  # '원본'을 포함한 이미지 크기 옵션 추가
2007
2082
  image_size = [480, 740, 650, 550, 480, 'original']
2008
2083
  size = 0
@@ -2026,6 +2101,7 @@ class Wordpress
2026
2101
 
2027
2102
  change_image_size(size) # 크기 변경 함수 호출
2028
2103
 
2104
+
2029
2105
  if @data['이미지설정']['필터사용'].checked?
2030
2106
  image_filter()
2031
2107
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tblog_duopack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.51
4
+ version: 0.0.53
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-29 00:00:00.000000000 Z
10
+ date: 2025-06-26 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: File to Clipboard gem
13
13
  email: mymin26@naver.com