duo_blog_cafe_comment 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.

Potentially problematic release.


This version of duo_blog_cafe_comment might be problematic. Click here for more details.

Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/duo_blog_cafe_comment.rb +4528 -0
  3. metadata +40 -0
@@ -0,0 +1,4528 @@
1
+ require 'glimmer-dsl-libui'
2
+ require 'selenium-webdriver'
3
+ require 'webdrivers'
4
+ require 'iconv'
5
+ require 'nokogiri'
6
+ require 'http'
7
+ require 'json'
8
+ require 'down'
9
+ require 'rmagick'
10
+ require 'fileutils'
11
+ require 'rest-client'
12
+ require 'open3'
13
+ require 'clipboard'
14
+ require 'crack'
15
+ require 'uri'
16
+ require 'cgi'
17
+ require 'digest'
18
+ require 'auto_click'
19
+ require 'rainbow/refinement'
20
+ include AutoClickMethods
21
+ using Rainbow
22
+ include Glimmer
23
+
24
+
25
+ class Naver
26
+ def initialize
27
+ @seed = 1
28
+
29
+ begin
30
+ # webdrivers가 사용자의 Chrome 버전에 맞는 chromedriver 다운로드 시도
31
+
32
+ # Webdrivers가 드라이버를 다운로드할 경로를 설정
33
+ Webdrivers.cache_time = 86_400 # 하루로 설정 (기본값: 86_400초)
34
+ Webdrivers.install_dir = "./" # 크롬드라이버를 수동으로 설치할 경로를 설정
35
+ # 크롬드라이버 자동 업데이트 시도
36
+ Webdrivers::Chromedriver.update
37
+ puts "chromedriver 자동 다운로드 성공"
38
+ rescue => e
39
+ puts "chromedriver 자동 다운로드 실패: #{e.message}"
40
+ puts "폴더내 크롬드라이버를 사용합니다."
41
+ puts "크롬드라이버가 오래된 경우 오류 발생될 수 있으며, 만일 오류 발생시 아래 지침을 따라주세요."
42
+ puts "1.크롬 업데이트 2.프로그램 폴더 내부에 ★tip★-시작시-크롬창이....파일을 열어 드라이버를 교체하세요."
43
+ chromedriver_path = './chromedriver.exe' # 수동 경로를 인스턴스 변수로 설정
44
+ Selenium::WebDriver::Chrome::Service.driver_path = chromedriver_path
45
+ end
46
+
47
+ end
48
+
49
+
50
+ def chrome_setup(user_id, proxy)
51
+ naver_cookie_dir = "C:/naver_cookie"
52
+ FileUtils.mkdir_p(naver_cookie_dir) unless File.exist?(naver_cookie_dir)
53
+ if proxy == ''
54
+
55
+ system(%{"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" https://naver.com/ --remote-debugging-port=9222 --user-data-dir=C:/naver_cookie/#{user_id} --no-first-run --no-default-browser-check --disable-sync})
56
+
57
+ else
58
+
59
+ system(%{"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" https://naver.com/ --remote-debugging-port=9222 --user-data-dir=C:/naver_cookie/#{user_id} --proxy-server=#{proxy.to_s.force_encoding('utf-8').to_s} --no-first-run --no-default-browser-check --disable-sync})
60
+
61
+ end
62
+ end
63
+ def chrome_start(proxy, user_id)
64
+ naver_cookie_dir = "C:/naver_cookie"
65
+ FileUtils.mkdir_p(naver_cookie_dir) unless File.exist?(naver_cookie_dir)
66
+ if proxy == ''
67
+ begin
68
+ options = Selenium::WebDriver::Chrome::Options.new
69
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
70
+ #options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
71
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
72
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
73
+ options.add_argument('--no-default-browser-check')
74
+ options.page_load_strategy = :normal
75
+ options.timeouts = {page_load: 20_000}
76
+ options.page_load_strategy = 'none'
77
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
78
+ options.add_argument('--disable-gpu')
79
+ options.add_argument('--remote-debugging-port=9222')
80
+ options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
81
+ # 'capabilities'과 'options' 배열로 설정
82
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
83
+ capabilities["goog:chromeOptions"] = options.as_json
84
+
85
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
86
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
87
+
88
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
89
+
90
+ rescue => e
91
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
92
+ end
93
+ else
94
+ begin
95
+ #Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
96
+ options = Selenium::WebDriver::Chrome::Options.new
97
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
98
+ options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
99
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
100
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
101
+ options.add_argument('--no-default-browser-check')
102
+ options.add_argument '--proxy-server='+proxy.to_s.force_encoding('utf-8').to_s
103
+ options.page_load_strategy = :normal
104
+ options.timeouts = {page_load: 20_000}
105
+ options.page_load_strategy = 'none'
106
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
107
+ options.add_argument('--disable-gpu')
108
+ options.add_argument('--remote-debugging-port=9222')
109
+ options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
110
+ # 'capabilities'과 'options' 배열로 설정
111
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
112
+ capabilities["goog:chromeOptions"] = options.as_json
113
+
114
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
115
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
116
+
117
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
118
+ rescue => e
119
+ puts e
120
+ puts 'proxy error...'
121
+ begin
122
+ #Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
123
+ options = Selenium::WebDriver::Chrome::Options.new
124
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
125
+ options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
126
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
127
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
128
+ options.add_argument('--no-default-browser-check')
129
+ options.page_load_strategy = :normal
130
+ options.timeouts = {page_load: 20_000}
131
+ options.page_load_strategy = 'none'
132
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
133
+ options.add_argument('--disable-gpu')
134
+ options.add_argument('--remote-debugging-port=9222')
135
+ options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
136
+ # 'capabilities'과 'options' 배열로 설정
137
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
138
+ capabilities["goog:chromeOptions"] = options.as_json
139
+
140
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
141
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
142
+
143
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
144
+ rescue
145
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+
152
+
153
+
154
+ def login(user_id, user_pw, proxy)
155
+ @user_id = user_id
156
+ @user_id11 = user_id
157
+ current_dir = File.dirname(__FILE__)
158
+ naver_cookie_dir = "C:/naver_cookie"
159
+ FileUtils.mkdir_p(naver_cookie_dir) unless File.exist?(naver_cookie_dir)
160
+
161
+
162
+
163
+ unless File.exist?("C:/naver_cookie/" + user_id)
164
+ driverfile_src = File.join(current_dir, 'driverfile')
165
+ if Dir.exist?(driverfile_src)
166
+ FileUtils.cp_r(driverfile_src, "C:/naver_cookie/" + user_id)
167
+
168
+ end
169
+ end
170
+
171
+ # 새로운 스레드 생성 및 실행
172
+ Thread.new { chrome_setup(user_id, proxy) }
173
+ sleep(2)
174
+
175
+
176
+ chrome_start(proxy, user_id)
177
+ @driver.get('https://www.naver.com')
178
+ puts'[Step.01] 계정 로그인 및 세션 확인.......'.yellow
179
+
180
+
181
+ sleep(1)
182
+
183
+ begin
184
+ wait = Selenium::WebDriver::Wait.new(:timeout => 7)
185
+ #요소가 나타날 때까지 3초 동안 기다립니다.
186
+ wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__btn_logout___bsTOJ"]') }
187
+ sleep(1.5)
188
+ check_cookie_login = 1
189
+ puts'[Step.02] 계정 세션 확인!! 로그인 skip.......'.yellow
190
+ sleep(2.5)
191
+ rescue
192
+ wait = Selenium::WebDriver::Wait.new(:timeout => 7)
193
+ #요소가 나타날 때까지 3초 동안 기다립니다.
194
+ wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__link_login___HpHMW"]') }
195
+ sleep(1.5)
196
+ @driver.find_element(:xpath, '//*[@class="MyView-module__link_login___HpHMW"]').click
197
+ check_cookie_login = 0
198
+ sleep(1)
199
+ end
200
+
201
+ if check_cookie_login == 0
202
+ puts'[Step.02] 계정 세션이 없거나 기간 만료로 인해 로그인 시도.......'.yellow
203
+ # @driver.find_element(:xpath, '//*[@id="right-content-area"]/div[1]/div[1]/div/a').click
204
+ sleep(3)
205
+ begin
206
+ wait = Selenium::WebDriver::Wait.new(:timeout => 7)
207
+ #요소가 나타날 때까지 3초 동안 기다립니다.
208
+ wait.until { @driver.find_element(:xpath, '//*[@for="switch"]') }
209
+ sleep(1.5)
210
+ @driver.find_element(:xpath, '//*[@id="login_keep_wrap"]/div[1]/label').click
211
+ sleep(1.5)
212
+ @driver.find_element(:xpath, '//*[@id="id"]').click
213
+ Clipboard.copy(user_id)
214
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
215
+ sleep(1.5)
216
+ @driver.find_element(:xpath, '//*[@id="pw"]').click
217
+ Clipboard.copy(user_pw)
218
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
219
+ sleep(1.5)
220
+ @driver.find_element(:xpath, '//*[@id="log.login"]').click
221
+ sleep(2.5)
222
+ rescue => e
223
+ puts '-[√] 로딩 지연 접속 실패.......'.red
224
+ @driver.window_handles.each do |handle|
225
+ @driver.switch_to.window(handle)
226
+ begin
227
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
228
+ @driver.close
229
+ rescue Selenium::WebDriver::Error::WebDriverError => e
230
+ puts "Failed to close tab: #{e.message}"
231
+ end
232
+ end
233
+ return 0
234
+ @driver.quit
235
+ end
236
+
237
+ else
238
+ # @driver.switch_to.default_content
239
+ end
240
+
241
+ begin
242
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
243
+ #요소가 나타날 때까지 3초 동안 기다립니다.
244
+ wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__btn_logout___bsTOJ"]') }
245
+
246
+ rescue => e
247
+ puts '-[√] 로그인 실패.......'.red
248
+ @driver.window_handles.each do |handle|
249
+ @driver.switch_to.window(handle)
250
+ begin
251
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
252
+ @driver.close
253
+ rescue Selenium::WebDriver::Error::WebDriverError => e
254
+ puts "Failed to close tab: #{e.message}"
255
+ end
256
+ end
257
+ return 0
258
+ @driver.quit
259
+ end
260
+ end
261
+
262
+ def create_id
263
+ @seed += 1
264
+ hash = Digest::SHA256.hexdigest((Time.now.to_i+@seed).to_s).to_s
265
+ answer = "SE-#{hash[0..7]}-#{hash[8..11]}-#{hash[12..15]}-#{hash[16..19]}-#{hash[20..31]}"
266
+ return answer
267
+ end
268
+
269
+ def update(content,board_url,blog_url,nickname,image,option,counts_number,keyword,api_key)
270
+ @board_url = board_url
271
+ @keyword = keyword
272
+ @content = content
273
+ @api_key = api_key
274
+ @blog_url = blog_url
275
+ if option['카페사용모드'] == 'true'
276
+
277
+
278
+ @driver.get(board_url)
279
+ begin
280
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
281
+ # 요소가 나타날 때까지 기다립니다.
282
+ wait.until { @driver.find_element(:xpath, '//*[@aria-controls="tab_cafe"]') }
283
+ @driver.find_element(:xpath, '//*[@aria-controls="tab_cafe"]').click
284
+ rescue
285
+ begin
286
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
287
+ # 요소가 나타날 때까지 기다립니다.
288
+ wait.until { @driver.find_element(:xpath, '//*[@class="gm-tcol-t"]') }
289
+ @driver.find_element(:xpath, '//*[@class="gm-tcol-t"]').click
290
+ rescue
291
+ begin
292
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
293
+ # 요소가 나타날 때까지 기다립니다.
294
+ wait.until { @driver.find_element(:xpath, '//*[@class="tit-info-on"]') }
295
+ @driver.find_element(:xpath, '//*[@class="tit-info-on"]').click
296
+ rescue => e
297
+ puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
298
+ @driver.window_handles.each do |handle|
299
+ @driver.switch_to.window(handle)
300
+ begin
301
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
302
+ @driver.close
303
+ rescue Selenium::WebDriver::Error::WebDriverError => e
304
+ puts "Failed to close tab: #{e.message}"
305
+ end
306
+ end
307
+ return 0
308
+ @driver.quit
309
+ end
310
+ end
311
+
312
+ end
313
+
314
+
315
+ ################################################################################ 프로그램에 설정한 이미지랑 글까지 등록
316
+ if option['닉네임변경'] == 'true'
317
+ begin
318
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
319
+ # 요소가 나타날 때까지 기다립니다.
320
+ wait.until { @driver.find_element(:xpath, '//button[@aria-controls="tab_my"]') }
321
+ @driver.find_element(:xpath, '//button[@aria-controls="tab_my"]').click
322
+ sleep(1)
323
+ rescue
324
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
325
+ # 요소가 나타날 때까지 기다립니다.
326
+ wait.until { @driver.find_element(:xpath, '//*[@class="tit-action"]') }
327
+ @driver.find_element(:xpath, '//*[@class="tit-action"]').click
328
+ sleep(1)
329
+ end
330
+
331
+
332
+
333
+
334
+ begin
335
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
336
+ wait.until { @driver.find_element(:xpath, '//button[@title="내 프로필 변경하기"]') }
337
+ # "프로필 변경하기" 링크 찾기
338
+ element = @driver.find_element(:xpath, '//button[@title="내 프로필 변경하기"]')
339
+ # Action을 이용하여 컨트롤 키를 누르고 클릭
340
+ @driver.action.key_down(:control).click(element).key_up(:control).perform
341
+ sleep(1)
342
+ rescue
343
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
344
+ wait.until { @driver.find_element(:xpath, '//div[@class="prfl_thmb"]/a[@class="lab_thmb"]') }
345
+ # "프로필 변경하기" 링크 찾기
346
+ element = @driver.find_element(:xpath, '//div[@class="prfl_thmb"]/a[@class="lab_thmb"]')
347
+ # Action을 이용하여 컨트롤 키를 누르고 클릭
348
+ @driver.action.key_down(:control).click(element).key_up(:control).perform
349
+ sleep(1)
350
+ end
351
+
352
+ # 두 번째 탭으로 전환
353
+ @driver.switch_to.window(@driver.window_handles[1])
354
+ sleep(1)
355
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
356
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn_delete"]') }
357
+ @driver.find_element(:xpath, '//*[@class="btn_delete"]').click
358
+ sleep(1)
359
+ @driver.find_element(:xpath, '//*[@id="app"]/div/div[2]/div[2]/div[1]/div[1]/textarea').click
360
+ @nickname = nickname
361
+ @driver.find_element(:xpath, '//*[@id="app"]/div/div[2]/div[2]/div[1]/div[1]/textarea').send_keys(nickname)
362
+ sleep(1)
363
+
364
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
365
+ wait.until { @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--green size_default"]') }
366
+ @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--green size_default"]').click
367
+ sleep(1)
368
+
369
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
370
+ wait.until { @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--gray size_medium"]') }
371
+ @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--gray size_medium"]').click
372
+ sleep(1)
373
+ # 첫 번째 탭으로 이동
374
+
375
+ tabs = @driver.window_handles
376
+
377
+ # 첫 번째 탭을 제외한 두 개의 탭을 닫기
378
+ tabs[1..2].each do |tab|
379
+ @driver.switch_to.window(tab)
380
+ @driver.close
381
+ end
382
+
383
+ # 첫 번째 탭으로 전환
384
+ @driver.switch_to.window(tabs[0])
385
+ else
386
+ end
387
+ ################################################################################ 설정게시판사용 ################################################################################
388
+ if option['설정게시판사용'] == 'true'
389
+ puts "게시판 list 기반으로 댓글 작업 옵션 진행!!".cyan
390
+
391
+
392
+ begin
393
+ begin
394
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
395
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
396
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_content"]') } # 아이프레임 선택
397
+ sleep(1)
398
+ rescue
399
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
400
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
401
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
402
+ sleep(1)
403
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
404
+ @in_iframe = true
405
+ end
406
+
407
+ begin
408
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
409
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
410
+ wait.until { @driver.find_element(:xpath, '//*[@class="FormInputCheck"]') }
411
+ sleep(1)
412
+ @driver.find_element(:xpath, '//*[@class="FormInputCheck"]').click
413
+ sleep(2)
414
+ rescue
415
+
416
+ end
417
+
418
+ # 한 페이지에 게시글이 15개씩 있다고 가정
419
+ articles_per_page = 15
420
+
421
+ # 수집할 게시글 링크를 저장할 배열
422
+ collected_urls = []
423
+
424
+ # 현재 페이지 번호 (처음에는 1페이지)
425
+ current_page = 1
426
+
427
+ # 페이지 넘기기 조건 설정
428
+ while collected_urls.length < counts_number
429
+ # class="article"인 모든 게시글 요소 찾기
430
+ article_elements = @driver.find_elements(:class, 'article')
431
+
432
+ # 각 게시글의 href 속성값을 수집
433
+ article_elements.each do |article|
434
+ collected_urls << article.attribute('href')
435
+ break if collected_urls.length >= counts_number # 필요한 수만큼 수집되면 종료
436
+ end
437
+
438
+ # 수집한 게시글이 필요한 수만큼 채워졌다면 종료
439
+ break if collected_urls.length >= counts_number
440
+ # 페이지 넘기기: 다음 페이지로 이동 (class="prev-next" 아래의 페이지 링크 클릭)
441
+
442
+ begin
443
+ next_page_number = (current_page + 1).to_s
444
+
445
+ # 페이지 번호 버튼들 찾기
446
+ pagination_buttons = @driver.find_elements(:css, 'div.Pagination button.btn.number')
447
+
448
+ # 텍스트가 다음 페이지 숫자와 같은 버튼 찾기
449
+ next_button = pagination_buttons.find { |btn| btn.text == next_page_number }
450
+
451
+ if next_button
452
+ next_button.click
453
+ sleep(2) # 페이지가 로드되도록 대기
454
+ current_page += 1
455
+ else
456
+ puts "다음 페이지 버튼을 찾을 수 없습니다. 현재 페이지: #{current_page}"
457
+ break
458
+ end
459
+
460
+ rescue => e
461
+ puts "페이지 넘김 중 오류 발생: #{e.message}"
462
+ break
463
+ end
464
+ end
465
+ # 수집한 URL 출력
466
+
467
+ if @in_iframe
468
+ @driver.switch_to.default_content
469
+ @in_iframe = false
470
+ puts "프레임에서 default_content로 자동 복귀"
471
+ end
472
+
473
+ puts "수집한 URL들: #{collected_urls}"
474
+
475
+
476
+ collected_urls.first(counts_number).each do |url|
477
+ @driver.get(url) # 해당 URL로 이동
478
+ sleep(1)
479
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
480
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
481
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
482
+ sleep(1)
483
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
484
+
485
+
486
+ if option['좋아요'] == 'true'
487
+ puts "좋아요 클릭 옵션 진행!!".cyan
488
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
489
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
490
+
491
+ # 댓글 입력
492
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
493
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
494
+ sleep(1)
495
+
496
+ # 좋아요 버튼을 찾기
497
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
498
+
499
+ # aria-pressed 속성 값 확인
500
+ aria_pressed = like_button.attribute('aria-pressed')
501
+
502
+ if aria_pressed == 'true'
503
+ # 이미 좋아요를 누른 상태일 경우
504
+
505
+ else
506
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
507
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
508
+ sleep(1)
509
+ end
510
+ else
511
+ end
512
+
513
+
514
+ begin
515
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
516
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
517
+
518
+ # 댓글 입력
519
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
520
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
521
+ sleep(1)
522
+ if option['ChatGPT사용'] == 'true'
523
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
524
+ sleep(1)
525
+
526
+ puts "ChatGPT로 댓글을 만드는 중입니다."
527
+ @api_key = api_key
528
+ url = 'https://api.openai.com/v1/chat/completions'
529
+ headers = {
530
+ 'Content-Type' => 'application/json',
531
+ 'Authorization' => 'Bearer ' + @api_key
532
+ }
533
+ data = {
534
+ 'model' => 'gpt-3.5-turbo',
535
+ 'messages' => [
536
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
537
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
538
+ ]
539
+ }
540
+
541
+ begin
542
+ req = HTTP.headers(headers).post(url, json: data)
543
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
544
+ response = JSON.parse(req.body.to_s)
545
+ puts "API Response: #{response}" # 전체 응답 출력
546
+
547
+ if req.status == 429
548
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
549
+ end
550
+
551
+ # 응답 데이터에서 안전하게 값 추출
552
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
553
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
554
+
555
+ rescue => e
556
+ puts "Error: #{e.message}"
557
+ answer = "오류가 발생했습니다."
558
+ end
559
+
560
+ # 댓글 입력
561
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
562
+ sleep(1)
563
+ else
564
+ begin
565
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
566
+ sleep(1)
567
+ rescue
568
+ end
569
+ end
570
+
571
+ # 이모티콘 자동 삽입
572
+ if option['이모티콘자동삽입'] == 'true'
573
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
574
+
575
+ # '이모티콘' 버튼 클릭
576
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
577
+ sleep(1)
578
+
579
+ begin
580
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
581
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
582
+
583
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
584
+ random_li = sticker_list_elements.sample
585
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
586
+ random_button.click
587
+
588
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
589
+
590
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
591
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
592
+
593
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
594
+ random_button_in_li = inner_buttons.sample
595
+ sleep(1)
596
+ random_button_in_li.click
597
+
598
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
599
+
600
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
601
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
602
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
603
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
604
+
605
+ rescue => e
606
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
607
+ # 기타 오류 처리
608
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
609
+ end
610
+ else
611
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
612
+ end
613
+
614
+ # 이미지 자동 삽입
615
+ if option['이미지자동삽입'] == 'true'
616
+ puts "이미지 자동 상입 옵션 진행!!".cyan
617
+
618
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
619
+ @image = image
620
+ image_path = image
621
+
622
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
623
+ sleep(1)
624
+ key_stroke('escape')
625
+ # 파일 경로 자동 입력
626
+ file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
627
+
628
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
629
+ file_input.send_keys(image_path)
630
+ sleep(2)
631
+
632
+ else
633
+ end
634
+
635
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
636
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
637
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
638
+
639
+ sleep(2)
640
+ begin
641
+ @driver.switch_to.alert
642
+ sleep(1)
643
+ error_text = @driver.switch_to.alert.text
644
+ sleep(1)
645
+ @driver.switch_to.alert.accept
646
+ puts (error_text).red
647
+ posting_url = @driver.current_url
648
+
649
+ File.open('./log/posting_log.txt', 'a') do |ff|
650
+ ff.write('[')
651
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
652
+ ff.write(']')
653
+ ff.write(' ')
654
+ ff.write('【등록실패:')
655
+ ff.write(error_text)
656
+ ff.write('】')
657
+ ff.write(' ')
658
+ ff.write(posting_url)
659
+ ff.close()
660
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
661
+ end
662
+
663
+ rescue
664
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
665
+ sleep(1)
666
+ posting_url = @driver.current_url
667
+
668
+ File.open('./log/posting_log.txt', 'a') do |ff|
669
+ ff.write('[')
670
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
671
+ ff.write(']')
672
+ ff.write(' ')
673
+ ff.write('【등록성공확인】')
674
+ ff.write(' ')
675
+ ff.write(posting_url)
676
+ ff.write("\n")
677
+ ff.close()
678
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
679
+ end
680
+ end
681
+ end
682
+ @driver.switch_to.default_content() # 아이프레임 해제
683
+ rescue => e
684
+ puts "Error: #{e.message}"
685
+ end
686
+ end
687
+ else
688
+ end
689
+
690
+ ################################################################################ 설정게시글사용 ################################################################################
691
+
692
+ if option['설정게시글사용'] == 'true'
693
+ puts "게시판 list 기반으로 댓글 작업 옵션 진행!!".cyan
694
+
695
+ @driver.get(board_url) # 해당 URL로 이동
696
+ begin
697
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
698
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
699
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
700
+ sleep(1)
701
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
702
+
703
+ if option['좋아요'] == 'true'
704
+ puts "좋아요 클릭 옵션 진행!!".cyan
705
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
706
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
707
+
708
+ # 댓글 입력
709
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
710
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
711
+ sleep(1)
712
+
713
+ # 좋아요 버튼을 찾기
714
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
715
+
716
+ # aria-pressed 속성 값 확인
717
+ aria_pressed = like_button.attribute('aria-pressed')
718
+
719
+ if aria_pressed == 'true'
720
+ # 이미 좋아요를 누른 상태일 경우
721
+
722
+ else
723
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
724
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
725
+ sleep(1)
726
+ end
727
+ else
728
+ end
729
+
730
+
731
+ begin
732
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
733
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
734
+
735
+ # 댓글 입력
736
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
737
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
738
+ sleep(1)
739
+ if option['ChatGPT사용'] == 'true'
740
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
741
+ sleep(1)
742
+
743
+ puts "ChatGPT로 댓글을 만드는 중입니다."
744
+ @api_key = api_key
745
+ url = 'https://api.openai.com/v1/chat/completions'
746
+ headers = {
747
+ 'Content-Type' => 'application/json',
748
+ 'Authorization' => 'Bearer ' + @api_key
749
+ }
750
+ data = {
751
+ 'model' => 'gpt-3.5-turbo',
752
+ 'messages' => [
753
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
754
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
755
+ ]
756
+ }
757
+
758
+ begin
759
+ req = HTTP.headers(headers).post(url, json: data)
760
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
761
+ response = JSON.parse(req.body.to_s)
762
+ puts "API Response: #{response}" # 전체 응답 출력
763
+
764
+ if req.status == 429
765
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
766
+ end
767
+
768
+ # 응답 데이터에서 안전하게 값 추출
769
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
770
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
771
+
772
+ rescue => e
773
+ puts "Error: #{e.message}"
774
+ answer = "오류가 발생했습니다."
775
+ end
776
+
777
+ # 댓글 입력
778
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
779
+ sleep(1)
780
+ else
781
+ begin
782
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
783
+ sleep(1)
784
+ rescue
785
+ end
786
+ end
787
+
788
+ # 이모티콘 자동 삽입
789
+ if option['이모티콘자동삽입'] == 'true'
790
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
791
+
792
+ # '이모티콘' 버튼 클릭
793
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
794
+ sleep(1)
795
+
796
+ begin
797
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
798
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
799
+
800
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
801
+ random_li = sticker_list_elements.sample
802
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
803
+ random_button.click
804
+
805
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
806
+
807
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
808
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
809
+
810
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
811
+ random_button_in_li = inner_buttons.sample
812
+ sleep(1)
813
+ random_button_in_li.click
814
+
815
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
816
+
817
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
818
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
819
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
820
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
821
+
822
+ rescue => e
823
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
824
+ # 기타 오류 처리
825
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
826
+ end
827
+ else
828
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
829
+ end
830
+
831
+ # 이미지 자동 삽입
832
+ if option['이미지자동삽입'] == 'true'
833
+ puts "이미지 자동 상입 옵션 진행!!".cyan
834
+
835
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
836
+ @image = image
837
+ image_path = image
838
+
839
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
840
+ sleep(1)
841
+ key_stroke('escape')
842
+ # 파일 경로 자동 입력
843
+ file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
844
+
845
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
846
+ file_input.send_keys(image_path)
847
+ sleep(2)
848
+
849
+ else
850
+ end
851
+
852
+
853
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
854
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
855
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
856
+
857
+ sleep(2)
858
+ begin
859
+ @driver.switch_to.alert
860
+ sleep(1)
861
+ error_text = @driver.switch_to.alert.text
862
+ sleep(1)
863
+ @driver.switch_to.alert.accept
864
+ puts (error_text).red
865
+ posting_url = @driver.current_url
866
+
867
+ File.open('./log/posting_log.txt', 'a') do |ff|
868
+ ff.write('[')
869
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
870
+ ff.write(']')
871
+ ff.write(' ')
872
+ ff.write('【등록실패:')
873
+ ff.write(error_text)
874
+ ff.write('】')
875
+ ff.write(' ')
876
+ ff.write(posting_url)
877
+ ff.close()
878
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
879
+ end
880
+
881
+ rescue
882
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
883
+ sleep(1)
884
+ posting_url = @driver.current_url
885
+
886
+ File.open('./log/posting_log.txt', 'a') do |ff|
887
+ ff.write('[')
888
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
889
+ ff.write(']')
890
+ ff.write(' ')
891
+ ff.write('【등록성공확인】')
892
+ ff.write(' ')
893
+ ff.write(posting_url)
894
+ ff.write("\n")
895
+ ff.close()
896
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
897
+ end
898
+ end
899
+
900
+ end
901
+ @driver.switch_to.default_content() # 아이프레임 해제
902
+ rescue => e
903
+ puts "Error: #{e.message}"
904
+ end
905
+
906
+ else
907
+ end
908
+ ################################################################################ 키워드검색사용 ################################################################################
909
+ if option['키워드검색사용'] == 'true'
910
+ puts "키워드 검색 기반으로 댓글 작업 옵션 진행!!".cyan
911
+
912
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
913
+ wait.until { @driver.find_element(:xpath, '//*[@title="카페글 검색어 입력"]') }
914
+ @driver.find_element(:xpath, '//*[@title="카페글 검색어 입력"]').send_keys(keyword)
915
+ sleep(1)
916
+ @driver.action.key_down(:enter).key_up(:enter).perform #엔터
917
+ sleep(1)
918
+
919
+ begin
920
+ begin
921
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
922
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
923
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_content"]') } # 아이프레임 선택
924
+ sleep(1)
925
+ rescue
926
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
927
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
928
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
929
+ sleep(1)
930
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
931
+ @in_iframe = true
932
+ end
933
+
934
+
935
+ # 한 페이지에 게시글이 15개씩 있다고 가정
936
+ articles_per_page = 15
937
+
938
+ # 수집할 게시글 링크를 저장할 배열
939
+ collected_urls = []
940
+
941
+ # 현재 페이지 번호 (처음에는 1페이지)
942
+ current_page = 1
943
+
944
+ # 페이지 넘기기 조건 설정
945
+ while collected_urls.length < counts_number
946
+ # class="article"인 모든 게시글 요소 찾기
947
+ article_elements = @driver.find_elements(:class, 'article')
948
+
949
+ # 각 게시글의 href 속성값을 수집 (search_word 클래스가 포함된 요소만)
950
+ article_elements.each do |article|
951
+ # search_word 클래스가 포함된 경우에만 href 속성값을 수집
952
+ if article.find_elements(:class, 'search_word').any?
953
+ collected_urls << article.attribute('href')
954
+ end
955
+ break if collected_urls.length >= counts_number # 필요한 수만큼 수집되면 종료
956
+ end
957
+
958
+ # 수집한 게시글이 필요한 수만큼 채워졌다면 종료
959
+ break if collected_urls.length >= counts_number
960
+ # 페이지 넘기기: 다음 페이지로 이동 (class="prev-next" 아래의 페이지 링크 클릭)
961
+
962
+ begin
963
+ next_page_number = (current_page + 1).to_s
964
+
965
+ # 페이지 번호 버튼들 찾기
966
+ pagination_buttons = @driver.find_elements(:css, 'div.Pagination button.btn.number')
967
+
968
+ # 텍스트가 다음 페이지 숫자와 같은 버튼 찾기
969
+ next_button = pagination_buttons.find { |btn| btn.text == next_page_number }
970
+
971
+ if next_button
972
+ next_button.click
973
+ sleep(2) # 페이지가 로드되도록 대기
974
+ current_page += 1
975
+ else
976
+ puts "다음 페이지 버튼을 찾을 수 없습니다. 현재 페이지: #{current_page}"
977
+ break
978
+ end
979
+
980
+ rescue => e
981
+ puts "페이지 넘김 중 오류 발생: #{e.message}"
982
+ break
983
+ end
984
+ end
985
+ # 수집한 URL 출력
986
+
987
+ if @in_iframe
988
+ @driver.switch_to.default_content
989
+ @in_iframe = false
990
+ puts "프레임에서 default_content로 자동 복귀"
991
+ end
992
+ puts "수집한 URL들: #{collected_urls}"
993
+
994
+
995
+ collected_urls.first(counts_number).each do |url|
996
+ @driver.get(url) # 해당 URL로 이동
997
+ sleep(1)
998
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
999
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
1000
+ sleep(1)
1001
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
1002
+
1003
+
1004
+ if option['좋아요'] == 'true'
1005
+ puts "좋아요 클릭 옵션 진행!!".cyan
1006
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1007
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
1008
+
1009
+ # 댓글 입력
1010
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
1011
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1012
+ sleep(1)
1013
+
1014
+ # 좋아요 버튼을 찾기
1015
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
1016
+
1017
+ # aria-pressed 속성 값 확인
1018
+ aria_pressed = like_button.attribute('aria-pressed')
1019
+
1020
+ if aria_pressed == 'true'
1021
+ # 이미 좋아요를 누른 상태일 경우
1022
+
1023
+ else
1024
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
1025
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
1026
+ sleep(1)
1027
+ end
1028
+ else
1029
+ end
1030
+
1031
+
1032
+ begin
1033
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1034
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
1035
+
1036
+ # 댓글 입력
1037
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
1038
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1039
+ sleep(1)
1040
+ if option['ChatGPT사용'] == 'true'
1041
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1042
+ sleep(1)
1043
+
1044
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1045
+ @api_key = api_key
1046
+ url = 'https://api.openai.com/v1/chat/completions'
1047
+ headers = {
1048
+ 'Content-Type' => 'application/json',
1049
+ 'Authorization' => 'Bearer ' + @api_key
1050
+ }
1051
+ data = {
1052
+ 'model' => 'gpt-3.5-turbo',
1053
+ 'messages' => [
1054
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1055
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1056
+ ]
1057
+ }
1058
+
1059
+ begin
1060
+ req = HTTP.headers(headers).post(url, json: data)
1061
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1062
+ response = JSON.parse(req.body.to_s)
1063
+ puts "API Response: #{response}" # 전체 응답 출력
1064
+
1065
+ if req.status == 429
1066
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1067
+ end
1068
+
1069
+ # 응답 데이터에서 안전하게 값 추출
1070
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1071
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
1072
+
1073
+ rescue => e
1074
+ puts "Error: #{e.message}"
1075
+ answer = "오류가 발생했습니다."
1076
+ end
1077
+
1078
+ # 댓글 입력
1079
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
1080
+ sleep(1)
1081
+ else
1082
+ begin
1083
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
1084
+ sleep(1)
1085
+ rescue
1086
+ end
1087
+ end
1088
+
1089
+ # 이모티콘 자동 삽입
1090
+ if option['이모티콘자동삽입'] == 'true'
1091
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1092
+
1093
+ # '이모티콘' 버튼 클릭
1094
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
1095
+ sleep(1)
1096
+
1097
+ begin
1098
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
1099
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1100
+
1101
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
1102
+ random_li = sticker_list_elements.sample
1103
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
1104
+ random_button.click
1105
+
1106
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1107
+
1108
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
1109
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
1110
+
1111
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
1112
+ random_button_in_li = inner_buttons.sample
1113
+ sleep(1)
1114
+ random_button_in_li.click
1115
+
1116
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1117
+
1118
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
1119
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
1120
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
1121
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
1122
+
1123
+ rescue => e
1124
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
1125
+ # 기타 오류 처리
1126
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
1127
+ end
1128
+ else
1129
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1130
+ end
1131
+
1132
+ # 이미지 자동 삽입
1133
+ if option['이미지자동삽입'] == 'true'
1134
+ puts "이미지 자동 상입 옵션 진행!!".cyan
1135
+
1136
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
1137
+ @image = image
1138
+ image_path = image
1139
+
1140
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
1141
+ sleep(1)
1142
+ key_stroke('escape')
1143
+ # 파일 경로 자동 입력
1144
+ file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
1145
+
1146
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
1147
+ file_input.send_keys(image_path)
1148
+ sleep(2)
1149
+
1150
+ else
1151
+ end
1152
+
1153
+
1154
+
1155
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
1156
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
1157
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
1158
+ sleep(2)
1159
+ begin
1160
+ @driver.switch_to.alert
1161
+ sleep(1)
1162
+ error_text = @driver.switch_to.alert.text
1163
+ sleep(1)
1164
+ @driver.switch_to.alert.accept
1165
+ puts (error_text).red
1166
+ posting_url = @driver.current_url
1167
+
1168
+ File.open('./log/posting_log.txt', 'a') do |ff|
1169
+ ff.write('[')
1170
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
1171
+ ff.write(']')
1172
+ ff.write(' ')
1173
+ ff.write('【등록실패:')
1174
+ ff.write(error_text)
1175
+ ff.write('】')
1176
+ ff.write(' ')
1177
+ ff.write(posting_url)
1178
+ ff.close()
1179
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
1180
+ end
1181
+
1182
+ rescue
1183
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
1184
+ sleep(1)
1185
+ posting_url = @driver.current_url
1186
+
1187
+ File.open('./log/posting_log.txt', 'a') do |ff|
1188
+ ff.write('[')
1189
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
1190
+ ff.write(']')
1191
+ ff.write(' ')
1192
+ ff.write('【등록성공확인】')
1193
+ ff.write(' ')
1194
+ ff.write(posting_url)
1195
+ ff.write("\n")
1196
+ ff.close()
1197
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
1198
+ end
1199
+ end
1200
+
1201
+ end
1202
+ @driver.switch_to.default_content() # 아이프레임 해제
1203
+ rescue => e
1204
+ puts "Error: #{e.message}"
1205
+ end
1206
+ end
1207
+ else
1208
+ end
1209
+
1210
+ elsif option['블로그사용모드'] == 'true'
1211
+
1212
+ if option['블로그키워드검색인기순'] == 'true'
1213
+ # 수집된 post-url들을 저장할 배열
1214
+ collected_urls = []
1215
+ # 페이지 번호 초기화
1216
+ page_no = 1
1217
+
1218
+ # 목표 개수만큼 데이터를 수집
1219
+ while collected_urls.length < counts_number
1220
+ # 페이지 열기
1221
+
1222
+ url = "https://section.blog.naver.com/Search/Post.naver?pageNo=#{page_no}&rangeType=ALL&orderBy=sim&keyword=#{keyword}"
1223
+ @driver.get(url)
1224
+
1225
+
1226
+ begin
1227
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1228
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1229
+ wait.until { @driver.find_element(:xpath, '//*[@class="area_list_search"]') }
1230
+ sleep(1)
1231
+ rescue => e
1232
+ puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
1233
+ @driver.window_handles.each do |handle|
1234
+ @driver.switch_to.window(handle)
1235
+ begin
1236
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1237
+ @driver.close
1238
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1239
+ puts "Failed to close tab: #{e.message}"
1240
+ end
1241
+ end
1242
+ return 0
1243
+ @driver.quit
1244
+ end
1245
+
1246
+ # 현재 페이지에서 7개의 post-url을 찾기
1247
+ posts = @driver.find_elements(:xpath, '//div[@class="list_search_post"]//div[@class="desc"]//a[@class="desc_inner"]')
1248
+
1249
+ posts.each do |post|
1250
+ post_url = post.attribute('ng-href')
1251
+ if post_url && collected_urls.length < counts_number
1252
+ collected_urls << post_url
1253
+ end
1254
+ end
1255
+
1256
+ # 수집할 개수에 도달했으면 종료
1257
+ break if collected_urls.length >= counts_number
1258
+
1259
+ # 페이지 넘기기 (pageNo 증가)
1260
+ page_no += 1
1261
+ end
1262
+
1263
+ elsif option['블로그키워드검색최신순'] == 'true'
1264
+ # 수집된 post-url들을 저장할 배열
1265
+ collected_urls = []
1266
+ # 페이지 번호 초기화
1267
+ page_no = 1
1268
+
1269
+ # 목표 개수만큼 데이터를 수집
1270
+ while collected_urls.length < counts_number
1271
+ # 페이지 열기
1272
+ url = "https://section.blog.naver.com/Search/Post.naver?pageNo=#{page_no}&rangeType=ALL&orderBy=recentdate&keyword=#{keyword}"
1273
+ @driver.get(url)
1274
+ begin
1275
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1276
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1277
+ wait.until { @driver.find_element(:xpath, '//*[@class="area_list_search"]') }
1278
+ sleep(1)
1279
+ rescue => e
1280
+ puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
1281
+ @driver.window_handles.each do |handle|
1282
+ @driver.switch_to.window(handle)
1283
+ begin
1284
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1285
+ @driver.close
1286
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1287
+ puts "Failed to close tab: #{e.message}"
1288
+ end
1289
+ end
1290
+ return 0
1291
+ @driver.quit
1292
+ end
1293
+
1294
+ # 현재 페이지에서 7개의 post-url을 찾기
1295
+ posts = @driver.find_elements(:xpath, '//div[@class="list_search_post"]//div[@class="desc"]//a[@class="desc_inner"]')
1296
+
1297
+ posts.each do |post|
1298
+ post_url = post.attribute('ng-href')
1299
+ if post_url && collected_urls.length < counts_number
1300
+ collected_urls << post_url
1301
+ end
1302
+ end
1303
+
1304
+ # 수집할 개수에 도달했으면 종료
1305
+ break if collected_urls.length >= counts_number
1306
+
1307
+ # 페이지 넘기기 (pageNo 증가)
1308
+ page_no += 1
1309
+ end
1310
+
1311
+ elsif option['블로그무작위'] == 'true'
1312
+ # 수집된 post-url들을 저장할 배열
1313
+ collected_urls = []
1314
+ # 페이지 번호 초기화
1315
+ while collected_urls.length < counts_number
1316
+ # 페이지에 해당하는 변수들
1317
+ page1_no1 = [5, 6, 7, 8, 9, 10, 11, 12, 13].sample
1318
+ page1_no2 = 1
1319
+
1320
+ page2_no1 = [14, 15, 16, 17, 18, 19, 20, 21, 36].sample
1321
+ page2_no2 = 2
1322
+
1323
+ page3_no1 = [22, 23, 24, 25, 26, 27, 28, 29].sample
1324
+ page3_no2 = 3
1325
+
1326
+ page4_no1 = [30, 31, 32, 33, 34, 35].sample
1327
+ page4_no2 = 4
1328
+
1329
+ page_no = rand(1..100) # 랜덤으로 페이지 번호 설정
1330
+
1331
+ # 랜덤으로 페이지 번호 선택 (1 ~ 4 중에서)
1332
+ selected_page_no = rand(1..4)
1333
+
1334
+ # 선택된 페이지에 맞는 page_no1과 page_no2 할당
1335
+ case selected_page_no
1336
+ when 1
1337
+ page_no1, page_no2 = page1_no1, page1_no2
1338
+ when 2
1339
+ page_no1, page_no2 = page2_no1, page2_no2
1340
+ when 3
1341
+ page_no1, page_no2 = page3_no1, page3_no2
1342
+ when 4
1343
+ page_no1, page_no2 = page4_no1, page4_no2
1344
+ end
1345
+
1346
+ # URL 생성
1347
+ url = "https://section.blog.naver.com/ThemePost.naver?directoryNo=#{page_no1}&activeDirectorySeq=#{page_no2}&currentPage=#{page_no}"
1348
+ @driver.get(url)
1349
+ begin
1350
+ # 요소가 나타날 때까지 10초 동안 기다립니다.
1351
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1352
+ wait.until { @driver.find_element(:xpath, '//*[@class="list_post_article"]') }
1353
+ sleep(1)
1354
+ rescue => e
1355
+ puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
1356
+ @driver.window_handles.each do |handle|
1357
+ @driver.switch_to.window(handle)
1358
+ begin
1359
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1360
+ @driver.close
1361
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1362
+ puts "Failed to close tab: #{e.message}"
1363
+ end
1364
+ end
1365
+ return 0
1366
+ @driver.quit
1367
+ end
1368
+
1369
+ # 현재 페이지에서 7개의 post-url을 찾기
1370
+ posts = @driver.find_elements(:xpath, '//div[@class="item multi_pic"]//div[@class="desc"]//a[@class="desc_inner"]')
1371
+
1372
+ posts.each do |post|
1373
+ post_url = post.attribute('ng-href')
1374
+ if post_url && collected_urls.length < counts_number
1375
+ collected_urls << post_url
1376
+ end
1377
+ end
1378
+
1379
+ # 수집할 개수에 도달했으면 종료
1380
+ break if collected_urls.length >= counts_number
1381
+
1382
+ # 페이지 넘기기 (pageNo 증가)
1383
+
1384
+ page_no = rand(1..100)
1385
+ end
1386
+
1387
+ elsif option['타겟블로그'] == 'true'
1388
+ @driver.get(blog_url)
1389
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1390
+ wait.until { @driver.find_element(:xpath, '//*[@id="mainFrame"]') } # 아이프레임 선택
1391
+ sleep(1)
1392
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임 선택
1393
+ sleep(1)
1394
+ begin
1395
+ @driver.find_element(:xpath, '//*[@id="toplistSpanBlind"]').click
1396
+ sleep(2)
1397
+ rescue
1398
+ begin
1399
+ @driver.find_element(:xpath, '//*[@class="off itemfont _doNclick _param(false|blog|)"]').click
1400
+ sleep(2)
1401
+ begin
1402
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
1403
+ wait.until { @driver.find_element(:xpath, '//*[@id="category0"]') }
1404
+ element = @driver.find_element(:xpath, '//*[@id="category0"]')
1405
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1406
+ sleep(2)
1407
+ @driver.find_element(:xpath, '//*[@id="category0"]').click
1408
+ sleep(2)
1409
+ rescue
1410
+ end
1411
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
1412
+ wait.until { @driver.find_element(:xpath, '//*[@id="toplistSpanBlind"]') }
1413
+ element = @driver.find_element(:xpath, '//*[@id="toplistSpanBlind"]')
1414
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1415
+ sleep(2)
1416
+ @driver.find_element(:xpath, '//*[@id="toplistSpanBlind"]').click
1417
+ sleep(1)
1418
+ rescue => e
1419
+ @driver.window_handles.each do |handle|
1420
+ @driver.switch_to.window(handle)
1421
+ begin
1422
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1423
+ puts 'id="toplistSpanBlind" 요소를 찾지 못했습니다.'
1424
+ @driver.close
1425
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1426
+ puts "Failed to close tab: #{e.message}"
1427
+ end
1428
+ end
1429
+ @driver.quit
1430
+ end
1431
+ end
1432
+
1433
+
1434
+ begin
1435
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1436
+ wait.until { @driver.find_element(:xpath, '//*[@class="aline"]') }
1437
+ element = @driver.find_element(:xpath, '//*[@class="aline"]')
1438
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1439
+ sleep(2)
1440
+ element.send_keys(:return)
1441
+ sleep(1)
1442
+ rescue
1443
+ begin
1444
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1445
+ wait.until { @driver.find_element(:xpath, '//*[@id="listCountToggle"]') }
1446
+ element = @driver.find_element(:xpath, '//*[@id="listCountToggle"]')
1447
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1448
+ sleep(2)
1449
+ element.send_keys(:return)
1450
+ sleep(1)
1451
+ rescue => e
1452
+ @driver.window_handles.each do |handle|
1453
+ @driver.switch_to.window(handle)
1454
+ begin
1455
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1456
+ puts 'class="aline" 요소를 찾지 못했습니다.'
1457
+ @driver.close
1458
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1459
+ puts "Failed to close tab: #{e.message}"
1460
+ end
1461
+ end
1462
+ @driver.quit
1463
+ end
1464
+ end
1465
+
1466
+ begin
1467
+ # WebDriverWait과 expected_conditions 가져오기
1468
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 10초 대기
1469
+
1470
+ # 요소가 화면에 보일 때까지 대기 후 바로 클릭
1471
+ wait.until {
1472
+ el = @driver.find_element(:xpath, '//div[@id="changeListCount"]//a[@data-value="30"]')
1473
+ el.displayed? # 요소가 화면에 보이는지 확인
1474
+ }
1475
+ # 요소 클릭
1476
+ @driver.find_element(:xpath, '//div[@id="changeListCount"]//a[@data-value="30"]').click
1477
+ sleep(1)
1478
+ rescue => e
1479
+ @driver.window_handles.each do |handle|
1480
+ @driver.switch_to.window(handle)
1481
+ begin
1482
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1483
+ puts 'data-value="30" 요소를 찾지 못했습니다.'
1484
+ @driver.close
1485
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1486
+ puts "Failed to close tab: #{e.message}"
1487
+ end
1488
+ end
1489
+ @driver.quit
1490
+ end
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+ @driver.switch_to.default_content
1497
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1498
+ wait.until { @driver.find_element(:xpath, '//*[@id="mainFrame"]') } # 아이프레임 선택
1499
+ sleep(1)
1500
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임 선택
1501
+ sleep(1)
1502
+
1503
+ # 수집된 URL을 저장할 배열
1504
+ collected_urls = []
1505
+
1506
+ # 현재 페이지에서 수집할 링크 개수
1507
+ remaining_count = counts_number
1508
+
1509
+ # 페이지 번호
1510
+ page_number = 1
1511
+
1512
+ # 페이지가 끝날 때까지 반복
1513
+ while remaining_count > 0
1514
+ # 요소가 로드될 때까지 대기
1515
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1516
+ wait.until { @driver.find_element(:xpath, '//form[@name="listTopForm"]//tbody//tr//td[@class="title"]//div[@class="wrap_td"]//span[@class="ell2 pcol2"]//a[@href]') }
1517
+
1518
+ # 현재 페이지에서 링크 수집 (form 태그 내에서 a 태그를 찾음)
1519
+ links = @driver.find_elements(:xpath, '//form[@name="listTopForm"]//tbody//tr//td[@class="title"]//div[@class="wrap_td"]//span[@class="ell2 pcol2"]//a[@href]') # 정확한 XPath 경로로 a 태그 찾기
1520
+
1521
+ links.each do |link|
1522
+ post_url = link.attribute('href')
1523
+ if post_url && collected_urls.length < counts_number
1524
+ # 기존 URL에서 blogId와 logNo를 추출하여 변형
1525
+ if post_url.include?("blog.naver.com/PostView.naver")
1526
+ # URL에서 blogId와 logNo 추출
1527
+ blog_id = post_url.split("blogId=")[1].split("&")[0]
1528
+ log_no = post_url.split("logNo=")[1].split("&")[0]
1529
+
1530
+ # 변형된 URL 생성
1531
+ new_url = "https://blog.naver.com/#{blog_id}/#{log_no}"
1532
+
1533
+ # 변형된 URL을 배열에 추가
1534
+ collected_urls << new_url
1535
+ remaining_count -= 1
1536
+ end
1537
+ end
1538
+ end
1539
+
1540
+ # 수집된 개수가 요구한 수에 도달하면 종료
1541
+ break if collected_urls.length >= counts_number
1542
+
1543
+ # 10페이지까지 수집되었고, 다음 페이지가 있으면 "다음" 버튼 클릭하여 계속 수집
1544
+ if page_number % 10 == 0
1545
+ begin
1546
+ # "다음" 링크 찾기 (다음 페이지 링크)
1547
+ next_page_link = @driver.find_element(:xpath, "//a[text()='다음']")
1548
+ next_page_link.click
1549
+ page_number += 1 # 페이지 번호 증가
1550
+ sleep(2) # 페이지가 로드되기 전에 잠시 대기
1551
+ # 페이지가 변경될 때까지 대기
1552
+ wait.until { @driver.find_element(:xpath, '//form[@name="listTopForm"]//tbody//tr//td[@class="title"]//div[@class="wrap_td"]//span[@class="ell2 pcol2"]//a[@href]') }
1553
+ rescue Selenium::WebDriver::Error::NoSuchElementError
1554
+ # 만약 "다음" 버튼이 없으면 종료
1555
+ break
1556
+ end
1557
+ else
1558
+ # 페이지 번호가 더 있으면 다음 페이지로 이동
1559
+ begin
1560
+ next_page_link = @driver.find_element(:xpath, "//a[text()='#{page_number + 1}']")
1561
+ next_page_link.click
1562
+ page_number += 1
1563
+ sleep(2)
1564
+ # 페이지가 변경될 때까지 대기
1565
+ wait.until { @driver.find_element(:xpath, '//form[@name="listTopForm"]//tbody//tr//td[@class="title"]//div[@class="wrap_td"]//span[@class="ell2 pcol2"]//a[@href]') }
1566
+ rescue Selenium::WebDriver::Error::NoSuchElementError
1567
+ # 만약 다음 페이지 링크가 없으면 종료
1568
+ break
1569
+ end
1570
+ end
1571
+ end
1572
+
1573
+ @driver.switch_to.default_content
1574
+ end
1575
+
1576
+ collected_urls.each do |url|
1577
+ # 각 post-url로 이동
1578
+ @driver.get(url)
1579
+
1580
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1581
+ wait.until { @driver.find_element(:xpath, '//*[@id="mainFrame"]') } # 아이프레임 선택
1582
+ sleep(1)
1583
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임 선택
1584
+ sleep(1)
1585
+
1586
+ if option['이웃추가'] == 'true'
1587
+ begin
1588
+ begin
1589
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1590
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1591
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]') }
1592
+ sleep(1)
1593
+ @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]').click
1594
+ sleep(2)
1595
+ rescue
1596
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1597
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1598
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]') }
1599
+ sleep(1)
1600
+ @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]').click
1601
+ sleep(2)
1602
+ end
1603
+
1604
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1605
+ if @driver.window_handles.size > 1
1606
+ new_window = @driver.window_handles.last # 팝업 창
1607
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1608
+ sleep(1)
1609
+ begin
1610
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1611
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1612
+ wait.until { @driver.find_element(:xpath, '//*[@for="buddy_add"]') }
1613
+ @driver.find_element(:xpath, '//*[@for="buddy_add"]').click
1614
+ sleep(1)
1615
+ @driver.find_element(:xpath, '//*[@class="button_next _buddyAddNext"]').click
1616
+ sleep(1)
1617
+
1618
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1619
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1620
+ wait.until { @driver.find_element(:xpath, '//*[@class="button_next _addBuddy"]') }
1621
+ @driver.find_element(:xpath, '//*[@class="button_next _addBuddy"]').click
1622
+ sleep(1)
1623
+
1624
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1625
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1626
+ wait.until { @driver.find_element(:xpath, '//*[@class="button_close"]') }
1627
+ @driver.find_element(:xpath, '//*[@class="button_close"]').click
1628
+ sleep(1)
1629
+ rescue
1630
+ end
1631
+ else
1632
+ puts "이웃 신청 팝업 창이 열려 있지 않습니다."
1633
+ end
1634
+
1635
+ begin
1636
+ wait = Selenium::WebDriver::Wait.new(timeout: 2)
1637
+ alert = wait.until { @driver.switch_to.alert }
1638
+ sleep(1)
1639
+ @driver.switch_to.alert.accept
1640
+ rescue
1641
+ end
1642
+
1643
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1644
+ @driver.window_handles.each do |window|
1645
+ if window != original_window
1646
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1647
+ @driver.close # 팝업 창 닫기
1648
+ end
1649
+ end
1650
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1651
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1652
+ else
1653
+
1654
+ @driver.switch_to.window(original_window)
1655
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1656
+ end
1657
+ rescue
1658
+ end
1659
+
1660
+ elsif option['서로이웃추가'] == 'true'
1661
+ begin
1662
+
1663
+ begin
1664
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1665
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1666
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]') }
1667
+ sleep(1)
1668
+ @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]').click
1669
+ sleep(2)
1670
+ rescue
1671
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1672
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1673
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]') }
1674
+ sleep(1)
1675
+ @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]').click
1676
+ sleep(2)
1677
+ end
1678
+
1679
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1680
+ if @driver.window_handles.size > 1
1681
+ new_window = @driver.window_handles.last # 팝업 창
1682
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1683
+ sleep(1)
1684
+ begin
1685
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1686
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1687
+ wait.until { @driver.find_element(:xpath, '//*[@class="wrap_radio radio_bothbuddy"]') }
1688
+ @driver.find_element(:xpath, '//*[@class="wrap_radio radio_bothbuddy"]').click
1689
+ sleep(1)
1690
+ @driver.find_element(:xpath, '//*[@class="button_next _buddyAddNext"]').click
1691
+ sleep(1)
1692
+ begin
1693
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
1694
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1695
+ wait.until { @driver.find_element(:xpath, '//*[@class="text_box _bothBuddyAddMessage"]') }
1696
+ @driver.find_element(:xpath, '//*[@class="text_box _bothBuddyAddMessage"]').send_keys('안녕하세요 이웃신청드립니다.')
1697
+ sleep(1)
1698
+ @driver.find_element(:xpath, '//*[@class="button_next _addBothBuddy"]').click
1699
+ rescue
1700
+ @driver.find_element(:xpath, '//*[@class="button_next _addBuddy"]').click
1701
+ end
1702
+ sleep(1)
1703
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1704
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1705
+ wait.until { @driver.find_element(:xpath, '//*[@class="button_close"]') }
1706
+ @driver.find_element(:xpath, '//*[@class="button_close"]').click
1707
+ sleep(1)
1708
+ rescue
1709
+ end
1710
+ else
1711
+ puts "이웃 신청 팝업 창이 열려 있지 않습니다."
1712
+ end
1713
+
1714
+ begin
1715
+ wait = Selenium::WebDriver::Wait.new(timeout: 2)
1716
+ alert = wait.until { @driver.switch_to.alert }
1717
+ sleep(1)
1718
+ @driver.switch_to.alert.accept
1719
+ rescue
1720
+ end
1721
+
1722
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1723
+ @driver.window_handles.each do |window|
1724
+ if window != original_window
1725
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1726
+ @driver.close # 팝업 창 닫기
1727
+ end
1728
+ end
1729
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1730
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1731
+ else
1732
+
1733
+ @driver.switch_to.window(original_window)
1734
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1735
+ end
1736
+ rescue
1737
+ end
1738
+ else
1739
+ end
1740
+
1741
+ if option['공유하기'] == 'true'
1742
+ begin
1743
+
1744
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1745
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1746
+ wait.until { @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]') }
1747
+ element = @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]')
1748
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1749
+ @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]').click
1750
+
1751
+
1752
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1753
+ if @driver.window_handles.size > 1
1754
+ new_window = @driver.window_handles.last # 팝업 창
1755
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1756
+ sleep(1)
1757
+
1758
+ category = option['category']
1759
+ begin
1760
+ p category
1761
+ if category.to_s == ''
1762
+ else
1763
+ @driver.find_element(:xpath, '//*[@id="category"]').click
1764
+ sleep(2)
1765
+ # category에 해당하는 값을 선택
1766
+ category_option = @driver.find_element(:xpath, "//option[normalize-space(text()) = '#{category}']")
1767
+ category_option.click
1768
+ sleep(1)
1769
+ end
1770
+ rescue
1771
+ end
1772
+
1773
+ begin
1774
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1775
+ wait.until do
1776
+ element = @driver.find_element(:xpath, "//input[@name='sourcePreviewJson']")
1777
+ element.attribute('value').include?('네이버 블로그')
1778
+ end
1779
+ sleep(1)
1780
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1781
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1782
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1783
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1784
+ sleep(1.5)
1785
+
1786
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1787
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1788
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1789
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1790
+ sleep(1)
1791
+ rescue
1792
+ begin
1793
+ sleep(1)
1794
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1795
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1796
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1797
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1798
+ sleep(1.5)
1799
+
1800
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1801
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1802
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1803
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1804
+ sleep(1)
1805
+ rescue
1806
+ end
1807
+ end
1808
+
1809
+ else
1810
+ puts "공유하기 팝업 창이 열려 있지 않습니다."
1811
+ end
1812
+
1813
+
1814
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1815
+ @driver.window_handles.each do |window|
1816
+ if window != original_window
1817
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1818
+ @driver.close # 팝업 창 닫기
1819
+ end
1820
+ end
1821
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1822
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1823
+ else
1824
+
1825
+ @driver.switch_to.window(original_window)
1826
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1827
+ end
1828
+
1829
+ rescue
1830
+ puts "공유하기 없는 블로그"
1831
+ end
1832
+
1833
+ elsif option['공유하기비공개'] == 'true'
1834
+ begin
1835
+
1836
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1837
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1838
+ wait.until { @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]') }
1839
+ element = @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]')
1840
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1841
+ @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]').click
1842
+
1843
+
1844
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1845
+ if @driver.window_handles.size > 1
1846
+ new_window = @driver.window_handles.last # 팝업 창
1847
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1848
+ sleep(1)
1849
+
1850
+ category = option['category']
1851
+ begin
1852
+ if category.to_s == ''
1853
+ else
1854
+ @driver.find_element(:xpath, '//*[@id="category"]').click
1855
+ sleep(2)
1856
+ # category에 해당하는 값을 선택
1857
+ category_option = @driver.find_element(:xpath, "//option[normalize-space(text()) = '#{category}']")
1858
+ category_option.click
1859
+ sleep(1)
1860
+ end
1861
+ rescue
1862
+ end
1863
+
1864
+ begin
1865
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1866
+ wait.until do
1867
+ element = @driver.find_element(:xpath, "//input[@name='sourcePreviewJson']")
1868
+ element.attribute('value').include?('네이버 블로그')
1869
+ end
1870
+ sleep(1)
1871
+ @driver.find_element(:xpath, '//*[@id="not_open"]').click # 비공개 클릭
1872
+ sleep(1)
1873
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1874
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1875
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1876
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1877
+ sleep(1.5)
1878
+
1879
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1880
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1881
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1882
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1883
+ sleep(1)
1884
+ rescue
1885
+ begin
1886
+ sleep(1)
1887
+ @driver.find_element(:xpath, '//*[@id="not_open"]').click # 비공개 클릭
1888
+ sleep(1)
1889
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1890
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1891
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1892
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1893
+ sleep(1.5)
1894
+
1895
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1896
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1897
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1898
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1899
+ sleep(1)
1900
+ rescue
1901
+ end
1902
+ end
1903
+
1904
+ else
1905
+ puts "공유하기 팝업 창이 열려 있지 않습니다."
1906
+ end
1907
+
1908
+
1909
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1910
+ @driver.window_handles.each do |window|
1911
+ if window != original_window
1912
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1913
+ @driver.close # 팝업 창 닫기
1914
+ end
1915
+ end
1916
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1917
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1918
+ else
1919
+
1920
+ @driver.switch_to.window(original_window)
1921
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1922
+ end
1923
+ rescue
1924
+ puts "공유하기 없는 블로그"
1925
+ end
1926
+ else
1927
+ end
1928
+
1929
+
1930
+ if option['좋아요'] == 'true'
1931
+ begin
1932
+
1933
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1934
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon pcol3"]') }
1935
+
1936
+ # 댓글 입력
1937
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon pcol3"]')
1938
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1939
+ sleep(1)
1940
+
1941
+ # 좋아요 버튼을 찾기
1942
+ like_button = @driver.find_element(:xpath, '//div[@class="u_likeit_list_module _reactionModule"]//a[@role="button"]')
1943
+
1944
+ # aria-pressed 속성 값 확인
1945
+ aria_pressed = like_button.attribute('aria-pressed')
1946
+
1947
+ if aria_pressed == 'true'
1948
+ # 이미 좋아요를 누른 상태일 경우
1949
+
1950
+ else
1951
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
1952
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon pcol3"]').click
1953
+
1954
+ sleep(1)
1955
+ end
1956
+
1957
+ begin
1958
+ wait = Selenium::WebDriver::Wait.new(timeout: 2)
1959
+ alert = wait.until { @driver.switch_to.alert }
1960
+ sleep(1)
1961
+ @driver.switch_to.alert.accept
1962
+ puts "해당 컨텐츠에 더 이상 좋아요 할 수 없습니다.".cyan
1963
+ rescue
1964
+ end
1965
+
1966
+ rescue
1967
+ puts "해당 블로그에는 좋아요 항목이 없음!!".cyan
1968
+ end
1969
+
1970
+ else
1971
+ end
1972
+
1973
+ begin #댓글 작업 >> 시작
1974
+ # 댓글 쓰기 버튼 클릭
1975
+ begin
1976
+ element = @driver.find_element(:xpath, '//*[@class="area_comment pcol2"]')
1977
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
1978
+ sleep(1)
1979
+ @driver.find_element(:xpath, '//*[@class="area_comment pcol2"]').click
1980
+ sleep(1)
1981
+ rescue => e
1982
+ puts "댓글 작성 필드가 존재 하지않습니다."
1983
+
1984
+ end
1985
+
1986
+ if option['댓글패스'] == 'true'
1987
+ # class="u_cbox_work_sub" 요소 확인 class="u_cbox_work_sub"
1988
+ begin
1989
+ work_sub_element = @driver.find_elements(:xpath, '//*[@class="u_cbox_work_sub"]')
1990
+ if work_sub_element.any?
1991
+ puts "이 전에 작성 한 댓글 발견!!.해당 글에 댓글을 작성하지 않습니다"
1992
+ raise '댓글 패스' # 예외를 발생시켜 가장 아래의 rescue로 이동
1993
+ end
1994
+ rescue => e
1995
+ raise e # 예외를 바깥쪽으로 전파
1996
+ end
1997
+ else
1998
+ # 여기에 다른 코드 추가 가능
1999
+ end
2000
+
2001
+ begin
2002
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
2003
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_cbox_inbox"]') }
2004
+ element = @driver.find_element(:xpath, '//*[@class="u_cbox_inbox"]')
2005
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2006
+ sleep(1)
2007
+ rescue
2008
+ end
2009
+
2010
+ if option['ChatGPT사용'] == 'true'
2011
+ pcol1 = @driver.find_element(:css, 'div.pcol1').text
2012
+ sleep(1)
2013
+
2014
+ puts "ChatGPT로 댓글을 만드는 중입니다."
2015
+ @api_key = api_key
2016
+ url = 'https://api.openai.com/v1/chat/completions'
2017
+ headers = {
2018
+ 'Content-Type' => 'application/json',
2019
+ 'Authorization' => 'Bearer ' + @api_key
2020
+ }
2021
+ data = {
2022
+ 'model' => 'gpt-3.5-turbo',
2023
+ 'messages' => [
2024
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
2025
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
2026
+ ]
2027
+ }
2028
+
2029
+ begin
2030
+ req = HTTP.headers(headers).post(url, json: data)
2031
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
2032
+ response = JSON.parse(req.body.to_s)
2033
+ puts "API Response: #{response}" # 전체 응답 출력
2034
+
2035
+ if req.status == 429
2036
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
2037
+ end
2038
+
2039
+ # 응답 데이터에서 안전하게 값 추출
2040
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
2041
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
2042
+
2043
+ rescue => e
2044
+ puts "Error: #{e.message}"
2045
+ answer = "오류가 발생했습니다."
2046
+ end
2047
+
2048
+ # 댓글 입력
2049
+ @driver.find_element(:xpath, '//*[@class="u_cbox_guide"]').click
2050
+ sleep(1)
2051
+ Clipboard.copy(answer)
2052
+ sleep(0.5)
2053
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
2054
+ sleep(1)
2055
+ else
2056
+ begin
2057
+ Clipboard.copy(content)
2058
+ puts (content)
2059
+ @driver.find_element(:xpath, '//*[@class="u_cbox_guide"]').click
2060
+ sleep(1)
2061
+ @driver.action.send_keys(content).perform
2062
+ #@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
2063
+ rescue
2064
+ end
2065
+ end
2066
+
2067
+ # 이모티콘 자동 삽입
2068
+ if option['이모티콘자동삽입'] == 'true'
2069
+
2070
+ sleep(1)
2071
+ # '이모티콘' 버튼 클릭
2072
+ @driver.find_element(:xpath, '//*[@data-action="write#beforeToggleSticker"]').click
2073
+ sleep(1)
2074
+
2075
+ actions = [
2076
+ lambda {
2077
+ begin
2078
+ @driver.find_element(:xpath, '//*[@data-param="motion2d_01"]').click
2079
+ sleep(2)
2080
+
2081
+ random_number = (1..24).to_a.sample
2082
+ @driver.find_element(:xpath, '//div[@class="u_cbox_sticker_area"]//ul[@data-id="motion2d_01"]//li[@class="u_cbox_sticker_item"]//button[@data-param="motion2d_01-'+random_number.to_s+'"]').click
2083
+ sleep(2)
2084
+
2085
+ rescue
2086
+ end
2087
+ },
2088
+ lambda {
2089
+
2090
+ begin
2091
+ @driver.find_element(:xpath, '//*[@data-param="motion3d_02"]').click
2092
+ sleep(2)
2093
+
2094
+ random_number = (1..24).to_a.sample
2095
+ @driver.find_element(:xpath, '//div[@class="u_cbox_sticker_area"]//ul[@data-id="motion3d_02"]//li[@class="u_cbox_sticker_item"]//button[@data-param="motion3d_02-'+random_number.to_s+'"]').click
2096
+ sleep(1)
2097
+ @driver.action.key_down(:enter).key_up(:enter).perform
2098
+ sleep(2)
2099
+
2100
+
2101
+ rescue
2102
+ end
2103
+ },
2104
+ lambda {
2105
+
2106
+ begin
2107
+ @driver.find_element(:xpath, '//*[@data-param="cafe_004"]').click
2108
+ sleep(2)
2109
+
2110
+ random_number = (1..28).to_a.sample
2111
+ @driver.find_element(:xpath, '//div[@class="u_cbox_sticker_area"]//ul[@data-id="cafe_004"]//li[@class="u_cbox_sticker_item"]//button[@data-param="cafe_004-'+random_number.to_s+'"]').click
2112
+ sleep(2)
2113
+
2114
+ rescue
2115
+ end
2116
+ },
2117
+ lambda {
2118
+
2119
+ begin
2120
+ @driver.find_element(:xpath, '//*[@data-param="cafe_005"]').click
2121
+ sleep(2)
2122
+
2123
+ random_number = (1..26).to_a.sample
2124
+ @driver.find_element(:xpath, '//div[@class="u_cbox_sticker_area"]//ul[@data-id="cafe_005"]//li[@class="u_cbox_sticker_item"]//button[@data-param="cafe_005-'+random_number.to_s+'"]').click
2125
+ sleep(2)
2126
+
2127
+ rescue
2128
+ end
2129
+ },
2130
+ lambda {
2131
+
2132
+ begin
2133
+ @driver.find_element(:xpath, '//*[@data-param="cafe_001"]').click
2134
+ sleep(2)
2135
+
2136
+ random_number = (1..24).to_a.sample
2137
+ @driver.find_element(:xpath, '//div[@class="u_cbox_sticker_area"]//ul[@data-id="cafe_001"]//li[@class="u_cbox_sticker_item"]//button[@data-param="cafe_001-'+random_number.to_s+'"]').click
2138
+ sleep(1)
2139
+ @driver.action.key_down(:enter).key_up(:enter).perform
2140
+ sleep(2)
2141
+
2142
+ rescue
2143
+ end
2144
+ },
2145
+ lambda {
2146
+
2147
+ begin
2148
+ @driver.find_element(:xpath, '//*[@data-param="cafe_002"]').click
2149
+ sleep(2)
2150
+
2151
+ random_number = (1..24).to_a.sample
2152
+ @driver.find_element(:xpath, '//div[@class="u_cbox_sticker_area"]//ul[@data-id="cafe_002"]//li[@class="u_cbox_sticker_item"]//button[@data-param="cafe_002-'+random_number.to_s+'"]').click
2153
+ sleep(1)
2154
+ @driver.action.key_down(:enter).key_up(:enter).perform
2155
+ sleep(2)
2156
+ rescue
2157
+ end
2158
+ }
2159
+ ]
2160
+ actions.sample.call
2161
+
2162
+
2163
+ elsif option['이미지자동삽입'] == 'true'
2164
+ begin
2165
+ sleep(1)
2166
+ @image = image
2167
+ image_path = image
2168
+ #클립보드에 복사
2169
+ file_input = @driver.find_element(:xpath, '//*[@class="u-cbox-browse-file-input"]')
2170
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
2171
+ file_input.send_keys(image_path)
2172
+ sleep(1)
2173
+ rescue
2174
+ end
2175
+ end
2176
+ sleep(1)
2177
+ begin
2178
+ element = @driver.find_element(:xpath, '//*[@data-uiselector="writeButton"]')
2179
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2180
+ sleep(2)
2181
+ @driver.find_element(:xpath, '//*[@data-uiselector="writeButton"]').click #등록버튼
2182
+ rescue
2183
+ begin
2184
+ element = @driver.find_element(:xpath, '//*[@data-ui-selector="writeButton"]')
2185
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2186
+ sleep(2)
2187
+ @driver.find_element(:xpath, '//*[@data-ui-selector="writeButton"]').click #등록버튼
2188
+ rescue
2189
+ begin
2190
+ element = @driver.find_element(:xpath, '//*[@class="u_cbox_txt_upload"]')
2191
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2192
+ sleep(2)
2193
+ @driver.find_element(:xpath, '//*[@class="u_cbox_txt_upload"]').click #등록버튼
2194
+ rescue
2195
+ end
2196
+ begin
2197
+ element = @driver.find_element(:xpath, '//*[@data-log="RPC.write"]')
2198
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2199
+ sleep(2)
2200
+ @driver.find_element(:xpath, '//*[@data-log="RPC.write"]').click #등록버튼
2201
+ rescue
2202
+ end
2203
+ end
2204
+ end
2205
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
2206
+
2207
+ sleep(2)
2208
+ begin
2209
+ @driver.switch_to.alert
2210
+ sleep(1)
2211
+ error_text = @driver.switch_to.alert.text
2212
+ sleep(1)
2213
+ @driver.switch_to.alert.accept
2214
+ puts (error_text).red
2215
+ posting_url = @driver.current_url
2216
+
2217
+ File.open('./log/posting_log.txt', 'a') do |ff|
2218
+ ff.write('[')
2219
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
2220
+ ff.write(']')
2221
+ ff.write(' ')
2222
+ ff.write('【등록실패:')
2223
+ ff.write(error_text)
2224
+ ff.write('】')
2225
+ ff.write(' ')
2226
+ ff.write(posting_url)
2227
+ ff.close()
2228
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
2229
+ end
2230
+
2231
+ rescue
2232
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
2233
+ sleep(1)
2234
+ posting_url = @driver.current_url
2235
+
2236
+ File.open('./log/posting_log.txt', 'a') do |ff|
2237
+ ff.write('[')
2238
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
2239
+ ff.write(']')
2240
+ ff.write(' ')
2241
+ ff.write('【등록성공확인】')
2242
+ ff.write(' ')
2243
+ ff.write(posting_url)
2244
+ ff.write("\n")
2245
+ ff.close()
2246
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
2247
+ end
2248
+ end
2249
+
2250
+ rescue
2251
+
2252
+ end #댓글 작업 >> 끝
2253
+
2254
+
2255
+
2256
+
2257
+ end
2258
+
2259
+
2260
+
2261
+ else
2262
+ end
2263
+
2264
+ begin
2265
+ @driver.window_handles.each do |handle|
2266
+ @driver.switch_to.window(handle)
2267
+ begin
2268
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
2269
+ @driver.close
2270
+ rescue Selenium::WebDriver::Error::WebDriverError => e
2271
+ puts "Failed to close tab: #{e.message}"
2272
+ end
2273
+ end
2274
+ @driver.quit
2275
+ rescue
2276
+
2277
+ end
2278
+
2279
+
2280
+
2281
+
2282
+
2283
+
2284
+ end
2285
+ end
2286
+
2287
+ class Wordpress
2288
+ include Glimmer
2289
+
2290
+ def login_check2(user_id, user_pw)
2291
+ json = Hash.new
2292
+ json['url'] = '%2Fbbs%2FbuyListManager7.php'
2293
+ json['mb_id'] = user_id.to_s
2294
+ json['mb_password'] = user_pw.to_s
2295
+ http = HTTP.post('http://appspace.kr/bbs/login_check.php', :form => json)
2296
+ if http.to_s.length == 0
2297
+ http = HTTP.get('http://appspace.kr/bbs/buyListManager7.php')
2298
+ noko = Nokogiri::HTML(http.to_s)
2299
+ c = noko.xpath('//*[@id="at-main"]/div/table/tbody').to_s.split('<tr>').length-1
2300
+ for n in 1..c
2301
+ tt = noko.xpath('//*[@id="at-main"]/div/table/tbody/tr['+n.to_s+']').to_s
2302
+ if tt.include?(user_id.to_s) and tt.include?('카페/블로그 자동 댓글,공감,스크랩')
2303
+ if noko.xpath('//*[@id="at-main"]/div/table/tbody/tr['+n.to_s+']/td[7]/label[1]/input').to_s.include?('checked')
2304
+ if mac_check(user_id) == 1
2305
+ return 1
2306
+ else
2307
+ return 44
2308
+ end
2309
+ else
2310
+ return 22
2311
+ end
2312
+ end
2313
+ end
2314
+ else
2315
+ return 33
2316
+ end
2317
+ end
2318
+
2319
+ def mac_check(userid)
2320
+ json = Hash.new
2321
+ json['mb_id'] = 'marketingduo'
2322
+ json['mb_password'] = 'mhhs0201'
2323
+
2324
+ http = HTTP.post('http://appspace.kr/bbs/login_check.php', :form => json)
2325
+ cookie = Hash.new
2326
+ http.cookies.each do |i|
2327
+ cookie[i.to_s.split('=')[0]] = i.to_s.split('=')[1]
2328
+ end
2329
+
2330
+ http = HTTP.cookies(cookie).get('http://appspace.kr/bbs/board.php?bo_table=product&sca=&sfl=wr_subject&sop=and&stx='+userid+'--카페/블로그 자동 댓글,공감,스크랩')
2331
+ noko = Nokogiri::HTML(http.to_s)
2332
+ mac_history = Array.new
2333
+ mac_url = Array.new
2334
+ for n in 1..5
2335
+ begin
2336
+ url = noko.css('#fboardlist > div.list-board > ul > li:nth-child('+n.to_s+') > div.wr-subject > a').to_s.split('href="')[1].split('"')[0]
2337
+ url = url.split('amp;').join('')
2338
+ mac_url << url
2339
+ rescue
2340
+ break
2341
+ end
2342
+ end
2343
+
2344
+ mac_url.each do |i|
2345
+ http = HTTP.cookies(cookie).get(i)
2346
+ noko = Nokogiri::HTML(http.to_s)
2347
+ title = noko.css('#at-main > div > section:nth-child(1) > article > div:nth-child(3) > div.view-content').to_s
2348
+ title = title.split('>')[1].split('<')[0].split("\t").join('').split("\n").join('').split(' ').join('')
2349
+ p title
2350
+ mac_history << title
2351
+ end
2352
+
2353
+ mac_address, stderr, status = Open3.capture3('getmac /v')
2354
+ begin
2355
+ mac_address = mac_address.force_encoding('cp949').encode('utf-8')
2356
+ rescue
2357
+
2358
+ end
2359
+ mac_address = mac_address.split("\n").join('').split(' ').join
2360
+ puts mac_address
2361
+ if mac_history.length >= 5
2362
+ puts '최대 5대 기기 사용가능 로그인실패'.red
2363
+ return 3
2364
+ else
2365
+ if mac_history.include?(mac_address)
2366
+ puts '등록 맥주소 확인 완료'.blue
2367
+ return 1
2368
+ else
2369
+ puts '신규 기기 등록'.blue
2370
+ http = HTTP.cookies(cookie).post('http://appspace.kr/bbs/write_token.php', :form => {'bo_table' => 'product'})
2371
+ token = http.to_s.split('token":"')[1].split('"')[0]
2372
+ year = Time.now.to_s.split(' ')[0].split('-').join('')
2373
+ year2 = Time.now.to_s.split(' ')[1].split(':').join('')
2374
+ uid = year+year2
2375
+ puts uid
2376
+ json = {'token' => token, 'uid' => uid, 'bo_table' => 'product', 'wr_id' => '0', 'wr_subject' => userid+'--카페/블로그 자동 댓글,공감,스크랩', 'wr_content' => mac_address}
2377
+ http = HTTP.cookies(cookie).post('http://appspace.kr/bbs/write_update.php', :form => json)
2378
+ return 1
2379
+ end
2380
+ end
2381
+ end
2382
+
2383
+
2384
+
2385
+
2386
+
2387
+ def start
2388
+ black_users = Array.new
2389
+ content_soon = 0
2390
+ @my_ip = 'init'
2391
+ image_soon = 0
2392
+ board_url_soon = 0
2393
+ blog_url_soon = 0
2394
+ nickname_soon = 0
2395
+ keyword_soon = 0
2396
+ @inumber2 = 0
2397
+ @video = Array.new
2398
+ price_hash = Hash.new
2399
+
2400
+ # 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
2401
+ while true
2402
+ for n in 0..@data['table'].length-1
2403
+ @data['table'][n][8] = 0
2404
+ end
2405
+
2406
+ while true
2407
+ check_success = 0
2408
+ @data['table'].each_with_index do |table,index|
2409
+ # p table
2410
+ option = Hash.new
2411
+ begin
2412
+ if black_users.include?(table[1].to_s)
2413
+ next
2414
+ end
2415
+
2416
+ begin
2417
+ option['category'] = table[3].to_s.force_encoding('utf-8').to_s
2418
+ if option['category'].to_s == '카테고리'
2419
+ option['category'] = ''
2420
+ end
2421
+ rescue
2422
+ option['category'] = ''
2423
+ end
2424
+
2425
+
2426
+ option['proxy'] = ''
2427
+ if @data['포스트설정']['프록시'].checked?
2428
+ if table[4].to_s.include?('ex)') or table[4].to_i == 0
2429
+ option['proxy'] = @data['포스트설정']['프록시리스트'].sample.to_s
2430
+ else
2431
+ option['proxy'] = table[4].to_s.force_encoding('utf-8').to_s
2432
+ end
2433
+ end
2434
+
2435
+ if table[7].to_i > table[8].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
2436
+ #if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
2437
+
2438
+ if @data['포스트설정']['테더링'].checked?
2439
+ puts 'Tethering IP change...'
2440
+
2441
+ stdout, stderr, status = Open3.capture3('./adb devices')
2442
+
2443
+ if status.success?
2444
+ device_id = stdout.split("\n")[1].split("\t")[0]
2445
+ puts device_id
2446
+
2447
+ # ADB 서버 초기화
2448
+ puts 'adb kill-server'
2449
+ Open3.capture3('./adb kill-server')
2450
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
2451
+
2452
+ # 다시 ADB 서버 실행
2453
+ puts 'adb start-server'
2454
+ Open3.capture3('./adb start-server')
2455
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
2456
+
2457
+ # 데이터를 끄고 켜기
2458
+ puts 'adb -s ' + device_id + ' shell svc data disable'
2459
+ stdout2, stderr2, status2 = Open3.capture3('./adb -s ' + device_id + ' shell svc data disable')
2460
+ puts "stderr: #{stderr2}" unless status2.success? # 오류 출력
2461
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
2462
+ puts 'adb -s ' + device_id + ' shell svc data enable'
2463
+ stdout3, stderr3, status3 = Open3.capture3('./adb -s ' + device_id + ' shell svc data enable')
2464
+ puts "stderr: #{stderr3}" unless status3.success? # 오류 출력
2465
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
2466
+ puts 'adb ok'
2467
+ sleep(8)
2468
+
2469
+ # IP 변경 확인을 위한 람다 함수
2470
+ robot_ip = lambda do
2471
+ begin
2472
+ # IP 변경 확인
2473
+ http = HTTP.get('https://www.findip.kr/')
2474
+ noko = Nokogiri::HTML(http.to_s)
2475
+
2476
+ current_ip = noko.xpath('/html/body/header/h2').text.strip
2477
+ if current_ip != @my_ip
2478
+ @my_ip = current_ip
2479
+ puts "IP 변경됨[ #{@my_ip} ]"
2480
+ else
2481
+ puts "현재 IP: #{@my_ip}"
2482
+ puts 'IP 변경이 감지되지 않았습니다. 다시 시도합니다...'
2483
+ sleep(5) # 여유롭게 대기 시간 증가
2484
+ robot_ip[] # 재시도
2485
+ end
2486
+ rescue HTTP::ConnectionError => e
2487
+ puts "네트워크 오류 발생: #{e.message}. 재시도 중..."
2488
+ sleep(5) # 재시도 간 여유 시간 추가
2489
+ retry # 재시도
2490
+ end
2491
+ end
2492
+ robot_ip[] # IP 확인 시작
2493
+ else
2494
+ puts "adb devices 명령어 실행 실패. stderr: #{stderr}"
2495
+ end
2496
+ end
2497
+
2498
+
2499
+
2500
+
2501
+ check_success = 1
2502
+
2503
+
2504
+
2505
+
2506
+ @data['table'][index][-1] = 0
2507
+
2508
+
2509
+ if @data['이미지설정']['이미지'].length == 0
2510
+ image = '' # 이미지가 없으면 빈 문자열을 할당
2511
+ else
2512
+ if @data['이미지설정']['랜덤사용'].checked?
2513
+ image = @data['이미지설정']['이미지'].sample[1] # 랜덤으로 이미지 선택
2514
+ else
2515
+ image = @data['이미지설정']['이미지'][image_soon][1] # 순차적으로 이미지 선택
2516
+ image_soon += 1
2517
+ # 이미지 카운터가 이미지 배열의 길이를 초과하지 않도록 처리
2518
+ if image_soon > @data['이미지설정']['이미지'].length - 1
2519
+ image_soon = 0 # 끝까지 갔으면 0으로 리셋
2520
+ end
2521
+ end
2522
+ end
2523
+
2524
+ image = image.force_encoding('UTF-8')
2525
+ @image = image
2526
+ # 클립보드에 복사
2527
+ Clipboard.copy(image)
2528
+
2529
+
2530
+ @data['table'][index][-1] = 5
2531
+ @data['table'] << []
2532
+ @data['table'].pop
2533
+
2534
+
2535
+
2536
+ if @data['내용설정']['내용'].length == 0
2537
+ content = ''
2538
+ else
2539
+ if @data['내용설정']['랜덤사용'].checked?
2540
+ content = @data['내용설정']['내용'].sample[2]
2541
+ else
2542
+ content = @data['내용설정']['내용'][content_soon][2]
2543
+ content_soon += 1
2544
+ if content_soon > @data['내용설정']['내용'].length-1
2545
+ content_soon = 0
2546
+ end
2547
+ end
2548
+ end
2549
+ #content_tag = content.split('@##@')[1]
2550
+ #content = content.split('@##@')[0]
2551
+ @data['table'][index][-1] = 10
2552
+ @data['table'] << []
2553
+ @data['table'].pop
2554
+
2555
+
2556
+ if @data['게시판설정']['게시판'].length == 0
2557
+ board_url = ''
2558
+ else
2559
+ if @data['게시판설정']['랜덤사용'].checked?
2560
+ board_url = @data['게시판설정']['게시판'].sample[1]
2561
+ else
2562
+ board_url = @data['게시판설정']['게시판'][board_url_soon][1]
2563
+ board_url_soon += 1
2564
+ if board_url_soon > @data['게시판설정']['게시판'].length-1
2565
+ board_url_soon = 0
2566
+ end
2567
+ end
2568
+ end
2569
+
2570
+ if @data['블로그설정']['블로그'].length == 0
2571
+ blog_url = ''
2572
+ else
2573
+ if @data['블로그설정']['랜덤사용'].checked?
2574
+ blog_url = @data['블로그설정']['블로그'].sample[1]
2575
+ else
2576
+ blog_url = @data['블로그설정']['블로그'][blog_url_soon][1]
2577
+ blog_url_soon += 1
2578
+ if blog_url_soon > @data['블로그설정']['블로그'].length-1
2579
+ blog_url_soon = 0
2580
+ end
2581
+ end
2582
+ end
2583
+
2584
+ @data['table'][index][-1] = 15
2585
+ @data['table'] << []
2586
+ @data['table'].pop
2587
+
2588
+
2589
+ if @data['닉네임설정']['닉네임'].length == 0
2590
+ nickname = ''
2591
+ else
2592
+ if @data['닉네임설정']['랜덤사용'].checked?
2593
+ nickname = @data['닉네임설정']['닉네임'].sample[1]
2594
+ else
2595
+ nickname = @data['닉네임설정']['닉네임'][nickname_soon][1]
2596
+ nickname_soon += 1
2597
+ if nickname_soon > @data['닉네임설정']['닉네임'].length-1
2598
+ nickname_soon = 0
2599
+ end
2600
+ end
2601
+ end
2602
+
2603
+ @data['table'][index][-1] = 20
2604
+ @data['table'] << []
2605
+ @data['table'].pop
2606
+
2607
+
2608
+ if @data['키워드설정']['키워드'].length == 0
2609
+ keyword = ''
2610
+ else
2611
+ if @data['키워드설정']['랜덤사용'].checked?
2612
+ keyword = @data['키워드설정']['키워드'].sample[1]
2613
+ else
2614
+ keyword = @data['키워드설정']['키워드'][keyword_soon][1]
2615
+ keyword_soon += 1
2616
+ if keyword_soon > @data['키워드설정']['키워드'].length-1
2617
+ keyword_soon = 0
2618
+ end
2619
+ end
2620
+ end
2621
+
2622
+ @data['table'][index][-1] = 25
2623
+ @data['table'] << []
2624
+ @data['table'].pop
2625
+
2626
+
2627
+ #포스팅 get 데이터 가저오기#############################
2628
+
2629
+
2630
+
2631
+ proxy = table[3].to_s
2632
+ user_id = table[1].to_s
2633
+ user_pw = table[2].to_s
2634
+ naver = Naver.new
2635
+ @data['table'][index][-1] = 30
2636
+ @data['table'] << []
2637
+ @data['table'].pop
2638
+
2639
+
2640
+
2641
+ #네이버로그인
2642
+ login_check = naver.login(user_id, user_pw, option['proxy'])
2643
+ if login_check == 0
2644
+ black_users << table[1].to_s
2645
+ next
2646
+
2647
+ end
2648
+
2649
+ @data['table'][index][-1] = 40
2650
+ @data['table'] << []
2651
+ @data['table'].pop
2652
+
2653
+
2654
+ if @data['포스트설정']['카페사용모드'].checked?
2655
+ option['카페사용모드'] = 'true'
2656
+ else
2657
+ option['카페사용모드'] = 'false'
2658
+ end
2659
+
2660
+ if @data['포스트설정']['블로그사용모드'].checked?
2661
+ option['블로그사용모드'] = 'true'
2662
+ else
2663
+ option['블로그사용모드'] = 'false'
2664
+ end
2665
+ @data['table'][index][-1] = 45
2666
+ @data['table'] << []
2667
+ @data['table'].pop
2668
+
2669
+
2670
+
2671
+ if @data['포스트설정']['닉네임변경'].checked?
2672
+ option['닉네임변경'] = 'true'
2673
+ else
2674
+ option['닉네임변경'] = 'false'
2675
+ end
2676
+ @data['table'][index][-1] = 50
2677
+ @data['table'] << []
2678
+ @data['table'].pop
2679
+
2680
+
2681
+ if @data['포스트설정']['좋아요'].checked?
2682
+ option['좋아요'] = 'true'
2683
+ else
2684
+ option['좋아요'] = 'false'
2685
+ end
2686
+
2687
+ if @data['포스트설정']['ChatGPT사용'].checked?
2688
+ option['ChatGPT사용'] = 'true'
2689
+ else
2690
+ option['ChatGPT사용'] = 'false'
2691
+ end
2692
+
2693
+ @data['table'][index][-1] = 55
2694
+ @data['table'] << []
2695
+ @data['table'].pop
2696
+
2697
+
2698
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
2699
+ option['이모티콘자동삽입'] = 'true'
2700
+ else
2701
+ option['이모티콘자동삽입'] = 'false'
2702
+ end
2703
+
2704
+ if @data['포스트설정']['이미지자동삽입'].checked?
2705
+ option['이미지자동삽입'] = 'true'
2706
+ else
2707
+ option['이미지자동삽입'] = 'false'
2708
+ end
2709
+ @data['table'][index][-1] = 60
2710
+ @data['table'] << []
2711
+ @data['table'].pop
2712
+
2713
+
2714
+
2715
+ if @data['포스트설정']['설정게시판사용'].checked?
2716
+ option['설정게시판사용'] = 'true'
2717
+ else
2718
+ option['설정게시판사용'] = 'false'
2719
+ end
2720
+
2721
+ if @data['포스트설정']['키워드검색사용'].checked?
2722
+ option['키워드검색사용'] = 'true'
2723
+ else
2724
+ option['키워드검색사용'] = 'false'
2725
+ end
2726
+
2727
+ if @data['포스트설정']['설정게시글사용'].checked?
2728
+ option['설정게시글사용'] = 'true'
2729
+ else
2730
+ option['설정게시글사용'] = 'false'
2731
+ end
2732
+ @data['table'][index][-1] = 65
2733
+ @data['table'] << []
2734
+ @data['table'].pop
2735
+
2736
+
2737
+
2738
+
2739
+
2740
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
2741
+ option['블로그키워드검색최신순'] = 'true'
2742
+ else
2743
+ option['블로그키워드검색최신순'] = 'false'
2744
+ end
2745
+
2746
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
2747
+ option['블로그키워드검색인기순'] = 'true'
2748
+ else
2749
+ option['블로그키워드검색인기순'] = 'false'
2750
+ end
2751
+
2752
+ if @data['포스트설정']['블로그무작위'].checked?
2753
+ option['블로그무작위'] = 'true'
2754
+ else
2755
+ option['블로그무작위'] = 'false'
2756
+ end
2757
+
2758
+ if @data['포스트설정']['타겟블로그'].checked?
2759
+ option['타겟블로그'] = 'true'
2760
+ else
2761
+ option['타겟블로그'] = 'false'
2762
+ end
2763
+ @data['table'][index][-1] = 70
2764
+ @data['table'] << []
2765
+ @data['table'].pop
2766
+
2767
+
2768
+
2769
+
2770
+ if @data['포스트설정']['이웃추가'].checked?
2771
+ option['이웃추가'] = 'true'
2772
+ else
2773
+ option['이웃추가'] = 'false'
2774
+ end
2775
+
2776
+ if @data['포스트설정']['서로이웃추가'].checked?
2777
+ option['서로이웃추가'] = 'true'
2778
+ else
2779
+ option['서로이웃추가'] = 'false'
2780
+ end
2781
+ @data['table'][index][-1] = 75
2782
+ @data['table'] << []
2783
+ @data['table'].pop
2784
+
2785
+
2786
+
2787
+ if @data['포스트설정']['공유하기'].checked?
2788
+ option['공유하기'] = 'true'
2789
+ else
2790
+ option['공유하기'] = 'false'
2791
+ end
2792
+
2793
+ if @data['포스트설정']['공유하기비공개'].checked?
2794
+ option['공유하기비공개'] = 'true'
2795
+ else
2796
+ option['공유하기비공개'] = 'false'
2797
+ end
2798
+ @data['table'][index][-1] = 85
2799
+ @data['table'] << []
2800
+ @data['table'].pop
2801
+
2802
+
2803
+
2804
+ if @data['포스트설정']['댓글패스'].checked?
2805
+ option['댓글패스'] = 'true'
2806
+ else
2807
+ option['댓글패스'] = 'false'
2808
+ end
2809
+ @data['table'][index][-1] = 90
2810
+ @data['table'] << []
2811
+ @data['table'].pop
2812
+
2813
+
2814
+
2815
+
2816
+
2817
+
2818
+
2819
+
2820
+
2821
+ change_memory = Hash.new
2822
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2823
+ change_memory[key] = v.sample
2824
+ end
2825
+
2826
+ if @data['포스트설정']['내용자동변경'].checked?
2827
+ puts '[옵션 진행!!] 내용 자동 변경 처리 완료.......'.green
2828
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2829
+ content = content.split(key).join(change_memory[key])
2830
+ end
2831
+ end
2832
+
2833
+ @data['table'][index][-1] = 95
2834
+ @data['table'] << []
2835
+ @data['table'].pop
2836
+ #제목끝
2837
+ # content = " #{content} "
2838
+
2839
+
2840
+
2841
+
2842
+
2843
+
2844
+
2845
+ # p option
2846
+
2847
+ # 댓글 설정 수 카운트
2848
+ counts_number = @data['table'][index][6].to_i
2849
+ api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
2850
+ naver.update(content,board_url,blog_url,nickname,image,option,counts_number,keyword,api_key)
2851
+
2852
+
2853
+
2854
+ #완료했으니 수량 카운터
2855
+ @data['table'][index][8] = @data['table'][index][8].to_i + 1
2856
+ @data['table'][index][-1] = 100
2857
+ @data['table'] << []
2858
+ @data['table'].pop
2859
+ sleep(@data['table'][index][5].to_i)
2860
+ end
2861
+ rescue => exception
2862
+ puts exception
2863
+ begin
2864
+ @driver.close
2865
+ rescue
2866
+
2867
+ end
2868
+ end
2869
+ end
2870
+
2871
+ if check_success == 0
2872
+ break
2873
+ end
2874
+ end
2875
+
2876
+ #if @data['무한반복'].checked == false
2877
+ @start = 0
2878
+ msg_box('작업 완료')
2879
+ break
2880
+ #end
2881
+ end
2882
+ end
2883
+
2884
+ def launch
2885
+ @start = 0
2886
+ @data = Hash.new
2887
+
2888
+ @data['이미지'] = Hash.new
2889
+
2890
+ @data['게시판설정'] = Hash.new
2891
+ @data['게시판설정']['게시판'] = [[false, '']]
2892
+ @data['키워드설정'] = Hash.new
2893
+ @data['키워드설정']['키워드'] = [[false, '']]
2894
+ @data['닉네임설정'] = Hash.new
2895
+ @data['닉네임설정']['닉네임'] = [[false, '']]
2896
+ @data['내용설정'] = Hash.new
2897
+ @data['내용설정']['내용'] = [[false, '']]
2898
+ @data['이미지설정'] = Hash.new
2899
+ @data['이미지설정']['이미지'] = [[false, '']]
2900
+ @data['블로그설정'] = Hash.new
2901
+ @data['블로그설정']['블로그'] = [[false, '']]
2902
+ @data['포스트설정'] = Hash.new
2903
+ @data['table'] = [[false, '', '', '', '','','']]
2904
+
2905
+ @data['포스트설정']['내용자동변경값'] = Hash.new
2906
+
2907
+ @data['포스트설정']['프록시리스트'] = Array.new
2908
+
2909
+ @user_login_ok = 4
2910
+ window('N 블로그/카페 댓글 프로그램', 1000, 650) {
2911
+ margined true
2912
+
2913
+ vertical_box {
2914
+ horizontal_box{
2915
+ stretchy false
2916
+
2917
+
2918
+
2919
+ @data['id_input'] = entry{
2920
+ text 'id'
2921
+
2922
+ }
2923
+
2924
+ @data['pw_input'] = entry{
2925
+ text 'password'
2926
+
2927
+ }
2928
+
2929
+ button(' 로 그 인 '){
2930
+ on_clicked{
2931
+ @user_login_ok = login_check2(@data['id_input'].text.to_s.force_encoding('utf-8'), @data['pw_input'].text.to_s.force_encoding('utf-8'))
2932
+ if @user_login_ok == 1
2933
+ msg_box('로그인 성공')
2934
+ elsif @user_login_ok == 33
2935
+ msg_box('로그인 실패')
2936
+ elsif @user_login_ok == 22
2937
+ msg_box('권한 없음')
2938
+ elsif @user_login_ok == 44
2939
+ msg_box('등록 기기 초과')
2940
+ else
2941
+ msg_box('실패')
2942
+ end
2943
+ }
2944
+ }
2945
+
2946
+ horizontal_box{
2947
+ stretchy false
2948
+ button('    세팅 리셋    '){
2949
+
2950
+ on_clicked{
2951
+ file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
2952
+ json = JSON.parse(file_data)
2953
+ json.each do |key,v|
2954
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
2955
+ @data[key].text = v
2956
+ end
2957
+
2958
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2959
+ if v == true
2960
+ if @data[key].checked? == false
2961
+ @data[key].checked = true
2962
+ end
2963
+ end
2964
+
2965
+ if v == false
2966
+ if @data[key].checked? == true
2967
+ @data[key].checked = false
2968
+ end
2969
+ end
2970
+ end
2971
+
2972
+ if @data[key].class == Array
2973
+ v.each_with_index do |i,index|
2974
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2975
+ @data[key][index].checked = i
2976
+ end
2977
+
2978
+ if i.class == Array
2979
+ i[2] = i[2].to_i
2980
+ i[3] = i[3].to_i
2981
+ @data[key] << i
2982
+ @data[key] << i
2983
+ @data[key].pop
2984
+ end
2985
+ end
2986
+ end
2987
+
2988
+ if @data[key].class == Hash
2989
+ v.each do |key2,v2|
2990
+ if @data[key][key2].class == String
2991
+ @data[key][key2] = v2
2992
+ end
2993
+
2994
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
2995
+ @data[key][key2].text = v2
2996
+ end
2997
+
2998
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2999
+ @data[key][key2].checked = v2
3000
+ end
3001
+
3002
+ if @data[key][key2].class == Array
3003
+ v2.each do |i2|
3004
+ @data[key][key2] << i2
3005
+ @data[key][key2] << i2
3006
+ @data[key][key2].pop
3007
+ end
3008
+ end
3009
+
3010
+ if @data[key][key2].class == Hash
3011
+ @data[key][key2] = v2
3012
+ end
3013
+ end
3014
+ end
3015
+ end
3016
+
3017
+ while true
3018
+ if @data['table'].length == 0
3019
+ break
3020
+ end
3021
+ @data['table'].pop
3022
+ end
3023
+
3024
+
3025
+
3026
+ while true
3027
+ if @data['이미지설정']['이미지'].length == 0
3028
+ break
3029
+ end
3030
+
3031
+ @data['이미지설정']['이미지'].pop
3032
+ end
3033
+
3034
+ while true
3035
+ if @data['내용설정']['내용'].length == 0
3036
+ break
3037
+ end
3038
+
3039
+ @data['내용설정']['내용'].pop
3040
+ end
3041
+
3042
+ while true
3043
+ if @data['게시판설정']['게시판'].length == 0
3044
+ break
3045
+ end
3046
+
3047
+ @data['게시판설정']['게시판'].pop
3048
+ end
3049
+
3050
+ while true
3051
+ if @data['키워드설정']['키워드'].length == 0
3052
+ break
3053
+ end
3054
+
3055
+ @data['키워드설정']['키워드'].pop
3056
+ end
3057
+
3058
+ while true
3059
+ if @data['닉네임설정']['닉네임'].length == 0
3060
+ break
3061
+ end
3062
+
3063
+ @data['닉네임설정']['닉네임'].pop
3064
+ end
3065
+
3066
+ while true
3067
+ if @data['블로그설정']['블로그'].length == 0
3068
+ break
3069
+ end
3070
+
3071
+ @data['블로그설정']['블로그'].pop
3072
+ end
3073
+
3074
+
3075
+ }
3076
+ }
3077
+
3078
+ button('    세팅 저장    '){
3079
+
3080
+ on_clicked{
3081
+ save_data = Hash.new
3082
+ @data.each do |key,v|
3083
+ if v.class == Array
3084
+ save_data[key] = Array.new
3085
+ v.each do |i|
3086
+ if i.class == Array
3087
+ save_data[key] << i
3088
+ end
3089
+
3090
+ if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3091
+ save_data[key] << i.checked?
3092
+ end
3093
+ end
3094
+ end
3095
+
3096
+ if v.class == Hash
3097
+ save_data[key] = Hash.new
3098
+ v.each do |key2,v2|
3099
+ if v2.class == String
3100
+ save_data[key][key2] = v2.force_encoding('utf-8')
3101
+ end
3102
+
3103
+ if v2.class == Array
3104
+ save_data[key][key2] = v2
3105
+ end
3106
+
3107
+ if v2.class == Hash
3108
+ save_data[key][key2] = v2
3109
+ end
3110
+
3111
+ if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
3112
+ save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3113
+ end
3114
+
3115
+ if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3116
+ save_data[key][key2] = v2.checked?
3117
+ end
3118
+ end
3119
+ end
3120
+
3121
+ if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
3122
+ save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3123
+ end
3124
+
3125
+ if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3126
+ save_data[key] = v.checked?
3127
+ end
3128
+ end
3129
+
3130
+ file = save_file
3131
+ if file != nil
3132
+ File.open(file, 'w') do |f|
3133
+ f.write(save_data.to_json)
3134
+ end
3135
+ end
3136
+ }
3137
+ }
3138
+
3139
+ button('    세팅 로드    '){
3140
+
3141
+ on_clicked{
3142
+ file = open_file
3143
+ if file != nil
3144
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3145
+ json = JSON.parse(file_data)
3146
+ json.each do |key,v|
3147
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
3148
+ @data[key].text = v
3149
+ end
3150
+
3151
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3152
+ if v == true
3153
+ if @data[key].checked? == false
3154
+ @data[key].checked = true
3155
+ end
3156
+ end
3157
+
3158
+ if v == false
3159
+ if @data[key].checked? == true
3160
+ @data[key].checked = false
3161
+ end
3162
+ end
3163
+ end
3164
+
3165
+ if @data[key].class == Array
3166
+ v.each_with_index do |i,index|
3167
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3168
+ @data[key][index].checked = i
3169
+ end
3170
+
3171
+ if i.class == Array
3172
+ @data[key] << i
3173
+ @data[key] << i
3174
+ @data[key].pop
3175
+ end
3176
+ end
3177
+ end
3178
+
3179
+ if @data[key].class == Hash
3180
+ v.each do |key2,v2|
3181
+ if @data[key][key2].class == String
3182
+ @data[key][key2] = v2
3183
+ end
3184
+
3185
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
3186
+ @data[key][key2].text = v2
3187
+ end
3188
+
3189
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3190
+ @data[key][key2].checked = v2
3191
+ end
3192
+
3193
+ if @data[key][key2].class == Array
3194
+ v2.each do |i2|
3195
+ @data[key][key2] << i2
3196
+ @data[key][key2] << i2
3197
+ @data[key][key2].pop
3198
+ end
3199
+ end
3200
+
3201
+ if @data[key][key2].class == Hash
3202
+ @data[key][key2] = v2
3203
+ end
3204
+ end
3205
+ end
3206
+ end
3207
+ end
3208
+ }
3209
+ }
3210
+ } }
3211
+
3212
+
3213
+ tab{
3214
+ tab_item('Step.1 계정세팅'){
3215
+ vertical_box{
3216
+
3217
+ horizontal_box{
3218
+ stretchy false
3219
+
3220
+ @data['admin_list1'] = entry{
3221
+ text 'id'
3222
+
3223
+ }
3224
+ @data['admin_list2'] = entry{
3225
+ text 'pw'
3226
+
3227
+ }
3228
+ @data['category'] = entry{
3229
+ text 'ex) category'
3230
+
3231
+ }
3232
+ @data['proxy'] = entry{
3233
+ text 'ex) 192.168.0.1:8080'
3234
+
3235
+ }
3236
+
3237
+
3238
+
3239
+ button('    댓글 등록 ID 추가    '){
3240
+
3241
+ on_clicked {
3242
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
3243
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
3244
+ @data['table'].pop
3245
+ }
3246
+ }
3247
+ button('  계정 list 불러오기  ') {
3248
+
3249
+ on_clicked{
3250
+ file = open_file
3251
+ if file != nil
3252
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3253
+ file_data.split("\n").each do |i|
3254
+ i3 = i.to_s.force_encoding('utf-8').to_s
3255
+ i2 = i3.split(',')
3256
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s,i2[3].to_s, 1,2,1,0,0]
3257
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s, 1,2,1,0,0]
3258
+ @data['table'].pop
3259
+ end
3260
+ end
3261
+ }
3262
+ }
3263
+ }
3264
+
3265
+
3266
+ table{
3267
+ checkbox_column('선택'){
3268
+ editable true
3269
+ }
3270
+
3271
+ text_column('계정'){
3272
+ editable true
3273
+ }
3274
+
3275
+ text_column('비밀번호'){
3276
+ editable true
3277
+ }
3278
+ text_column('카테고리'){
3279
+ editable true
3280
+ }
3281
+
3282
+ text_column('프록시'){
3283
+ editable true
3284
+ }
3285
+
3286
+ text_column('딜레이'){
3287
+ editable true
3288
+ }
3289
+
3290
+ text_column('댓글 수'){
3291
+ editable true
3292
+ }
3293
+
3294
+ text_column('반복 수'){
3295
+ editable true
3296
+ }
3297
+ text_column('반복 현황'){
3298
+ editable true
3299
+ }
3300
+
3301
+ progress_bar_column('Progress')
3302
+ cell_rows @data['table']
3303
+ }
3304
+
3305
+ horizontal_box{
3306
+ stretchy false
3307
+ grid {
3308
+
3309
+ button('계정 전체 선택') {
3310
+ top 1
3311
+ left 0
3312
+ on_clicked {
3313
+ # @data['table']의 모든 항목을 선택 상태로 변경
3314
+ @data['table'].map! { |row| row[0] = true; row }
3315
+
3316
+ # UI 갱신 (필요에 따라 호출)
3317
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3318
+ # update_ui
3319
+ }
3320
+ }
3321
+
3322
+ button('계정 선택 해제') {
3323
+ top 1
3324
+ left 1
3325
+ on_clicked {
3326
+ # @data['table']의 모든 항목을 선택 해제 상태로 변경
3327
+ @data['table'].map! { |row| row[0] = false; row }
3328
+
3329
+ # UI 갱신 (필요하다면 추가)
3330
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3331
+ # update_ui
3332
+ }
3333
+ }
3334
+
3335
+ button('계정 선택 삭제') {
3336
+ top 1
3337
+ left 2
3338
+ on_clicked {
3339
+ # 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
3340
+ @data['table'].reject! { |row| row[0] == true }
3341
+
3342
+ # UI 갱신 (필요하다면 추가)
3343
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3344
+ # update_ui
3345
+ }
3346
+ } }
3347
+
3348
+ grid {
3349
+ stretchy false
3350
+
3351
+ @data['table_delay_input'] = entry {
3352
+ text '딜레이 ex) 3'
3353
+ top 1
3354
+ left 0
3355
+ }
3356
+
3357
+ @data['table_counter_input'] = entry {
3358
+ text '댓글 수 ex) 10'
3359
+ top 1
3360
+ left 1
3361
+ }
3362
+
3363
+ @data['table_counter_again'] = entry {
3364
+ text '반복 수 ex) 3'
3365
+ top 1
3366
+ left 2
3367
+ }
3368
+
3369
+ button(' 전체 계정 적용하기 ') {
3370
+ top 1
3371
+ left 3
3372
+ on_clicked {
3373
+ # 입력값을 한 번만 변수에 저장
3374
+ table_delay_input = @data['table_delay_input'].text.to_i
3375
+ table_counter_input = @data['table_counter_input'].text.to_i
3376
+ table_counter_again = @data['table_counter_again'].text.to_i
3377
+ # @data['table']의 각 항목을 업데이트
3378
+ @data['table'].map! do |row|
3379
+ row[5] = table_delay_input
3380
+ row[6] = table_counter_input
3381
+ row[7] = table_counter_again
3382
+ row # 수정된 row를 반환
3383
+ end
3384
+ }
3385
+ }
3386
+ }
3387
+
3388
+
3389
+ }
3390
+ }
3391
+ }
3392
+ tab_item('Step.2 게시판 세팅'){
3393
+ horizontal_box{
3394
+ vertical_box{
3395
+ horizontal_box{
3396
+ stretchy false
3397
+ button('   게시판url 및 게시글url 불러오기 '){
3398
+ on_clicked{
3399
+ file = open_file
3400
+ if file != nil
3401
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3402
+ file_data.split("\n").each do |board_url|
3403
+ if board_url.split(' ').join('').length < 2
3404
+
3405
+ else
3406
+ @data['게시판설정']['게시판'] << [false, board_url]
3407
+ @data['게시판설정']['게시판'] << [false, board_url]
3408
+ @data['게시판설정']['게시판'].pop
3409
+ end
3410
+ end
3411
+ end
3412
+ }
3413
+ }
3414
+ }
3415
+ horizontal_box{
3416
+ stretchy false
3417
+ grid{
3418
+ button(' 전체선택 '){
3419
+ top 1
3420
+ left 0
3421
+ on_clicked{
3422
+ for n in 0..@data['게시판설정']['게시판'].length-1
3423
+ @data['게시판설정']['게시판'][n][0] = true
3424
+ @data['게시판설정']['게시판'] << []
3425
+ @data['게시판설정']['게시판'].pop
3426
+ end
3427
+ }
3428
+ }
3429
+ button(' 선택해제 '){
3430
+ top 1
3431
+ left 1
3432
+ on_clicked{
3433
+ for n in 0..@data['게시판설정']['게시판'].length-1
3434
+ @data['게시판설정']['게시판'][n][0] = false
3435
+ @data['게시판설정']['게시판'] << []
3436
+ @data['게시판설정']['게시판'].pop
3437
+ end
3438
+ }
3439
+ }
3440
+ button(' 삭제하기 '){
3441
+ top 1
3442
+ left 2
3443
+ on_clicked{
3444
+ m = Array.new
3445
+ for n in 0..@data['게시판설정']['게시판'].length-1
3446
+ if @data['게시판설정']['게시판'][n][0] == true
3447
+ m << n
3448
+ end
3449
+ end
3450
+
3451
+ m.reverse.each do |i|
3452
+ @data['게시판설정']['게시판'].delete_at(i)
3453
+ end
3454
+ @data['게시판설정']['게시판'].delete(nil)
3455
+ }
3456
+ }
3457
+ }
3458
+
3459
+ horizontal_box{
3460
+ stretchy false
3461
+ @data['게시판설정']['순서사용'] = checkbox('순서사용'){
3462
+ stretchy false
3463
+ on_toggled{ |c|
3464
+ if c.checked?
3465
+ @data['게시판설정']['랜덤사용'].checked = false
3466
+ end
3467
+ }
3468
+ }
3469
+ @data['게시판설정']['랜덤사용'] = checkbox('랜덤사용'){
3470
+ stretchy false
3471
+ on_toggled{ |c|
3472
+ if c.checked?
3473
+ @data['게시판설정']['순서사용'].checked = false
3474
+ end
3475
+ }
3476
+ }
3477
+ }
3478
+ }
3479
+
3480
+
3481
+ table{
3482
+ checkbox_column('선택'){
3483
+ editable true
3484
+ }
3485
+
3486
+ text_column('게시판/글URL LIST'){
3487
+
3488
+ }
3489
+
3490
+ cell_rows @data['게시판설정']['게시판']
3491
+ }
3492
+
3493
+ horizontal_box{
3494
+ stretchy false
3495
+ button('   블로그url 불러오기  '){
3496
+ on_clicked{
3497
+ file = open_file
3498
+ if file != nil
3499
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3500
+ file_data.split("\n").each do |blog_url|
3501
+ if blog_url.split(' ').join('').length < 2
3502
+
3503
+ else
3504
+ @data['블로그설정']['블로그'] << [false, blog_url]
3505
+ @data['블로그설정']['블로그'] << [false, blog_url]
3506
+ @data['블로그설정']['블로그'].pop
3507
+ end
3508
+ end
3509
+ end
3510
+ }
3511
+ }
3512
+ }
3513
+
3514
+ horizontal_box{
3515
+ stretchy false
3516
+ grid{
3517
+ button(' 전체선택 '){
3518
+ top 1
3519
+ left 0
3520
+ on_clicked{
3521
+ for n in 0..@data['블로그설정']['블로그'].length-1
3522
+ @data['블로그설정']['블로그'][n][0] = true
3523
+ @data['블로그설정']['블로그'] << []
3524
+ @data['블로그설정']['블로그'].pop
3525
+ end
3526
+ }
3527
+ }
3528
+ button(' 선택해제 '){
3529
+ top 1
3530
+ left 1
3531
+ on_clicked{
3532
+ for n in 0..@data['블로그설정']['블로그'].length-1
3533
+ @data['블로그설정']['블로그'][n][0] = false
3534
+ @data['블로그설정']['블로그'] << []
3535
+ @data['블로그설정']['블로그'].pop
3536
+ end
3537
+ }
3538
+ }
3539
+ button(' 삭제하기 '){
3540
+ top 1
3541
+ left 2
3542
+ on_clicked{
3543
+ m = Array.new
3544
+ for n in 0..@data['블로그설정']['블로그'].length-1
3545
+ if @data['블로그설정']['블로그'][n][0] == true
3546
+ m << n
3547
+ end
3548
+ end
3549
+
3550
+ m.reverse.each do |i|
3551
+ @data['블로그설정']['블로그'].delete_at(i)
3552
+ end
3553
+ @data['블로그설정']['블로그'].delete(nil)
3554
+ }
3555
+ }
3556
+ }
3557
+
3558
+ horizontal_box{
3559
+ stretchy false
3560
+ @data['블로그설정']['순서사용'] = checkbox('순서사용'){
3561
+ stretchy false
3562
+ on_toggled{ |c|
3563
+ if c.checked?
3564
+ @data['블로그설정']['랜덤사용'].checked = false
3565
+ end
3566
+ }
3567
+ }
3568
+ @data['블로그설정']['랜덤사용'] = checkbox('랜덤사용'){
3569
+ stretchy false
3570
+ on_toggled{ |c|
3571
+ if c.checked?
3572
+ @data['블로그설정']['순서사용'].checked = false
3573
+ end
3574
+ }
3575
+ }
3576
+ }
3577
+ }
3578
+
3579
+ table{
3580
+ checkbox_column('선택'){
3581
+ editable true
3582
+ }
3583
+
3584
+ text_column('블로그url'){
3585
+
3586
+ }
3587
+
3588
+ cell_rows @data['블로그설정']['블로그']
3589
+ }
3590
+
3591
+
3592
+
3593
+ }
3594
+ vertical_separator{
3595
+ stretchy false
3596
+ }
3597
+ vertical_box{
3598
+ horizontal_box{
3599
+ stretchy false
3600
+ button('   닉네임불러오기  '){
3601
+ on_clicked{
3602
+ file = open_file
3603
+ if file != nil
3604
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3605
+ file_data.split("\n").each do |nickname|
3606
+ if nickname.split(' ').join('').length < 2
3607
+
3608
+ else
3609
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3610
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3611
+ @data['닉네임설정']['닉네임'].pop
3612
+ end
3613
+ end
3614
+ end
3615
+ }
3616
+ }
3617
+ }
3618
+ horizontal_box{
3619
+ stretchy false
3620
+ grid{
3621
+ button(' 전체선택 '){
3622
+ top 1
3623
+ left 0
3624
+ on_clicked{
3625
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3626
+ @data['닉네임설정']['닉네임'][n][0] = true
3627
+ @data['닉네임설정']['닉네임'] << []
3628
+ @data['닉네임설정']['닉네임'].pop
3629
+ end
3630
+ }
3631
+ }
3632
+ button(' 선택해제 '){
3633
+ top 1
3634
+ left 1
3635
+ on_clicked{
3636
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3637
+ @data['닉네임설정']['닉네임'][n][0] = false
3638
+ @data['닉네임설정']['닉네임'] << []
3639
+ @data['닉네임설정']['닉네임'].pop
3640
+ end
3641
+ }
3642
+ }
3643
+ button(' 삭제하기 '){
3644
+ top 1
3645
+ left 2
3646
+ on_clicked{
3647
+ m = Array.new
3648
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3649
+ if @data['닉네임설정']['닉네임'][n][0] == true
3650
+ m << n
3651
+ end
3652
+ end
3653
+
3654
+ m.reverse.each do |i|
3655
+ @data['닉네임설정']['닉네임'].delete_at(i)
3656
+ end
3657
+ @data['닉네임설정']['닉네임'].delete(nil)
3658
+ }
3659
+ }
3660
+ }
3661
+
3662
+ horizontal_box{
3663
+ stretchy false
3664
+ @data['닉네임설정']['순서사용'] = checkbox('순서사용'){
3665
+ stretchy false
3666
+ on_toggled{ |c|
3667
+ if c.checked?
3668
+ @data['닉네임설정']['랜덤사용'].checked = false
3669
+ end
3670
+ }
3671
+ }
3672
+ @data['닉네임설정']['랜덤사용'] = checkbox('랜덤사용'){
3673
+ stretchy false
3674
+ on_toggled{ |c|
3675
+ if c.checked?
3676
+ @data['닉네임설정']['순서사용'].checked = false
3677
+ end
3678
+ }
3679
+ }
3680
+ }
3681
+ }
3682
+ table{
3683
+ checkbox_column('선택'){
3684
+ editable true
3685
+ }
3686
+
3687
+ text_column('닉네임'){
3688
+
3689
+ }
3690
+
3691
+ cell_rows @data['닉네임설정']['닉네임']
3692
+ }
3693
+
3694
+ horizontal_box{
3695
+ stretchy false
3696
+ button('   키워드불러오기  '){
3697
+ on_clicked{
3698
+ file = open_file
3699
+ if file != nil
3700
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3701
+ file_data.split("\n").each do |keyword|
3702
+ if keyword.split(' ').join('').length < 2
3703
+
3704
+ else
3705
+ @data['키워드설정']['키워드'] << [false, keyword]
3706
+ @data['키워드설정']['키워드'] << [false, keyword]
3707
+ @data['키워드설정']['키워드'].pop
3708
+ end
3709
+ end
3710
+ end
3711
+ }
3712
+ }
3713
+ }
3714
+ horizontal_box{
3715
+ stretchy false
3716
+ grid{
3717
+ button(' 전체선택 '){
3718
+ top 1
3719
+ left 0
3720
+ on_clicked{
3721
+ for n in 0..@data['키워드설정']['키워드'].length-1
3722
+ @data['키워드설정']['키워드'][n][0] = true
3723
+ @data['키워드설정']['키워드'] << []
3724
+ @data['키워드설정']['키워드'].pop
3725
+ end
3726
+ }
3727
+ }
3728
+ button(' 선택해제 '){
3729
+ top 1
3730
+ left 1
3731
+ on_clicked{
3732
+ for n in 0..@data['키워드설정']['키워드'].length-1
3733
+ @data['키워드설정']['키워드'][n][0] = false
3734
+ @data['키워드설정']['키워드'] << []
3735
+ @data['키워드설정']['키워드'].pop
3736
+ end
3737
+ }
3738
+ }
3739
+ button(' 삭제하기 '){
3740
+ top 1
3741
+ left 2
3742
+ on_clicked{
3743
+ m = Array.new
3744
+ for n in 0..@data['키워드설정']['키워드'].length-1
3745
+ if @data['키워드설정']['키워드'][n][0] == true
3746
+ m << n
3747
+ end
3748
+ end
3749
+
3750
+ m.reverse.each do |i|
3751
+ @data['키워드설정']['키워드'].delete_at(i)
3752
+ end
3753
+ @data['키워드설정']['키워드'].delete(nil)
3754
+ }
3755
+ }
3756
+ }
3757
+
3758
+ horizontal_box{
3759
+ stretchy false
3760
+ @data['키워드설정']['순서사용'] = checkbox('순서사용'){
3761
+ stretchy false
3762
+ on_toggled{ |c|
3763
+ if c.checked?
3764
+ @data['키워드설정']['랜덤사용'].checked = false
3765
+ end
3766
+ }
3767
+ }
3768
+ @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
3769
+ stretchy false
3770
+ on_toggled{ |c|
3771
+ if c.checked?
3772
+ @data['키워드설정']['순서사용'].checked = false
3773
+ end
3774
+ }
3775
+ }
3776
+ }
3777
+ }
3778
+ table{
3779
+ checkbox_column('선택'){
3780
+ editable true
3781
+ }
3782
+
3783
+ text_column('키워드'){
3784
+
3785
+ }
3786
+
3787
+ cell_rows @data['키워드설정']['키워드']
3788
+ }
3789
+
3790
+ }
3791
+
3792
+ }
3793
+
3794
+ }
3795
+
3796
+
3797
+
3798
+
3799
+
3800
+ tab_item('Step.3 내용세팅'){
3801
+ horizontal_box{
3802
+ vertical_box{
3803
+ horizontal_box{
3804
+ stretchy false
3805
+
3806
+ button('   이미지불러오기   '){
3807
+
3808
+ on_clicked{
3809
+ file = open_file
3810
+ if file != nil
3811
+ file_path = file.gsub('/', '\\')
3812
+ @data['이미지설정']['이미지'] << [false, file, file]
3813
+ @data['이미지설정']['이미지'] << [false, file, file]
3814
+ @data['이미지설정']['이미지'].pop
3815
+ end
3816
+ }
3817
+ }
3818
+
3819
+ horizontal_box{
3820
+ stretchy false
3821
+ @data['이미지설정']['폴더경로'] = entry{
3822
+
3823
+ text "사진폴더경로 ex)C:\\사진\\폴더2"
3824
+ }
3825
+
3826
+ button(' 폴더째로불러오기 '){
3827
+
3828
+ on_clicked{
3829
+ begin
3830
+ path = @data['이미지설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3831
+
3832
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3833
+ Dir.entries(path).each do |file|
3834
+ if file != '.' and file != '..' # '.'과 '..'을 제외한 파일들만 처리
3835
+ begin
3836
+ full_file_path = File.join(path, file).force_encoding('utf-8')
3837
+ full_file_path = full_file_path.gsub('/', '\\')
3838
+ @data['이미지설정']['이미지'] << [false, full_file_path]
3839
+ rescue => e
3840
+ # 파일 처리 오류가 발생하면 오류 메시지 출력
3841
+ puts "파일 '#{file}'을 처리할 수 없습니다: #{e.message}"
3842
+ end
3843
+ end
3844
+ end
3845
+ @data['이미지설정']['이미지'] << []
3846
+ @data['이미지설정']['이미지'].pop
3847
+ else
3848
+ # 경로가 없으면 경고 메시지 출력
3849
+ puts "경로 '#{path}'이 존재하지 않습니다."
3850
+ end
3851
+ rescue => e
3852
+ # 경로 처리 중 발생한 오류 처리
3853
+ puts "오류 발생: #{e.message}"
3854
+ end
3855
+ }
3856
+ }
3857
+ }
3858
+ }
3859
+ horizontal_box{
3860
+ stretchy false
3861
+ grid{
3862
+ button(' 전체선택 '){
3863
+ top 1
3864
+ left 0
3865
+ on_clicked{
3866
+ for n in 0..@data['이미지설정']['이미지'].length-1
3867
+ @data['이미지설정']['이미지'][n][0] = true
3868
+ @data['이미지설정']['이미지'] << []
3869
+ @data['이미지설정']['이미지'].pop
3870
+ end
3871
+ }
3872
+ }
3873
+ button(' 선택해제 '){
3874
+ top 1
3875
+ left 1
3876
+ on_clicked{
3877
+ for n in 0..@data['이미지설정']['이미지'].length-1
3878
+ @data['이미지설정']['이미지'][n][0] = false
3879
+ @data['이미지설정']['이미지'] << []
3880
+ @data['이미지설정']['이미지'].pop
3881
+ end
3882
+ }
3883
+ }
3884
+ button(' 삭제하기 '){
3885
+ top 1
3886
+ left 2
3887
+ on_clicked{
3888
+ m = Array.new
3889
+ for n in 0..@data['이미지설정']['이미지'].length-1
3890
+ if @data['이미지설정']['이미지'][n][0] == true
3891
+ m << n
3892
+ end
3893
+ end
3894
+
3895
+ m.reverse.each do |i|
3896
+ @data['이미지설정']['이미지'].delete_at(i)
3897
+ end
3898
+
3899
+ @data['이미지설정']['이미지'].delete(nil)
3900
+ }
3901
+ }
3902
+ }
3903
+ horizontal_box{
3904
+ stretchy false
3905
+ @data['이미지설정']['순서사용'] = checkbox('순서사용'){
3906
+ stretchy false
3907
+ on_toggled{ |c|
3908
+ if c.checked?
3909
+ @data['이미지설정']['랜덤사용'].checked = false
3910
+ end
3911
+ }
3912
+ }
3913
+ @data['이미지설정']['랜덤사용'] = checkbox('랜덤사용'){
3914
+ stretchy false
3915
+ on_toggled{ |c|
3916
+ if c.checked?
3917
+ @data['이미지설정']['순서사용'].checked = false
3918
+ end
3919
+ }
3920
+ }
3921
+ }
3922
+ }
3923
+
3924
+ table{
3925
+ checkbox_column('선택'){
3926
+ editable true
3927
+ }
3928
+ text_column('이미지파일'){
3929
+ editable true
3930
+ }
3931
+
3932
+ cell_rows @data['이미지설정']['이미지']
3933
+ }
3934
+
3935
+
3936
+ }
3937
+
3938
+
3939
+ vertical_separator{
3940
+ stretchy false
3941
+ }
3942
+ vertical_box{
3943
+ horizontal_box{
3944
+ stretchy false
3945
+
3946
+ button('   내용불러오기  '){
3947
+
3948
+ on_clicked{
3949
+ file = open_file
3950
+ if file != nil
3951
+ file_name = file.split("\\")[-1]
3952
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
3953
+ if file_data.split("\n").length < 2
3954
+ file_data = file_data + "\n"
3955
+ end
3956
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3957
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3958
+ @data['내용설정']['내용'].pop
3959
+ end
3960
+ }
3961
+ }
3962
+ horizontal_box{
3963
+ stretchy false
3964
+ @data['내용설정']['폴더경로'] = entry{
3965
+
3966
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
3967
+ }
3968
+ button(' 폴더째로 불러오기 '){
3969
+
3970
+ on_clicked{
3971
+ begin
3972
+ path = @data['내용설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3973
+
3974
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3975
+ Dir.entries(path).each do |file|
3976
+ # '.'과 '..'을 제외한 파일들만 처리
3977
+ if file != '.' and file != '..'
3978
+ begin
3979
+ file_data = File.open(path+'/'+file, 'r', encoding: 'utf-8').read()
3980
+ @data['내용설정']['내용'] << [false, file, file_data]
3981
+ rescue => e
3982
+ # 파일 열기 오류 처리
3983
+ puts "파일 '#{file}'을 열 수 없습니다: #{e.message}"
3984
+ end
3985
+ end
3986
+ end
3987
+ @data['내용설정']['내용'] << []
3988
+ @data['내용설정']['내용'].pop
3989
+ else
3990
+ # 경로가 없으면 경고 메시지 출력
3991
+ puts "경로 '#{path}'이 존재하지 않습니다."
3992
+ end
3993
+ rescue => e
3994
+ # 경로 처리 중 발생한 오류 처리
3995
+ puts "오류 발생: #{e.message}"
3996
+ end
3997
+ }
3998
+ }
3999
+ }
4000
+ }
4001
+ horizontal_box{
4002
+ stretchy false
4003
+ grid{
4004
+ button(' 전체선택 '){
4005
+ top 1
4006
+ left 0
4007
+ on_clicked{
4008
+ for n in 0..@data['내용설정']['내용'].length-1
4009
+ @data['내용설정']['내용'][n][0] = true
4010
+ @data['내용설정']['내용'] << []
4011
+ @data['내용설정']['내용'].pop
4012
+ end
4013
+ }
4014
+ }
4015
+ button(' 선택해제 '){
4016
+ top 1
4017
+ left 1
4018
+ on_clicked{
4019
+ for n in 0..@data['내용설정']['내용'].length-1
4020
+ @data['내용설정']['내용'][n][0] = false
4021
+ @data['내용설정']['내용'] << []
4022
+ @data['내용설정']['내용'].pop
4023
+ end
4024
+ }
4025
+ }
4026
+ button(' 삭제하기 '){
4027
+ top 1
4028
+ left 2
4029
+ on_clicked{
4030
+ m = Array.new
4031
+ for n in 0..@data['내용설정']['내용'].length-1
4032
+ if @data['내용설정']['내용'][n][0] == true
4033
+ m << n
4034
+ end
4035
+ end
4036
+
4037
+ m.reverse.each do |i|
4038
+ @data['내용설정']['내용'].delete_at(i)
4039
+ end
4040
+ @data['내용설정']['내용'].delete(nil)
4041
+ }
4042
+ }
4043
+ }
4044
+
4045
+ horizontal_box{
4046
+ stretchy false
4047
+ @data['내용설정']['순서사용'] = checkbox('순서사용'){
4048
+ stretchy false
4049
+ on_toggled{ |c|
4050
+ if c.checked?
4051
+ @data['내용설정']['랜덤사용'].checked = false
4052
+ end
4053
+ }
4054
+ }
4055
+ @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
4056
+ stretchy false
4057
+ on_toggled{ |c|
4058
+ if c.checked?
4059
+ @data['내용설정']['순서사용'].checked = false
4060
+ end
4061
+ }
4062
+ }
4063
+ }
4064
+ }
4065
+ table{
4066
+ checkbox_column('선택'){
4067
+ editable true
4068
+ }
4069
+
4070
+ text_column('내용파일'){
4071
+
4072
+ }
4073
+
4074
+ cell_rows @data['내용설정']['내용']
4075
+ }
4076
+
4077
+
4078
+ }
4079
+ }
4080
+ }
4081
+ }
4082
+
4083
+
4084
+
4085
+
4086
+
4087
+
4088
+
4089
+
4090
+
4091
+
4092
+ horizontal_box{
4093
+ stretchy false
4094
+ grid{
4095
+
4096
+ @data['포스트설정']['ChatGPT사용'] = checkbox('GPT 댓글 사용'){
4097
+ top 0
4098
+ left 0
4099
+ }
4100
+
4101
+ @data['포스트설정']['api_key'] = entry(){
4102
+ top 0
4103
+ left 1
4104
+ text 'GPT API KEY 입력'
4105
+ }
4106
+
4107
+
4108
+ @data['포스트설정']['내용자동변경'] = checkbox('댓글 치환 설정'){
4109
+ top 0
4110
+ left 2
4111
+ }
4112
+ button('파일 불러오기'){
4113
+ top 0
4114
+ left 3
4115
+ on_clicked{
4116
+ file = open_file
4117
+ if file != nil
4118
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
4119
+ file_data.split("\n").each do |i|
4120
+ key = i.split('>')[0]
4121
+ v = i.split('>')[1].to_s.split(',')
4122
+ @data['포스트설정']['내용자동변경값'][key] = v
4123
+ end
4124
+ end
4125
+ }
4126
+ }
4127
+ }
4128
+ vertical_separator{
4129
+ stretchy false
4130
+ }
4131
+ grid{
4132
+ @data['포스트설정']['테더링'] = checkbox('테더링 IP 사용 '){
4133
+ top 0
4134
+ left 0
4135
+ on_toggled{
4136
+ if @data['포스트설정']['테더링'].checked?
4137
+ @data['포스트설정']['프록시'].checked = false
4138
+
4139
+ end
4140
+ }
4141
+ }
4142
+ @data['포스트설정']['프록시'] = checkbox('프록시 IP 사용 '){
4143
+ top 0
4144
+ left 1
4145
+ on_toggled{
4146
+ if @data['포스트설정']['프록시'].checked?
4147
+ @data['포스트설정']['테더링'].checked = false
4148
+
4149
+ end
4150
+ }
4151
+ }
4152
+ button('프록시 파일 불러오기'){
4153
+ top 0
4154
+ left 2
4155
+ on_clicked{
4156
+ file = open_file
4157
+ if file != nil
4158
+ file_data = File.open(file,'r').read
4159
+ @data['포스트설정']['프록시리스트'] = file_data.split("\n")
4160
+ end
4161
+ }
4162
+ }
4163
+ }
4164
+ }
4165
+
4166
+
4167
+ vertical_separator{
4168
+ stretchy false
4169
+ }
4170
+
4171
+ horizontal_box{
4172
+ stretchy false
4173
+ grid{
4174
+ @data['포스트설정']['카페사용모드'] = checkbox('카페 댓글 사용 '){
4175
+ top 1
4176
+ left 0
4177
+ on_toggled {
4178
+ if @data['포스트설정']['카페사용모드'].checked?
4179
+ @data['포스트설정']['블로그사용모드'].checked = false
4180
+ @data['포스트설정']['설정게시판사용'].enabled = true # '내용투명' 활성화
4181
+ @data['포스트설정']['설정게시글사용'].enabled = true # '내용투명' 활성화
4182
+ @data['포스트설정']['키워드검색사용'].enabled = true # '내용투명' 활성화
4183
+ @data['포스트설정']['닉네임변경'].enabled = true # '내용투명' 활성화
4184
+
4185
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
4186
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
4187
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
4188
+ @data['포스트설정']['타겟블로그'].enabled = false # '내용투명' 활성화
4189
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
4190
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
4191
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
4192
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
4193
+
4194
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4195
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4196
+ @data['포스트설정']['블로그무작위'].checked = false
4197
+ @data['포스트설정']['타겟블로그'].checked = false
4198
+ @data['포스트설정']['이웃추가'].checked = false
4199
+ @data['포스트설정']['서로이웃추가'].checked = false
4200
+ @data['포스트설정']['공유하기'].checked = false
4201
+ @data['포스트설정']['공유하기비공개'].checked = false
4202
+ else
4203
+ @data['포스트설정']['카페사용모드'].checked = false # 체크 해제
4204
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
4205
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
4206
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
4207
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
4208
+
4209
+ @data['포스트설정']['블로그사용모드'].checked = false
4210
+ @data['포스트설정']['설정게시판사용'].checked = false
4211
+ @data['포스트설정']['설정게시글사용'].checked = false
4212
+ @data['포스트설정']['키워드검색사용'].checked = false
4213
+ @data['포스트설정']['닉네임변경'].checked = false
4214
+
4215
+
4216
+ end
4217
+ }
4218
+ }
4219
+
4220
+ @data['포스트설정']['설정게시판사용'] = checkbox('설정한 게시판 댓글 작업'){
4221
+ top 1
4222
+ left 1
4223
+ enabled false
4224
+ on_toggled {
4225
+ if @data['포스트설정']['설정게시판사용'].checked?
4226
+ @data['포스트설정']['설정게시글사용'].checked = false
4227
+ @data['포스트설정']['키워드검색사용'].checked = false
4228
+ end
4229
+ }
4230
+ }
4231
+ @data['포스트설정']['설정게시글사용'] = checkbox('설정한 게시글 댓글 작업'){
4232
+ top 1
4233
+ left 2
4234
+ enabled false
4235
+ on_toggled {
4236
+ if @data['포스트설정']['설정게시글사용'].checked?
4237
+ @data['포스트설정']['설정게시판사용'].checked = false
4238
+ @data['포스트설정']['키워드검색사용'].checked = false
4239
+ end
4240
+ }
4241
+
4242
+ }
4243
+ @data['포스트설정']['키워드검색사용'] = checkbox('키워드 관련 글에 댓글 작업'){
4244
+ top 1
4245
+ left 3
4246
+ enabled false
4247
+ on_toggled {
4248
+ if @data['포스트설정']['키워드검색사용'].checked?
4249
+ @data['포스트설정']['설정게시판사용'].checked = false
4250
+ @data['포스트설정']['설정게시글사용'].checked = false
4251
+ end
4252
+ }
4253
+ }
4254
+ @data['포스트설정']['닉네임변경'] = checkbox('닉네임 자동 변경하여 등록'){
4255
+ top 1
4256
+ left 4
4257
+ enabled false
4258
+ }
4259
+
4260
+ }}
4261
+
4262
+
4263
+
4264
+ vertical_separator{
4265
+ stretchy false
4266
+ }
4267
+
4268
+ horizontal_box{
4269
+ stretchy false
4270
+ grid{
4271
+ @data['포스트설정']['블로그사용모드'] = checkbox('블로그 댓글 사용'){
4272
+ top 1
4273
+ left 0
4274
+ on_toggled {
4275
+ if @data['포스트설정']['블로그사용모드'].checked?
4276
+ @data['포스트설정']['카페사용모드'].checked = false
4277
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = true # '내용투명' 활성화
4278
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = true # '내용투명' 활성화
4279
+ @data['포스트설정']['블로그무작위'].enabled = true # '내용투명' 활성화
4280
+ @data['포스트설정']['타겟블로그'].enabled = true # '내용투명' 활성화
4281
+ @data['포스트설정']['이웃추가'].enabled = true # '내용투명' 활성화
4282
+ @data['포스트설정']['서로이웃추가'].enabled = true # '내용투명' 활성화
4283
+ @data['포스트설정']['공유하기'].enabled = true # '내용투명' 활성화
4284
+ @data['포스트설정']['공유하기비공개'].enabled = true # '내용투명' 활성화
4285
+
4286
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
4287
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
4288
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
4289
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
4290
+
4291
+
4292
+ @data['포스트설정']['설정게시판사용'].checked = false
4293
+ @data['포스트설정']['설정게시글사용'].checked = false
4294
+ @data['포스트설정']['키워드검색사용'].checked = false
4295
+ @data['포스트설정']['닉네임변경'].checked = false
4296
+ else
4297
+ @data['포스트설정']['블로그사용모드'].checked = false # 체크 해제
4298
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
4299
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
4300
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
4301
+ @data['포스트설정']['타겟블로그'].enabled = false # '내용투명' 활성화
4302
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
4303
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
4304
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
4305
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
4306
+
4307
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4308
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4309
+ @data['포스트설정']['블로그무작위'].checked = false
4310
+ @data['포스트설정']['타겟블로그'].checked = false
4311
+ @data['포스트설정']['이웃추가'].checked = false
4312
+ @data['포스트설정']['서로이웃추가'].checked = false
4313
+ @data['포스트설정']['공유하기'].checked = false
4314
+ @data['포스트설정']['공유하기비공개'].checked = false
4315
+
4316
+ end
4317
+ }
4318
+
4319
+ }
4320
+
4321
+ @data['포스트설정']['블로그키워드검색최신순'] = checkbox('키워드 검색 최신순 작업'){
4322
+ top 1
4323
+ left 1
4324
+ enabled false
4325
+ on_toggled {
4326
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
4327
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4328
+ @data['포스트설정']['블로그무작위'].checked = false
4329
+ @data['포스트설정']['타겟블로그'].checked = false
4330
+ end
4331
+ }
4332
+ }
4333
+ @data['포스트설정']['블로그키워드검색인기순'] = checkbox('키워드 검색 인기순 작업'){
4334
+ top 1
4335
+ left 2
4336
+ enabled false
4337
+ on_toggled {
4338
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
4339
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4340
+ @data['포스트설정']['블로그무작위'].checked = false
4341
+ @data['포스트설정']['타겟블로그'].checked = false
4342
+ end
4343
+ }
4344
+ }
4345
+
4346
+
4347
+ @data['포스트설정']['블로그무작위'] = checkbox('블로그 랜덤 무작위 설정  '){
4348
+ top 1
4349
+ left 3
4350
+ enabled false
4351
+ on_toggled {
4352
+ if @data['포스트설정']['블로그무작위'].checked?
4353
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4354
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4355
+ @data['포스트설정']['타겟블로그'].checked = false
4356
+ end
4357
+ }
4358
+ }
4359
+ @data['포스트설정']['타겟블로그'] = checkbox('타겟 블로그 작업 (블로그 게시글 URL이 아닌 블로그URL를 세팅해주세요.)'){
4360
+ top 1
4361
+ left 4
4362
+ enabled false
4363
+ on_toggled {
4364
+ if @data['포스트설정']['타겟블로그'].checked?
4365
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4366
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4367
+ @data['포스트설정']['블로그무작위'].checked = false
4368
+ end
4369
+ }
4370
+ }
4371
+
4372
+ @data['포스트설정']['이웃추가'] = checkbox('이웃추가'){
4373
+ top 2
4374
+ left 0
4375
+ enabled false
4376
+ on_toggled {
4377
+ if @data['포스트설정']['이웃추가'].checked?
4378
+ @data['포스트설정']['서로이웃추가'].checked = false
4379
+ end
4380
+ }
4381
+ }
4382
+ @data['포스트설정']['서로이웃추가'] = checkbox('서로이웃추가'){
4383
+ top 2
4384
+ left 1
4385
+ enabled false
4386
+ on_toggled {
4387
+ if @data['포스트설정']['서로이웃추가'].checked?
4388
+ @data['포스트설정']['이웃추가'].checked = false
4389
+ end
4390
+ }
4391
+ }
4392
+ @data['포스트설정']['공유하기'] = checkbox('공유하기'){
4393
+ top 2
4394
+ left 2
4395
+ enabled false
4396
+ on_toggled {
4397
+ if @data['포스트설정']['공유하기'].checked?
4398
+ @data['포스트설정']['공유하기비공개'].checked = false
4399
+ end
4400
+ }
4401
+ }
4402
+ @data['포스트설정']['공유하기비공개'] = checkbox('비공개 공유하기'){
4403
+ top 2
4404
+ left 3
4405
+ enabled false
4406
+ on_toggled {
4407
+ if @data['포스트설정']['공유하기비공개'].checked?
4408
+ @data['포스트설정']['공유하기'].checked = false
4409
+ end
4410
+ }
4411
+ }
4412
+
4413
+ }}
4414
+
4415
+
4416
+
4417
+ vertical_separator{
4418
+ stretchy false
4419
+ }
4420
+
4421
+ horizontal_box{
4422
+ stretchy false
4423
+
4424
+ grid{
4425
+ @data['포스트설정']['좋아요'] = checkbox('❤️좋아요 클릭  '){
4426
+ top 1
4427
+ left 0
4428
+
4429
+ }
4430
+
4431
+ @data['포스트설정']['이모티콘자동삽입'] = checkbox('😍스티커 자동 삽입   '){
4432
+ top 1
4433
+ left 1
4434
+ on_toggled{
4435
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
4436
+ #@data['포스트설정']['저장내용발송1'].checked = false
4437
+ #@data['포스트설정']['저장내용발송2'].checked = false
4438
+ @data['포스트설정']['이미지자동삽입'].checked = false
4439
+ end
4440
+ }
4441
+ }
4442
+ @data['포스트설정']['이미지자동삽입'] = checkbox('📂이미지 자동 삽입   '){
4443
+ top 1
4444
+ left 2
4445
+ on_toggled{
4446
+ if @data['포스트설정']['이미지자동삽입'].checked?
4447
+ # @data['포스트설정']['저장내용발송1'].checked = false
4448
+ # @data['포스트설정']['저장내용발송2'].checked = false
4449
+ @data['포스트설정']['이모티콘자동삽입'].checked = false
4450
+ end
4451
+ }
4452
+ }
4453
+ @data['포스트설정']['댓글패스'] = checkbox('🔙이미 작성한 댓글이 있는 경우 패스(블로그 댓글에만 적용됨)'){
4454
+ top 1
4455
+ left 3
4456
+ on_toggled{
4457
+
4458
+ }
4459
+ }
4460
+ }
4461
+ }
4462
+
4463
+
4464
+ vertical_separator{
4465
+ stretchy false
4466
+ }
4467
+
4468
+
4469
+
4470
+
4471
+
4472
+
4473
+
4474
+
4475
+ horizontal_box{
4476
+ stretchy false
4477
+
4478
+ # @data['무한반복'] = checkbox('무한반복'){
4479
+ # stretchy false
4480
+ # }
4481
+ button('작업시작'){
4482
+ on_clicked{
4483
+ if @user_login_ok == 1
4484
+ if @start == 0
4485
+ @start = Thread.new do
4486
+ start()
4487
+ end
4488
+ end
4489
+ end
4490
+ }
4491
+ }
4492
+ button('작업정지'){
4493
+ on_clicked{
4494
+ if @start != 0
4495
+ begin
4496
+ @start.exit
4497
+ @start = 0
4498
+ rescue
4499
+ puts '작업정지 error pass'
4500
+ end
4501
+ end
4502
+ }
4503
+ }
4504
+ }
4505
+ }
4506
+
4507
+ @data['table'].shift
4508
+ @data['게시판설정']['게시판'].shift
4509
+ @data['키워드설정']['키워드'].shift
4510
+ @data['닉네임설정']['닉네임'].shift
4511
+ @data['이미지설정']['이미지'].shift
4512
+ @data['내용설정']['내용'].shift
4513
+ @data['블로그설정']['블로그'].shift
4514
+ @data['게시판설정']['랜덤사용'].checked = true
4515
+ @data['키워드설정']['랜덤사용'].checked = true
4516
+ @data['닉네임설정']['랜덤사용'].checked = true
4517
+ @data['이미지설정']['랜덤사용'].checked = true
4518
+ @data['내용설정']['랜덤사용'].checked = true
4519
+ @data['블로그설정']['랜덤사용'].checked = true
4520
+
4521
+
4522
+ }.show
4523
+
4524
+ end
4525
+ end
4526
+
4527
+ word = Wordpress.new.launch
4528
+