tblog_zon 0.0.37 → 0.0.50
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_zon.rb +402 -236
- metadata +3 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06d765fda4fbf3a4758df37b162e7275cfb67fcd6980f42d0bd97d1707ffd85a
|
4
|
+
data.tar.gz: eab1e8cc76c8f0e1af500b180a4bffcf835e384da8732dd1e9966190f49c10b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 835975aa79061c10dfca5b8dfe06baaeeb94ee5fbfa33b49bf540265d255cad84c07a5c95655bdbf3bc6cc925f331e53547ba7e0a4602b64d8f86b0e7d67f0ff
|
7
|
+
data.tar.gz: 0a1439d23c400f2a3ae178cbaa870a38ba125cb65971fc8c489d56c6d5f51d189d972da9677745a127ffaced909a4890d041d48d32d6280f5e0669d88092c372
|
data/lib/tblog_zon.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'glimmer-dsl-libui'
|
2
2
|
require 'selenium-webdriver'
|
3
|
-
# require 'webdrivers'
|
4
3
|
require 'iconv'
|
5
4
|
require 'nokogiri'
|
6
5
|
require 'http'
|
@@ -14,9 +13,9 @@ require 'clipboard'
|
|
14
13
|
require 'crack'
|
15
14
|
require 'uri'
|
16
15
|
require 'cgi'
|
17
|
-
require 'digest'
|
18
16
|
require 'auto_click'
|
19
17
|
require 'rainbow/refinement'
|
18
|
+
require 'httpclient'
|
20
19
|
include AutoClickMethods
|
21
20
|
using Rainbow
|
22
21
|
include Glimmer
|
@@ -249,7 +248,18 @@ class Naver
|
|
249
248
|
|
250
249
|
def chrome_start(proxy)
|
251
250
|
# 공통 옵션 설정
|
252
|
-
|
251
|
+
begin
|
252
|
+
Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
253
|
+
rescue => e
|
254
|
+
puts "chromedriver 버전 불일치!!"
|
255
|
+
puts "아래 지침을 따라주세요."
|
256
|
+
puts "1.프로그램 종료!"
|
257
|
+
puts "2.크롬 업데이트!"
|
258
|
+
puts "3.프로그램 폴더 내부에 ★tip★-시작시-크롬창이....파일 실행"
|
259
|
+
puts "4.안내된 방식으로 크롬 드라이버 교체"
|
260
|
+
puts "5.재 시작"
|
261
|
+
exit 1
|
262
|
+
end
|
253
263
|
options = Selenium::WebDriver::Chrome::Options.new
|
254
264
|
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
255
265
|
options.add_extension('./crx/app.crx') # 확장 프로그램을 첫 번째 탭에 추가
|
@@ -268,7 +278,7 @@ class Naver
|
|
268
278
|
options.add_argument('--disable-translate')
|
269
279
|
options.add_argument('--disable-extensions-file-access-check')
|
270
280
|
options.add_argument('--disable-impl-side-painting')
|
271
|
-
|
281
|
+
options.add_argument('--log-level=3')
|
272
282
|
# 자동화된 테스트 제거
|
273
283
|
options.exclude_switches = ['enable-automation']
|
274
284
|
|
@@ -299,7 +309,21 @@ class Naver
|
|
299
309
|
# 두 번째 탭에서 로그인 페이지 열기
|
300
310
|
@driver.get('https://www.tistory.com/auth/login')
|
301
311
|
sleep(1)
|
302
|
-
|
312
|
+
|
313
|
+
# 현재 탭 핸들 저장
|
314
|
+
main_tab = @driver.window_handle
|
315
|
+
|
316
|
+
# 모든 탭 순회
|
317
|
+
@driver.window_handles.each do |handle|
|
318
|
+
next if handle == main_tab # 현재 탭은 남긴다
|
319
|
+
|
320
|
+
@driver.switch_to.window(handle)
|
321
|
+
@driver.close # 다른 탭 닫기
|
322
|
+
end
|
323
|
+
|
324
|
+
# 다시 로그인 탭으로 전환
|
325
|
+
@driver.switch_to.window(main_tab)
|
326
|
+
sleep(1)
|
303
327
|
rescue => e
|
304
328
|
|
305
329
|
puts "Error: #{e.message}"
|
@@ -319,44 +343,90 @@ class Naver
|
|
319
343
|
# 두 번째 탭에서 로그인 페이지 열기
|
320
344
|
@driver.get('https://www.tistory.com/auth/login')
|
321
345
|
sleep(1)
|
346
|
+
|
347
|
+
# 현재 탭 핸들 저장
|
348
|
+
main_tab = @driver.window_handle
|
349
|
+
|
350
|
+
# 모든 탭 순회
|
351
|
+
@driver.window_handles.each do |handle|
|
352
|
+
next if handle == main_tab # 현재 탭은 남긴다
|
353
|
+
|
354
|
+
@driver.switch_to.window(handle)
|
355
|
+
@driver.close # 다른 탭 닫기
|
356
|
+
end
|
357
|
+
|
358
|
+
# 다시 로그인 탭으로 전환
|
359
|
+
@driver.switch_to.window(main_tab)
|
360
|
+
sleep(1)
|
322
361
|
end
|
323
362
|
end
|
324
363
|
|
325
364
|
def login(user_id, user_pw, proxy, captcha_api_key)
|
326
|
-
|
327
|
-
|
328
|
-
|
365
|
+
chrome_start(proxy)
|
366
|
+
@captcha_api_key = captcha_api_key
|
367
|
+
@user_id = user_id
|
329
368
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
369
|
+
if captcha_api_key != 'captcha_api_key 입력' && !captcha_api_key.to_s.strip.empty?
|
370
|
+
puts "캡처 키 확인 됨: '#{captcha_api_key}'".red
|
371
|
+
@driver.switch_to.new_window(:tab)
|
372
|
+
sleep(1.5)
|
373
|
+
@driver.switch_to.window(@driver.window_handles[1])
|
374
|
+
@driver.navigate.to("chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html")
|
375
|
+
sleep(3)
|
376
|
+
@driver.find_element(:xpath, '//*[@name="apiKey"]').click
|
377
|
+
Clipboard.copy(captcha_api_key)
|
378
|
+
sleep(0.5)
|
379
|
+
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
380
|
+
sleep(0.5)
|
381
|
+
@driver.find_element(:xpath, '//*[@data-lang="login"]').click
|
382
|
+
|
383
|
+
begin
|
384
|
+
sleep(2)
|
385
|
+
@driver.switch_to.alert.dismiss
|
386
|
+
sleep(1)
|
387
|
+
rescue
|
388
|
+
end
|
389
|
+
@driver.close
|
390
|
+
sleep(1)
|
391
|
+
@driver.switch_to.window(@driver.window_handles[0])
|
392
|
+
sleep(2)
|
393
|
+
else
|
394
|
+
end
|
395
|
+
|
396
|
+
user_cookie_file = []
|
397
|
+
begin
|
398
|
+
Dir.entries('./cookie').each do |i|
|
399
|
+
if i != '.' && i != '..'
|
400
|
+
user_cookie_file << i
|
401
|
+
end
|
402
|
+
end
|
403
|
+
rescue
|
336
404
|
end
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
@cookie4 = JSON.parse(f.read)
|
344
|
-
f.close
|
345
|
-
end
|
346
|
-
|
347
|
-
# 기존 쿠키가 있으면 쿠키를 추가
|
348
|
-
begin
|
349
|
-
@cookie4.each do |i|
|
350
|
-
@driver.manage.add_cookie(name: i['name'], value: i['value'], same_site: i['same_site'], domain: i['domain'], path: i['path'])
|
405
|
+
|
406
|
+
@cookie4 = {}
|
407
|
+
if user_cookie_file.include?(user_id+'.txt')
|
408
|
+
f = File.open('./cookie/'+user_id+'.txt', 'r')
|
409
|
+
@cookie4 = JSON.parse(f.read)
|
410
|
+
f.close
|
351
411
|
end
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
412
|
+
|
413
|
+
|
414
|
+
|
415
|
+
# 기존 쿠키가 있으면 쿠키를 추가
|
416
|
+
begin
|
417
|
+
@cookie4.each do |i|
|
418
|
+
@driver.manage.add_cookie(name: i['name'], value: i['value'], same_site: i['same_site'], domain: i['domain'], path: i['path'])
|
419
|
+
end
|
420
|
+
rescue
|
421
|
+
end
|
422
|
+
|
423
|
+
|
424
|
+
sleep(1.5)
|
425
|
+
@driver.get('https://www.tistory.com/auth/login')
|
359
426
|
sleep(1)
|
427
|
+
@driver.switch_to.window(@driver.window_handles[0])
|
428
|
+
|
429
|
+
|
360
430
|
begin
|
361
431
|
wait = Selenium::WebDriver::Wait.new(:timeout => 3)
|
362
432
|
wait.until { @driver.find_element(:xpath, '//*[@id="cMain"]/div/div/div/div/a[2]/span[2]') }
|
@@ -394,25 +464,7 @@ class Naver
|
|
394
464
|
wait.until { @driver.find_element(:xpath, '//*[@id="captchaContainer"]') }
|
395
465
|
puts '-[√] 로그인 중 캡챠 요구 발생 처리 진행.......'.yellow
|
396
466
|
sleep(1)
|
397
|
-
|
398
|
-
sleep(1)
|
399
|
-
@driver.find_element(:xpath, '//*[@name="apiKey"]').click
|
400
|
-
Clipboard.copy(captcha_api_key)
|
401
|
-
sleep(0.5)
|
402
|
-
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
403
|
-
sleep(0.5)
|
404
|
-
@driver.find_element(:xpath, '//*[@data-lang="login"]').click
|
405
|
-
|
406
|
-
begin
|
407
|
-
sleep(2)
|
408
|
-
@driver.switch_to.alert.dismiss
|
409
|
-
sleep(1)
|
410
|
-
rescue
|
411
|
-
|
412
|
-
end
|
413
|
-
|
414
|
-
# 두 번째 탭으로 전환
|
415
|
-
@driver.switch_to.window(@driver.window_handles[1])
|
467
|
+
|
416
468
|
|
417
469
|
begin
|
418
470
|
wait = Selenium::WebDriver::Wait.new(:timeout => 7)
|
@@ -518,6 +570,7 @@ class Naver
|
|
518
570
|
|
519
571
|
|
520
572
|
|
573
|
+
|
521
574
|
def update(title, content, option, url, keyword, captcha_api_key)#dd_time
|
522
575
|
puts 'start...'.yellow
|
523
576
|
puts(url)
|
@@ -540,20 +593,6 @@ class Naver
|
|
540
593
|
end
|
541
594
|
|
542
595
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
596
|
#@driver.manage.window.maximize
|
558
597
|
#창 크기 최대화
|
559
598
|
category2 = option['category'].to_s
|
@@ -578,12 +617,6 @@ class Naver
|
|
578
617
|
end
|
579
618
|
|
580
619
|
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
620
|
sleep(1)
|
588
621
|
|
589
622
|
begin
|
@@ -596,10 +629,6 @@ class Naver
|
|
596
629
|
puts e
|
597
630
|
end
|
598
631
|
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
632
|
|
604
633
|
|
605
634
|
sleep(1)
|
@@ -1239,29 +1268,7 @@ class Naver
|
|
1239
1268
|
wait.until { @driver.find_element(:xpath, '//*[@id="captchaContainer"]') }
|
1240
1269
|
puts '-[√] 로그인 중 캡챠 요구 발생 처리 진행.......'.yellow
|
1241
1270
|
sleep(1)
|
1242
|
-
@driver.switch_to.window(@driver.window_handles[0])
|
1243
|
-
sleep(1)
|
1244
|
-
@driver.find_element(:xpath, '//*[@name="apiKey"]').click
|
1245
|
-
sleep(0.5)
|
1246
|
-
@driver.find_element(:xpath, '//*[@name="apiKey"]').clear
|
1247
|
-
sleep(0.5)
|
1248
|
-
Clipboard.copy(captcha_api_key)
|
1249
|
-
sleep(0.5)
|
1250
|
-
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
1251
|
-
sleep(0.5)
|
1252
|
-
@driver.find_element(:xpath, '//*[@data-lang="login"]').click
|
1253
1271
|
|
1254
|
-
begin
|
1255
|
-
sleep(2)
|
1256
|
-
@driver.switch_to.alert.dismiss
|
1257
|
-
sleep(1)
|
1258
|
-
rescue
|
1259
|
-
|
1260
|
-
end
|
1261
|
-
|
1262
|
-
# 두 번째 탭으로 전환
|
1263
|
-
@driver.switch_to.window(@driver.window_handles[1])
|
1264
|
-
|
1265
1272
|
begin
|
1266
1273
|
wait = Selenium::WebDriver::Wait.new(:timeout => 7)
|
1267
1274
|
wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
|
@@ -1390,7 +1397,7 @@ class Naver
|
|
1390
1397
|
@driver.find_element(:xpath, '//*[@id="publish-btn"]').click #등록완료버튼
|
1391
1398
|
rescue
|
1392
1399
|
# 타임아웃을 100초로 설정
|
1393
|
-
wait = Selenium::WebDriver::Wait.new(:timeout =>
|
1400
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 120)
|
1394
1401
|
# 요소가 나타날 때까지 100초 동안 기다립니다.
|
1395
1402
|
wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
|
1396
1403
|
sleep(2)
|
@@ -1436,14 +1443,7 @@ class Naver
|
|
1436
1443
|
rescue
|
1437
1444
|
end
|
1438
1445
|
end
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1446
|
+
|
1447
1447
|
|
1448
1448
|
end
|
1449
1449
|
end
|
@@ -1475,38 +1475,7 @@ class Wordpress
|
|
1475
1475
|
end
|
1476
1476
|
end
|
1477
1477
|
|
1478
|
-
|
1479
|
-
# begin
|
1480
|
-
# Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
1481
|
-
# @driver = Selenium::WebDriver.for :chrome
|
1482
|
-
# rescue
|
1483
|
-
# @driver = Selenium::WebDriver.for :chrome
|
1484
|
-
# end
|
1485
|
-
# @driver.get('https://search.naver.com/search.naver?display=15&f=&filetype=0&page=3&query='+q.to_s+'&research_url=&sm=tab_pge&start=16&where=web')
|
1486
|
-
# noko = Nokogiri::HTML(@driver.page_source)
|
1487
|
-
# tt = noko.xpath('//*[@id="main_pack"]/section/div/ul').text
|
1488
|
-
# aa33 = '하였습니다,하였어요,하게됬어요,했답니다,했었는데요,하게되었어요,했어요,그랬답니다,그랬어요,합니다,그랬어요,그랬답니다,그랬답니다,그러합니다,좋아요,좋습니다,됬어요,되었어요,되었답니다,되었구요,되었어요,되네요,하네요,해요,할거예요,할수었이요,입니다,인데요,이예요,이랍니다,이였어요,그랬어요,그랬거든요,그랬습니다,었어요,었습니다,있었어요'.split(',')
|
1489
|
-
# for page in 3..8
|
1490
|
-
# @driver.get('https://www.google.com/search?q='+q.to_s+'&start='+(page*10).to_s)
|
1491
|
-
# noko = Nokogiri::HTML(@driver.page_source)
|
1492
|
-
# for n in 1..15
|
1493
|
-
# tt2 = noko.xpath('//*[@id="rso"]/div['+n.to_s+']/div/div/div[2]/div').text
|
1494
|
-
# if tt2.length < 5
|
1495
|
-
|
1496
|
-
# else
|
1497
|
-
# tt2 = tt2.split('...').join('')+aa3.sample
|
1498
|
-
# tt += tt2
|
1499
|
-
# end
|
1500
|
-
# end
|
1501
|
-
# end
|
1502
|
-
# @driver.close
|
1503
|
-
# tt = tt.split(' ').shuffle.join(' ')[0..1000]
|
1504
|
-
# m = Array.new
|
1505
|
-
# for n in 0..19
|
1506
|
-
# m << tt[(n*100)..(n*100+100)]
|
1507
|
-
# end
|
1508
|
-
# return m.join("\n")
|
1509
|
-
# end
|
1478
|
+
|
1510
1479
|
|
1511
1480
|
def get_naver_text(q)
|
1512
1481
|
begin
|
@@ -1598,21 +1567,81 @@ class Wordpress
|
|
1598
1567
|
|
1599
1568
|
|
1600
1569
|
|
1601
|
-
def auto_image
|
1570
|
+
def auto_image(keyword = nil)
|
1571
|
+
keyword ||= @keyword
|
1572
|
+
puts "키워드: #{keyword}"
|
1573
|
+
|
1574
|
+
client = HTTPClient.new
|
1575
|
+
client.default_header = {
|
1576
|
+
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
|
1577
|
+
'(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
1578
|
+
'Accept' => 'application/json, text/javascript, */*; q=0.01',
|
1579
|
+
'Accept-Language' => 'en-US,en;q=0.9',
|
1580
|
+
'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
|
1581
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
1582
|
+
}
|
1583
|
+
|
1584
|
+
retry_count = 0
|
1585
|
+
max_retries = 10
|
1586
|
+
results = []
|
1587
|
+
|
1602
1588
|
begin
|
1603
1589
|
page = rand(1..15)
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1590
|
+
url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
|
1591
|
+
puts "Request URL: #{url}"
|
1592
|
+
res = client.get(url)
|
1593
|
+
|
1594
|
+
unless res.status == 200
|
1595
|
+
puts "HTTP Error: #{res.status}"
|
1596
|
+
raise "HTTP Error"
|
1609
1597
|
end
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1598
|
+
|
1599
|
+
json = JSON.parse(res.body)
|
1600
|
+
results = json['results']
|
1601
|
+
mm = []
|
1602
|
+
|
1603
|
+
results.each do |photo|
|
1604
|
+
full_url = photo.dig('urls', 'full').to_s
|
1605
|
+
regular_url = photo.dig('urls', 'regular').to_s
|
1606
|
+
|
1607
|
+
if full_url.start_with?("https://images.unsplash.com/photo-") &&
|
1608
|
+
regular_url.include?("1080")
|
1609
|
+
mm << full_url
|
1610
|
+
end
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
if mm.empty?
|
1614
|
+
raise "No matching image"
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
selected_url = mm.sample
|
1618
|
+
Down.download(selected_url, destination: "./image/memory.png")
|
1619
|
+
puts "이미지 다운로드 완료: #{selected_url}"
|
1620
|
+
|
1621
|
+
rescue => e
|
1622
|
+
retry_count += 1
|
1623
|
+
puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
|
1624
|
+
sleep(3)
|
1625
|
+
if retry_count < max_retries
|
1615
1626
|
retry
|
1627
|
+
else
|
1628
|
+
puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
|
1629
|
+
|
1630
|
+
if results && !results.empty?
|
1631
|
+
random_photo = results.sample
|
1632
|
+
fallback_url = random_photo.dig('urls', 'full')
|
1633
|
+
if fallback_url
|
1634
|
+
Down.download(fallback_url, destination: "./image/memory.png")
|
1635
|
+
puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
|
1636
|
+
else
|
1637
|
+
puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
|
1638
|
+
color_image
|
1639
|
+
end
|
1640
|
+
else
|
1641
|
+
puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
|
1642
|
+
color_image
|
1643
|
+
end
|
1644
|
+
end
|
1616
1645
|
end
|
1617
1646
|
end
|
1618
1647
|
|
@@ -1624,35 +1653,52 @@ class Wordpress
|
|
1624
1653
|
|
1625
1654
|
def save_image
|
1626
1655
|
if @data['이미지설정']['이미지'].length == 0
|
1627
|
-
|
1656
|
+
return
|
1657
|
+
end
|
1658
|
+
|
1659
|
+
if @data['이미지설정']['순서사용'].checked?
|
1660
|
+
image_path = @data['이미지설정']['이미지'][@image_counter][2]
|
1661
|
+
@image_counter += 1
|
1662
|
+
if @image_counter > @data['이미지설정']['이미지'].length - 1
|
1663
|
+
@image_counter = 0
|
1664
|
+
end
|
1628
1665
|
else
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
@image_counter = 0
|
1634
|
-
end
|
1635
|
-
else
|
1636
|
-
image_path = @data['이미지설정']['이미지'].sample[2]
|
1666
|
+
# 초기화가 안됐거나 다 썼으면 새롭게 섞는다
|
1667
|
+
@shuffled_images ||= []
|
1668
|
+
if @shuffled_images.empty?
|
1669
|
+
@shuffled_images = @data['이미지설정']['이미지'].shuffle
|
1637
1670
|
end
|
1638
|
-
|
1639
|
-
|
1671
|
+
|
1672
|
+
image_path = @shuffled_images.shift[2]
|
1640
1673
|
end
|
1674
|
+
|
1675
|
+
img = Magick::Image.read(image_path).first
|
1676
|
+
img.write('./image/memory.png')
|
1641
1677
|
end
|
1642
1678
|
|
1643
1679
|
def change_image_size(w)
|
1644
1680
|
img = Magick::Image.read('./image/memory.png').first
|
1645
1681
|
width = img.columns
|
1646
1682
|
height = img.rows
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1683
|
+
|
1684
|
+
# '원본'이 선택된 경우, 리사이징을 하지 않고 원본 이미지를 그대로 반환
|
1685
|
+
if w == 'original'
|
1686
|
+
return img # 원본 이미지 그대로 반환
|
1687
|
+
else
|
1688
|
+
begin
|
1689
|
+
if @data['image_type'][0].checked? or @data['image_type'][2].checked?
|
1690
|
+
# 비율을 맞추어 리사이징
|
1691
|
+
img.resize!(w, w * (height.to_f / width.to_f))
|
1692
|
+
else
|
1693
|
+
# 정사각형으로 리사이징
|
1694
|
+
img.resize!(w, w)
|
1695
|
+
end
|
1696
|
+
rescue
|
1697
|
+
img.resize!(w, w) # 예외 처리 시에도 리사이징
|
1652
1698
|
end
|
1653
|
-
rescue
|
1654
|
-
img.resize!(w, w)
|
1655
1699
|
end
|
1700
|
+
|
1701
|
+
# 리사이징된 이미지 저장
|
1656
1702
|
img.write('./image/memory.png')
|
1657
1703
|
end
|
1658
1704
|
|
@@ -1724,22 +1770,28 @@ class Wordpress
|
|
1724
1770
|
auto_image()
|
1725
1771
|
end
|
1726
1772
|
|
1727
|
-
|
1773
|
+
# '원본'을 포함한 이미지 크기 옵션 추가
|
1774
|
+
image_size = [480, 740, 650, 550, 480, 'original']
|
1728
1775
|
size = 0
|
1729
|
-
|
1776
|
+
|
1777
|
+
for n in 0..5 # 0부터 5까지 반복, '원본' 옵션까지 포함
|
1730
1778
|
if @data['image_size'][n].checked?
|
1731
|
-
if n ==
|
1732
|
-
size =
|
1779
|
+
if n == 5 # '원본'이 선택되었을 경우
|
1780
|
+
size = 'original'
|
1781
|
+
elsif n == 0
|
1782
|
+
size = image_size.sample # 랜덤 선택
|
1733
1783
|
else
|
1734
1784
|
size = image_size[n]
|
1735
1785
|
end
|
1736
1786
|
end
|
1737
1787
|
end
|
1788
|
+
|
1789
|
+
# '원본'이 선택되지 않았다면 기본 값 설정
|
1738
1790
|
if size == 0
|
1739
1791
|
size = 480
|
1740
1792
|
end
|
1741
|
-
|
1742
|
-
change_image_size(size)
|
1793
|
+
|
1794
|
+
change_image_size(size) # 크기 변경 함수 호출
|
1743
1795
|
|
1744
1796
|
if @data['이미지설정']['필터사용'].checked?
|
1745
1797
|
image_filter()
|
@@ -2134,6 +2186,22 @@ class Wordpress
|
|
2134
2186
|
@data['table'].pop
|
2135
2187
|
#제목끝
|
2136
2188
|
# content = " #{content} "
|
2189
|
+
if @data['포스트설정']['gpt키워드'].checked?
|
2190
|
+
gpt_keyword_prompt = @data['포스트설정']['gpt키워드_프롬프트'].text.to_s.force_encoding('utf-8')
|
2191
|
+
gpt_keyword_prompt_sample = gpt_keyword_prompt.strip.empty? ? "프롬프트: 관련된 글을 1500자에서 2500자 사이로 만들어줘" : gpt_keyword_prompt
|
2192
|
+
chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt)
|
2193
|
+
gpt_text = chat.message(keyword)
|
2194
|
+
#content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
|
2195
|
+
content = content.to_s + "(자동생성글)" + gpt_text.to_s
|
2196
|
+
elsif @data['포스트설정']['내용을자동생성'].checked?
|
2197
|
+
content = auto_text
|
2198
|
+
elsif @data['포스트설정']['내용과자동생성'].checked?
|
2199
|
+
#content = content + "\n(자동생성글)\n" + auto_text
|
2200
|
+
content = content + "(자동생성글)" + auto_text
|
2201
|
+
end
|
2202
|
+
@data['table'][index][-1] = 45
|
2203
|
+
@data['table'] << []
|
2204
|
+
@data['table'].pop
|
2137
2205
|
|
2138
2206
|
if @data['포스트설정']['특정단어굵기'].checked?
|
2139
2207
|
content2 = ''
|
@@ -2173,7 +2241,7 @@ class Wordpress
|
|
2173
2241
|
content = content2
|
2174
2242
|
end
|
2175
2243
|
end
|
2176
|
-
@data['table'][index][-1] =
|
2244
|
+
@data['table'][index][-1] = 50
|
2177
2245
|
@data['table'] << []
|
2178
2246
|
@data['table'].pop
|
2179
2247
|
if @data['포스트설정']['단어크기변경'].checked?
|
@@ -2194,19 +2262,7 @@ class Wordpress
|
|
2194
2262
|
@data['table'][index][-1] = 50
|
2195
2263
|
@data['table'] << []
|
2196
2264
|
@data['table'].pop
|
2197
|
-
|
2198
|
-
gpt_keyword_prompt = @data['포스트설정']['gpt키워드_프롬프트'].text.to_s.force_encoding('utf-8')
|
2199
|
-
gpt_keyword_prompt_sample = gpt_keyword_prompt.strip.empty? ? "프롬프트: 관련된 글을 1500자에서 2500자 사이로 만들어줘" : gpt_keyword_prompt
|
2200
|
-
chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt)
|
2201
|
-
gpt_text = chat.message(keyword)
|
2202
|
-
#content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
|
2203
|
-
content = content.to_s + "(자동생성글)" + gpt_text.to_s
|
2204
|
-
elsif @data['포스트설정']['내용을자동생성'].checked?
|
2205
|
-
content = auto_text
|
2206
|
-
elsif @data['포스트설정']['내용과자동생성'].checked?
|
2207
|
-
#content = content + "\n(자동생성글)\n" + auto_text
|
2208
|
-
content = content + "(자동생성글)" + auto_text
|
2209
|
-
end
|
2265
|
+
|
2210
2266
|
|
2211
2267
|
if @data['포스트설정']['내용키워드삽입'].checked?
|
2212
2268
|
puts '내용키워드삽입...'
|
@@ -2388,7 +2444,6 @@ class Wordpress
|
|
2388
2444
|
|
2389
2445
|
if @data['포스트설정']['내용사진자동삽입'].checked?
|
2390
2446
|
puts '내용사진자동삽입...'
|
2391
|
-
|
2392
2447
|
sn = @data['포스트설정']['내용사진자동삽입시작숫자'].text.to_s.force_encoding('utf-8').to_i
|
2393
2448
|
en = @data['포스트설정']['내용사진자동삽입끝숫자'].text.to_s.force_encoding('utf-8').to_i
|
2394
2449
|
|
@@ -2400,54 +2455,71 @@ class Wordpress
|
|
2400
2455
|
end
|
2401
2456
|
|
2402
2457
|
if cn != 0
|
2403
|
-
#
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
2409
|
-
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
2413
|
-
missing_empty_lines = cn - empty_positions.length
|
2414
|
-
missing_empty_lines.times do
|
2415
|
-
content5 << "" # 텍스트 마지막에 빈 줄 추가
|
2458
|
+
# content5 구성 및 위치 배열 생성
|
2459
|
+
if @data['포스트설정']['내용과자동생성'].checked?
|
2460
|
+
if @data['포스트설정']['자동글 수식에 입력'].checked?
|
2461
|
+
content5 = content.split("(자동생성글)")[0].to_s.split("\n")
|
2462
|
+
content55 = content.split("(자동생성글)")[1].to_s
|
2463
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2464
|
+
else
|
2465
|
+
content5 = content.split("(자동생성글)")[0].to_s.split("\n")
|
2466
|
+
content55 = content.split("(자동생성글)")[1].to_s
|
2467
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2416
2468
|
end
|
2417
|
-
|
2469
|
+
elsif @data['포스트설정']['gpt키워드'].checked?
|
2470
|
+
content5 = content.split("(자동생성글)")[1].to_s.split("\n")
|
2471
|
+
content_prefix = content.split("(자동생성글)")[0].to_s
|
2472
|
+
content55 = ''
|
2473
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2474
|
+
else
|
2475
|
+
content5 = content.split("\n")
|
2476
|
+
content55 = ''
|
2477
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2418
2478
|
end
|
2419
2479
|
|
2420
|
-
#
|
2421
|
-
|
2480
|
+
# 중복 필터링 로직
|
2481
|
+
while true
|
2482
|
+
check11 = 0
|
2483
|
+
position.each_with_index do |pos, idx|
|
2484
|
+
if content5[pos].to_s.include?('style') || content5[pos].to_s.include?('<') || content5[pos].to_s.include?('>')
|
2485
|
+
check11 = 1
|
2486
|
+
position[idx] += 4
|
2487
|
+
end
|
2488
|
+
end
|
2489
|
+
break if check11 == 0
|
2490
|
+
end
|
2422
2491
|
|
2423
|
-
# 이미지 URL 가져오기
|
2424
2492
|
if @data['포스트설정']['내용과자동생성'].checked? || @data['포스트설정']['gpt키워드'].checked?
|
2425
|
-
|
2493
|
+
sleep(2)
|
2494
|
+
puts '이미지 자동 세탁 중 · · · '
|
2426
2495
|
end
|
2427
|
-
|
2428
|
-
|
2496
|
+
|
2497
|
+
p content5
|
2498
|
+
puts content55
|
2499
|
+
p position
|
2500
|
+
|
2501
|
+
sleep(2)
|
2429
2502
|
position.each do |i|
|
2430
|
-
|
2431
|
-
puts '사진넣는위치 => ' + i.to_s
|
2432
|
-
|
2433
|
-
# 링크가 있을 경우 링크 포함
|
2503
|
+
image_url22 = get_image_file().force_encoding('utf-8')
|
2434
2504
|
if @data['포스트설정']['내용사진링크'].checked?
|
2435
|
-
|
2436
|
-
|
2505
|
+
image_tag = '<a href="' + @data['포스트설정']['내용사진링크값'].text.to_s.force_encoding('utf-8') +
|
2506
|
+
'"><img src="' + image_url22 + '" alt="' + keyword.force_encoding('utf-8') + '" class="aligncenter size-full"></a>'
|
2437
2507
|
else
|
2438
|
-
|
2439
|
-
content5[i] = '**image**' # 빈 줄에 이미지를 삽입
|
2508
|
+
image_tag = '<img src="' + image_url22 + '" alt="' + keyword + '" class="aligncenter size-full">'
|
2440
2509
|
end
|
2510
|
+
content5.insert(i, image_tag)
|
2441
2511
|
end
|
2442
2512
|
|
2443
|
-
|
2444
|
-
|
2513
|
+
sleep(2)
|
2514
|
+
puts '이미지 자동 세탁 완료 · · · '
|
2515
|
+
|
2516
|
+
if @data['포스트설정']['내용과자동생성'].checked?
|
2445
2517
|
content = content5.join("\n") + '(자동생성글)' + content55
|
2518
|
+
elsif @data['포스트설정']['gpt키워드'].checked?
|
2519
|
+
content = content_prefix + "(자동생성글)" + content5.join("\n")
|
2446
2520
|
else
|
2447
2521
|
content = content5.join("\n")
|
2448
2522
|
end
|
2449
|
-
|
2450
|
-
puts content
|
2451
2523
|
end
|
2452
2524
|
end
|
2453
2525
|
|
@@ -2459,12 +2531,22 @@ class Wordpress
|
|
2459
2531
|
content = content_memory[0]
|
2460
2532
|
content_end = content_memory[1].to_s
|
2461
2533
|
|
2534
|
+
if @data['포스트설정']['gpt키워드'].checked?
|
2535
|
+
if @data['포스트설정']['gpt상단'].checked?
|
2536
|
+
content = "(자동생성글)\n" + content_end + "\n" + content
|
2537
|
+
else
|
2538
|
+
content = content + "\n(자동생성글)\n" + content_end
|
2539
|
+
end
|
2540
|
+
else
|
2541
|
+
content = content + "\n(자동생성글)\n" + content_end
|
2542
|
+
end
|
2543
|
+
|
2462
2544
|
if @data['포스트설정']['특정단어키워드로변경'].checked?
|
2463
2545
|
@data['포스트설정']['특정단어키워드로변경값'].text.to_s.force_encoding('utf-8').split(',').each do |i|
|
2464
2546
|
content = content.split(i.force_encoding('utf-8')).join(keyword)
|
2465
2547
|
end
|
2466
2548
|
end
|
2467
|
-
|
2549
|
+
|
2468
2550
|
@data['table'][index][-1] = 75
|
2469
2551
|
@data['table'] << []
|
2470
2552
|
@data['table'].pop
|
@@ -2580,11 +2662,76 @@ class Wordpress
|
|
2580
2662
|
# end
|
2581
2663
|
#end
|
2582
2664
|
|
2583
|
-
|
2584
|
-
@data['포스트설정']['
|
2585
|
-
|
2665
|
+
if @data['포스트설정']['지도로변경'].checked?
|
2666
|
+
map_address = @data['포스트설정']['지도주소'].text.to_s.force_encoding('utf-8')
|
2667
|
+
change_words = @data['포스트설정']['지도로변경단어'].text.to_s.force_encoding('utf-8').split(',')
|
2668
|
+
|
2669
|
+
content_lines = content.split("\n")
|
2670
|
+
new_lines = []
|
2671
|
+
|
2672
|
+
content_lines.each do |line|
|
2673
|
+
# 이미 처리된 줄은 건너뜀
|
2674
|
+
if line.include?("<koreamap>")
|
2675
|
+
new_lines << line
|
2676
|
+
next
|
2677
|
+
end
|
2678
|
+
|
2679
|
+
processed = false
|
2680
|
+
|
2681
|
+
change_words.each do |change_word|
|
2682
|
+
# 1. [단어][주소] 패턴 처리: 분리 + 출력
|
2683
|
+
if line =~ /#{Regexp.escape(change_word)}\[(.*?)\]/
|
2684
|
+
match_data = line.match(/(.*)#{Regexp.escape(change_word)}\[(.*?)\](.*)/)
|
2685
|
+
if match_data
|
2686
|
+
before = match_data[1]
|
2687
|
+
address = match_data[2]
|
2688
|
+
after = match_data[3]
|
2689
|
+
|
2690
|
+
# 태그 추출
|
2691
|
+
open_tag = before[/<p[^>]*?>/i] || ""
|
2692
|
+
close_tag = after[/<\/p>/i] || ""
|
2693
|
+
|
2694
|
+
# 텍스트 정리
|
2695
|
+
before_text = before.sub(open_tag, '')
|
2696
|
+
after_text = after.sub(close_tag, '')
|
2697
|
+
|
2698
|
+
# 줄 분리
|
2699
|
+
new_lines << "#{open_tag}#{before_text}</p>" unless before_text.strip.empty?
|
2700
|
+
new_lines << "<koreamap>#{address}</koreamap>"
|
2701
|
+
new_lines << "#{open_tag}#{after_text}#{close_tag}" unless after_text.strip.empty?
|
2702
|
+
|
2703
|
+
processed = true
|
2704
|
+
break
|
2705
|
+
end
|
2706
|
+
end
|
2707
|
+
|
2708
|
+
# 2. 일반 단어 처리 (한 줄에만 등장하는 경우)
|
2709
|
+
if !processed && line.include?(change_word)
|
2710
|
+
parts = line.split(change_word, 2)
|
2711
|
+
prefix = parts[0]
|
2712
|
+
suffix = parts[1]
|
2713
|
+
|
2714
|
+
open_tag = prefix[/<p[^>]*?>/i] || ""
|
2715
|
+
close_tag = suffix[/<\/p>/i] || ""
|
2716
|
+
|
2717
|
+
prefix_text = prefix.sub(open_tag, '')
|
2718
|
+
suffix_text = suffix.sub(close_tag, '')
|
2719
|
+
|
2720
|
+
new_lines << "#{open_tag}#{prefix_text}</p>" unless prefix_text.strip.empty?
|
2721
|
+
new_lines << "<koreamap>#{map_address}</koreamap>"
|
2722
|
+
new_lines << "#{open_tag}#{suffix_text}#{close_tag}" unless suffix_text.strip.empty?
|
2723
|
+
|
2724
|
+
processed = true
|
2725
|
+
break
|
2726
|
+
end
|
2727
|
+
end
|
2728
|
+
|
2729
|
+
# 변경이 없었으면 원래 줄 추가
|
2730
|
+
new_lines << line unless processed
|
2586
2731
|
end
|
2587
|
-
|
2732
|
+
|
2733
|
+
content = new_lines.join("\n")
|
2734
|
+
end
|
2588
2735
|
|
2589
2736
|
|
2590
2737
|
|
@@ -2598,15 +2745,18 @@ class Wordpress
|
|
2598
2745
|
# content = content
|
2599
2746
|
# soosick_1 = content_end
|
2600
2747
|
#else
|
2601
|
-
|
2602
|
-
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2748
|
+
parts = content.split('(자동생성글)', 2)
|
2749
|
+
content_main = parts[0].strip
|
2750
|
+
content_end = parts[1].to_s.strip
|
2751
|
+
|
2752
|
+
if @data['포스트설정']['gpt키워드'].checked?
|
2753
|
+
if @data['포스트설정']['gpt상단'].checked?
|
2754
|
+
content = content_end + "\n" + content_main + "\n"
|
2607
2755
|
else
|
2608
|
-
|
2609
|
-
|
2756
|
+
content = content_main + "\n" + content_end + "\n"
|
2757
|
+
end
|
2758
|
+
else
|
2759
|
+
content = content_main + "\n" + content_end + "\n"
|
2610
2760
|
end
|
2611
2761
|
|
2612
2762
|
|
@@ -3889,6 +4039,7 @@ class Wordpress
|
|
3889
4039
|
@data['image_size'][2].checked = false
|
3890
4040
|
@data['image_size'][3].checked = false
|
3891
4041
|
@data['image_size'][4].checked = false
|
4042
|
+
@data['image_size'][5].checked = false
|
3892
4043
|
end
|
3893
4044
|
}
|
3894
4045
|
}
|
@@ -3899,6 +4050,7 @@ class Wordpress
|
|
3899
4050
|
@data['image_size'][2].checked = false
|
3900
4051
|
@data['image_size'][3].checked = false
|
3901
4052
|
@data['image_size'][4].checked = false
|
4053
|
+
@data['image_size'][5].checked = false
|
3902
4054
|
end
|
3903
4055
|
}
|
3904
4056
|
}
|
@@ -3909,6 +4061,7 @@ class Wordpress
|
|
3909
4061
|
@data['image_size'][0].checked = false
|
3910
4062
|
@data['image_size'][3].checked = false
|
3911
4063
|
@data['image_size'][4].checked = false
|
4064
|
+
@data['image_size'][5].checked = false
|
3912
4065
|
end
|
3913
4066
|
}
|
3914
4067
|
}
|
@@ -3919,6 +4072,7 @@ class Wordpress
|
|
3919
4072
|
@data['image_size'][2].checked = false
|
3920
4073
|
@data['image_size'][0].checked = false
|
3921
4074
|
@data['image_size'][4].checked = false
|
4075
|
+
@data['image_size'][5].checked = false
|
3922
4076
|
end
|
3923
4077
|
}
|
3924
4078
|
}
|
@@ -3929,6 +4083,18 @@ class Wordpress
|
|
3929
4083
|
@data['image_size'][2].checked = false
|
3930
4084
|
@data['image_size'][3].checked = false
|
3931
4085
|
@data['image_size'][0].checked = false
|
4086
|
+
@data['image_size'][5].checked = false
|
4087
|
+
end
|
4088
|
+
}
|
4089
|
+
}
|
4090
|
+
@data['image_size'][5] = checkbox('원본 px'){
|
4091
|
+
on_toggled{
|
4092
|
+
if @data['image_size'][5].checked?
|
4093
|
+
@data['image_size'][1].checked = false
|
4094
|
+
@data['image_size'][2].checked = false
|
4095
|
+
@data['image_size'][3].checked = false
|
4096
|
+
@data['image_size'][0].checked = false
|
4097
|
+
@data['image_size'][4].checked = false
|
3932
4098
|
end
|
3933
4099
|
}
|
3934
4100
|
}
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tblog_zon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.50
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zon
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-05-23 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: File to Clipboard gem
|
14
13
|
email: mymin26@naver.com
|
@@ -21,7 +20,6 @@ homepage: ''
|
|
21
20
|
licenses:
|
22
21
|
- zon
|
23
22
|
metadata: {}
|
24
|
-
post_install_message:
|
25
23
|
rdoc_options: []
|
26
24
|
require_paths:
|
27
25
|
- lib
|
@@ -36,8 +34,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
36
34
|
- !ruby/object:Gem::Version
|
37
35
|
version: '0'
|
38
36
|
requirements: []
|
39
|
-
rubygems_version: 3.
|
40
|
-
signing_key:
|
37
|
+
rubygems_version: 3.6.7
|
41
38
|
specification_version: 4
|
42
39
|
summary: file to clipboard
|
43
40
|
test_files: []
|