nblog_zon 111.120.001 → 111.120.003

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/nblog_zon.rb +188 -109
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e878087c2dca81eb560830ac36bef62b0555a09031fb7ea6b8230bee47c0007
4
- data.tar.gz: 9acc1171220502c7395f5674eff0cb07d8df5c4ed1e16168b2d0cc59042e2163
3
+ metadata.gz: fe5bf260ce4df25706be5b4c50d08b9b31c50949b0e7ed6c17dbd6dbc566b622
4
+ data.tar.gz: 0d4b42bf5d55b0b553c6dede47877dc82b218b49c7deba4c2474cd59ab426cc1
5
5
  SHA512:
6
- metadata.gz: 9132d31e3a36202c849b2df2ba64dddd681a41863fde72ad3093cafa4c754764cf33142e02bb5814d7fc356cb321820a0ad878dc197c6c1e0be449a14c126222
7
- data.tar.gz: 9211eca1af240c069a09f4548d1034d20ced569a3268deced7df4ae407b030357665f89959620add1c18243eada3c94533ba9cd50d37bdd794de0ab4bcf79567
6
+ metadata.gz: '0870375b45d3327fc7b74eb96a86ccf16f3c9d0714f1c3f0942174af02a2f3bfcd4703f5f3bedfe7b1db225bec6d26ae9e9db11de602e20f4d486b29b9316482'
7
+ data.tar.gz: 3bece6f01d16968e558695f5d457809f90f5ae6c141e7c5ba908fcc34d490027111e8aa9e259d6486e9fc36be1c5963dd03eaeb384b69efc670cff976591b1a7
data/lib/nblog_zon.rb CHANGED
@@ -2240,83 +2240,115 @@ class Wordpress
2240
2240
  return @data2
2241
2241
  end
2242
2242
 
2243
- def auto_image(keyword = nil)
2244
- keyword ||= @keyword
2245
- puts "키워드: #{keyword}"
2246
-
2247
- client = HTTPClient.new
2248
- client.default_header = {
2249
- 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2250
- '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2251
- 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2252
- 'Accept-Language' => 'en-US,en;q=0.9',
2253
- 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2254
- 'X-Requested-With' => 'XMLHttpRequest'
2255
- }
2243
+ def crop_image_height_under_width(path, min_crop_ratio = 0.625)
2244
+ img = Magick::Image.read(path).first
2245
+ width = img.columns
2246
+ height = img.rows
2256
2247
 
2257
- retry_count = 0
2258
- max_retries = 10
2259
- results = []
2248
+ if height > width
2249
+ min_height = (width * min_crop_ratio).to_i
2250
+ new_height = rand(min_height..width)
2251
+ crop_top = ((height - new_height) / 2.0).round
2260
2252
 
2261
- begin
2262
- page = rand(1..15)
2263
- url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2264
- puts "Request URL: #{url}"
2265
- res = client.get(url)
2266
-
2267
- unless res.status == 200
2268
- puts "HTTP Error: #{res.status}"
2269
- raise "HTTP Error"
2253
+ cropped = img.crop(0, crop_top, width, new_height, true)
2254
+
2255
+ retries = 0
2256
+ begin
2257
+ cropped.write(path)
2258
+ rescue => e
2259
+ retries += 1
2260
+ puts "이미지 저장 오류 (#{e.message}), 재시도 #{retries}/5"
2261
+ sleep(1)
2262
+ retry if retries < 5
2263
+ raise "이미지 저장 실패: #{e.message}"
2270
2264
  end
2265
+ end
2266
+ end
2271
2267
 
2272
- json = JSON.parse(res.body)
2273
- results = json['results']
2274
- mm = []
2268
+ def auto_image(keyword = nil)
2269
+ # auto_image 내부에서만 crop 호출
2270
+ keyword ||= @keyword
2271
+ puts "키워드: #{keyword}"
2272
+
2273
+ client = HTTPClient.new
2274
+ client.default_header = {
2275
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2276
+ '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2277
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2278
+ 'Accept-Language' => 'en-US,en;q=0.9',
2279
+ 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2280
+ 'X-Requested-With' => 'XMLHttpRequest'
2281
+ }
2282
+
2283
+ retry_count = 0
2284
+ max_retries = 10
2285
+ results = []
2286
+
2287
+ begin
2288
+ page = rand(1..15)
2289
+ url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2290
+ puts "Request URL: #{url}"
2291
+ res = client.get(url)
2292
+
2293
+ unless res.status == 200
2294
+ puts "HTTP Error: #{res.status}"
2295
+ raise "HTTP Error"
2296
+ end
2275
2297
 
2276
- results.each do |photo|
2277
- full_url = photo.dig('urls', 'full').to_s
2278
- regular_url = photo.dig('urls', 'regular').to_s
2298
+ json = JSON.parse(res.body)
2299
+ results = json['results']
2300
+ mm = []
2279
2301
 
2280
- if full_url.start_with?("https://images.unsplash.com/photo-") &&
2281
- regular_url.include?("1080")
2282
- mm << full_url
2283
- end
2284
- end
2302
+ results.each do |photo|
2303
+ full_url = photo.dig('urls', 'full').to_s
2304
+ regular_url = photo.dig('urls', 'regular').to_s
2285
2305
 
2286
- if mm.empty?
2287
- raise "No matching image"
2288
- end
2306
+ if full_url.start_with?("https://images.unsplash.com/photo-") &&
2307
+ regular_url.include?("1080")
2308
+ mm << full_url
2309
+ end
2310
+ end
2289
2311
 
2290
- selected_url = mm.sample
2291
- Down.download(selected_url, destination: "./image/memory.png")
2292
- puts "이미지 다운로드 완료: #{selected_url}"
2312
+ if mm.empty?
2313
+ raise "No matching image"
2314
+ end
2293
2315
 
2294
- rescue => e
2295
- retry_count += 1
2296
- puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2297
- sleep(3)
2298
- if retry_count < max_retries
2299
- retry
2300
- else
2301
- puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2302
-
2303
- if results && !results.empty?
2304
- random_photo = results.sample
2305
- fallback_url = random_photo.dig('urls', 'full')
2306
- if fallback_url
2307
- Down.download(fallback_url, destination: "./image/memory.png")
2308
- puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2309
- else
2310
- puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2311
- color_image
2312
- end
2316
+ selected_url = mm.sample
2317
+ destination_path = "./image/memory.png"
2318
+ Down.download(selected_url, destination: destination_path)
2319
+ puts "이미지 다운로드 완료: #{selected_url}"
2320
+
2321
+ # 오직 auto_image에서만 자르기 호출
2322
+ crop_image_height_under_width(destination_path)
2323
+
2324
+ rescue => e
2325
+ retry_count += 1
2326
+ puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2327
+ sleep(3)
2328
+ if retry_count < max_retries
2329
+ retry
2330
+ else
2331
+ puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2332
+
2333
+ if results && !results.empty?
2334
+ random_photo = results.sample
2335
+ fallback_url = random_photo.dig('urls', 'full')
2336
+ if fallback_url
2337
+ Down.download(fallback_url, destination: "./image/memory.png")
2338
+ puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2339
+ crop_image_height_under_width("./image/memory.png")
2313
2340
  else
2314
- puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2315
- color_image
2316
- end
2341
+ puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2342
+ color_image
2317
2343
  end
2344
+ else
2345
+ puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2346
+ color_image
2347
+ end
2318
2348
  end
2319
2349
  end
2350
+ end
2351
+
2320
2352
 
2321
2353
  def color_image
2322
2354
  color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
@@ -2411,56 +2443,103 @@ class Wordpress
2411
2443
 
2412
2444
 
2413
2445
  def image_text(text1, text2)
2446
+ begin
2447
+ color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
2448
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2449
+ font2 = './fonts/' + font_files.sample
2450
+
2451
+ # 랜덤 글자색 선택
2452
+ color2 = color.sample
2453
+
2454
+ # 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
2455
+ def hex_to_rgb(hex)
2456
+ hex = hex.delete('#')
2457
+ [hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
2458
+ end
2459
+
2460
+ # 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
2461
+ def color_distance(c1, c2)
2462
+ Math.sqrt(
2463
+ (c1[0] - c2[0])**2 +
2464
+ (c1[1] - c2[1])**2 +
2465
+ (c1[2] - c2[2])**2
2466
+ )
2467
+ end
2468
+
2469
+ # 대비가 충분히 되는 테두리 색상 선택
2470
+ max_attempts = 10
2471
+ stroke_color = nil
2472
+ base_rgb = hex_to_rgb(color2)
2473
+
2474
+ max_attempts.times do
2475
+ candidate = color.sample
2476
+ candidate_rgb = hex_to_rgb(candidate)
2477
+ dist = color_distance(base_rgb, candidate_rgb)
2478
+
2479
+ # 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
2480
+ if dist > 100
2481
+ stroke_color = candidate
2482
+ break
2483
+ end
2484
+ end
2485
+ stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
2486
+
2487
+ img = Magick::Image.read('./image/memory.png').first
2488
+ draw = Magick::Draw.new
2489
+
2490
+ raw_message = "#{text1}\n#{text2}".strip
2491
+ max_width = img.columns * 0.85
2492
+ max_height = img.rows * 0.6
2493
+
2414
2494
  begin
2415
- color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
2416
- font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2417
- font2 = './fonts/' + font_files.sample
2418
- color2 = color.sample
2419
-
2420
- img = Magick::Image.read('./image/memory.png').first
2421
- draw = Magick::Draw.new
2422
-
2423
- raw_message = "#{text1}\n#{text2}".strip
2424
- max_width = img.columns * 0.85
2425
- max_height = img.rows * 0.6
2426
-
2427
- begin
2428
- size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2429
- rescue
2430
- size = 30
2431
- end
2432
-
2433
- wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2434
-
2435
- if @data['이미지설정']['글자그림자'].checked?
2436
- img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2437
- draw.gravity = Magick::CenterGravity
2438
- draw.pointsize = adjusted_size
2439
- draw.fill = '#000000'
2440
- draw.font = font2
2441
- end
2442
- end
2443
-
2444
- draw2 = Magick::Draw.new
2445
- img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2446
- draw2.gravity = Magick::CenterGravity
2447
- draw2.pointsize = adjusted_size
2448
- draw2.fill = color2
2449
- draw2.font = font2
2450
- if @data['이미지설정']['글자테두리'].checked?
2451
- draw2.stroke_width = 2
2452
- draw2.stroke = '#000000'
2453
- end
2454
- end
2455
-
2456
- img.write('./image/memory.png')
2495
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2457
2496
  rescue
2458
- puts '이미지 폰트 불러오기 오류 재시도...'
2459
- sleep(3)
2460
- retry
2497
+ size = 30
2498
+ end
2499
+
2500
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2501
+
2502
+ if @data['이미지설정']['글자그림자'].checked?
2503
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2504
+ draw.gravity = Magick::CenterGravity
2505
+ draw.pointsize = adjusted_size
2506
+ draw.fill = '#000000'
2507
+ draw.font = font2
2508
+ end
2509
+ end
2510
+
2511
+ if @data['이미지설정']['글자테두리'].checked?
2512
+ draw_stroke = Magick::Draw.new
2513
+ img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
2514
+ draw_stroke.gravity = Magick::CenterGravity
2515
+ draw_stroke.pointsize = adjusted_size
2516
+ draw_stroke.fill = 'none'
2517
+ draw_stroke.stroke = stroke_color
2518
+ draw_stroke.stroke_width = rand(5..10)
2519
+ draw_stroke.font = font2
2520
+ end
2461
2521
  end
2522
+
2523
+ draw2 = Magick::Draw.new
2524
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2525
+ draw2.gravity = Magick::CenterGravity
2526
+ draw2.pointsize = adjusted_size
2527
+ draw2.fill = color2
2528
+ draw2.stroke = 'none'
2529
+ draw2.font = font2
2530
+ end
2531
+
2532
+ img.write('./image/memory.png')
2533
+
2534
+ rescue => e
2535
+ puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
2536
+ sleep(3)
2537
+ retry
2538
+ end
2462
2539
  end
2463
2540
 
2541
+
2542
+
2464
2543
  def border()
2465
2544
  color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
2466
2545
  img = Magick::Image.read('./image/memory.png').first
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nblog_zon
3
3
  version: !ruby/object:Gem::Version
4
- version: 111.120.001
4
+ version: 111.120.003
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon