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.
- checksums.yaml +4 -4
- data/lib/tblog_zon.rb +390 -286
- 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: 67e5e86fdb73d7c7289e465bafb25e6df65aec1c57b28da68b8cc4072094d26d
|
4
|
+
data.tar.gz: 530e2bc465993abd0203eedacc1460a229f4f70bd34635258d02e0317d756ee6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
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
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
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
|
-
|
284
|
-
|
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
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
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
|
-
|
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
|
-
|
313
|
-
|
315
|
+
# 모든 탭 순회
|
316
|
+
@driver.window_handles.each do |handle|
|
317
|
+
next if handle == main_tab # 현재 탭은 남긴다
|
314
318
|
|
315
|
-
|
319
|
+
@driver.switch_to.window(handle)
|
320
|
+
@driver.close # 다른 탭 닫기
|
321
|
+
end
|
316
322
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
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
|
-
|
332
|
-
|
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
|
-
|
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
|
-
|
350
|
-
|
351
|
-
|
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
|
-
|
357
|
-
|
358
|
-
|
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
|
-
|
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 =>
|
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
|
-
|
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
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
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
|
-
|
1640
|
-
|
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
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
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
|
-
|
1712
|
+
# '원본'을 포함한 이미지 크기 옵션 추가
|
1713
|
+
image_size = [480, 740, 650, 550, 480, 'original']
|
1729
1714
|
size = 0
|
1730
|
-
|
1715
|
+
|
1716
|
+
for n in 0..5 # 0부터 5까지 반복, '원본' 옵션까지 포함
|
1731
1717
|
if @data['image_size'][n].checked?
|
1732
|
-
if n ==
|
1733
|
-
size =
|
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] =
|
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
|
-
|
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
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
2409
|
-
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
2432
|
-
puts '사진넣는위치 => ' + i.to_s
|
2433
|
-
|
2434
|
-
# 링크가 있을 경우 링크 포함
|
2442
|
+
image_url22 = get_image_file().force_encoding('utf-8')
|
2435
2443
|
if @data['포스트설정']['내용사진링크'].checked?
|
2436
|
-
|
2437
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
2585
|
-
@data['포스트설정']['
|
2586
|
-
|
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
|
-
|
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
|
-
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
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
|
-
|
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.
|
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: []
|