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.
- checksums.yaml +4 -4
- data/lib/tblog_duopack.rb +219 -143
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a7bae240113c68c4b89024c456e78eacdc3f64af192ce1bda0d7587229297c6
|
4
|
+
data.tar.gz: 997b8630952fe379fd09e480582bd17c4246c94bfe713497461206bc4c5375dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
252
|
+
#def kill_selenium_chrome
|
253
|
+
# wmi = WIN32OLE.connect("winmgmts://")
|
254
254
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
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
|
-
|
263
|
-
|
264
|
-
|
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
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
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
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
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
|
1760
|
-
|
1761
|
-
|
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
|
-
|
1789
|
-
|
1790
|
-
|
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
|
-
|
1793
|
-
|
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
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1774
|
+
|
1775
|
+
else
|
1776
|
+
|
1777
|
+
end
|
1778
|
+
end
|
1801
1779
|
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
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
|
-
|
1807
|
-
|
1808
|
-
|
1810
|
+
json = JSON.parse(res.body)
|
1811
|
+
results = json['results']
|
1812
|
+
mm = []
|
1809
1813
|
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
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
|
-
|
1831
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1975
|
-
|
1976
|
-
|
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.
|
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-
|
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
|