tblog_zon 0.0.33 → 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_zon.rb +390 -286
  3. metadata +3 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af125531c5abb4f735518a15a00613310da34ed91d5e429e83a1816e8be60a0a
4
- data.tar.gz: 4b7b8a41441690612b25dde68ae846b892c8cf098cf9bca7f87262f928d753bc
3
+ metadata.gz: 67e5e86fdb73d7c7289e465bafb25e6df65aec1c57b28da68b8cc4072094d26d
4
+ data.tar.gz: 530e2bc465993abd0203eedacc1460a229f4f70bd34635258d02e0317d756ee6
5
5
  SHA512:
6
- metadata.gz: 19cd6335c20c748982f7db099b6293dc0775b06999ec9b7204cea1d2e8662329be4949b0eae84de8bf7c4c56885ec636ae925f7495a9263fc93169e1eec0eec5
7
- data.tar.gz: cb06cab1a20556a661fb530862e4bea5a261f1f31d3afff76bd0c272c80006fe4325004f0a90fa9067e0e081189774a6ca512d6dff2408d91f6fd3f2ba12fcb0
6
+ metadata.gz: 6312719754b5a867969059b5acfce86869660fe7e9f5b904858dc2feac115e035bb01d490a43a409cf04bacd882a1def0a0e5465c2af6efd795700952e90ba3c
7
+ data.tar.gz: 8d231b376fb6c482d403b4a78eb44e178872a66f9a2d4ece4c948ba56414ff009c2e3ad51dfa2a5ee3bb6c6b179d4beb29f680b93cbe2b24ff7d84eb793daf6a
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,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,116 +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_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
256
- options.add_extension('./crx/app.crx') # 확장 프로그램을 첫 번째 탭에 추가
257
- options.add_argument('--disable-blink-features=AutomationControlled')
258
- options.add_argument('--disable-popup-blocking')
259
- options.add_argument('--dns-prefetch-disable')
260
- options.add_argument('--disable-dev-shm-usage')
261
- options.add_argument('--disable-software-rasterizer')
262
- options.add_argument('--ignore-certificate-errors')
263
- options.add_argument('--disable-gpu') # GPU 가속 끄기
264
- 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 위조
265
- options.add_argument('--disable-web-security')
266
- options.add_argument('--allow-running-insecure-content')
267
- options.add_argument('--allow-insecure-localhost')
268
- options.add_argument('--no-sandbox')
269
- options.add_argument('--disable-translate')
270
- options.add_argument('--disable-extensions-file-access-check')
271
- 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']
272
283
 
273
- # 자동화된 테스트 제거
274
- options.exclude_switches = ['enable-automation']
275
-
276
- options.add_preference("profile.password_manager_enabled", false) # 비밀번호 관리자 비활성화
277
- options.add_preference("credentials_enable_service", false) # 비밀번호 저장 기능 비활성화
278
- #options.add_preference("profile.managed_default_content_settings.cookies", 2) # 쿠키 관련 팝업 차단
279
- options.add_preference("profile.default_content_setting_values.notifications", 2) # 알림 차단
280
- 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
+
281
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
282
301
 
283
- # Proxy 설정
284
- if proxy != ''
285
- options.add_argument('--proxy-server=' + proxy.to_s.force_encoding('utf-8'))
286
- end
302
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
303
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
287
304
 
288
- # 브라우저 실행
289
- begin
290
- # 'capabilities'과 'options' 배열로 설정
291
- capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
292
- capabilities["goog:chromeOptions"] = options.as_json
293
-
294
- # Selenium 4에서는 'capabilities'만 사용하는 방식
295
- @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
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)
296
311
 
297
- @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
298
-
299
- sleep(1)
300
- # 두 번째 탭에서 로그인 페이지 열기
301
- @driver.get('https://www.tistory.com/auth/login')
302
- sleep(1)
303
-
304
- rescue => e
305
-
306
- puts "Error: #{e.message}"
307
- puts 'Using default Chrome driver without proxy'
308
- # 'capabilities'과 'options' 배열로 설정
309
- capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
310
- capabilities["goog:chromeOptions"] = options.as_json
312
+ # 현재 핸들 저장
313
+ main_tab = @driver.window_handle
311
314
 
312
- # Selenium 4에서는 'capabilities'만 사용하는 방식
313
- @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
315
+ # 모든 순회
316
+ @driver.window_handles.each do |handle|
317
+ next if handle == main_tab # 현재 탭은 남긴다
314
318
 
315
- @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
319
+ @driver.switch_to.window(handle)
320
+ @driver.close # 다른 탭 닫기
321
+ end
316
322
 
317
- # 번째 탭에서 확장 프로그램을 로드
318
- #@driver.get("chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html")
319
- sleep(1)
320
- # 번째 탭에서 로그인 페이지 열기
321
- @driver.get('https://www.tistory.com/auth/login')
322
- sleep(1)
323
- end
324
- end
325
-
326
- def login(user_id, user_pw, proxy, captcha_api_key)
327
- chrome_start(proxy)
328
- @captcha_api_key = captcha_api_key
329
- @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
330
333
 
331
- user_cookie_file = []
332
- begin
333
- Dir.entries('./cookie').each do |i|
334
- if i != '.' && i != '..'
335
- user_cookie_file << i
336
- end
337
- end
338
- rescue
339
- end
334
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
335
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
340
336
 
341
- @cookie4 = {}
342
- if user_cookie_file.include?(user_id+'.txt')
343
- f = File.open('./cookie/'+user_id+'.txt', 'r')
344
- @cookie4 = JSON.parse(f.read)
345
- f.close
346
- end
337
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
347
338
 
348
- # 기존 쿠키가 있으면 쿠키를 추가
349
- begin
350
- @cookie4.each do |i|
351
- @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)
352
360
  end
353
- rescue
354
361
  end
355
362
 
356
- @driver.switch_to.window(@driver.window_handles.last)
357
- sleep(1.5)
358
- @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
359
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')
360
425
  sleep(1)
426
+ @driver.switch_to.window(@driver.window_handles[0])
427
+
428
+
361
429
  begin
362
430
  wait = Selenium::WebDriver::Wait.new(:timeout => 3)
363
431
  wait.until { @driver.find_element(:xpath, '//*[@id="cMain"]/div/div/div/div/a[2]/span[2]') }
@@ -395,25 +463,7 @@ class Naver
395
463
  wait.until { @driver.find_element(:xpath, '//*[@id="captchaContainer"]') }
396
464
  puts '-[√] 로그인 중 캡챠 요구 발생 처리 진행.......'.yellow
397
465
  sleep(1)
398
- @driver.switch_to.window(@driver.window_handles[0])
399
- sleep(1)
400
- @driver.find_element(:xpath, '//*[@name="apiKey"]').click
401
- Clipboard.copy(captcha_api_key)
402
- sleep(0.5)
403
- @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
404
- sleep(0.5)
405
- @driver.find_element(:xpath, '//*[@data-lang="login"]').click
406
-
407
- begin
408
- sleep(2)
409
- @driver.switch_to.alert.dismiss
410
- sleep(1)
411
- rescue
412
-
413
- end
414
-
415
- # 두 번째 탭으로 전환
416
- @driver.switch_to.window(@driver.window_handles[1])
466
+
417
467
 
418
468
  begin
419
469
  wait = Selenium::WebDriver::Wait.new(:timeout => 7)
@@ -519,6 +569,7 @@ class Naver
519
569
 
520
570
 
521
571
 
572
+
522
573
  def update(title, content, option, url, keyword, captcha_api_key)#dd_time
523
574
  puts 'start...'.yellow
524
575
  puts(url)
@@ -541,20 +592,6 @@ class Naver
541
592
  end
542
593
 
543
594
 
544
-
545
-
546
-
547
-
548
-
549
-
550
-
551
-
552
-
553
-
554
-
555
-
556
-
557
-
558
595
  #@driver.manage.window.maximize
559
596
  #창 크기 최대화
560
597
  category2 = option['category'].to_s
@@ -579,12 +616,6 @@ class Naver
579
616
  end
580
617
 
581
618
 
582
-
583
-
584
-
585
-
586
-
587
-
588
619
  sleep(1)
589
620
 
590
621
  begin
@@ -597,10 +628,6 @@ class Naver
597
628
  puts e
598
629
  end
599
630
 
600
-
601
-
602
-
603
-
604
631
 
605
632
 
606
633
  sleep(1)
@@ -1240,29 +1267,7 @@ class Naver
1240
1267
  wait.until { @driver.find_element(:xpath, '//*[@id="captchaContainer"]') }
1241
1268
  puts '-[√] 로그인 중 캡챠 요구 발생 처리 진행.......'.yellow
1242
1269
  sleep(1)
1243
- @driver.switch_to.window(@driver.window_handles[0])
1244
- sleep(1)
1245
- @driver.find_element(:xpath, '//*[@name="apiKey"]').click
1246
- sleep(0.5)
1247
- @driver.find_element(:xpath, '//*[@name="apiKey"]').clear
1248
- sleep(0.5)
1249
- Clipboard.copy(captcha_api_key)
1250
- sleep(0.5)
1251
- @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
1252
- sleep(0.5)
1253
- @driver.find_element(:xpath, '//*[@data-lang="login"]').click
1254
1270
 
1255
- begin
1256
- sleep(2)
1257
- @driver.switch_to.alert.dismiss
1258
- sleep(1)
1259
- rescue
1260
-
1261
- end
1262
-
1263
- # 두 번째 탭으로 전환
1264
- @driver.switch_to.window(@driver.window_handles[1])
1265
-
1266
1271
  begin
1267
1272
  wait = Selenium::WebDriver::Wait.new(:timeout => 7)
1268
1273
  wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
@@ -1391,7 +1396,7 @@ class Naver
1391
1396
  @driver.find_element(:xpath, '//*[@id="publish-btn"]').click #등록완료버튼
1392
1397
  rescue
1393
1398
  # 타임아웃을 100초로 설정
1394
- wait = Selenium::WebDriver::Wait.new(:timeout => 100)
1399
+ wait = Selenium::WebDriver::Wait.new(:timeout => 120)
1395
1400
  # 요소가 나타날 때까지 100초 동안 기다립니다.
1396
1401
  wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
1397
1402
  sleep(2)
@@ -1437,14 +1442,7 @@ class Naver
1437
1442
  rescue
1438
1443
  end
1439
1444
  end
1440
-
1441
-
1442
-
1443
-
1444
-
1445
-
1446
-
1447
-
1445
+
1448
1446
 
1449
1447
  end
1450
1448
  end
@@ -1476,38 +1474,7 @@ class Wordpress
1476
1474
  end
1477
1475
  end
1478
1476
 
1479
- # def get_naver_text(q)
1480
- # begin
1481
- # Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
1482
- # @driver = Selenium::WebDriver.for :chrome
1483
- # rescue
1484
- # @driver = Selenium::WebDriver.for :chrome
1485
- # end
1486
- # @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')
1487
- # noko = Nokogiri::HTML(@driver.page_source)
1488
- # tt = noko.xpath('//*[@id="main_pack"]/section/div/ul').text
1489
- # aa33 = '하였습니다,하였어요,하게됬어요,했답니다,했었는데요,하게되었어요,했어요,그랬답니다,그랬어요,합니다,그랬어요,그랬답니다,그랬답니다,그러합니다,좋아요,좋습니다,됬어요,되었어요,되었답니다,되었구요,되었어요,되네요,하네요,해요,할거예요,할수었이요,입니다,인데요,이예요,이랍니다,이였어요,그랬어요,그랬거든요,그랬습니다,었어요,었습니다,있었어요'.split(',')
1490
- # for page in 3..8
1491
- # @driver.get('https://www.google.com/search?q='+q.to_s+'&start='+(page*10).to_s)
1492
- # noko = Nokogiri::HTML(@driver.page_source)
1493
- # for n in 1..15
1494
- # tt2 = noko.xpath('//*[@id="rso"]/div['+n.to_s+']/div/div/div[2]/div').text
1495
- # if tt2.length < 5
1496
-
1497
- # else
1498
- # tt2 = tt2.split('...').join('')+aa3.sample
1499
- # tt += tt2
1500
- # end
1501
- # end
1502
- # end
1503
- # @driver.close
1504
- # tt = tt.split(' ').shuffle.join(' ')[0..1000]
1505
- # m = Array.new
1506
- # for n in 0..19
1507
- # m << tt[(n*100)..(n*100+100)]
1508
- # end
1509
- # return m.join("\n")
1510
- # end
1477
+
1511
1478
 
1512
1479
  def get_naver_text(q)
1513
1480
  begin
@@ -1625,35 +1592,52 @@ class Wordpress
1625
1592
 
1626
1593
  def save_image
1627
1594
  if @data['이미지설정']['이미지'].length == 0
1628
-
1595
+ return
1596
+ end
1597
+
1598
+ if @data['이미지설정']['순서사용'].checked?
1599
+ image_path = @data['이미지설정']['이미지'][@image_counter][2]
1600
+ @image_counter += 1
1601
+ if @image_counter > @data['이미지설정']['이미지'].length - 1
1602
+ @image_counter = 0
1603
+ end
1629
1604
  else
1630
- if @data['이미지설정']['순서사용'].checked?
1631
- image_path = @data['이미지설정']['이미지'][@image_counter][2]
1632
- @image_counter += 1
1633
- if @image_counter > @data['이미지설정']['이미지'].length-1
1634
- @image_counter = 0
1635
- end
1636
- else
1637
- image_path = @data['이미지설정']['이미지'].sample[2]
1605
+ # 초기화가 안됐거나 다 썼으면 새롭게 섞는다
1606
+ @shuffled_images ||= []
1607
+ if @shuffled_images.empty?
1608
+ @shuffled_images = @data['이미지설정']['이미지'].shuffle
1638
1609
  end
1639
- img = Magick::Image.read(image_path).first
1640
- img.write('./image/memory.png')
1610
+
1611
+ image_path = @shuffled_images.shift[2]
1641
1612
  end
1613
+
1614
+ img = Magick::Image.read(image_path).first
1615
+ img.write('./image/memory.png')
1642
1616
  end
1643
1617
 
1644
1618
  def change_image_size(w)
1645
1619
  img = Magick::Image.read('./image/memory.png').first
1646
1620
  width = img.columns
1647
1621
  height = img.rows
1648
- begin
1649
- if @data['image_type'][0].checked? or @data['image_type'][2].checked?
1650
- img.resize!(w, w*(height.to_f/width.to_f))
1651
- else
1652
- img.resize!(w, w)
1622
+
1623
+ # '원본' 선택된 경우, 리사이징을 하지 않고 원본 이미지를 그대로 반환
1624
+ if w == 'original'
1625
+ return img # 원본 이미지 그대로 반환
1626
+ else
1627
+ begin
1628
+ if @data['image_type'][0].checked? or @data['image_type'][2].checked?
1629
+ # 비율을 맞추어 리사이징
1630
+ img.resize!(w, w * (height.to_f / width.to_f))
1631
+ else
1632
+ # 정사각형으로 리사이징
1633
+ img.resize!(w, w)
1634
+ end
1635
+ rescue
1636
+ img.resize!(w, w) # 예외 처리 시에도 리사이징
1653
1637
  end
1654
- rescue
1655
- img.resize!(w, w)
1656
1638
  end
1639
+
1640
+ # 리사이징된 이미지 저장
1657
1641
  img.write('./image/memory.png')
1658
1642
  end
1659
1643
 
@@ -1725,22 +1709,28 @@ class Wordpress
1725
1709
  auto_image()
1726
1710
  end
1727
1711
 
1728
- image_size = [480,740,650,550,480]
1712
+ # '원본'을 포함한 이미지 크기 옵션 추가
1713
+ image_size = [480, 740, 650, 550, 480, 'original']
1729
1714
  size = 0
1730
- for n in 0..4
1715
+
1716
+ for n in 0..5 # 0부터 5까지 반복, '원본' 옵션까지 포함
1731
1717
  if @data['image_size'][n].checked?
1732
- if n == 0
1733
- size = image_size.sample
1718
+ if n == 5 # '원본'이 선택되었을 경우
1719
+ size = 'original'
1720
+ elsif n == 0
1721
+ size = image_size.sample # 랜덤 선택
1734
1722
  else
1735
1723
  size = image_size[n]
1736
1724
  end
1737
1725
  end
1738
1726
  end
1727
+
1728
+ # '원본'이 선택되지 않았다면 기본 값 설정
1739
1729
  if size == 0
1740
1730
  size = 480
1741
1731
  end
1742
-
1743
- change_image_size(size)
1732
+
1733
+ change_image_size(size) # 크기 변경 함수 호출
1744
1734
 
1745
1735
  if @data['이미지설정']['필터사용'].checked?
1746
1736
  image_filter()
@@ -2135,6 +2125,22 @@ class Wordpress
2135
2125
  @data['table'].pop
2136
2126
  #제목끝
2137
2127
  # content = " #{content} "
2128
+ if @data['포스트설정']['gpt키워드'].checked?
2129
+ gpt_keyword_prompt = @data['포스트설정']['gpt키워드_프롬프트'].text.to_s.force_encoding('utf-8')
2130
+ gpt_keyword_prompt_sample = gpt_keyword_prompt.strip.empty? ? "프롬프트: 관련된 글을 1500자에서 2500자 사이로 만들어줘" : gpt_keyword_prompt
2131
+ chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt)
2132
+ gpt_text = chat.message(keyword)
2133
+ #content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
2134
+ content = content.to_s + "(자동생성글)" + gpt_text.to_s
2135
+ elsif @data['포스트설정']['내용을자동생성'].checked?
2136
+ content = auto_text
2137
+ elsif @data['포스트설정']['내용과자동생성'].checked?
2138
+ #content = content + "\n(자동생성글)\n" + auto_text
2139
+ content = content + "(자동생성글)" + auto_text
2140
+ end
2141
+ @data['table'][index][-1] = 45
2142
+ @data['table'] << []
2143
+ @data['table'].pop
2138
2144
 
2139
2145
  if @data['포스트설정']['특정단어굵기'].checked?
2140
2146
  content2 = ''
@@ -2174,7 +2180,7 @@ class Wordpress
2174
2180
  content = content2
2175
2181
  end
2176
2182
  end
2177
- @data['table'][index][-1] = 35
2183
+ @data['table'][index][-1] = 50
2178
2184
  @data['table'] << []
2179
2185
  @data['table'].pop
2180
2186
  if @data['포스트설정']['단어크기변경'].checked?
@@ -2195,19 +2201,7 @@ class Wordpress
2195
2201
  @data['table'][index][-1] = 50
2196
2202
  @data['table'] << []
2197
2203
  @data['table'].pop
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
2204
+
2211
2205
 
2212
2206
  if @data['포스트설정']['내용키워드삽입'].checked?
2213
2207
  puts '내용키워드삽입...'
@@ -2389,7 +2383,6 @@ class Wordpress
2389
2383
 
2390
2384
  if @data['포스트설정']['내용사진자동삽입'].checked?
2391
2385
  puts '내용사진자동삽입...'
2392
-
2393
2386
  sn = @data['포스트설정']['내용사진자동삽입시작숫자'].text.to_s.force_encoding('utf-8').to_i
2394
2387
  en = @data['포스트설정']['내용사진자동삽입끝숫자'].text.to_s.force_encoding('utf-8').to_i
2395
2388
 
@@ -2401,54 +2394,71 @@ class Wordpress
2401
2394
  end
2402
2395
 
2403
2396
  if cn != 0
2404
- # 내용 분할 (자동 생성 글과 텍스트)
2405
- content5 = content.split("(자동생성글)")[0].to_s.split("\n")
2406
- content55 = content.split("(자동생성글)")[1].to_s if @data['포스트설정']['내용과자동생성'].checked? || @data['포스트설정']['gpt키워드'].checked?
2407
-
2408
- # 줄 찾기
2409
- empty_positions = content5.each_with_index.select { |line, index| line.strip.empty? }.map { |line, index| index }
2410
-
2411
- # 줄이 부족하면 텍스트 끝에 빈 줄 추가
2412
- if empty_positions.length < cn
2413
- # 부족한 빈 줄의 수
2414
- missing_empty_lines = cn - empty_positions.length
2415
- missing_empty_lines.times do
2416
- content5 << "" # 텍스트 마지막에 빈 줄 추가
2397
+ # content5 구성 위치 배열 생성
2398
+ if @data['포스트설정']['내용과자동생성'].checked?
2399
+ if @data['포스트설정']['자동글 수식에 입력'].checked?
2400
+ content5 = content.split("(자동생성글)")[0].to_s.split("\n")
2401
+ content55 = content.split("(자동생성글)")[1].to_s
2402
+ position = content5.length.times.to_a.sample(cn).sort.reverse
2403
+ else
2404
+ content5 = content.split("(자동생성글)")[0].to_s.split("\n")
2405
+ content55 = content.split("(자동생성글)")[1].to_s
2406
+ position = content5.length.times.to_a.sample(cn).sort.reverse
2417
2407
  end
2418
- empty_positions = content5.each_with_index.select { |line, index| line.strip.empty? }.map { |line, index| index } # 다시 빈 줄 위치 계산
2408
+ elsif @data['포스트설정']['gpt키워드'].checked?
2409
+ content5 = content.split("(자동생성글)")[1].to_s.split("\n")
2410
+ content_prefix = content.split("(자동생성글)")[0].to_s
2411
+ content55 = ''
2412
+ position = content5.length.times.to_a.sample(cn).sort.reverse
2413
+ else
2414
+ content5 = content.split("\n")
2415
+ content55 = ''
2416
+ position = content5.length.times.to_a.sample(cn).sort.reverse
2419
2417
  end
2420
2418
 
2421
- # 이미지 삽입할 위치를 지정 (빈 줄 위치에 삽입)
2422
- position = empty_positions[0..cn-1]
2419
+ # 중복 필터링 로직
2420
+ while true
2421
+ check11 = 0
2422
+ position.each_with_index do |pos, idx|
2423
+ if content5[pos].to_s.include?('style') || content5[pos].to_s.include?('<') || content5[pos].to_s.include?('>')
2424
+ check11 = 1
2425
+ position[idx] += 4
2426
+ end
2427
+ end
2428
+ break if check11 == 0
2429
+ end
2423
2430
 
2424
- # 이미지 URL 가져오기
2425
2431
  if @data['포스트설정']['내용과자동생성'].checked? || @data['포스트설정']['gpt키워드'].checked?
2426
- image_url22 = get_image_file().force_encoding('utf-8')
2432
+ sleep(2)
2433
+ puts '이미지 자동 세탁 중 · · · '
2427
2434
  end
2428
-
2429
- # 각 위치에 이미지를 하나씩만 삽입
2435
+
2436
+ p content5
2437
+ puts content55
2438
+ p position
2439
+
2440
+ sleep(2)
2430
2441
  position.each do |i|
2431
- image_url = get_image_file().force_encoding('utf-8')
2432
- puts '사진넣는위치 => ' + i.to_s
2433
-
2434
- # 링크가 있을 경우 링크 포함
2442
+ image_url22 = get_image_file().force_encoding('utf-8')
2435
2443
  if @data['포스트설정']['내용사진링크'].checked?
2436
- image_memory << "<a href='" + @data['포스트설정']['내용사진링크값'].text.to_s.force_encoding('utf-8') + "'><img src='" + image_url + "' alt='" + keyword.force_encoding('utf-8') + "'></a>"
2437
- content5[i] = '**image**' # 줄에 이미지를 삽입
2444
+ image_tag = '<a href="' + @data['포스트설정']['내용사진링크값'].text.to_s.force_encoding('utf-8') +
2445
+ '"><img src="' + image_url22 + '" alt="' + keyword.force_encoding('utf-8') + '" class="aligncenter size-full"></a>'
2438
2446
  else
2439
- image_memory << "<img src='" + image_url + "' alt='" + keyword + "' class='aligncenter size-full'>"
2440
- content5[i] = '**image**' # 빈 줄에 이미지를 삽입
2447
+ image_tag = '<img src="' + image_url22 + '" alt="' + keyword + '" class="aligncenter size-full">'
2441
2448
  end
2449
+ content5.insert(i, image_tag)
2442
2450
  end
2443
2451
 
2444
- # 자동 생성된 내용과 합치기
2445
- if @data['포스트설정']['내용과자동생성'].checked? || @data['포스트설정']['gpt키워드'].checked?
2452
+ sleep(2)
2453
+ puts '이미지 자동 세탁 완료 · · · '
2454
+
2455
+ if @data['포스트설정']['내용과자동생성'].checked?
2446
2456
  content = content5.join("\n") + '(자동생성글)' + content55
2457
+ elsif @data['포스트설정']['gpt키워드'].checked?
2458
+ content = content_prefix + "(자동생성글)" + content5.join("\n")
2447
2459
  else
2448
2460
  content = content5.join("\n")
2449
2461
  end
2450
-
2451
- puts content
2452
2462
  end
2453
2463
  end
2454
2464
 
@@ -2460,12 +2470,22 @@ class Wordpress
2460
2470
  content = content_memory[0]
2461
2471
  content_end = content_memory[1].to_s
2462
2472
 
2473
+ if @data['포스트설정']['gpt키워드'].checked?
2474
+ if @data['포스트설정']['gpt상단'].checked?
2475
+ content = "(자동생성글)\n" + content_end + "\n" + content
2476
+ else
2477
+ content = content + "\n(자동생성글)\n" + content_end
2478
+ end
2479
+ else
2480
+ content = content + "\n(자동생성글)\n" + content_end
2481
+ end
2482
+
2463
2483
  if @data['포스트설정']['특정단어키워드로변경'].checked?
2464
2484
  @data['포스트설정']['특정단어키워드로변경값'].text.to_s.force_encoding('utf-8').split(',').each do |i|
2465
2485
  content = content.split(i.force_encoding('utf-8')).join(keyword)
2466
2486
  end
2467
2487
  end
2468
-
2488
+
2469
2489
  @data['table'][index][-1] = 75
2470
2490
  @data['table'] << []
2471
2491
  @data['table'].pop
@@ -2581,11 +2601,76 @@ class Wordpress
2581
2601
  # end
2582
2602
  #end
2583
2603
 
2584
- if @data['포스트설정']['지도로변경'].checked?
2585
- @data['포스트설정']['지도로변경단어'].text.to_s.force_encoding('utf-8').split(',').each do |i|
2586
- content = content.split(i.force_encoding('utf-8')).join(" ""<koreamap>"+@data['포스트설정']['지도주소'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')+"</koreamap>")
2604
+ if @data['포스트설정']['지도로변경'].checked?
2605
+ map_address = @data['포스트설정']['지도주소'].text.to_s.force_encoding('utf-8')
2606
+ change_words = @data['포스트설정']['지도로변경단어'].text.to_s.force_encoding('utf-8').split(',')
2607
+
2608
+ content_lines = content.split("\n")
2609
+ new_lines = []
2610
+
2611
+ content_lines.each do |line|
2612
+ # 이미 처리된 줄은 건너뜀
2613
+ if line.include?("<koreamap>")
2614
+ new_lines << line
2615
+ next
2616
+ end
2617
+
2618
+ processed = false
2619
+
2620
+ change_words.each do |change_word|
2621
+ # 1. [단어][주소] 패턴 처리: 분리 + 출력
2622
+ if line =~ /#{Regexp.escape(change_word)}\[(.*?)\]/
2623
+ match_data = line.match(/(.*)#{Regexp.escape(change_word)}\[(.*?)\](.*)/)
2624
+ if match_data
2625
+ before = match_data[1]
2626
+ address = match_data[2]
2627
+ after = match_data[3]
2628
+
2629
+ # 태그 추출
2630
+ open_tag = before[/<p[^>]*?>/i] || ""
2631
+ close_tag = after[/<\/p>/i] || ""
2632
+
2633
+ # 텍스트 정리
2634
+ before_text = before.sub(open_tag, '')
2635
+ after_text = after.sub(close_tag, '')
2636
+
2637
+ # 줄 분리
2638
+ new_lines << "#{open_tag}#{before_text}</p>" unless before_text.strip.empty?
2639
+ new_lines << "<koreamap>#{address}</koreamap>"
2640
+ new_lines << "#{open_tag}#{after_text}#{close_tag}" unless after_text.strip.empty?
2641
+
2642
+ processed = true
2643
+ break
2644
+ end
2645
+ end
2646
+
2647
+ # 2. 일반 단어 처리 (한 줄에만 등장하는 경우)
2648
+ if !processed && line.include?(change_word)
2649
+ parts = line.split(change_word, 2)
2650
+ prefix = parts[0]
2651
+ suffix = parts[1]
2652
+
2653
+ open_tag = prefix[/<p[^>]*?>/i] || ""
2654
+ close_tag = suffix[/<\/p>/i] || ""
2655
+
2656
+ prefix_text = prefix.sub(open_tag, '')
2657
+ suffix_text = suffix.sub(close_tag, '')
2658
+
2659
+ new_lines << "#{open_tag}#{prefix_text}</p>" unless prefix_text.strip.empty?
2660
+ new_lines << "<koreamap>#{map_address}</koreamap>"
2661
+ new_lines << "#{open_tag}#{suffix_text}#{close_tag}" unless suffix_text.strip.empty?
2662
+
2663
+ processed = true
2664
+ break
2665
+ end
2666
+ end
2667
+
2668
+ # 변경이 없었으면 원래 줄 추가
2669
+ new_lines << line unless processed
2587
2670
  end
2588
- end
2671
+
2672
+ content = new_lines.join("\n")
2673
+ end
2589
2674
 
2590
2675
 
2591
2676
 
@@ -2599,15 +2684,18 @@ class Wordpress
2599
2684
  # content = content
2600
2685
  # soosick_1 = content_end
2601
2686
  #else
2602
- if @data['포스트설정']['gpt키워드'].checked?
2603
- if @data['포스트설정']['gpt상단'].checked?
2604
- content = content_end+"\n"+content+"\n"
2605
- else
2606
- content = content+"\n"+content_end+"\n"
2607
- end
2687
+ parts = content.split('(자동생성글)', 2)
2688
+ content_main = parts[0].strip
2689
+ content_end = parts[1].to_s.strip
2690
+
2691
+ if @data['포스트설정']['gpt키워드'].checked?
2692
+ if @data['포스트설정']['gpt상단'].checked?
2693
+ content = content_end + "\n" + content_main + "\n"
2608
2694
  else
2609
- content = content+"\n"+content_end+"\n"
2610
-
2695
+ content = content_main + "\n" + content_end + "\n"
2696
+ end
2697
+ else
2698
+ content = content_main + "\n" + content_end + "\n"
2611
2699
  end
2612
2700
 
2613
2701
 
@@ -3890,6 +3978,7 @@ class Wordpress
3890
3978
  @data['image_size'][2].checked = false
3891
3979
  @data['image_size'][3].checked = false
3892
3980
  @data['image_size'][4].checked = false
3981
+ @data['image_size'][5].checked = false
3893
3982
  end
3894
3983
  }
3895
3984
  }
@@ -3900,6 +3989,7 @@ class Wordpress
3900
3989
  @data['image_size'][2].checked = false
3901
3990
  @data['image_size'][3].checked = false
3902
3991
  @data['image_size'][4].checked = false
3992
+ @data['image_size'][5].checked = false
3903
3993
  end
3904
3994
  }
3905
3995
  }
@@ -3910,6 +4000,7 @@ class Wordpress
3910
4000
  @data['image_size'][0].checked = false
3911
4001
  @data['image_size'][3].checked = false
3912
4002
  @data['image_size'][4].checked = false
4003
+ @data['image_size'][5].checked = false
3913
4004
  end
3914
4005
  }
3915
4006
  }
@@ -3920,6 +4011,7 @@ class Wordpress
3920
4011
  @data['image_size'][2].checked = false
3921
4012
  @data['image_size'][0].checked = false
3922
4013
  @data['image_size'][4].checked = false
4014
+ @data['image_size'][5].checked = false
3923
4015
  end
3924
4016
  }
3925
4017
  }
@@ -3930,6 +4022,18 @@ class Wordpress
3930
4022
  @data['image_size'][2].checked = false
3931
4023
  @data['image_size'][3].checked = false
3932
4024
  @data['image_size'][0].checked = false
4025
+ @data['image_size'][5].checked = false
4026
+ end
4027
+ }
4028
+ }
4029
+ @data['image_size'][5] = checkbox('원본 px'){
4030
+ on_toggled{
4031
+ if @data['image_size'][5].checked?
4032
+ @data['image_size'][1].checked = false
4033
+ @data['image_size'][2].checked = false
4034
+ @data['image_size'][3].checked = false
4035
+ @data['image_size'][0].checked = false
4036
+ @data['image_size'][4].checked = false
3933
4037
  end
3934
4038
  }
3935
4039
  }
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.33
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: []