cafe_buy 0.1.51 → 0.1.52

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/cafe_buy.rb +185 -110
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49bc96011f8df8c2209b64a155ab446ff9a41e7d78c33aa36ed16f7217591e1e
4
- data.tar.gz: 1f636c13ada4859c45d82846ab8f26f3c5f54779cab00da079a65afd2209fc34
3
+ metadata.gz: f94b7d1bcfb6264a812baed1a521a2f8f4ddf2724b49520f03db280675989019
4
+ data.tar.gz: a85ba553efe2bdc42104ca639ecc5d67035b4e74a1a87db6873ba082d1d7c4a7
5
5
  SHA512:
6
- metadata.gz: d43ba14d30b1fa8c51b0b726a84ff4a07482c42643da46c41745253737ac917290b8ab9b5ec31b3f4fcbb6b5281c20f4007c7b3b687261b94b653d29b7aef6bc
7
- data.tar.gz: e27a3c4ffa964422aff1cf95bb2a738ce26751210d8516a2f3cbee3dcad84a3726098321e28e21e77e5980dfba764daa9c6399c035f908ff15eda97caf7a8fab
6
+ metadata.gz: bc56b9eff065ad14f45f3ad5711e8cf1a6a5b0c8305e587454c3ed0c4ac749e9cedb668329ff84c66596f49cffa1e50bce12d2b0af7889c939e1bc49f87c6b52
7
+ data.tar.gz: 61bccdfb975cd969708c6729066408476b70ccd79f7df844c87fbb32ac67374725e3aff811d8e7fbc8ef002f913de8184434df30b73f7d036502ae1901ddeb2e
data/lib/cafe_buy.rb CHANGED
@@ -2366,84 +2366,112 @@ class Wordpress
2366
2366
 
2367
2367
 
2368
2368
 
2369
+ def crop_image_height_under_width(path, min_crop_ratio = 0.625)
2370
+ img = Magick::Image.read(path).first
2371
+ width = img.columns
2372
+ height = img.rows
2373
+
2374
+
2375
+
2376
+ if height > width
2377
+ min_height = (width * min_crop_ratio).to_i
2378
+ new_height = rand(min_height..width)
2379
+ crop_top = ((height - new_height) / 2.0).round
2380
+
2381
+ cropped = img.crop(0, crop_top, width, new_height, true)
2382
+ cropped.write(path)
2383
+
2384
+
2385
+ else
2386
+
2387
+ end
2388
+ end
2389
+
2369
2390
  def auto_image(keyword = nil)
2370
- keyword ||= @keyword
2371
- puts "키워드: #{keyword}"
2372
-
2373
- client = HTTPClient.new
2374
- client.default_header = {
2375
- 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2376
- '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2377
- 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2378
- 'Accept-Language' => 'en-US,en;q=0.9',
2379
- 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2380
- 'X-Requested-With' => 'XMLHttpRequest'
2381
- }
2391
+ # auto_image 내부에서만 crop 호출
2392
+ keyword ||= @keyword
2393
+ puts "키워드: #{keyword}"
2394
+
2395
+ client = HTTPClient.new
2396
+ client.default_header = {
2397
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2398
+ '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2399
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2400
+ 'Accept-Language' => 'en-US,en;q=0.9',
2401
+ 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2402
+ 'X-Requested-With' => 'XMLHttpRequest'
2403
+ }
2404
+
2405
+ retry_count = 0
2406
+ max_retries = 10
2407
+ results = []
2382
2408
 
2383
- retry_count = 0
2384
- max_retries = 10
2385
- results = []
2409
+ begin
2410
+ page = rand(1..15)
2411
+ url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2412
+ puts "Request URL: #{url}"
2413
+ res = client.get(url)
2414
+
2415
+ unless res.status == 200
2416
+ puts "HTTP Error: #{res.status}"
2417
+ raise "HTTP Error"
2418
+ end
2386
2419
 
2387
- begin
2388
- page = rand(1..15)
2389
- url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2390
- puts "Request URL: #{url}"
2391
- res = client.get(url)
2392
-
2393
- unless res.status == 200
2394
- puts "HTTP Error: #{res.status}"
2395
- raise "HTTP Error"
2396
- end
2420
+ json = JSON.parse(res.body)
2421
+ results = json['results']
2422
+ mm = []
2397
2423
 
2398
- json = JSON.parse(res.body)
2399
- results = json['results']
2400
- mm = []
2424
+ results.each do |photo|
2425
+ full_url = photo.dig('urls', 'full').to_s
2426
+ regular_url = photo.dig('urls', 'regular').to_s
2401
2427
 
2402
- results.each do |photo|
2403
- full_url = photo.dig('urls', 'full').to_s
2404
- regular_url = photo.dig('urls', 'regular').to_s
2428
+ if full_url.start_with?("https://images.unsplash.com/photo-") &&
2429
+ regular_url.include?("1080")
2430
+ mm << full_url
2431
+ end
2432
+ end
2405
2433
 
2406
- if full_url.start_with?("https://images.unsplash.com/photo-") &&
2407
- regular_url.include?("1080")
2408
- mm << full_url
2409
- end
2410
- end
2434
+ if mm.empty?
2435
+ raise "No matching image"
2436
+ end
2411
2437
 
2412
- if mm.empty?
2413
- raise "No matching image"
2414
- end
2438
+ selected_url = mm.sample
2439
+ destination_path = "./image/memory.png"
2440
+ Down.download(selected_url, destination: destination_path)
2441
+ puts "이미지 다운로드 완료: #{selected_url}"
2415
2442
 
2416
- selected_url = mm.sample
2417
- Down.download(selected_url, destination: "./image/memory.png")
2418
- puts "이미지 다운로드 완료: #{selected_url}"
2443
+ # 오직 auto_image에서만 자르기 호출
2444
+ crop_image_height_under_width(destination_path)
2419
2445
 
2420
- rescue => e
2421
- retry_count += 1
2422
- puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2423
- sleep(3)
2424
- if retry_count < max_retries
2425
- retry
2426
- else
2427
- puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2428
-
2429
- if results && !results.empty?
2430
- random_photo = results.sample
2431
- fallback_url = random_photo.dig('urls', 'full')
2432
- if fallback_url
2433
- Down.download(fallback_url, destination: "./image/memory.png")
2434
- puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2435
- else
2436
- puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2437
- color_image
2438
- end
2446
+ rescue => e
2447
+ retry_count += 1
2448
+ puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2449
+ sleep(3)
2450
+ if retry_count < max_retries
2451
+ retry
2452
+ else
2453
+ puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2454
+
2455
+ if results && !results.empty?
2456
+ random_photo = results.sample
2457
+ fallback_url = random_photo.dig('urls', 'full')
2458
+ if fallback_url
2459
+ Down.download(fallback_url, destination: "./image/memory.png")
2460
+ puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2461
+ crop_image_height_under_width("./image/memory.png")
2439
2462
  else
2440
- puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2441
- color_image
2442
- end
2463
+ puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2464
+ color_image
2443
2465
  end
2466
+ else
2467
+ puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2468
+ color_image
2444
2469
  end
2470
+ end
2471
+ end
2445
2472
  end
2446
2473
 
2474
+
2447
2475
  def color_image
2448
2476
  color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
2449
2477
  image = Magick::Image.new(740, 740) { |k| k.background_color = color.sample }
@@ -2536,57 +2564,104 @@ class Wordpress
2536
2564
  end
2537
2565
 
2538
2566
 
2539
- def image_text(text1, text2)
2567
+ def image_text(text1, text2)
2568
+ begin
2569
+ color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
2570
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2571
+ font2 = './fonts/' + font_files.sample
2572
+
2573
+ # 랜덤 글자색 선택
2574
+ color2 = color.sample
2575
+
2576
+ # 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
2577
+ def hex_to_rgb(hex)
2578
+ hex = hex.delete('#')
2579
+ [hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
2580
+ end
2581
+
2582
+ # 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
2583
+ def color_distance(c1, c2)
2584
+ Math.sqrt(
2585
+ (c1[0] - c2[0])**2 +
2586
+ (c1[1] - c2[1])**2 +
2587
+ (c1[2] - c2[2])**2
2588
+ )
2589
+ end
2590
+
2591
+ # 대비가 충분히 되는 테두리 색상 선택
2592
+ max_attempts = 10
2593
+ stroke_color = nil
2594
+ base_rgb = hex_to_rgb(color2)
2595
+
2596
+ max_attempts.times do
2597
+ candidate = color.sample
2598
+ candidate_rgb = hex_to_rgb(candidate)
2599
+ dist = color_distance(base_rgb, candidate_rgb)
2600
+
2601
+ # 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
2602
+ if dist > 100
2603
+ stroke_color = candidate
2604
+ break
2605
+ end
2606
+ end
2607
+ stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
2608
+
2609
+ img = Magick::Image.read('./image/memory.png').first
2610
+ draw = Magick::Draw.new
2611
+
2612
+ raw_message = "#{text1}\n#{text2}".strip
2613
+ max_width = img.columns * 0.85
2614
+ max_height = img.rows * 0.6
2615
+
2540
2616
  begin
2541
- color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
2542
- font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2543
- font2 = './fonts/' + font_files.sample
2544
- color2 = color.sample
2545
-
2546
- img = Magick::Image.read('./image/memory.png').first
2547
- draw = Magick::Draw.new
2548
-
2549
- raw_message = "#{text1}\n#{text2}".strip
2550
- max_width = img.columns * 0.85
2551
- max_height = img.rows * 0.6
2552
-
2553
- begin
2554
- size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2555
- rescue
2556
- size = 30
2557
- end
2558
-
2559
- wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2560
-
2561
- if @data['이미지설정']['글자그림자'].checked?
2562
- img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2563
- draw.gravity = Magick::CenterGravity
2564
- draw.pointsize = adjusted_size
2565
- draw.fill = '#000000'
2566
- draw.font = font2
2567
- end
2568
- end
2569
-
2570
- draw2 = Magick::Draw.new
2571
- img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2572
- draw2.gravity = Magick::CenterGravity
2573
- draw2.pointsize = adjusted_size
2574
- draw2.fill = color2
2575
- draw2.font = font2
2576
- if @data['이미지설정']['글자테두리'].checked?
2577
- draw2.stroke_width = 2
2578
- draw2.stroke = '#000000'
2579
- end
2580
- end
2581
-
2582
- img.write('./image/memory.png')
2617
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2583
2618
  rescue
2584
- puts '이미지 폰트 불러오기 오류 재시도...'
2585
- sleep(3)
2586
- retry
2619
+ size = 30
2620
+ end
2621
+
2622
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2623
+
2624
+ if @data['이미지설정']['글자그림자'].checked?
2625
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2626
+ draw.gravity = Magick::CenterGravity
2627
+ draw.pointsize = adjusted_size
2628
+ draw.fill = '#000000'
2629
+ draw.font = font2
2630
+ end
2631
+ end
2632
+
2633
+ if @data['이미지설정']['글자테두리'].checked?
2634
+ draw_stroke = Magick::Draw.new
2635
+ img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
2636
+ draw_stroke.gravity = Magick::CenterGravity
2637
+ draw_stroke.pointsize = adjusted_size
2638
+ draw_stroke.fill = 'none'
2639
+ draw_stroke.stroke = stroke_color
2640
+ draw_stroke.stroke_width = rand(5..10)
2641
+ draw_stroke.font = font2
2587
2642
  end
2643
+ end
2644
+
2645
+ draw2 = Magick::Draw.new
2646
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2647
+ draw2.gravity = Magick::CenterGravity
2648
+ draw2.pointsize = adjusted_size
2649
+ draw2.fill = color2
2650
+ draw2.stroke = 'none'
2651
+ draw2.font = font2
2652
+ end
2653
+
2654
+ img.write('./image/memory.png')
2655
+
2656
+ rescue => e
2657
+ puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
2658
+ sleep(3)
2659
+ retry
2660
+ end
2588
2661
  end
2589
2662
 
2663
+
2664
+
2590
2665
  def border()
2591
2666
  color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
2592
2667
  img = Magick::Image.read('./image/memory.png').first
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cafe_buy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.51
4
+ version: 0.1.52
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-25 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