tblog_duopack 0.0.37 → 0.0.39
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_duopack.rb +389 -253
- 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: 44cd103f7388e3c3b8d273b70b1e8e922d9c943f75c15b954f3c6b51bf9cae98
|
4
|
+
data.tar.gz: 96fe769e09a7a8dfd5654c4d12d9eede886dd61a1187ab149a9088a1d7257ac9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 005f2424612bab332af9179a7e25a49c7795ad52e2e4ab1a3b3da0d0599b4db504b7fe66e4be823a8f2bd8baf3397cfce4468d6a41dfaf531e4cabf502df83bf
|
7
|
+
data.tar.gz: 2201f3fdcfc633f45fddabee86f78d80ea6299c5acaba2eb0b65b88fe85180e68114e3ffee8047757bd39d8a7e0ff3c3fe9bb18e82f71ea5c52a530de95293f7
|
data/lib/tblog_duopack.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,7 +13,6 @@ 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'
|
20
18
|
include AutoClickMethods
|
@@ -248,115 +246,186 @@ class Naver
|
|
248
246
|
end
|
249
247
|
|
250
248
|
def chrome_start(proxy)
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
249
|
+
# 공통 옵션 설정
|
250
|
+
begin
|
251
|
+
Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
252
|
+
rescue => e
|
253
|
+
puts "chromedriver 버전 불일치!!"
|
254
|
+
puts "아래 지침을 따라주세요."
|
255
|
+
puts "1.프로그램 종료!"
|
256
|
+
puts "2.크롬 업데이트!"
|
257
|
+
puts "3.프로그램 폴더 내부에 ★tip★-시작시-크롬창이....파일 실행"
|
258
|
+
puts "4.안내된 방식으로 크롬 드라이버 교체"
|
259
|
+
puts "5.재 시작"
|
260
|
+
exit 1
|
261
|
+
end
|
262
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
263
|
+
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
264
|
+
options.add_extension('./crx/app.crx') # 확장 프로그램을 첫 번째 탭에 추가
|
265
|
+
options.add_argument('--disable-blink-features=AutomationControlled')
|
266
|
+
options.add_argument('--disable-popup-blocking')
|
267
|
+
options.add_argument('--dns-prefetch-disable')
|
268
|
+
options.add_argument('--disable-dev-shm-usage')
|
269
|
+
options.add_argument('--disable-software-rasterizer')
|
270
|
+
options.add_argument('--ignore-certificate-errors')
|
271
|
+
options.add_argument('--disable-gpu') # GPU 가속 끄기
|
272
|
+
options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36') # user-agent 위조
|
273
|
+
options.add_argument('--disable-web-security')
|
274
|
+
options.add_argument('--allow-running-insecure-content')
|
275
|
+
options.add_argument('--allow-insecure-localhost')
|
276
|
+
options.add_argument('--no-sandbox')
|
277
|
+
options.add_argument('--disable-translate')
|
278
|
+
options.add_argument('--disable-extensions-file-access-check')
|
279
|
+
options.add_argument('--disable-impl-side-painting')
|
280
|
+
options.add_argument('--log-level=3')
|
281
|
+
# 자동화된 테스트 제거
|
282
|
+
options.exclude_switches = ['enable-automation']
|
271
283
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
options.add_preference("profile.default_content_setting_values.notifications", 2) # 알림 차단
|
279
|
-
options.add_argument("--disable-save-password-bubble") # 비밀번호 저장 팝업 차단
|
284
|
+
options.add_preference("profile.password_manager_enabled", false) # 비밀번호 관리자 비활성화
|
285
|
+
options.add_preference("credentials_enable_service", false) # 비밀번호 저장 기능 비활성화
|
286
|
+
#options.add_preference("profile.managed_default_content_settings.cookies", 2) # 쿠키 관련 팝업 차단
|
287
|
+
options.add_preference("profile.default_content_setting_values.notifications", 2) # 알림 차단
|
288
|
+
options.add_argument("--disable-save-password-bubble") # 비밀번호 저장 팝업 차단
|
289
|
+
|
280
290
|
|
291
|
+
# Proxy 설정
|
292
|
+
if proxy != ''
|
293
|
+
options.add_argument('--proxy-server=' + proxy.to_s.force_encoding('utf-8'))
|
294
|
+
end
|
295
|
+
|
296
|
+
# 브라우저 실행
|
297
|
+
begin
|
298
|
+
# 'capabilities'과 'options' 배열로 설정
|
299
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
|
300
|
+
capabilities["goog:chromeOptions"] = options.as_json
|
281
301
|
|
282
|
-
|
283
|
-
|
284
|
-
options.add_argument('--proxy-server=' + proxy.to_s.force_encoding('utf-8'))
|
285
|
-
end
|
302
|
+
# Selenium 4에서는 'capabilities'만 사용하는 방식
|
303
|
+
@driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
|
286
304
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
305
|
+
@driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
|
306
|
+
|
307
|
+
sleep(1)
|
308
|
+
# 두 번째 탭에서 로그인 페이지 열기
|
309
|
+
@driver.get('https://www.tistory.com/auth/login')
|
310
|
+
sleep(1)
|
292
311
|
|
293
|
-
|
294
|
-
|
312
|
+
# 현재 탭 핸들 저장
|
313
|
+
main_tab = @driver.window_handle
|
295
314
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
# 두 번째 탭에서 로그인 페이지 열기
|
300
|
-
@driver.get('https://www.tistory.com/auth/login')
|
301
|
-
sleep(1)
|
302
|
-
|
303
|
-
rescue => e
|
304
|
-
|
305
|
-
puts "Error: #{e.message}"
|
306
|
-
puts 'Using default Chrome driver without proxy'
|
307
|
-
# 'capabilities'과 'options' 배열로 설정
|
308
|
-
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
|
309
|
-
capabilities["goog:chromeOptions"] = options.as_json
|
315
|
+
# 모든 탭 순회
|
316
|
+
@driver.window_handles.each do |handle|
|
317
|
+
next if handle == main_tab # 현재 탭은 남긴다
|
310
318
|
|
311
|
-
|
312
|
-
|
319
|
+
@driver.switch_to.window(handle)
|
320
|
+
@driver.close # 다른 탭 닫기
|
321
|
+
end
|
313
322
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
def login(user_id, user_pw, proxy, captcha_api_key)
|
326
|
-
chrome_start(proxy)
|
327
|
-
@captcha_api_key = captcha_api_key
|
328
|
-
@user_id = user_id
|
323
|
+
# 다시 로그인 탭으로 전환
|
324
|
+
@driver.switch_to.window(main_tab)
|
325
|
+
sleep(1)
|
326
|
+
rescue => e
|
327
|
+
|
328
|
+
puts "Error: #{e.message}"
|
329
|
+
puts 'Using default Chrome driver without proxy'
|
330
|
+
# 'capabilities'과 'options' 배열로 설정
|
331
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
|
332
|
+
capabilities["goog:chromeOptions"] = options.as_json
|
329
333
|
|
330
|
-
|
331
|
-
|
332
|
-
Dir.entries('./cookie').each do |i|
|
333
|
-
if i != '.' && i != '..'
|
334
|
-
user_cookie_file << i
|
335
|
-
end
|
336
|
-
end
|
337
|
-
rescue
|
338
|
-
end
|
334
|
+
# Selenium 4에서는 'capabilities'만 사용하는 방식
|
335
|
+
@driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
|
339
336
|
|
340
|
-
|
341
|
-
if user_cookie_file.include?(user_id+'.txt')
|
342
|
-
f = File.open('./cookie/'+user_id+'.txt', 'r')
|
343
|
-
@cookie4 = JSON.parse(f.read)
|
344
|
-
f.close
|
345
|
-
end
|
337
|
+
@driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
|
346
338
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
339
|
+
# 첫 번째 탭에서 확장 프로그램을 로드
|
340
|
+
#@driver.get("chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html")
|
341
|
+
sleep(1)
|
342
|
+
# 두 번째 탭에서 로그인 페이지 열기
|
343
|
+
@driver.get('https://www.tistory.com/auth/login')
|
344
|
+
sleep(1)
|
345
|
+
|
346
|
+
# 현재 탭 핸들 저장
|
347
|
+
main_tab = @driver.window_handle
|
348
|
+
|
349
|
+
# 모든 탭 순회
|
350
|
+
@driver.window_handles.each do |handle|
|
351
|
+
next if handle == main_tab # 현재 탭은 남긴다
|
352
|
+
|
353
|
+
@driver.switch_to.window(handle)
|
354
|
+
@driver.close # 다른 탭 닫기
|
355
|
+
end
|
356
|
+
|
357
|
+
# 다시 로그인 탭으로 전환
|
358
|
+
@driver.switch_to.window(main_tab)
|
359
|
+
sleep(1)
|
351
360
|
end
|
352
|
-
rescue
|
353
361
|
end
|
354
362
|
|
355
|
-
|
356
|
-
|
357
|
-
|
363
|
+
def login(user_id, user_pw, proxy, captcha_api_key)
|
364
|
+
chrome_start(proxy)
|
365
|
+
@captcha_api_key = captcha_api_key
|
366
|
+
@user_id = user_id
|
358
367
|
|
368
|
+
if captcha_api_key != 'captcha_api_key 입력' && !captcha_api_key.to_s.strip.empty?
|
369
|
+
puts "캡처 키 확인 됨: '#{captcha_api_key}'".red
|
370
|
+
@driver.switch_to.new_window(:tab)
|
371
|
+
sleep(1.5)
|
372
|
+
@driver.switch_to.window(@driver.window_handles[1])
|
373
|
+
@driver.navigate.to("chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html")
|
374
|
+
sleep(3)
|
375
|
+
@driver.find_element(:xpath, '//*[@name="apiKey"]').click
|
376
|
+
Clipboard.copy(captcha_api_key)
|
377
|
+
sleep(0.5)
|
378
|
+
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
379
|
+
sleep(0.5)
|
380
|
+
@driver.find_element(:xpath, '//*[@data-lang="login"]').click
|
381
|
+
|
382
|
+
begin
|
383
|
+
sleep(2)
|
384
|
+
@driver.switch_to.alert.dismiss
|
385
|
+
sleep(1)
|
386
|
+
rescue
|
387
|
+
end
|
388
|
+
@driver.close
|
389
|
+
sleep(1)
|
390
|
+
@driver.switch_to.window(@driver.window_handles[0])
|
391
|
+
sleep(2)
|
392
|
+
else
|
393
|
+
end
|
394
|
+
|
395
|
+
user_cookie_file = []
|
396
|
+
begin
|
397
|
+
Dir.entries('./cookie').each do |i|
|
398
|
+
if i != '.' && i != '..'
|
399
|
+
user_cookie_file << i
|
400
|
+
end
|
401
|
+
end
|
402
|
+
rescue
|
403
|
+
end
|
404
|
+
|
405
|
+
@cookie4 = {}
|
406
|
+
if user_cookie_file.include?(user_id+'.txt')
|
407
|
+
f = File.open('./cookie/'+user_id+'.txt', 'r')
|
408
|
+
@cookie4 = JSON.parse(f.read)
|
409
|
+
f.close
|
410
|
+
end
|
411
|
+
|
412
|
+
|
413
|
+
|
414
|
+
# 기존 쿠키가 있으면 쿠키를 추가
|
415
|
+
begin
|
416
|
+
@cookie4.each do |i|
|
417
|
+
@driver.manage.add_cookie(name: i['name'], value: i['value'], same_site: i['same_site'], domain: i['domain'], path: i['path'])
|
418
|
+
end
|
419
|
+
rescue
|
420
|
+
end
|
421
|
+
|
422
|
+
|
423
|
+
sleep(1.5)
|
424
|
+
@driver.get('https://www.tistory.com/auth/login')
|
359
425
|
sleep(1)
|
426
|
+
@driver.switch_to.window(@driver.window_handles[0])
|
427
|
+
|
428
|
+
|
360
429
|
begin
|
361
430
|
wait = Selenium::WebDriver::Wait.new(:timeout => 3)
|
362
431
|
wait.until { @driver.find_element(:xpath, '//*[@id="cMain"]/div/div/div/div/a[2]/span[2]') }
|
@@ -394,25 +463,7 @@ class Naver
|
|
394
463
|
wait.until { @driver.find_element(:xpath, '//*[@id="captchaContainer"]') }
|
395
464
|
puts '-[√] 로그인 중 캡챠 요구 발생 처리 진행.......'.yellow
|
396
465
|
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])
|
466
|
+
|
416
467
|
|
417
468
|
begin
|
418
469
|
wait = Selenium::WebDriver::Wait.new(:timeout => 7)
|
@@ -518,6 +569,7 @@ class Naver
|
|
518
569
|
|
519
570
|
|
520
571
|
|
572
|
+
|
521
573
|
def update(title, content, option, url, keyword, captcha_api_key)#dd_time
|
522
574
|
puts 'start...'.yellow
|
523
575
|
puts(url)
|
@@ -540,20 +592,6 @@ class Naver
|
|
540
592
|
end
|
541
593
|
|
542
594
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
595
|
#@driver.manage.window.maximize
|
558
596
|
#창 크기 최대화
|
559
597
|
category2 = option['category'].to_s
|
@@ -578,12 +616,6 @@ class Naver
|
|
578
616
|
end
|
579
617
|
|
580
618
|
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
619
|
sleep(1)
|
588
620
|
|
589
621
|
begin
|
@@ -596,10 +628,6 @@ class Naver
|
|
596
628
|
puts e
|
597
629
|
end
|
598
630
|
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
631
|
|
604
632
|
|
605
633
|
sleep(1)
|
@@ -1239,29 +1267,7 @@ class Naver
|
|
1239
1267
|
wait.until { @driver.find_element(:xpath, '//*[@id="captchaContainer"]') }
|
1240
1268
|
puts '-[√] 로그인 중 캡챠 요구 발생 처리 진행.......'.yellow
|
1241
1269
|
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
1270
|
|
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
1271
|
begin
|
1266
1272
|
wait = Selenium::WebDriver::Wait.new(:timeout => 7)
|
1267
1273
|
wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
|
@@ -1390,7 +1396,7 @@ class Naver
|
|
1390
1396
|
@driver.find_element(:xpath, '//*[@id="publish-btn"]').click #등록완료버튼
|
1391
1397
|
rescue
|
1392
1398
|
# 타임아웃을 100초로 설정
|
1393
|
-
wait = Selenium::WebDriver::Wait.new(:timeout =>
|
1399
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 120)
|
1394
1400
|
# 요소가 나타날 때까지 100초 동안 기다립니다.
|
1395
1401
|
wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
|
1396
1402
|
sleep(2)
|
@@ -1436,14 +1442,7 @@ class Naver
|
|
1436
1442
|
rescue
|
1437
1443
|
end
|
1438
1444
|
end
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1445
|
+
|
1447
1446
|
|
1448
1447
|
end
|
1449
1448
|
end
|
@@ -1663,35 +1662,52 @@ class Wordpress
|
|
1663
1662
|
|
1664
1663
|
def save_image
|
1665
1664
|
if @data['이미지설정']['이미지'].length == 0
|
1666
|
-
|
1665
|
+
return
|
1666
|
+
end
|
1667
|
+
|
1668
|
+
if @data['이미지설정']['순서사용'].checked?
|
1669
|
+
image_path = @data['이미지설정']['이미지'][@image_counter][2]
|
1670
|
+
@image_counter += 1
|
1671
|
+
if @image_counter > @data['이미지설정']['이미지'].length - 1
|
1672
|
+
@image_counter = 0
|
1673
|
+
end
|
1667
1674
|
else
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
@image_counter = 0
|
1673
|
-
end
|
1674
|
-
else
|
1675
|
-
image_path = @data['이미지설정']['이미지'].sample[2]
|
1675
|
+
# 초기화가 안됐거나 다 썼으면 새롭게 섞는다
|
1676
|
+
@shuffled_images ||= []
|
1677
|
+
if @shuffled_images.empty?
|
1678
|
+
@shuffled_images = @data['이미지설정']['이미지'].shuffle
|
1676
1679
|
end
|
1677
|
-
|
1678
|
-
|
1680
|
+
|
1681
|
+
image_path = @shuffled_images.shift[2]
|
1679
1682
|
end
|
1683
|
+
|
1684
|
+
img = Magick::Image.read(image_path).first
|
1685
|
+
img.write('./image/memory.png')
|
1680
1686
|
end
|
1681
1687
|
|
1682
1688
|
def change_image_size(w)
|
1683
1689
|
img = Magick::Image.read('./image/memory.png').first
|
1684
1690
|
width = img.columns
|
1685
1691
|
height = img.rows
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1692
|
+
|
1693
|
+
# '원본'이 선택된 경우, 리사이징을 하지 않고 원본 이미지를 그대로 반환
|
1694
|
+
if w == 'original'
|
1695
|
+
return img # 원본 이미지 그대로 반환
|
1696
|
+
else
|
1697
|
+
begin
|
1698
|
+
if @data['image_type'][0].checked? or @data['image_type'][2].checked?
|
1699
|
+
# 비율을 맞추어 리사이징
|
1700
|
+
img.resize!(w, w * (height.to_f / width.to_f))
|
1701
|
+
else
|
1702
|
+
# 정사각형으로 리사이징
|
1703
|
+
img.resize!(w, w)
|
1704
|
+
end
|
1705
|
+
rescue
|
1706
|
+
img.resize!(w, w) # 예외 처리 시에도 리사이징
|
1691
1707
|
end
|
1692
|
-
rescue
|
1693
|
-
img.resize!(w, w)
|
1694
1708
|
end
|
1709
|
+
|
1710
|
+
# 리사이징된 이미지 저장
|
1695
1711
|
img.write('./image/memory.png')
|
1696
1712
|
end
|
1697
1713
|
|
@@ -1763,22 +1779,28 @@ class Wordpress
|
|
1763
1779
|
auto_image()
|
1764
1780
|
end
|
1765
1781
|
|
1766
|
-
|
1782
|
+
# '원본'을 포함한 이미지 크기 옵션 추가
|
1783
|
+
image_size = [480, 740, 650, 550, 480, 'original']
|
1767
1784
|
size = 0
|
1768
|
-
|
1785
|
+
|
1786
|
+
for n in 0..5 # 0부터 5까지 반복, '원본' 옵션까지 포함
|
1769
1787
|
if @data['image_size'][n].checked?
|
1770
|
-
if n ==
|
1771
|
-
size =
|
1788
|
+
if n == 5 # '원본'이 선택되었을 경우
|
1789
|
+
size = 'original'
|
1790
|
+
elsif n == 0
|
1791
|
+
size = image_size.sample # 랜덤 선택
|
1772
1792
|
else
|
1773
1793
|
size = image_size[n]
|
1774
1794
|
end
|
1775
1795
|
end
|
1776
1796
|
end
|
1797
|
+
|
1798
|
+
# '원본'이 선택되지 않았다면 기본 값 설정
|
1777
1799
|
if size == 0
|
1778
1800
|
size = 480
|
1779
1801
|
end
|
1780
|
-
|
1781
|
-
change_image_size(size)
|
1802
|
+
|
1803
|
+
change_image_size(size) # 크기 변경 함수 호출
|
1782
1804
|
|
1783
1805
|
if @data['이미지설정']['필터사용'].checked?
|
1784
1806
|
image_filter()
|
@@ -2173,6 +2195,22 @@ class Wordpress
|
|
2173
2195
|
@data['table'].pop
|
2174
2196
|
#제목끝
|
2175
2197
|
# content = " #{content} "
|
2198
|
+
if @data['포스트설정']['gpt키워드'].checked?
|
2199
|
+
gpt_keyword_prompt = @data['포스트설정']['gpt키워드_프롬프트'].text.to_s.force_encoding('utf-8')
|
2200
|
+
gpt_keyword_prompt_sample = gpt_keyword_prompt.strip.empty? ? "프롬프트: 관련된 글을 1500자에서 2500자 사이로 만들어줘" : gpt_keyword_prompt
|
2201
|
+
chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt)
|
2202
|
+
gpt_text = chat.message(keyword)
|
2203
|
+
#content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
|
2204
|
+
content = content.to_s + "(자동생성글)" + gpt_text.to_s
|
2205
|
+
elsif @data['포스트설정']['내용을자동생성'].checked?
|
2206
|
+
content = auto_text
|
2207
|
+
elsif @data['포스트설정']['내용과자동생성'].checked?
|
2208
|
+
#content = content + "\n(자동생성글)\n" + auto_text
|
2209
|
+
content = content + "(자동생성글)" + auto_text
|
2210
|
+
end
|
2211
|
+
@data['table'][index][-1] = 45
|
2212
|
+
@data['table'] << []
|
2213
|
+
@data['table'].pop
|
2176
2214
|
|
2177
2215
|
if @data['포스트설정']['특정단어굵기'].checked?
|
2178
2216
|
content2 = ''
|
@@ -2212,7 +2250,7 @@ class Wordpress
|
|
2212
2250
|
content = content2
|
2213
2251
|
end
|
2214
2252
|
end
|
2215
|
-
@data['table'][index][-1] =
|
2253
|
+
@data['table'][index][-1] = 50
|
2216
2254
|
@data['table'] << []
|
2217
2255
|
@data['table'].pop
|
2218
2256
|
if @data['포스트설정']['단어크기변경'].checked?
|
@@ -2233,19 +2271,7 @@ class Wordpress
|
|
2233
2271
|
@data['table'][index][-1] = 50
|
2234
2272
|
@data['table'] << []
|
2235
2273
|
@data['table'].pop
|
2236
|
-
|
2237
|
-
gpt_keyword_prompt = @data['포스트설정']['gpt키워드_프롬프트'].text.to_s.force_encoding('utf-8')
|
2238
|
-
gpt_keyword_prompt_sample = gpt_keyword_prompt.strip.empty? ? "프롬프트: 관련된 글을 1500자에서 2500자 사이로 만들어줘" : gpt_keyword_prompt
|
2239
|
-
chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt)
|
2240
|
-
gpt_text = chat.message(keyword)
|
2241
|
-
#content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
|
2242
|
-
content = content.to_s + "(자동생성글)" + gpt_text.to_s
|
2243
|
-
elsif @data['포스트설정']['내용을자동생성'].checked?
|
2244
|
-
content = auto_text
|
2245
|
-
elsif @data['포스트설정']['내용과자동생성'].checked?
|
2246
|
-
#content = content + "\n(자동생성글)\n" + auto_text
|
2247
|
-
content = content + "(자동생성글)" + auto_text
|
2248
|
-
end
|
2274
|
+
|
2249
2275
|
|
2250
2276
|
if @data['포스트설정']['내용키워드삽입'].checked?
|
2251
2277
|
puts '내용키워드삽입...'
|
@@ -2427,7 +2453,6 @@ class Wordpress
|
|
2427
2453
|
|
2428
2454
|
if @data['포스트설정']['내용사진자동삽입'].checked?
|
2429
2455
|
puts '내용사진자동삽입...'
|
2430
|
-
|
2431
2456
|
sn = @data['포스트설정']['내용사진자동삽입시작숫자'].text.to_s.force_encoding('utf-8').to_i
|
2432
2457
|
en = @data['포스트설정']['내용사진자동삽입끝숫자'].text.to_s.force_encoding('utf-8').to_i
|
2433
2458
|
|
@@ -2439,54 +2464,71 @@ class Wordpress
|
|
2439
2464
|
end
|
2440
2465
|
|
2441
2466
|
if cn != 0
|
2442
|
-
#
|
2443
|
-
|
2444
|
-
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2448
|
-
|
2449
|
-
|
2450
|
-
|
2451
|
-
|
2452
|
-
missing_empty_lines = cn - empty_positions.length
|
2453
|
-
missing_empty_lines.times do
|
2454
|
-
content5 << "" # 텍스트 마지막에 빈 줄 추가
|
2467
|
+
# content5 구성 및 위치 배열 생성
|
2468
|
+
if @data['포스트설정']['내용과자동생성'].checked?
|
2469
|
+
if @data['포스트설정']['자동글 수식에 입력'].checked?
|
2470
|
+
content5 = content.split("(자동생성글)")[0].to_s.split("\n")
|
2471
|
+
content55 = content.split("(자동생성글)")[1].to_s
|
2472
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2473
|
+
else
|
2474
|
+
content5 = content.split("(자동생성글)")[0].to_s.split("\n")
|
2475
|
+
content55 = content.split("(자동생성글)")[1].to_s
|
2476
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2455
2477
|
end
|
2456
|
-
|
2478
|
+
elsif @data['포스트설정']['gpt키워드'].checked?
|
2479
|
+
content5 = content.split("(자동생성글)")[1].to_s.split("\n")
|
2480
|
+
content_prefix = content.split("(자동생성글)")[0].to_s
|
2481
|
+
content55 = ''
|
2482
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2483
|
+
else
|
2484
|
+
content5 = content.split("\n")
|
2485
|
+
content55 = ''
|
2486
|
+
position = content5.length.times.to_a.sample(cn).sort.reverse
|
2457
2487
|
end
|
2458
2488
|
|
2459
|
-
#
|
2460
|
-
|
2489
|
+
# 중복 필터링 로직
|
2490
|
+
while true
|
2491
|
+
check11 = 0
|
2492
|
+
position.each_with_index do |pos, idx|
|
2493
|
+
if content5[pos].to_s.include?('style') || content5[pos].to_s.include?('<') || content5[pos].to_s.include?('>')
|
2494
|
+
check11 = 1
|
2495
|
+
position[idx] += 4
|
2496
|
+
end
|
2497
|
+
end
|
2498
|
+
break if check11 == 0
|
2499
|
+
end
|
2461
2500
|
|
2462
|
-
# 이미지 URL 가져오기
|
2463
2501
|
if @data['포스트설정']['내용과자동생성'].checked? || @data['포스트설정']['gpt키워드'].checked?
|
2464
|
-
|
2502
|
+
sleep(2)
|
2503
|
+
puts '이미지 자동 세탁 중 · · · '
|
2465
2504
|
end
|
2466
|
-
|
2467
|
-
|
2505
|
+
|
2506
|
+
p content5
|
2507
|
+
puts content55
|
2508
|
+
p position
|
2509
|
+
|
2510
|
+
sleep(2)
|
2468
2511
|
position.each do |i|
|
2469
|
-
|
2470
|
-
puts '사진넣는위치 => ' + i.to_s
|
2471
|
-
|
2472
|
-
# 링크가 있을 경우 링크 포함
|
2512
|
+
image_url22 = get_image_file().force_encoding('utf-8')
|
2473
2513
|
if @data['포스트설정']['내용사진링크'].checked?
|
2474
|
-
|
2475
|
-
|
2514
|
+
image_tag = '<a href="' + @data['포스트설정']['내용사진링크값'].text.to_s.force_encoding('utf-8') +
|
2515
|
+
'"><img src="' + image_url22 + '" alt="' + keyword.force_encoding('utf-8') + '" class="aligncenter size-full"></a>'
|
2476
2516
|
else
|
2477
|
-
|
2478
|
-
content5[i] = '**image**' # 빈 줄에 이미지를 삽입
|
2517
|
+
image_tag = '<img src="' + image_url22 + '" alt="' + keyword + '" class="aligncenter size-full">'
|
2479
2518
|
end
|
2519
|
+
content5.insert(i, image_tag)
|
2480
2520
|
end
|
2481
2521
|
|
2482
|
-
|
2483
|
-
|
2522
|
+
sleep(2)
|
2523
|
+
puts '이미지 자동 세탁 완료 · · · '
|
2524
|
+
|
2525
|
+
if @data['포스트설정']['내용과자동생성'].checked?
|
2484
2526
|
content = content5.join("\n") + '(자동생성글)' + content55
|
2527
|
+
elsif @data['포스트설정']['gpt키워드'].checked?
|
2528
|
+
content = content_prefix + "(자동생성글)" + content5.join("\n")
|
2485
2529
|
else
|
2486
2530
|
content = content5.join("\n")
|
2487
2531
|
end
|
2488
|
-
|
2489
|
-
puts content
|
2490
2532
|
end
|
2491
2533
|
end
|
2492
2534
|
|
@@ -2498,12 +2540,22 @@ class Wordpress
|
|
2498
2540
|
content = content_memory[0]
|
2499
2541
|
content_end = content_memory[1].to_s
|
2500
2542
|
|
2543
|
+
if @data['포스트설정']['gpt키워드'].checked?
|
2544
|
+
if @data['포스트설정']['gpt상단'].checked?
|
2545
|
+
content = "(자동생성글)\n" + content_end + "\n" + content
|
2546
|
+
else
|
2547
|
+
content = content + "\n(자동생성글)\n" + content_end
|
2548
|
+
end
|
2549
|
+
else
|
2550
|
+
content = content + "\n(자동생성글)\n" + content_end
|
2551
|
+
end
|
2552
|
+
|
2501
2553
|
if @data['포스트설정']['특정단어키워드로변경'].checked?
|
2502
2554
|
@data['포스트설정']['특정단어키워드로변경값'].text.to_s.force_encoding('utf-8').split(',').each do |i|
|
2503
2555
|
content = content.split(i.force_encoding('utf-8')).join(keyword)
|
2504
2556
|
end
|
2505
2557
|
end
|
2506
|
-
|
2558
|
+
|
2507
2559
|
@data['table'][index][-1] = 75
|
2508
2560
|
@data['table'] << []
|
2509
2561
|
@data['table'].pop
|
@@ -2619,11 +2671,76 @@ class Wordpress
|
|
2619
2671
|
# end
|
2620
2672
|
#end
|
2621
2673
|
|
2622
|
-
|
2623
|
-
@data['포스트설정']['
|
2624
|
-
|
2674
|
+
if @data['포스트설정']['지도로변경'].checked?
|
2675
|
+
map_address = @data['포스트설정']['지도주소'].text.to_s.force_encoding('utf-8')
|
2676
|
+
change_words = @data['포스트설정']['지도로변경단어'].text.to_s.force_encoding('utf-8').split(',')
|
2677
|
+
|
2678
|
+
content_lines = content.split("\n")
|
2679
|
+
new_lines = []
|
2680
|
+
|
2681
|
+
content_lines.each do |line|
|
2682
|
+
# 이미 처리된 줄은 건너뜀
|
2683
|
+
if line.include?("<koreamap>")
|
2684
|
+
new_lines << line
|
2685
|
+
next
|
2686
|
+
end
|
2687
|
+
|
2688
|
+
processed = false
|
2689
|
+
|
2690
|
+
change_words.each do |change_word|
|
2691
|
+
# 1. [단어][주소] 패턴 처리: 분리 + 출력
|
2692
|
+
if line =~ /#{Regexp.escape(change_word)}\[(.*?)\]/
|
2693
|
+
match_data = line.match(/(.*)#{Regexp.escape(change_word)}\[(.*?)\](.*)/)
|
2694
|
+
if match_data
|
2695
|
+
before = match_data[1]
|
2696
|
+
address = match_data[2]
|
2697
|
+
after = match_data[3]
|
2698
|
+
|
2699
|
+
# 태그 추출
|
2700
|
+
open_tag = before[/<p[^>]*?>/i] || ""
|
2701
|
+
close_tag = after[/<\/p>/i] || ""
|
2702
|
+
|
2703
|
+
# 텍스트 정리
|
2704
|
+
before_text = before.sub(open_tag, '')
|
2705
|
+
after_text = after.sub(close_tag, '')
|
2706
|
+
|
2707
|
+
# 줄 분리
|
2708
|
+
new_lines << "#{open_tag}#{before_text}</p>" unless before_text.strip.empty?
|
2709
|
+
new_lines << "<koreamap>#{address}</koreamap>"
|
2710
|
+
new_lines << "#{open_tag}#{after_text}#{close_tag}" unless after_text.strip.empty?
|
2711
|
+
|
2712
|
+
processed = true
|
2713
|
+
break
|
2714
|
+
end
|
2715
|
+
end
|
2716
|
+
|
2717
|
+
# 2. 일반 단어 처리 (한 줄에만 등장하는 경우)
|
2718
|
+
if !processed && line.include?(change_word)
|
2719
|
+
parts = line.split(change_word, 2)
|
2720
|
+
prefix = parts[0]
|
2721
|
+
suffix = parts[1]
|
2722
|
+
|
2723
|
+
open_tag = prefix[/<p[^>]*?>/i] || ""
|
2724
|
+
close_tag = suffix[/<\/p>/i] || ""
|
2725
|
+
|
2726
|
+
prefix_text = prefix.sub(open_tag, '')
|
2727
|
+
suffix_text = suffix.sub(close_tag, '')
|
2728
|
+
|
2729
|
+
new_lines << "#{open_tag}#{prefix_text}</p>" unless prefix_text.strip.empty?
|
2730
|
+
new_lines << "<koreamap>#{map_address}</koreamap>"
|
2731
|
+
new_lines << "#{open_tag}#{suffix_text}#{close_tag}" unless suffix_text.strip.empty?
|
2732
|
+
|
2733
|
+
processed = true
|
2734
|
+
break
|
2735
|
+
end
|
2736
|
+
end
|
2737
|
+
|
2738
|
+
# 변경이 없었으면 원래 줄 추가
|
2739
|
+
new_lines << line unless processed
|
2625
2740
|
end
|
2626
|
-
|
2741
|
+
|
2742
|
+
content = new_lines.join("\n")
|
2743
|
+
end
|
2627
2744
|
|
2628
2745
|
|
2629
2746
|
|
@@ -2637,15 +2754,18 @@ class Wordpress
|
|
2637
2754
|
# content = content
|
2638
2755
|
# soosick_1 = content_end
|
2639
2756
|
#else
|
2640
|
-
|
2641
|
-
|
2642
|
-
|
2643
|
-
|
2644
|
-
|
2645
|
-
|
2757
|
+
parts = content.split('(자동생성글)', 2)
|
2758
|
+
content_main = parts[0].strip
|
2759
|
+
content_end = parts[1].to_s.strip
|
2760
|
+
|
2761
|
+
if @data['포스트설정']['gpt키워드'].checked?
|
2762
|
+
if @data['포스트설정']['gpt상단'].checked?
|
2763
|
+
content = content_end + "\n" + content_main + "\n"
|
2646
2764
|
else
|
2647
|
-
|
2648
|
-
|
2765
|
+
content = content_main + "\n" + content_end + "\n"
|
2766
|
+
end
|
2767
|
+
else
|
2768
|
+
content = content_main + "\n" + content_end + "\n"
|
2649
2769
|
end
|
2650
2770
|
|
2651
2771
|
|
@@ -3934,6 +4054,7 @@ class Wordpress
|
|
3934
4054
|
@data['image_size'][2].checked = false
|
3935
4055
|
@data['image_size'][3].checked = false
|
3936
4056
|
@data['image_size'][4].checked = false
|
4057
|
+
@data['image_size'][5].checked = false
|
3937
4058
|
end
|
3938
4059
|
}
|
3939
4060
|
}
|
@@ -3944,6 +4065,7 @@ class Wordpress
|
|
3944
4065
|
@data['image_size'][2].checked = false
|
3945
4066
|
@data['image_size'][3].checked = false
|
3946
4067
|
@data['image_size'][4].checked = false
|
4068
|
+
@data['image_size'][5].checked = false
|
3947
4069
|
end
|
3948
4070
|
}
|
3949
4071
|
}
|
@@ -3954,6 +4076,7 @@ class Wordpress
|
|
3954
4076
|
@data['image_size'][0].checked = false
|
3955
4077
|
@data['image_size'][3].checked = false
|
3956
4078
|
@data['image_size'][4].checked = false
|
4079
|
+
@data['image_size'][5].checked = false
|
3957
4080
|
end
|
3958
4081
|
}
|
3959
4082
|
}
|
@@ -3964,6 +4087,7 @@ class Wordpress
|
|
3964
4087
|
@data['image_size'][2].checked = false
|
3965
4088
|
@data['image_size'][0].checked = false
|
3966
4089
|
@data['image_size'][4].checked = false
|
4090
|
+
@data['image_size'][5].checked = false
|
3967
4091
|
end
|
3968
4092
|
}
|
3969
4093
|
}
|
@@ -3974,6 +4098,18 @@ class Wordpress
|
|
3974
4098
|
@data['image_size'][2].checked = false
|
3975
4099
|
@data['image_size'][3].checked = false
|
3976
4100
|
@data['image_size'][0].checked = false
|
4101
|
+
@data['image_size'][5].checked = false
|
4102
|
+
end
|
4103
|
+
}
|
4104
|
+
}
|
4105
|
+
@data['image_size'][5] = checkbox('원본 px'){
|
4106
|
+
on_toggled{
|
4107
|
+
if @data['image_size'][5].checked?
|
4108
|
+
@data['image_size'][1].checked = false
|
4109
|
+
@data['image_size'][2].checked = false
|
4110
|
+
@data['image_size'][3].checked = false
|
4111
|
+
@data['image_size'][0].checked = false
|
4112
|
+
@data['image_size'][4].checked = false
|
3977
4113
|
end
|
3978
4114
|
}
|
3979
4115
|
}
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tblog_duopack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.39
|
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-12 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: []
|