wp_posting_zon 0.0.7 → 0.0.9
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/wp_posting_zon.rb +303 -130
- 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: 5aeddc0ceb08cb7a26d1252f6b2e1c2b3cb3ee5c1404da3a2e97bf07c0ed0d0f
|
4
|
+
data.tar.gz: 3a33e130e13bc2ca04e57236c8620d03bfd29ed88b666882bb69e91746e1d056
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 959862a24098814c43dde5b88fe18ff2518c49d53c78e16c7f8d15ef8345d33fcada363599d7a06fd9e30d1ccf5fd4997f9be3f332677644dd3344e5958f17b4
|
7
|
+
data.tar.gz: 6ad3da66c7cc04822b594f32a64bb57051d05e7b61c7e9a5e7c3fe55712901c7142a5bf1f5245f1d2b78e8e77608f4ce3c36d23286202df4c83f461cc676e2b8
|
data/lib/wp_posting_zon.rb
CHANGED
@@ -338,83 +338,110 @@ class Wordpress
|
|
338
338
|
return @data2
|
339
339
|
end
|
340
340
|
|
341
|
-
def
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
client = HTTPClient.new
|
346
|
-
client.default_header = {
|
347
|
-
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
|
348
|
-
'(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
349
|
-
'Accept' => 'application/json, text/javascript, */*; q=0.01',
|
350
|
-
'Accept-Language' => 'en-US,en;q=0.9',
|
351
|
-
'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
|
352
|
-
'X-Requested-With' => 'XMLHttpRequest'
|
353
|
-
}
|
341
|
+
def crop_image_height_under_width(path, min_crop_ratio = 0.625)
|
342
|
+
img = Magick::Image.read(path).first
|
343
|
+
width = img.columns
|
344
|
+
height = img.rows
|
354
345
|
|
355
|
-
retry_count = 0
|
356
|
-
max_retries = 10
|
357
|
-
results = []
|
358
346
|
|
359
|
-
begin
|
360
|
-
page = rand(1..15)
|
361
|
-
url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
|
362
|
-
puts "Request URL: #{url}"
|
363
|
-
res = client.get(url)
|
364
|
-
|
365
|
-
unless res.status == 200
|
366
|
-
puts "HTTP Error: #{res.status}"
|
367
|
-
raise "HTTP Error"
|
368
|
-
end
|
369
347
|
|
370
|
-
|
371
|
-
|
372
|
-
|
348
|
+
if height > width
|
349
|
+
min_height = (width * min_crop_ratio).to_i
|
350
|
+
new_height = rand(min_height..width)
|
351
|
+
crop_top = ((height - new_height) / 2.0).round
|
373
352
|
|
374
|
-
|
375
|
-
|
376
|
-
regular_url = photo.dig('urls', 'regular').to_s
|
353
|
+
cropped = img.crop(0, crop_top, width, new_height, true)
|
354
|
+
cropped.write(path)
|
377
355
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
356
|
+
|
357
|
+
else
|
358
|
+
|
359
|
+
end
|
360
|
+
end
|
383
361
|
|
384
|
-
|
385
|
-
|
386
|
-
|
362
|
+
def auto_image(keyword = nil)
|
363
|
+
# auto_image 내부에서만 crop 호출
|
364
|
+
keyword ||= @keyword
|
365
|
+
puts "키워드: #{keyword}"
|
366
|
+
|
367
|
+
client = HTTPClient.new
|
368
|
+
client.default_header = {
|
369
|
+
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
|
370
|
+
'(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
371
|
+
'Accept' => 'application/json, text/javascript, */*; q=0.01',
|
372
|
+
'Accept-Language' => 'en-US,en;q=0.9',
|
373
|
+
'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
|
374
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
375
|
+
}
|
376
|
+
|
377
|
+
retry_count = 0
|
378
|
+
max_retries = 10
|
379
|
+
results = []
|
380
|
+
|
381
|
+
begin
|
382
|
+
page = rand(1..15)
|
383
|
+
url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
|
384
|
+
puts "Request URL: #{url}"
|
385
|
+
res = client.get(url)
|
386
|
+
|
387
|
+
unless res.status == 200
|
388
|
+
puts "HTTP Error: #{res.status}"
|
389
|
+
raise "HTTP Error"
|
390
|
+
end
|
387
391
|
|
388
|
-
|
389
|
-
|
390
|
-
|
392
|
+
json = JSON.parse(res.body)
|
393
|
+
results = json['results']
|
394
|
+
mm = []
|
391
395
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
396
|
+
results.each do |photo|
|
397
|
+
full_url = photo.dig('urls', 'full').to_s
|
398
|
+
regular_url = photo.dig('urls', 'regular').to_s
|
399
|
+
|
400
|
+
if full_url.start_with?("https://images.unsplash.com/photo-") &&
|
401
|
+
regular_url.include?("1080")
|
402
|
+
mm << full_url
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
if mm.empty?
|
407
|
+
raise "No matching image"
|
408
|
+
end
|
409
|
+
|
410
|
+
selected_url = mm.sample
|
411
|
+
destination_path = "./image/memory.png"
|
412
|
+
Down.download(selected_url, destination: destination_path)
|
413
|
+
puts "이미지 다운로드 완료: #{selected_url}"
|
414
|
+
|
415
|
+
# 오직 auto_image에서만 자르기 호출
|
416
|
+
crop_image_height_under_width(destination_path)
|
417
|
+
|
418
|
+
rescue => e
|
419
|
+
retry_count += 1
|
420
|
+
puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
|
421
|
+
sleep(3)
|
422
|
+
if retry_count < max_retries
|
423
|
+
retry
|
424
|
+
else
|
425
|
+
puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
|
426
|
+
|
427
|
+
if results && !results.empty?
|
428
|
+
random_photo = results.sample
|
429
|
+
fallback_url = random_photo.dig('urls', 'full')
|
430
|
+
if fallback_url
|
431
|
+
Down.download(fallback_url, destination: "./image/memory.png")
|
432
|
+
puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
|
433
|
+
crop_image_height_under_width("./image/memory.png")
|
411
434
|
else
|
412
|
-
|
413
|
-
|
414
|
-
end
|
435
|
+
puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
|
436
|
+
color_image
|
415
437
|
end
|
438
|
+
else
|
439
|
+
puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
|
440
|
+
color_image
|
441
|
+
end
|
416
442
|
end
|
417
443
|
end
|
444
|
+
end
|
418
445
|
|
419
446
|
|
420
447
|
def color_image
|
@@ -425,80 +452,188 @@ class Wordpress
|
|
425
452
|
|
426
453
|
def save_image
|
427
454
|
if @data['이미지설정']['이미지'].length == 0
|
428
|
-
|
455
|
+
return
|
456
|
+
end
|
457
|
+
|
458
|
+
if @data['이미지설정']['순서사용'].checked?
|
459
|
+
image_path = @data['이미지설정']['이미지'][@image_counter][2]
|
460
|
+
@image_counter += 1
|
461
|
+
if @image_counter > @data['이미지설정']['이미지'].length - 1
|
462
|
+
@image_counter = 0
|
463
|
+
end
|
429
464
|
else
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
@image_counter = 0
|
435
|
-
end
|
436
|
-
else
|
437
|
-
image_path = @data['이미지설정']['이미지'].sample[2]
|
465
|
+
# 초기화가 안됐거나 다 썼으면 새롭게 섞는다
|
466
|
+
@shuffled_images ||= []
|
467
|
+
if @shuffled_images.empty?
|
468
|
+
@shuffled_images = @data['이미지설정']['이미지'].shuffle
|
438
469
|
end
|
439
|
-
|
440
|
-
|
470
|
+
|
471
|
+
image_path = @shuffled_images.shift[2]
|
441
472
|
end
|
473
|
+
|
474
|
+
img = Magick::Image.read(image_path).first
|
475
|
+
img.write('./image/memory.png')
|
442
476
|
end
|
443
477
|
|
444
478
|
def change_image_size(w)
|
445
479
|
img = Magick::Image.read('./image/memory.png').first
|
446
480
|
width = img.columns
|
447
481
|
height = img.rows
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
482
|
+
|
483
|
+
# '원본'이 선택된 경우, 리사이징을 하지 않고 원본 이미지를 그대로 반환
|
484
|
+
if w == 'original'
|
485
|
+
return img # 원본 이미지 그대로 반환
|
486
|
+
else
|
487
|
+
begin
|
488
|
+
if @data['image_type'][0].checked? or @data['image_type'][2].checked?
|
489
|
+
# 비율을 맞추어 리사이징
|
490
|
+
img.resize!(w, w * (height.to_f / width.to_f))
|
491
|
+
else
|
492
|
+
# 정사각형으로 리사이징
|
493
|
+
img.resize!(w, w)
|
494
|
+
end
|
495
|
+
rescue
|
496
|
+
img.resize!(w, w) # 예외 처리 시에도 리사이징
|
453
497
|
end
|
454
|
-
rescue
|
455
|
-
img.resize!(w, w)
|
456
498
|
end
|
499
|
+
|
500
|
+
# 리사이징된 이미지 저장
|
457
501
|
img.write('./image/memory.png')
|
458
502
|
end
|
459
503
|
|
460
|
-
def
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
text.fill = '#000000'
|
479
|
-
text.font = font2
|
504
|
+
def wrap_text_to_fit(draw, text, max_width, max_height, font_path, initial_size)
|
505
|
+
size = initial_size
|
506
|
+
draw.font = font_path
|
507
|
+
|
508
|
+
loop do
|
509
|
+
draw.pointsize = size
|
510
|
+
words = text.chars # 글자 단위로 자름 (한국어 기준)
|
511
|
+
lines = []
|
512
|
+
line = ""
|
513
|
+
|
514
|
+
words.each do |char|
|
515
|
+
test_line = line + char
|
516
|
+
metrics = draw.get_type_metrics(test_line)
|
517
|
+
if metrics.width > max_width
|
518
|
+
lines << line
|
519
|
+
line = char
|
520
|
+
else
|
521
|
+
line = test_line
|
480
522
|
end
|
481
523
|
end
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
524
|
+
lines << line unless line.empty?
|
525
|
+
|
526
|
+
line_height = draw.get_type_metrics("가").height
|
527
|
+
total_height = line_height * lines.size
|
528
|
+
|
529
|
+
# 세로 초과 안 하면 성공
|
530
|
+
if total_height <= max_height || size <= 10
|
531
|
+
return [lines.join("\n"), size]
|
532
|
+
else
|
533
|
+
size -= 2
|
492
534
|
end
|
493
|
-
|
494
|
-
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
|
539
|
+
def image_text(text1, text2)
|
540
|
+
begin
|
541
|
+
color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
|
542
|
+
font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
|
543
|
+
font2 = './fonts/' + font_files.sample
|
544
|
+
|
545
|
+
# 랜덤 글자색 선택
|
546
|
+
color2 = color.sample
|
547
|
+
|
548
|
+
# 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
|
549
|
+
def hex_to_rgb(hex)
|
550
|
+
hex = hex.delete('#')
|
551
|
+
[hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
|
552
|
+
end
|
553
|
+
|
554
|
+
# 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
|
555
|
+
def color_distance(c1, c2)
|
556
|
+
Math.sqrt(
|
557
|
+
(c1[0] - c2[0])**2 +
|
558
|
+
(c1[1] - c2[1])**2 +
|
559
|
+
(c1[2] - c2[2])**2
|
560
|
+
)
|
561
|
+
end
|
562
|
+
|
563
|
+
# 대비가 충분히 되는 테두리 색상 선택
|
564
|
+
max_attempts = 10
|
565
|
+
stroke_color = nil
|
566
|
+
base_rgb = hex_to_rgb(color2)
|
567
|
+
|
568
|
+
max_attempts.times do
|
569
|
+
candidate = color.sample
|
570
|
+
candidate_rgb = hex_to_rgb(candidate)
|
571
|
+
dist = color_distance(base_rgb, candidate_rgb)
|
572
|
+
|
573
|
+
# 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
|
574
|
+
if dist > 100
|
575
|
+
stroke_color = candidate
|
576
|
+
break
|
577
|
+
end
|
578
|
+
end
|
579
|
+
stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
|
580
|
+
|
581
|
+
img = Magick::Image.read('./image/memory.png').first
|
582
|
+
draw = Magick::Draw.new
|
583
|
+
|
584
|
+
raw_message = "#{text1}\n#{text2}".strip
|
585
|
+
max_width = img.columns * 0.85
|
586
|
+
max_height = img.rows * 0.6
|
587
|
+
|
588
|
+
begin
|
589
|
+
size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
|
495
590
|
rescue
|
496
|
-
|
497
|
-
|
498
|
-
|
591
|
+
size = 30
|
592
|
+
end
|
593
|
+
|
594
|
+
wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
|
595
|
+
|
596
|
+
if @data['이미지설정']['글자그림자'].checked?
|
597
|
+
img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
|
598
|
+
draw.gravity = Magick::CenterGravity
|
599
|
+
draw.pointsize = adjusted_size
|
600
|
+
draw.fill = '#000000'
|
601
|
+
draw.font = font2
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
if @data['이미지설정']['글자테두리'].checked?
|
606
|
+
draw_stroke = Magick::Draw.new
|
607
|
+
img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
|
608
|
+
draw_stroke.gravity = Magick::CenterGravity
|
609
|
+
draw_stroke.pointsize = adjusted_size
|
610
|
+
draw_stroke.fill = 'none'
|
611
|
+
draw_stroke.stroke = stroke_color
|
612
|
+
draw_stroke.stroke_width = rand(5..10)
|
613
|
+
draw_stroke.font = font2
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
draw2 = Magick::Draw.new
|
618
|
+
img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
|
619
|
+
draw2.gravity = Magick::CenterGravity
|
620
|
+
draw2.pointsize = adjusted_size
|
621
|
+
draw2.fill = color2
|
622
|
+
draw2.stroke = 'none'
|
623
|
+
draw2.font = font2
|
499
624
|
end
|
625
|
+
|
626
|
+
img.write('./image/memory.png')
|
627
|
+
|
628
|
+
rescue => e
|
629
|
+
puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
|
630
|
+
sleep(3)
|
631
|
+
retry
|
632
|
+
end
|
500
633
|
end
|
501
634
|
|
635
|
+
|
636
|
+
|
502
637
|
def border()
|
503
638
|
color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
|
504
639
|
img = Magick::Image.read('./image/memory.png').first
|
@@ -524,48 +659,86 @@ class Wordpress
|
|
524
659
|
else
|
525
660
|
auto_image()
|
526
661
|
end
|
527
|
-
|
528
|
-
|
662
|
+
|
663
|
+
# '원본'을 포함한 이미지 크기 옵션 추가
|
664
|
+
image_size = [480, 740, 650, 550, 480, 'original']
|
529
665
|
size = 0
|
530
|
-
|
666
|
+
|
667
|
+
for n in 0..5 # 0부터 5까지 반복, '원본' 옵션까지 포함
|
531
668
|
if @data['image_size'][n].checked?
|
532
|
-
if n ==
|
533
|
-
size =
|
669
|
+
if n == 5 # '원본'이 선택되었을 경우
|
670
|
+
size = 'original'
|
671
|
+
elsif n == 0
|
672
|
+
size = image_size.sample # 랜덤 선택
|
534
673
|
else
|
535
674
|
size = image_size[n]
|
536
675
|
end
|
537
676
|
end
|
538
677
|
end
|
678
|
+
|
679
|
+
# '원본'이 선택되지 않았다면 기본 값 설정
|
539
680
|
if size == 0
|
540
681
|
size = 480
|
541
682
|
end
|
683
|
+
|
684
|
+
change_image_size(size) # 크기 변경 함수 호출
|
542
685
|
|
543
|
-
change_image_size(size)
|
544
686
|
|
545
687
|
if @data['이미지설정']['필터사용'].checked?
|
546
688
|
image_filter()
|
547
689
|
end
|
548
690
|
|
549
|
-
insert_image_text1 = ''
|
550
|
-
insert_image_text2 = ''
|
551
691
|
if @data['이미지설정']['글자삽입1'].checked?
|
552
|
-
|
692
|
+
if @data['이미지설정']['이미지글자1'].length == 0
|
693
|
+
image_text_path1 = ''
|
694
|
+
else
|
695
|
+
if @data['이미지설정']['글자랜덤'].checked?
|
696
|
+
image_text_path1 = @data['이미지설정']['이미지글자1'].sample
|
697
|
+
else
|
698
|
+
image_text_path1 = @data['이미지설정']['이미지글자1'][@image_text_soon1]
|
699
|
+
@image_text_soon1 += 1
|
700
|
+
if @image_text_soon1 > @data['이미지설정']['이미지글자1'].length - 1
|
701
|
+
@image_text_soon1 = 0
|
702
|
+
end
|
703
|
+
end
|
704
|
+
end
|
553
705
|
end
|
554
706
|
|
555
707
|
if @data['이미지설정']['글자삽입2'].checked?
|
556
|
-
|
708
|
+
if @data['이미지설정']['이미지글자2'].length == 0
|
709
|
+
image_text_path2 = ''
|
710
|
+
else
|
711
|
+
if @data['이미지설정']['글자랜덤'].checked?
|
712
|
+
image_text_path2 = @data['이미지설정']['이미지글자2'].sample
|
713
|
+
else
|
714
|
+
image_text_path2 = @data['이미지설정']['이미지글자2'][@image_text_soon2]
|
715
|
+
@image_text_soon2 += 1
|
716
|
+
if @image_text_soon2 > @data['이미지설정']['이미지글자2'].length - 1
|
717
|
+
@image_text_soon2 = 0
|
718
|
+
end
|
719
|
+
end
|
720
|
+
end
|
557
721
|
end
|
558
|
-
|
722
|
+
|
559
723
|
if @data['이미지설정']['글자삽입1'].checked? or @data['이미지설정']['글자삽입2'].checked?
|
560
|
-
image_text(
|
724
|
+
image_text(image_text_path1, image_text_path2)
|
561
725
|
end
|
562
726
|
|
563
727
|
if @data['이미지설정']['테두리사용'].checked?
|
564
728
|
border()
|
565
729
|
end
|
566
730
|
|
731
|
+
sleep(1)
|
567
732
|
time = Time.now.to_s.split(' ')[0..1].join('').split(':').join('').split('-').join('')
|
568
733
|
FileUtils.cp('./image/memory.png', './image/'+@keyword+time+'.png')
|
734
|
+
hi_dir = Dir.pwd
|
735
|
+
iconv = Iconv.new('UTF-8', 'CP949')
|
736
|
+
begin
|
737
|
+
hi_dir = iconv.iconv(hi_dir)
|
738
|
+
rescue
|
739
|
+
|
740
|
+
end
|
741
|
+
return hi_dir+'/image/'+@keyword+time+'.png'
|
569
742
|
end
|
570
743
|
|
571
744
|
def image_update22
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wp_posting_zon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
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
|