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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tblog_duopack.rb +389 -253
  3. metadata +3 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a1b0ef75c64d091e8224a4f7617c78c90df8a17c0a008942b8ce99d99fd0c89
4
- data.tar.gz: 858eb135367f64e0cd028f3883ee873b4bb443b67f762485e6af749508a07ed0
3
+ metadata.gz: 44cd103f7388e3c3b8d273b70b1e8e922d9c943f75c15b954f3c6b51bf9cae98
4
+ data.tar.gz: 96fe769e09a7a8dfd5654c4d12d9eede886dd61a1187ab149a9088a1d7257ac9
5
5
  SHA512:
6
- metadata.gz: 787f8a9f2f72c86dfccb4a721916ec4881fb16f8b8ef431aff25e97513bd028b1b6d6c898b018c0ac7cdc1167d2fbb9facc893d09aff559b2fd652c7f277b47d
7
- data.tar.gz: 587816d392ee1c14cd4ec2c6acbd6d7543598b8ab29c9a28d02513cd3883c1bcf5bdd232111395101e6af7467b197232d761201f465ed4298005a22509f2d282
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
- Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
253
- options = Selenium::WebDriver::Chrome::Options.new
254
- options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
255
- options.add_extension('./crx/app.crx') # 확장 프로그램을 첫 번째 탭에 추가
256
- options.add_argument('--disable-blink-features=AutomationControlled')
257
- options.add_argument('--disable-popup-blocking')
258
- options.add_argument('--dns-prefetch-disable')
259
- options.add_argument('--disable-dev-shm-usage')
260
- options.add_argument('--disable-software-rasterizer')
261
- options.add_argument('--ignore-certificate-errors')
262
- options.add_argument('--disable-gpu') # GPU 가속 끄기
263
- 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 위조
264
- options.add_argument('--disable-web-security')
265
- options.add_argument('--allow-running-insecure-content')
266
- options.add_argument('--allow-insecure-localhost')
267
- options.add_argument('--no-sandbox')
268
- options.add_argument('--disable-translate')
269
- options.add_argument('--disable-extensions-file-access-check')
270
- options.add_argument('--disable-impl-side-painting')
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
- options.exclude_switches = ['enable-automation']
274
-
275
- options.add_preference("profile.password_manager_enabled", false) # 비밀번호 관리자 비활성화
276
- options.add_preference("credentials_enable_service", false) # 비밀번호 저장 기능 비활성화
277
- #options.add_preference("profile.managed_default_content_settings.cookies", 2) # 쿠키 관련 팝업 차단
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
- # Proxy 설정
283
- if proxy != ''
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
- begin
289
- # 'capabilities'과 'options' 배열로 설정
290
- capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
291
- capabilities["goog:chromeOptions"] = options.as_json
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
- # Selenium 4에서는 'capabilities'만 사용하는 방식
294
- @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
312
+ # 현재 핸들 저장
313
+ main_tab = @driver.window_handle
295
314
 
296
- @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
297
-
298
- sleep(1)
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
- # Selenium 4에서는 'capabilities'만 사용하는 방식
312
- @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
319
+ @driver.switch_to.window(handle)
320
+ @driver.close # 다른 닫기
321
+ end
313
322
 
314
- @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
315
-
316
- # 첫 번째 탭에서 확장 프로그램을 로드
317
- #@driver.get("chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html")
318
- sleep(1)
319
- # 번째 탭에서 로그인 페이지 열기
320
- @driver.get('https://www.tistory.com/auth/login')
321
- sleep(1)
322
- end
323
- end
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
- user_cookie_file = []
331
- begin
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
- @cookie4 = {}
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
- 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'])
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
- @driver.switch_to.window(@driver.window_handles.last)
356
- sleep(1.5)
357
- @driver.get('https://www.tistory.com/auth/login')
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
- @driver.switch_to.window(@driver.window_handles[0])
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 => 100)
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
- 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
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
- img = Magick::Image.read(image_path).first
1678
- img.write('./image/memory.png')
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
- begin
1687
- if @data['image_type'][0].checked? or @data['image_type'][2].checked?
1688
- img.resize!(w, w*(height.to_f/width.to_f))
1689
- else
1690
- img.resize!(w, w)
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
- image_size = [480,740,650,550,480]
1782
+ # '원본'을 포함한 이미지 크기 옵션 추가
1783
+ image_size = [480, 740, 650, 550, 480, 'original']
1767
1784
  size = 0
1768
- for n in 0..4
1785
+
1786
+ for n in 0..5 # 0부터 5까지 반복, '원본' 옵션까지 포함
1769
1787
  if @data['image_size'][n].checked?
1770
- if n == 0
1771
- size = image_size.sample
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] = 35
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
- if @data['포스트설정']['gpt키워드'].checked?
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
- content5 = content.split("(자동생성글)")[0].to_s.split("\n")
2444
- content55 = content.split("(자동생성글)")[1].to_s if @data['포스트설정']['내용과자동생성'].checked? || @data['포스트설정']['gpt키워드'].checked?
2445
-
2446
- # 줄 찾기
2447
- empty_positions = content5.each_with_index.select { |line, index| line.strip.empty? }.map { |line, index| index }
2448
-
2449
- # 줄이 부족하면 텍스트 끝에 빈 줄 추가
2450
- if empty_positions.length < cn
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
- empty_positions = content5.each_with_index.select { |line, index| line.strip.empty? }.map { |line, index| index } # 다시 빈 줄 위치 계산
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
- position = empty_positions[0..cn-1]
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
- image_url22 = get_image_file().force_encoding('utf-8')
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
- image_url = get_image_file().force_encoding('utf-8')
2470
- puts '사진넣는위치 => ' + i.to_s
2471
-
2472
- # 링크가 있을 경우 링크 포함
2512
+ image_url22 = get_image_file().force_encoding('utf-8')
2473
2513
  if @data['포스트설정']['내용사진링크'].checked?
2474
- image_memory << "<a href='" + @data['포스트설정']['내용사진링크값'].text.to_s.force_encoding('utf-8') + "'><img src='" + image_url + "' alt='" + keyword.force_encoding('utf-8') + "'></a>"
2475
- content5[i] = '**image**' # 줄에 이미지를 삽입
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
- image_memory << "<img src='" + image_url + "' alt='" + keyword + "' class='aligncenter size-full'>"
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
- if @data['포스트설정']['내용과자동생성'].checked? || @data['포스트설정']['gpt키워드'].checked?
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
- if @data['포스트설정']['지도로변경'].checked?
2623
- @data['포스트설정']['지도로변경단어'].text.to_s.force_encoding('utf-8').split(',').each do |i|
2624
- content = content.split(i.force_encoding('utf-8')).join(" ""<koreamap>"+@data['포스트설정']['지도주소'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')+"</koreamap>")
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
- end
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
- if @data['포스트설정']['gpt키워드'].checked?
2641
- if @data['포스트설정']['gpt상단'].checked?
2642
- content = content_end+"\n"+content+"\n"
2643
- else
2644
- content = content+"\n"+content_end+"\n"
2645
- end
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
- content = content+"\n"+content_end+"\n"
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.37
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-02-13 00:00:00.000000000 Z
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.3.7
40
- signing_key:
37
+ rubygems_version: 3.6.7
41
38
  specification_version: 4
42
39
  summary: file to clipboard
43
40
  test_files: []