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