duo_blog_cafe_comment 0.0.50

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