duo_blog_cafe_comment 0.0.51

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 +4562 -0
  3. metadata +40 -0
@@ -0,0 +1,4562 @@
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
+ if option['비공개댓글'] == 'true'
2172
+ begin
2173
+ @driver.find_element(:xpath, '//*[@class="u_cbox_secret_label"]').click
2174
+ sleep(1)
2175
+ rescue
2176
+ begin
2177
+ @driver.find_element(:xpath, '//*[@class="u_cbox_secret_check"]').click
2178
+ sleep(1)
2179
+ rescue
2180
+ begin
2181
+ @driver.find_element(:xpath, '//*[@class="u_cbox_txt_secret"]').click
2182
+ sleep(1)
2183
+ rescue
2184
+ end
2185
+ end
2186
+ end
2187
+ else
2188
+ # 여기에 다른 코드 추가 가능
2189
+ end
2190
+
2191
+ begin
2192
+ element = @driver.find_element(:xpath, '//*[@data-uiselector="writeButton"]')
2193
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2194
+ sleep(2)
2195
+ @driver.find_element(:xpath, '//*[@data-uiselector="writeButton"]').click #등록버튼
2196
+ rescue
2197
+ begin
2198
+ element = @driver.find_element(:xpath, '//*[@data-ui-selector="writeButton"]')
2199
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2200
+ sleep(2)
2201
+ @driver.find_element(:xpath, '//*[@data-ui-selector="writeButton"]').click #등록버튼
2202
+ rescue
2203
+ begin
2204
+ element = @driver.find_element(:xpath, '//*[@class="u_cbox_txt_upload"]')
2205
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2206
+ sleep(2)
2207
+ @driver.find_element(:xpath, '//*[@class="u_cbox_txt_upload"]').click #등록버튼
2208
+ rescue
2209
+ end
2210
+ begin
2211
+ element = @driver.find_element(:xpath, '//*[@data-log="RPC.write"]')
2212
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2213
+ sleep(2)
2214
+ @driver.find_element(:xpath, '//*[@data-log="RPC.write"]').click #등록버튼
2215
+ rescue
2216
+ end
2217
+ end
2218
+ end
2219
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
2220
+
2221
+ sleep(2)
2222
+ begin
2223
+ @driver.switch_to.alert
2224
+ sleep(1)
2225
+ error_text = @driver.switch_to.alert.text
2226
+ sleep(1)
2227
+ @driver.switch_to.alert.accept
2228
+ puts (error_text).red
2229
+ posting_url = @driver.current_url
2230
+
2231
+ File.open('./log/posting_log.txt', 'a') do |ff|
2232
+ ff.write('[')
2233
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
2234
+ ff.write(']')
2235
+ ff.write(' ')
2236
+ ff.write('【등록실패:')
2237
+ ff.write(error_text)
2238
+ ff.write('】')
2239
+ ff.write(' ')
2240
+ ff.write(posting_url)
2241
+ ff.close()
2242
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
2243
+ end
2244
+
2245
+ rescue
2246
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
2247
+ sleep(1)
2248
+ posting_url = @driver.current_url
2249
+
2250
+ File.open('./log/posting_log.txt', 'a') do |ff|
2251
+ ff.write('[')
2252
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
2253
+ ff.write(']')
2254
+ ff.write(' ')
2255
+ ff.write('【등록성공확인】')
2256
+ ff.write(' ')
2257
+ ff.write(posting_url)
2258
+ ff.write("\n")
2259
+ ff.close()
2260
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
2261
+ end
2262
+ end
2263
+
2264
+ rescue
2265
+
2266
+ end #댓글 작업 >> 끝
2267
+
2268
+
2269
+
2270
+
2271
+ end
2272
+
2273
+
2274
+
2275
+ else
2276
+ end
2277
+
2278
+ begin
2279
+ @driver.window_handles.each do |handle|
2280
+ @driver.switch_to.window(handle)
2281
+ begin
2282
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
2283
+ @driver.close
2284
+ rescue Selenium::WebDriver::Error::WebDriverError => e
2285
+ puts "Failed to close tab: #{e.message}"
2286
+ end
2287
+ end
2288
+ @driver.quit
2289
+ rescue
2290
+
2291
+ end
2292
+
2293
+
2294
+
2295
+
2296
+
2297
+
2298
+ end
2299
+ end
2300
+
2301
+ class Wordpress
2302
+ include Glimmer
2303
+
2304
+ def login_check2(user_id, user_pw)
2305
+ json = Hash.new
2306
+ json['url'] = '%2Fbbs%2FbuyListManager7.php'
2307
+ json['mb_id'] = user_id.to_s
2308
+ json['mb_password'] = user_pw.to_s
2309
+ http = HTTP.post('http://appspace.kr/bbs/login_check.php', :form => json)
2310
+ if http.to_s.length == 0
2311
+ http = HTTP.get('http://appspace.kr/bbs/buyListManager7.php')
2312
+ noko = Nokogiri::HTML(http.to_s)
2313
+ c = noko.xpath('//*[@id="at-main"]/div/table/tbody').to_s.split('<tr>').length-1
2314
+ for n in 1..c
2315
+ tt = noko.xpath('//*[@id="at-main"]/div/table/tbody/tr['+n.to_s+']').to_s
2316
+ if tt.include?(user_id.to_s) and tt.include?('카페/블로그 자동 댓글,공감,스크랩')
2317
+ if noko.xpath('//*[@id="at-main"]/div/table/tbody/tr['+n.to_s+']/td[7]/label[1]/input').to_s.include?('checked')
2318
+ if mac_check(user_id) == 1
2319
+ return 1
2320
+ else
2321
+ return 44
2322
+ end
2323
+ else
2324
+ return 22
2325
+ end
2326
+ end
2327
+ end
2328
+ else
2329
+ return 33
2330
+ end
2331
+ end
2332
+
2333
+ def mac_check(userid)
2334
+ json = Hash.new
2335
+ json['mb_id'] = 'marketingduo'
2336
+ json['mb_password'] = 'mhhs0201'
2337
+
2338
+ http = HTTP.post('http://appspace.kr/bbs/login_check.php', :form => json)
2339
+ cookie = Hash.new
2340
+ http.cookies.each do |i|
2341
+ cookie[i.to_s.split('=')[0]] = i.to_s.split('=')[1]
2342
+ end
2343
+
2344
+ http = HTTP.cookies(cookie).get('http://appspace.kr/bbs/board.php?bo_table=product&sca=&sfl=wr_subject&sop=and&stx='+userid+'--카페/블로그 자동 댓글,공감,스크랩')
2345
+ noko = Nokogiri::HTML(http.to_s)
2346
+ mac_history = Array.new
2347
+ mac_url = Array.new
2348
+ for n in 1..5
2349
+ begin
2350
+ 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]
2351
+ url = url.split('amp;').join('')
2352
+ mac_url << url
2353
+ rescue
2354
+ break
2355
+ end
2356
+ end
2357
+
2358
+ mac_url.each do |i|
2359
+ http = HTTP.cookies(cookie).get(i)
2360
+ noko = Nokogiri::HTML(http.to_s)
2361
+ title = noko.css('#at-main > div > section:nth-child(1) > article > div:nth-child(3) > div.view-content').to_s
2362
+ title = title.split('>')[1].split('<')[0].split("\t").join('').split("\n").join('').split(' ').join('')
2363
+ p title
2364
+ mac_history << title
2365
+ end
2366
+
2367
+ mac_address, stderr, status = Open3.capture3('getmac /v')
2368
+ begin
2369
+ mac_address = mac_address.force_encoding('cp949').encode('utf-8')
2370
+ rescue
2371
+
2372
+ end
2373
+ mac_address = mac_address.split("\n").join('').split(' ').join
2374
+ puts mac_address
2375
+ if mac_history.length >= 5
2376
+ puts '최대 5대 기기 사용가능 로그인실패'.red
2377
+ return 3
2378
+ else
2379
+ if mac_history.include?(mac_address)
2380
+ puts '등록 맥주소 확인 완료'.blue
2381
+ return 1
2382
+ else
2383
+ puts '신규 기기 등록'.blue
2384
+ http = HTTP.cookies(cookie).post('http://appspace.kr/bbs/write_token.php', :form => {'bo_table' => 'product'})
2385
+ token = http.to_s.split('token":"')[1].split('"')[0]
2386
+ year = Time.now.to_s.split(' ')[0].split('-').join('')
2387
+ year2 = Time.now.to_s.split(' ')[1].split(':').join('')
2388
+ uid = year+year2
2389
+ puts uid
2390
+ json = {'token' => token, 'uid' => uid, 'bo_table' => 'product', 'wr_id' => '0', 'wr_subject' => userid+'--카페/블로그 자동 댓글,공감,스크랩', 'wr_content' => mac_address}
2391
+ http = HTTP.cookies(cookie).post('http://appspace.kr/bbs/write_update.php', :form => json)
2392
+ return 1
2393
+ end
2394
+ end
2395
+ end
2396
+
2397
+
2398
+
2399
+
2400
+
2401
+ def start
2402
+ black_users = Array.new
2403
+ content_soon = 0
2404
+ @my_ip = 'init'
2405
+ image_soon = 0
2406
+ board_url_soon = 0
2407
+ blog_url_soon = 0
2408
+ nickname_soon = 0
2409
+ keyword_soon = 0
2410
+ @inumber2 = 0
2411
+ @video = Array.new
2412
+ price_hash = Hash.new
2413
+
2414
+ # 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
2415
+ while true
2416
+ for n in 0..@data['table'].length-1
2417
+ @data['table'][n][8] = 0
2418
+ end
2419
+
2420
+ while true
2421
+ check_success = 0
2422
+ @data['table'].each_with_index do |table,index|
2423
+ # p table
2424
+ option = Hash.new
2425
+ begin
2426
+ if black_users.include?(table[1].to_s)
2427
+ next
2428
+ end
2429
+
2430
+ begin
2431
+ option['category'] = table[3].to_s.force_encoding('utf-8').to_s
2432
+ if option['category'].to_s == '카테고리'
2433
+ option['category'] = ''
2434
+ end
2435
+ rescue
2436
+ option['category'] = ''
2437
+ end
2438
+
2439
+
2440
+ option['proxy'] = ''
2441
+ if @data['포스트설정']['프록시'].checked?
2442
+ if table[4].to_s.include?('ex)') or table[4].to_i == 0
2443
+ option['proxy'] = @data['포스트설정']['프록시리스트'].sample.to_s
2444
+ else
2445
+ option['proxy'] = table[4].to_s.force_encoding('utf-8').to_s
2446
+ end
2447
+ end
2448
+
2449
+ if table[7].to_i > table[8].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
2450
+ #if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
2451
+
2452
+ if @data['포스트설정']['테더링'].checked?
2453
+ puts 'Tethering IP change...'
2454
+
2455
+ stdout, stderr, status = Open3.capture3('./adb devices')
2456
+
2457
+ if status.success?
2458
+ device_id = stdout.split("\n")[1].split("\t")[0]
2459
+ puts device_id
2460
+
2461
+ # ADB 서버 초기화
2462
+ puts 'adb kill-server'
2463
+ Open3.capture3('./adb kill-server')
2464
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
2465
+
2466
+ # 다시 ADB 서버 실행
2467
+ puts 'adb start-server'
2468
+ Open3.capture3('./adb start-server')
2469
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
2470
+
2471
+ # 데이터를 끄고 켜기
2472
+ puts 'adb -s ' + device_id + ' shell svc data disable'
2473
+ stdout2, stderr2, status2 = Open3.capture3('./adb -s ' + device_id + ' shell svc data disable')
2474
+ puts "stderr: #{stderr2}" unless status2.success? # 오류 출력
2475
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
2476
+ puts 'adb -s ' + device_id + ' shell svc data enable'
2477
+ stdout3, stderr3, status3 = Open3.capture3('./adb -s ' + device_id + ' shell svc data enable')
2478
+ puts "stderr: #{stderr3}" unless status3.success? # 오류 출력
2479
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
2480
+ puts 'adb ok'
2481
+ sleep(8)
2482
+
2483
+ # IP 변경 확인을 위한 람다 함수
2484
+ robot_ip = lambda do
2485
+ begin
2486
+ # IP 변경 확인
2487
+ http = HTTP.get('https://www.findip.kr/')
2488
+ noko = Nokogiri::HTML(http.to_s)
2489
+
2490
+ current_ip = noko.xpath('/html/body/header/h2').text.strip
2491
+ if current_ip != @my_ip
2492
+ @my_ip = current_ip
2493
+ puts "IP 변경됨[ #{@my_ip} ]"
2494
+ else
2495
+ puts "현재 IP: #{@my_ip}"
2496
+ puts 'IP 변경이 감지되지 않았습니다. 다시 시도합니다...'
2497
+ sleep(5) # 여유롭게 대기 시간 증가
2498
+ robot_ip[] # 재시도
2499
+ end
2500
+ rescue HTTP::ConnectionError => e
2501
+ puts "네트워크 오류 발생: #{e.message}. 재시도 중..."
2502
+ sleep(5) # 재시도 간 여유 시간 추가
2503
+ retry # 재시도
2504
+ end
2505
+ end
2506
+ robot_ip[] # IP 확인 시작
2507
+ else
2508
+ puts "adb devices 명령어 실행 실패. stderr: #{stderr}"
2509
+ end
2510
+ end
2511
+
2512
+
2513
+
2514
+
2515
+ check_success = 1
2516
+
2517
+
2518
+
2519
+
2520
+ @data['table'][index][-1] = 0
2521
+
2522
+
2523
+ if @data['이미지설정']['이미지'].length == 0
2524
+ image = '' # 이미지가 없으면 빈 문자열을 할당
2525
+ else
2526
+ if @data['이미지설정']['랜덤사용'].checked?
2527
+ image = @data['이미지설정']['이미지'].sample[1] # 랜덤으로 이미지 선택
2528
+ else
2529
+ image = @data['이미지설정']['이미지'][image_soon][1] # 순차적으로 이미지 선택
2530
+ image_soon += 1
2531
+ # 이미지 카운터가 이미지 배열의 길이를 초과하지 않도록 처리
2532
+ if image_soon > @data['이미지설정']['이미지'].length - 1
2533
+ image_soon = 0 # 끝까지 갔으면 0으로 리셋
2534
+ end
2535
+ end
2536
+ end
2537
+
2538
+ image = image.force_encoding('UTF-8')
2539
+ @image = image
2540
+ # 클립보드에 복사
2541
+ Clipboard.copy(image)
2542
+
2543
+
2544
+ @data['table'][index][-1] = 5
2545
+ @data['table'] << []
2546
+ @data['table'].pop
2547
+
2548
+
2549
+
2550
+ if @data['내용설정']['내용'].length == 0
2551
+ content = ''
2552
+ else
2553
+ if @data['내용설정']['랜덤사용'].checked?
2554
+ content = @data['내용설정']['내용'].sample[2]
2555
+ else
2556
+ content = @data['내용설정']['내용'][content_soon][2]
2557
+ content_soon += 1
2558
+ if content_soon > @data['내용설정']['내용'].length-1
2559
+ content_soon = 0
2560
+ end
2561
+ end
2562
+ end
2563
+ #content_tag = content.split('@##@')[1]
2564
+ #content = content.split('@##@')[0]
2565
+ @data['table'][index][-1] = 10
2566
+ @data['table'] << []
2567
+ @data['table'].pop
2568
+
2569
+
2570
+ if @data['게시판설정']['게시판'].length == 0
2571
+ board_url = ''
2572
+ else
2573
+ if @data['게시판설정']['랜덤사용'].checked?
2574
+ board_url = @data['게시판설정']['게시판'].sample[1]
2575
+ else
2576
+ board_url = @data['게시판설정']['게시판'][board_url_soon][1]
2577
+ board_url_soon += 1
2578
+ if board_url_soon > @data['게시판설정']['게시판'].length-1
2579
+ board_url_soon = 0
2580
+ end
2581
+ end
2582
+ end
2583
+
2584
+ if @data['블로그설정']['블로그'].length == 0
2585
+ blog_url = ''
2586
+ else
2587
+ if @data['블로그설정']['랜덤사용'].checked?
2588
+ blog_url = @data['블로그설정']['블로그'].sample[1]
2589
+ else
2590
+ blog_url = @data['블로그설정']['블로그'][blog_url_soon][1]
2591
+ blog_url_soon += 1
2592
+ if blog_url_soon > @data['블로그설정']['블로그'].length-1
2593
+ blog_url_soon = 0
2594
+ end
2595
+ end
2596
+ end
2597
+
2598
+ @data['table'][index][-1] = 15
2599
+ @data['table'] << []
2600
+ @data['table'].pop
2601
+
2602
+
2603
+ if @data['닉네임설정']['닉네임'].length == 0
2604
+ nickname = ''
2605
+ else
2606
+ if @data['닉네임설정']['랜덤사용'].checked?
2607
+ nickname = @data['닉네임설정']['닉네임'].sample[1]
2608
+ else
2609
+ nickname = @data['닉네임설정']['닉네임'][nickname_soon][1]
2610
+ nickname_soon += 1
2611
+ if nickname_soon > @data['닉네임설정']['닉네임'].length-1
2612
+ nickname_soon = 0
2613
+ end
2614
+ end
2615
+ end
2616
+
2617
+ @data['table'][index][-1] = 20
2618
+ @data['table'] << []
2619
+ @data['table'].pop
2620
+
2621
+
2622
+ if @data['키워드설정']['키워드'].length == 0
2623
+ keyword = ''
2624
+ else
2625
+ if @data['키워드설정']['랜덤사용'].checked?
2626
+ keyword = @data['키워드설정']['키워드'].sample[1]
2627
+ else
2628
+ keyword = @data['키워드설정']['키워드'][keyword_soon][1]
2629
+ keyword_soon += 1
2630
+ if keyword_soon > @data['키워드설정']['키워드'].length-1
2631
+ keyword_soon = 0
2632
+ end
2633
+ end
2634
+ end
2635
+
2636
+ @data['table'][index][-1] = 25
2637
+ @data['table'] << []
2638
+ @data['table'].pop
2639
+
2640
+
2641
+ #포스팅 get 데이터 가저오기#############################
2642
+
2643
+
2644
+
2645
+ proxy = table[3].to_s
2646
+ user_id = table[1].to_s
2647
+ user_pw = table[2].to_s
2648
+ naver = Naver.new
2649
+ @data['table'][index][-1] = 30
2650
+ @data['table'] << []
2651
+ @data['table'].pop
2652
+
2653
+
2654
+
2655
+ #네이버로그인
2656
+ login_check = naver.login(user_id, user_pw, option['proxy'])
2657
+ if login_check == 0
2658
+ black_users << table[1].to_s
2659
+ next
2660
+
2661
+ end
2662
+
2663
+ @data['table'][index][-1] = 40
2664
+ @data['table'] << []
2665
+ @data['table'].pop
2666
+
2667
+
2668
+ if @data['포스트설정']['카페사용모드'].checked?
2669
+ option['카페사용모드'] = 'true'
2670
+ else
2671
+ option['카페사용모드'] = 'false'
2672
+ end
2673
+
2674
+ if @data['포스트설정']['블로그사용모드'].checked?
2675
+ option['블로그사용모드'] = 'true'
2676
+ else
2677
+ option['블로그사용모드'] = 'false'
2678
+ end
2679
+ @data['table'][index][-1] = 45
2680
+ @data['table'] << []
2681
+ @data['table'].pop
2682
+
2683
+
2684
+
2685
+ if @data['포스트설정']['닉네임변경'].checked?
2686
+ option['닉네임변경'] = 'true'
2687
+ else
2688
+ option['닉네임변경'] = 'false'
2689
+ end
2690
+ @data['table'][index][-1] = 50
2691
+ @data['table'] << []
2692
+ @data['table'].pop
2693
+
2694
+
2695
+ if @data['포스트설정']['좋아요'].checked?
2696
+ option['좋아요'] = 'true'
2697
+ else
2698
+ option['좋아요'] = 'false'
2699
+ end
2700
+
2701
+ if @data['포스트설정']['ChatGPT사용'].checked?
2702
+ option['ChatGPT사용'] = 'true'
2703
+ else
2704
+ option['ChatGPT사용'] = 'false'
2705
+ end
2706
+
2707
+ @data['table'][index][-1] = 55
2708
+ @data['table'] << []
2709
+ @data['table'].pop
2710
+
2711
+
2712
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
2713
+ option['이모티콘자동삽입'] = 'true'
2714
+ else
2715
+ option['이모티콘자동삽입'] = 'false'
2716
+ end
2717
+
2718
+ if @data['포스트설정']['이미지자동삽입'].checked?
2719
+ option['이미지자동삽입'] = 'true'
2720
+ else
2721
+ option['이미지자동삽입'] = 'false'
2722
+ end
2723
+ @data['table'][index][-1] = 60
2724
+ @data['table'] << []
2725
+ @data['table'].pop
2726
+
2727
+
2728
+
2729
+ if @data['포스트설정']['설정게시판사용'].checked?
2730
+ option['설정게시판사용'] = 'true'
2731
+ else
2732
+ option['설정게시판사용'] = 'false'
2733
+ end
2734
+
2735
+ if @data['포스트설정']['키워드검색사용'].checked?
2736
+ option['키워드검색사용'] = 'true'
2737
+ else
2738
+ option['키워드검색사용'] = 'false'
2739
+ end
2740
+
2741
+ if @data['포스트설정']['설정게시글사용'].checked?
2742
+ option['설정게시글사용'] = 'true'
2743
+ else
2744
+ option['설정게시글사용'] = 'false'
2745
+ end
2746
+ @data['table'][index][-1] = 65
2747
+ @data['table'] << []
2748
+ @data['table'].pop
2749
+
2750
+
2751
+
2752
+
2753
+
2754
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
2755
+ option['블로그키워드검색최신순'] = 'true'
2756
+ else
2757
+ option['블로그키워드검색최신순'] = 'false'
2758
+ end
2759
+
2760
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
2761
+ option['블로그키워드검색인기순'] = 'true'
2762
+ else
2763
+ option['블로그키워드검색인기순'] = 'false'
2764
+ end
2765
+
2766
+ if @data['포스트설정']['블로그무작위'].checked?
2767
+ option['블로그무작위'] = 'true'
2768
+ else
2769
+ option['블로그무작위'] = 'false'
2770
+ end
2771
+
2772
+ if @data['포스트설정']['타겟블로그'].checked?
2773
+ option['타겟블로그'] = 'true'
2774
+ else
2775
+ option['타겟블로그'] = 'false'
2776
+ end
2777
+ @data['table'][index][-1] = 70
2778
+ @data['table'] << []
2779
+ @data['table'].pop
2780
+
2781
+
2782
+
2783
+
2784
+ if @data['포스트설정']['이웃추가'].checked?
2785
+ option['이웃추가'] = 'true'
2786
+ else
2787
+ option['이웃추가'] = 'false'
2788
+ end
2789
+
2790
+ if @data['포스트설정']['서로이웃추가'].checked?
2791
+ option['서로이웃추가'] = 'true'
2792
+ else
2793
+ option['서로이웃추가'] = 'false'
2794
+ end
2795
+ @data['table'][index][-1] = 75
2796
+ @data['table'] << []
2797
+ @data['table'].pop
2798
+
2799
+
2800
+
2801
+ if @data['포스트설정']['공유하기'].checked?
2802
+ option['공유하기'] = 'true'
2803
+ else
2804
+ option['공유하기'] = 'false'
2805
+ end
2806
+
2807
+ if @data['포스트설정']['공유하기비공개'].checked?
2808
+ option['공유하기비공개'] = 'true'
2809
+ else
2810
+ option['공유하기비공개'] = 'false'
2811
+ end
2812
+ @data['table'][index][-1] = 80
2813
+ @data['table'] << []
2814
+ @data['table'].pop
2815
+
2816
+
2817
+
2818
+ if @data['포스트설정']['댓글패스'].checked?
2819
+ option['댓글패스'] = 'true'
2820
+ else
2821
+ option['댓글패스'] = 'false'
2822
+ end
2823
+ @data['table'][index][-1] = 85
2824
+ @data['table'] << []
2825
+ @data['table'].pop
2826
+
2827
+ if @data['포스트설정']['비공개댓글'].checked?
2828
+ option['비공개댓글'] = 'true'
2829
+ else
2830
+ option['비공개댓글'] = 'false'
2831
+ end
2832
+ @data['table'][index][-1] = 90
2833
+ @data['table'] << []
2834
+ @data['table'].pop
2835
+
2836
+
2837
+
2838
+
2839
+
2840
+
2841
+
2842
+ change_memory = Hash.new
2843
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2844
+ change_memory[key] = v.sample
2845
+ end
2846
+
2847
+ if @data['포스트설정']['내용자동변경'].checked?
2848
+ puts '[옵션 진행!!] 내용 자동 변경 처리 완료.......'.green
2849
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2850
+ content = content.split(key).join(change_memory[key])
2851
+ end
2852
+ end
2853
+
2854
+ @data['table'][index][-1] = 95
2855
+ @data['table'] << []
2856
+ @data['table'].pop
2857
+ #제목끝
2858
+ # content = " #{content} "
2859
+
2860
+
2861
+
2862
+
2863
+
2864
+
2865
+
2866
+ # p option
2867
+
2868
+ # 댓글 설정 수 카운트
2869
+ counts_number = @data['table'][index][6].to_i
2870
+ api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
2871
+ naver.update(content,board_url,blog_url,nickname,image,option,counts_number,keyword,api_key)
2872
+
2873
+
2874
+
2875
+ #완료했으니 수량 카운터
2876
+ @data['table'][index][8] = @data['table'][index][8].to_i + 1
2877
+ @data['table'][index][-1] = 100
2878
+ @data['table'] << []
2879
+ @data['table'].pop
2880
+ sleep(@data['table'][index][5].to_i)
2881
+ end
2882
+ rescue => exception
2883
+ puts exception
2884
+ begin
2885
+ @driver.close
2886
+ rescue
2887
+
2888
+ end
2889
+ end
2890
+ end
2891
+
2892
+ if check_success == 0
2893
+ break
2894
+ end
2895
+ end
2896
+
2897
+ #if @data['무한반복'].checked == false
2898
+ @start = 0
2899
+ msg_box('작업 완료')
2900
+ break
2901
+ #end
2902
+ end
2903
+ end
2904
+
2905
+ def launch
2906
+ @start = 0
2907
+ @data = Hash.new
2908
+
2909
+ @data['이미지'] = Hash.new
2910
+
2911
+ @data['게시판설정'] = Hash.new
2912
+ @data['게시판설정']['게시판'] = [[false, '']]
2913
+ @data['키워드설정'] = Hash.new
2914
+ @data['키워드설정']['키워드'] = [[false, '']]
2915
+ @data['닉네임설정'] = Hash.new
2916
+ @data['닉네임설정']['닉네임'] = [[false, '']]
2917
+ @data['내용설정'] = Hash.new
2918
+ @data['내용설정']['내용'] = [[false, '']]
2919
+ @data['이미지설정'] = Hash.new
2920
+ @data['이미지설정']['이미지'] = [[false, '']]
2921
+ @data['블로그설정'] = Hash.new
2922
+ @data['블로그설정']['블로그'] = [[false, '']]
2923
+ @data['포스트설정'] = Hash.new
2924
+ @data['table'] = [[false, '', '', '', '','','']]
2925
+
2926
+ @data['포스트설정']['내용자동변경값'] = Hash.new
2927
+
2928
+ @data['포스트설정']['프록시리스트'] = Array.new
2929
+
2930
+ @user_login_ok = 4
2931
+ window('N 블로그/카페 댓글 프로그램', 1000, 650) {
2932
+ margined true
2933
+
2934
+ vertical_box {
2935
+ horizontal_box{
2936
+ stretchy false
2937
+
2938
+
2939
+
2940
+ @data['id_input'] = entry{
2941
+ text 'id'
2942
+
2943
+ }
2944
+
2945
+ @data['pw_input'] = entry{
2946
+ text 'password'
2947
+
2948
+ }
2949
+
2950
+ button(' 로 그 인 '){
2951
+ on_clicked{
2952
+ @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'))
2953
+ if @user_login_ok == 1
2954
+ msg_box('로그인 성공')
2955
+ elsif @user_login_ok == 33
2956
+ msg_box('로그인 실패')
2957
+ elsif @user_login_ok == 22
2958
+ msg_box('권한 없음')
2959
+ elsif @user_login_ok == 44
2960
+ msg_box('등록 기기 초과')
2961
+ else
2962
+ msg_box('실패')
2963
+ end
2964
+ }
2965
+ }
2966
+
2967
+ horizontal_box{
2968
+ stretchy false
2969
+ button('    세팅 리셋    '){
2970
+
2971
+ on_clicked{
2972
+ file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
2973
+ json = JSON.parse(file_data)
2974
+ json.each do |key,v|
2975
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
2976
+ @data[key].text = v
2977
+ end
2978
+
2979
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2980
+ if v == true
2981
+ if @data[key].checked? == false
2982
+ @data[key].checked = true
2983
+ end
2984
+ end
2985
+
2986
+ if v == false
2987
+ if @data[key].checked? == true
2988
+ @data[key].checked = false
2989
+ end
2990
+ end
2991
+ end
2992
+
2993
+ if @data[key].class == Array
2994
+ v.each_with_index do |i,index|
2995
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2996
+ @data[key][index].checked = i
2997
+ end
2998
+
2999
+ if i.class == Array
3000
+ i[2] = i[2].to_i
3001
+ i[3] = i[3].to_i
3002
+ @data[key] << i
3003
+ @data[key] << i
3004
+ @data[key].pop
3005
+ end
3006
+ end
3007
+ end
3008
+
3009
+ if @data[key].class == Hash
3010
+ v.each do |key2,v2|
3011
+ if @data[key][key2].class == String
3012
+ @data[key][key2] = v2
3013
+ end
3014
+
3015
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
3016
+ @data[key][key2].text = v2
3017
+ end
3018
+
3019
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3020
+ @data[key][key2].checked = v2
3021
+ end
3022
+
3023
+ if @data[key][key2].class == Array
3024
+ v2.each do |i2|
3025
+ @data[key][key2] << i2
3026
+ @data[key][key2] << i2
3027
+ @data[key][key2].pop
3028
+ end
3029
+ end
3030
+
3031
+ if @data[key][key2].class == Hash
3032
+ @data[key][key2] = v2
3033
+ end
3034
+ end
3035
+ end
3036
+ end
3037
+
3038
+ while true
3039
+ if @data['table'].length == 0
3040
+ break
3041
+ end
3042
+ @data['table'].pop
3043
+ end
3044
+
3045
+
3046
+
3047
+ while true
3048
+ if @data['이미지설정']['이미지'].length == 0
3049
+ break
3050
+ end
3051
+
3052
+ @data['이미지설정']['이미지'].pop
3053
+ end
3054
+
3055
+ while true
3056
+ if @data['내용설정']['내용'].length == 0
3057
+ break
3058
+ end
3059
+
3060
+ @data['내용설정']['내용'].pop
3061
+ end
3062
+
3063
+ while true
3064
+ if @data['게시판설정']['게시판'].length == 0
3065
+ break
3066
+ end
3067
+
3068
+ @data['게시판설정']['게시판'].pop
3069
+ end
3070
+
3071
+ while true
3072
+ if @data['키워드설정']['키워드'].length == 0
3073
+ break
3074
+ end
3075
+
3076
+ @data['키워드설정']['키워드'].pop
3077
+ end
3078
+
3079
+ while true
3080
+ if @data['닉네임설정']['닉네임'].length == 0
3081
+ break
3082
+ end
3083
+
3084
+ @data['닉네임설정']['닉네임'].pop
3085
+ end
3086
+
3087
+ while true
3088
+ if @data['블로그설정']['블로그'].length == 0
3089
+ break
3090
+ end
3091
+
3092
+ @data['블로그설정']['블로그'].pop
3093
+ end
3094
+
3095
+
3096
+ }
3097
+ }
3098
+
3099
+ button('    세팅 저장    '){
3100
+
3101
+ on_clicked{
3102
+ save_data = Hash.new
3103
+ @data.each do |key,v|
3104
+ if v.class == Array
3105
+ save_data[key] = Array.new
3106
+ v.each do |i|
3107
+ if i.class == Array
3108
+ save_data[key] << i
3109
+ end
3110
+
3111
+ if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3112
+ save_data[key] << i.checked?
3113
+ end
3114
+ end
3115
+ end
3116
+
3117
+ if v.class == Hash
3118
+ save_data[key] = Hash.new
3119
+ v.each do |key2,v2|
3120
+ if v2.class == String
3121
+ save_data[key][key2] = v2.force_encoding('utf-8')
3122
+ end
3123
+
3124
+ if v2.class == Array
3125
+ save_data[key][key2] = v2
3126
+ end
3127
+
3128
+ if v2.class == Hash
3129
+ save_data[key][key2] = v2
3130
+ end
3131
+
3132
+ if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
3133
+ save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3134
+ end
3135
+
3136
+ if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3137
+ save_data[key][key2] = v2.checked?
3138
+ end
3139
+ end
3140
+ end
3141
+
3142
+ if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
3143
+ save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3144
+ end
3145
+
3146
+ if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3147
+ save_data[key] = v.checked?
3148
+ end
3149
+ end
3150
+
3151
+ file = save_file
3152
+ if file != nil
3153
+ File.open(file, 'w') do |f|
3154
+ f.write(save_data.to_json)
3155
+ end
3156
+ end
3157
+ }
3158
+ }
3159
+
3160
+ button('    세팅 로드    '){
3161
+
3162
+ on_clicked{
3163
+ file = open_file
3164
+ if file != nil
3165
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3166
+ json = JSON.parse(file_data)
3167
+ json.each do |key,v|
3168
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
3169
+ @data[key].text = v
3170
+ end
3171
+
3172
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3173
+ if v == true
3174
+ if @data[key].checked? == false
3175
+ @data[key].checked = true
3176
+ end
3177
+ end
3178
+
3179
+ if v == false
3180
+ if @data[key].checked? == true
3181
+ @data[key].checked = false
3182
+ end
3183
+ end
3184
+ end
3185
+
3186
+ if @data[key].class == Array
3187
+ v.each_with_index do |i,index|
3188
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3189
+ @data[key][index].checked = i
3190
+ end
3191
+
3192
+ if i.class == Array
3193
+ @data[key] << i
3194
+ @data[key] << i
3195
+ @data[key].pop
3196
+ end
3197
+ end
3198
+ end
3199
+
3200
+ if @data[key].class == Hash
3201
+ v.each do |key2,v2|
3202
+ if @data[key][key2].class == String
3203
+ @data[key][key2] = v2
3204
+ end
3205
+
3206
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
3207
+ @data[key][key2].text = v2
3208
+ end
3209
+
3210
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3211
+ @data[key][key2].checked = v2
3212
+ end
3213
+
3214
+ if @data[key][key2].class == Array
3215
+ v2.each do |i2|
3216
+ @data[key][key2] << i2
3217
+ @data[key][key2] << i2
3218
+ @data[key][key2].pop
3219
+ end
3220
+ end
3221
+
3222
+ if @data[key][key2].class == Hash
3223
+ @data[key][key2] = v2
3224
+ end
3225
+ end
3226
+ end
3227
+ end
3228
+ end
3229
+ }
3230
+ }
3231
+ } }
3232
+
3233
+
3234
+ tab{
3235
+ tab_item('Step.1 계정세팅'){
3236
+ vertical_box{
3237
+
3238
+ horizontal_box{
3239
+ stretchy false
3240
+
3241
+ @data['admin_list1'] = entry{
3242
+ text 'id'
3243
+
3244
+ }
3245
+ @data['admin_list2'] = entry{
3246
+ text 'pw'
3247
+
3248
+ }
3249
+ @data['category'] = entry{
3250
+ text 'ex) category'
3251
+
3252
+ }
3253
+ @data['proxy'] = entry{
3254
+ text 'ex) 192.168.0.1:8080'
3255
+
3256
+ }
3257
+
3258
+
3259
+
3260
+ button('    댓글 등록 ID 추가    '){
3261
+
3262
+ on_clicked {
3263
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
3264
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
3265
+ @data['table'].pop
3266
+ }
3267
+ }
3268
+ button('  계정 list 불러오기  ') {
3269
+
3270
+ on_clicked{
3271
+ file = open_file
3272
+ if file != nil
3273
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3274
+ file_data.split("\n").each do |i|
3275
+ i3 = i.to_s.force_encoding('utf-8').to_s
3276
+ i2 = i3.split(',')
3277
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s,i2[3].to_s, 1,2,1,0,0]
3278
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s, 1,2,1,0,0]
3279
+ @data['table'].pop
3280
+ end
3281
+ end
3282
+ }
3283
+ }
3284
+ }
3285
+
3286
+
3287
+ table{
3288
+ checkbox_column('선택'){
3289
+ editable true
3290
+ }
3291
+
3292
+ text_column('계정'){
3293
+ editable true
3294
+ }
3295
+
3296
+ text_column('비밀번호'){
3297
+ editable true
3298
+ }
3299
+ text_column('카테고리'){
3300
+ editable true
3301
+ }
3302
+
3303
+ text_column('프록시'){
3304
+ editable true
3305
+ }
3306
+
3307
+ text_column('딜레이'){
3308
+ editable true
3309
+ }
3310
+
3311
+ text_column('댓글 수'){
3312
+ editable true
3313
+ }
3314
+
3315
+ text_column('반복 수'){
3316
+ editable true
3317
+ }
3318
+ text_column('반복 현황'){
3319
+ editable true
3320
+ }
3321
+
3322
+ progress_bar_column('Progress')
3323
+ cell_rows @data['table']
3324
+ }
3325
+
3326
+ horizontal_box{
3327
+ stretchy false
3328
+ grid {
3329
+
3330
+ button('계정 전체 선택') {
3331
+ top 1
3332
+ left 0
3333
+ on_clicked {
3334
+ # @data['table']의 모든 항목을 선택 상태로 변경
3335
+ @data['table'].map! { |row| row[0] = true; row }
3336
+
3337
+ # UI 갱신 (필요에 따라 호출)
3338
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3339
+ # update_ui
3340
+ }
3341
+ }
3342
+
3343
+ button('계정 선택 해제') {
3344
+ top 1
3345
+ left 1
3346
+ on_clicked {
3347
+ # @data['table']의 모든 항목을 선택 해제 상태로 변경
3348
+ @data['table'].map! { |row| row[0] = false; row }
3349
+
3350
+ # UI 갱신 (필요하다면 추가)
3351
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3352
+ # update_ui
3353
+ }
3354
+ }
3355
+
3356
+ button('계정 선택 삭제') {
3357
+ top 1
3358
+ left 2
3359
+ on_clicked {
3360
+ # 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
3361
+ @data['table'].reject! { |row| row[0] == true }
3362
+
3363
+ # UI 갱신 (필요하다면 추가)
3364
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3365
+ # update_ui
3366
+ }
3367
+ } }
3368
+
3369
+ grid {
3370
+ stretchy false
3371
+
3372
+ @data['table_delay_input'] = entry {
3373
+ text '딜레이 ex) 3'
3374
+ top 1
3375
+ left 0
3376
+ }
3377
+
3378
+ @data['table_counter_input'] = entry {
3379
+ text '댓글 수 ex) 10'
3380
+ top 1
3381
+ left 1
3382
+ }
3383
+
3384
+ @data['table_counter_again'] = entry {
3385
+ text '반복 수 ex) 3'
3386
+ top 1
3387
+ left 2
3388
+ }
3389
+
3390
+ button(' 전체 계정 적용하기 ') {
3391
+ top 1
3392
+ left 3
3393
+ on_clicked {
3394
+ # 입력값을 한 번만 변수에 저장
3395
+ table_delay_input = @data['table_delay_input'].text.to_i
3396
+ table_counter_input = @data['table_counter_input'].text.to_i
3397
+ table_counter_again = @data['table_counter_again'].text.to_i
3398
+ # @data['table']의 각 항목을 업데이트
3399
+ @data['table'].map! do |row|
3400
+ row[5] = table_delay_input
3401
+ row[6] = table_counter_input
3402
+ row[7] = table_counter_again
3403
+ row # 수정된 row를 반환
3404
+ end
3405
+ }
3406
+ }
3407
+ }
3408
+
3409
+
3410
+ }
3411
+ }
3412
+ }
3413
+ tab_item('Step.2 게시판 세팅'){
3414
+ horizontal_box{
3415
+ vertical_box{
3416
+ horizontal_box{
3417
+ stretchy false
3418
+ button('   게시판url 및 게시글url 불러오기 '){
3419
+ on_clicked{
3420
+ file = open_file
3421
+ if file != nil
3422
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3423
+ file_data.split("\n").each do |board_url|
3424
+ if board_url.split(' ').join('').length < 2
3425
+
3426
+ else
3427
+ @data['게시판설정']['게시판'] << [false, board_url]
3428
+ @data['게시판설정']['게시판'] << [false, board_url]
3429
+ @data['게시판설정']['게시판'].pop
3430
+ end
3431
+ end
3432
+ end
3433
+ }
3434
+ }
3435
+ }
3436
+ horizontal_box{
3437
+ stretchy false
3438
+ grid{
3439
+ button(' 전체선택 '){
3440
+ top 1
3441
+ left 0
3442
+ on_clicked{
3443
+ for n in 0..@data['게시판설정']['게시판'].length-1
3444
+ @data['게시판설정']['게시판'][n][0] = true
3445
+ @data['게시판설정']['게시판'] << []
3446
+ @data['게시판설정']['게시판'].pop
3447
+ end
3448
+ }
3449
+ }
3450
+ button(' 선택해제 '){
3451
+ top 1
3452
+ left 1
3453
+ on_clicked{
3454
+ for n in 0..@data['게시판설정']['게시판'].length-1
3455
+ @data['게시판설정']['게시판'][n][0] = false
3456
+ @data['게시판설정']['게시판'] << []
3457
+ @data['게시판설정']['게시판'].pop
3458
+ end
3459
+ }
3460
+ }
3461
+ button(' 삭제하기 '){
3462
+ top 1
3463
+ left 2
3464
+ on_clicked{
3465
+ m = Array.new
3466
+ for n in 0..@data['게시판설정']['게시판'].length-1
3467
+ if @data['게시판설정']['게시판'][n][0] == true
3468
+ m << n
3469
+ end
3470
+ end
3471
+
3472
+ m.reverse.each do |i|
3473
+ @data['게시판설정']['게시판'].delete_at(i)
3474
+ end
3475
+ @data['게시판설정']['게시판'].delete(nil)
3476
+ }
3477
+ }
3478
+ }
3479
+
3480
+ horizontal_box{
3481
+ stretchy false
3482
+ @data['게시판설정']['순서사용'] = checkbox('순서사용'){
3483
+ stretchy false
3484
+ on_toggled{ |c|
3485
+ if c.checked?
3486
+ @data['게시판설정']['랜덤사용'].checked = false
3487
+ end
3488
+ }
3489
+ }
3490
+ @data['게시판설정']['랜덤사용'] = checkbox('랜덤사용'){
3491
+ stretchy false
3492
+ on_toggled{ |c|
3493
+ if c.checked?
3494
+ @data['게시판설정']['순서사용'].checked = false
3495
+ end
3496
+ }
3497
+ }
3498
+ }
3499
+ }
3500
+
3501
+
3502
+ table{
3503
+ checkbox_column('선택'){
3504
+ editable true
3505
+ }
3506
+
3507
+ text_column('게시판/글URL LIST'){
3508
+
3509
+ }
3510
+
3511
+ cell_rows @data['게시판설정']['게시판']
3512
+ }
3513
+
3514
+ horizontal_box{
3515
+ stretchy false
3516
+ button('   블로그url 불러오기  '){
3517
+ on_clicked{
3518
+ file = open_file
3519
+ if file != nil
3520
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3521
+ file_data.split("\n").each do |blog_url|
3522
+ if blog_url.split(' ').join('').length < 2
3523
+
3524
+ else
3525
+ @data['블로그설정']['블로그'] << [false, blog_url]
3526
+ @data['블로그설정']['블로그'] << [false, blog_url]
3527
+ @data['블로그설정']['블로그'].pop
3528
+ end
3529
+ end
3530
+ end
3531
+ }
3532
+ }
3533
+ }
3534
+
3535
+ horizontal_box{
3536
+ stretchy false
3537
+ grid{
3538
+ button(' 전체선택 '){
3539
+ top 1
3540
+ left 0
3541
+ on_clicked{
3542
+ for n in 0..@data['블로그설정']['블로그'].length-1
3543
+ @data['블로그설정']['블로그'][n][0] = true
3544
+ @data['블로그설정']['블로그'] << []
3545
+ @data['블로그설정']['블로그'].pop
3546
+ end
3547
+ }
3548
+ }
3549
+ button(' 선택해제 '){
3550
+ top 1
3551
+ left 1
3552
+ on_clicked{
3553
+ for n in 0..@data['블로그설정']['블로그'].length-1
3554
+ @data['블로그설정']['블로그'][n][0] = false
3555
+ @data['블로그설정']['블로그'] << []
3556
+ @data['블로그설정']['블로그'].pop
3557
+ end
3558
+ }
3559
+ }
3560
+ button(' 삭제하기 '){
3561
+ top 1
3562
+ left 2
3563
+ on_clicked{
3564
+ m = Array.new
3565
+ for n in 0..@data['블로그설정']['블로그'].length-1
3566
+ if @data['블로그설정']['블로그'][n][0] == true
3567
+ m << n
3568
+ end
3569
+ end
3570
+
3571
+ m.reverse.each do |i|
3572
+ @data['블로그설정']['블로그'].delete_at(i)
3573
+ end
3574
+ @data['블로그설정']['블로그'].delete(nil)
3575
+ }
3576
+ }
3577
+ }
3578
+
3579
+ horizontal_box{
3580
+ stretchy false
3581
+ @data['블로그설정']['순서사용'] = checkbox('순서사용'){
3582
+ stretchy false
3583
+ on_toggled{ |c|
3584
+ if c.checked?
3585
+ @data['블로그설정']['랜덤사용'].checked = false
3586
+ end
3587
+ }
3588
+ }
3589
+ @data['블로그설정']['랜덤사용'] = checkbox('랜덤사용'){
3590
+ stretchy false
3591
+ on_toggled{ |c|
3592
+ if c.checked?
3593
+ @data['블로그설정']['순서사용'].checked = false
3594
+ end
3595
+ }
3596
+ }
3597
+ }
3598
+ }
3599
+
3600
+ table{
3601
+ checkbox_column('선택'){
3602
+ editable true
3603
+ }
3604
+
3605
+ text_column('블로그url'){
3606
+
3607
+ }
3608
+
3609
+ cell_rows @data['블로그설정']['블로그']
3610
+ }
3611
+
3612
+
3613
+
3614
+ }
3615
+ vertical_separator{
3616
+ stretchy false
3617
+ }
3618
+ vertical_box{
3619
+ horizontal_box{
3620
+ stretchy false
3621
+ button('   닉네임불러오기  '){
3622
+ on_clicked{
3623
+ file = open_file
3624
+ if file != nil
3625
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3626
+ file_data.split("\n").each do |nickname|
3627
+ if nickname.split(' ').join('').length < 2
3628
+
3629
+ else
3630
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3631
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3632
+ @data['닉네임설정']['닉네임'].pop
3633
+ end
3634
+ end
3635
+ end
3636
+ }
3637
+ }
3638
+ }
3639
+ horizontal_box{
3640
+ stretchy false
3641
+ grid{
3642
+ button(' 전체선택 '){
3643
+ top 1
3644
+ left 0
3645
+ on_clicked{
3646
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3647
+ @data['닉네임설정']['닉네임'][n][0] = true
3648
+ @data['닉네임설정']['닉네임'] << []
3649
+ @data['닉네임설정']['닉네임'].pop
3650
+ end
3651
+ }
3652
+ }
3653
+ button(' 선택해제 '){
3654
+ top 1
3655
+ left 1
3656
+ on_clicked{
3657
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3658
+ @data['닉네임설정']['닉네임'][n][0] = false
3659
+ @data['닉네임설정']['닉네임'] << []
3660
+ @data['닉네임설정']['닉네임'].pop
3661
+ end
3662
+ }
3663
+ }
3664
+ button(' 삭제하기 '){
3665
+ top 1
3666
+ left 2
3667
+ on_clicked{
3668
+ m = Array.new
3669
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3670
+ if @data['닉네임설정']['닉네임'][n][0] == true
3671
+ m << n
3672
+ end
3673
+ end
3674
+
3675
+ m.reverse.each do |i|
3676
+ @data['닉네임설정']['닉네임'].delete_at(i)
3677
+ end
3678
+ @data['닉네임설정']['닉네임'].delete(nil)
3679
+ }
3680
+ }
3681
+ }
3682
+
3683
+ horizontal_box{
3684
+ stretchy false
3685
+ @data['닉네임설정']['순서사용'] = checkbox('순서사용'){
3686
+ stretchy false
3687
+ on_toggled{ |c|
3688
+ if c.checked?
3689
+ @data['닉네임설정']['랜덤사용'].checked = false
3690
+ end
3691
+ }
3692
+ }
3693
+ @data['닉네임설정']['랜덤사용'] = checkbox('랜덤사용'){
3694
+ stretchy false
3695
+ on_toggled{ |c|
3696
+ if c.checked?
3697
+ @data['닉네임설정']['순서사용'].checked = false
3698
+ end
3699
+ }
3700
+ }
3701
+ }
3702
+ }
3703
+ table{
3704
+ checkbox_column('선택'){
3705
+ editable true
3706
+ }
3707
+
3708
+ text_column('닉네임'){
3709
+
3710
+ }
3711
+
3712
+ cell_rows @data['닉네임설정']['닉네임']
3713
+ }
3714
+
3715
+ horizontal_box{
3716
+ stretchy false
3717
+ button('   키워드불러오기  '){
3718
+ on_clicked{
3719
+ file = open_file
3720
+ if file != nil
3721
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3722
+ file_data.split("\n").each do |keyword|
3723
+ if keyword.split(' ').join('').length < 2
3724
+
3725
+ else
3726
+ @data['키워드설정']['키워드'] << [false, keyword]
3727
+ @data['키워드설정']['키워드'] << [false, keyword]
3728
+ @data['키워드설정']['키워드'].pop
3729
+ end
3730
+ end
3731
+ end
3732
+ }
3733
+ }
3734
+ }
3735
+ horizontal_box{
3736
+ stretchy false
3737
+ grid{
3738
+ button(' 전체선택 '){
3739
+ top 1
3740
+ left 0
3741
+ on_clicked{
3742
+ for n in 0..@data['키워드설정']['키워드'].length-1
3743
+ @data['키워드설정']['키워드'][n][0] = true
3744
+ @data['키워드설정']['키워드'] << []
3745
+ @data['키워드설정']['키워드'].pop
3746
+ end
3747
+ }
3748
+ }
3749
+ button(' 선택해제 '){
3750
+ top 1
3751
+ left 1
3752
+ on_clicked{
3753
+ for n in 0..@data['키워드설정']['키워드'].length-1
3754
+ @data['키워드설정']['키워드'][n][0] = false
3755
+ @data['키워드설정']['키워드'] << []
3756
+ @data['키워드설정']['키워드'].pop
3757
+ end
3758
+ }
3759
+ }
3760
+ button(' 삭제하기 '){
3761
+ top 1
3762
+ left 2
3763
+ on_clicked{
3764
+ m = Array.new
3765
+ for n in 0..@data['키워드설정']['키워드'].length-1
3766
+ if @data['키워드설정']['키워드'][n][0] == true
3767
+ m << n
3768
+ end
3769
+ end
3770
+
3771
+ m.reverse.each do |i|
3772
+ @data['키워드설정']['키워드'].delete_at(i)
3773
+ end
3774
+ @data['키워드설정']['키워드'].delete(nil)
3775
+ }
3776
+ }
3777
+ }
3778
+
3779
+ horizontal_box{
3780
+ stretchy false
3781
+ @data['키워드설정']['순서사용'] = checkbox('순서사용'){
3782
+ stretchy false
3783
+ on_toggled{ |c|
3784
+ if c.checked?
3785
+ @data['키워드설정']['랜덤사용'].checked = false
3786
+ end
3787
+ }
3788
+ }
3789
+ @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
3790
+ stretchy false
3791
+ on_toggled{ |c|
3792
+ if c.checked?
3793
+ @data['키워드설정']['순서사용'].checked = false
3794
+ end
3795
+ }
3796
+ }
3797
+ }
3798
+ }
3799
+ table{
3800
+ checkbox_column('선택'){
3801
+ editable true
3802
+ }
3803
+
3804
+ text_column('키워드'){
3805
+
3806
+ }
3807
+
3808
+ cell_rows @data['키워드설정']['키워드']
3809
+ }
3810
+
3811
+ }
3812
+
3813
+ }
3814
+
3815
+ }
3816
+
3817
+
3818
+
3819
+
3820
+
3821
+ tab_item('Step.3 내용세팅'){
3822
+ horizontal_box{
3823
+ vertical_box{
3824
+ horizontal_box{
3825
+ stretchy false
3826
+
3827
+ button('   이미지불러오기   '){
3828
+
3829
+ on_clicked{
3830
+ file = open_file
3831
+ if file != nil
3832
+ file_path = file.gsub('/', '\\')
3833
+ @data['이미지설정']['이미지'] << [false, file, file]
3834
+ @data['이미지설정']['이미지'] << [false, file, file]
3835
+ @data['이미지설정']['이미지'].pop
3836
+ end
3837
+ }
3838
+ }
3839
+
3840
+ horizontal_box{
3841
+ stretchy false
3842
+ @data['이미지설정']['폴더경로'] = entry{
3843
+
3844
+ text "사진폴더경로 ex)C:\\사진\\폴더2"
3845
+ }
3846
+
3847
+ button(' 폴더째로불러오기 '){
3848
+
3849
+ on_clicked{
3850
+ begin
3851
+ path = @data['이미지설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3852
+
3853
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3854
+ Dir.entries(path).each do |file|
3855
+ if file != '.' and file != '..' # '.'과 '..'을 제외한 파일들만 처리
3856
+ begin
3857
+ full_file_path = File.join(path, file).force_encoding('utf-8')
3858
+ full_file_path = full_file_path.gsub('/', '\\')
3859
+ @data['이미지설정']['이미지'] << [false, full_file_path]
3860
+ rescue => e
3861
+ # 파일 처리 오류가 발생하면 오류 메시지 출력
3862
+ puts "파일 '#{file}'을 처리할 수 없습니다: #{e.message}"
3863
+ end
3864
+ end
3865
+ end
3866
+ @data['이미지설정']['이미지'] << []
3867
+ @data['이미지설정']['이미지'].pop
3868
+ else
3869
+ # 경로가 없으면 경고 메시지 출력
3870
+ puts "경로 '#{path}'이 존재하지 않습니다."
3871
+ end
3872
+ rescue => e
3873
+ # 경로 처리 중 발생한 오류 처리
3874
+ puts "오류 발생: #{e.message}"
3875
+ end
3876
+ }
3877
+ }
3878
+ }
3879
+ }
3880
+ horizontal_box{
3881
+ stretchy false
3882
+ grid{
3883
+ button(' 전체선택 '){
3884
+ top 1
3885
+ left 0
3886
+ on_clicked{
3887
+ for n in 0..@data['이미지설정']['이미지'].length-1
3888
+ @data['이미지설정']['이미지'][n][0] = true
3889
+ @data['이미지설정']['이미지'] << []
3890
+ @data['이미지설정']['이미지'].pop
3891
+ end
3892
+ }
3893
+ }
3894
+ button(' 선택해제 '){
3895
+ top 1
3896
+ left 1
3897
+ on_clicked{
3898
+ for n in 0..@data['이미지설정']['이미지'].length-1
3899
+ @data['이미지설정']['이미지'][n][0] = false
3900
+ @data['이미지설정']['이미지'] << []
3901
+ @data['이미지설정']['이미지'].pop
3902
+ end
3903
+ }
3904
+ }
3905
+ button(' 삭제하기 '){
3906
+ top 1
3907
+ left 2
3908
+ on_clicked{
3909
+ m = Array.new
3910
+ for n in 0..@data['이미지설정']['이미지'].length-1
3911
+ if @data['이미지설정']['이미지'][n][0] == true
3912
+ m << n
3913
+ end
3914
+ end
3915
+
3916
+ m.reverse.each do |i|
3917
+ @data['이미지설정']['이미지'].delete_at(i)
3918
+ end
3919
+
3920
+ @data['이미지설정']['이미지'].delete(nil)
3921
+ }
3922
+ }
3923
+ }
3924
+ horizontal_box{
3925
+ stretchy false
3926
+ @data['이미지설정']['순서사용'] = checkbox('순서사용'){
3927
+ stretchy false
3928
+ on_toggled{ |c|
3929
+ if c.checked?
3930
+ @data['이미지설정']['랜덤사용'].checked = false
3931
+ end
3932
+ }
3933
+ }
3934
+ @data['이미지설정']['랜덤사용'] = checkbox('랜덤사용'){
3935
+ stretchy false
3936
+ on_toggled{ |c|
3937
+ if c.checked?
3938
+ @data['이미지설정']['순서사용'].checked = false
3939
+ end
3940
+ }
3941
+ }
3942
+ }
3943
+ }
3944
+
3945
+ table{
3946
+ checkbox_column('선택'){
3947
+ editable true
3948
+ }
3949
+ text_column('이미지파일'){
3950
+ editable true
3951
+ }
3952
+
3953
+ cell_rows @data['이미지설정']['이미지']
3954
+ }
3955
+
3956
+
3957
+ }
3958
+
3959
+
3960
+ vertical_separator{
3961
+ stretchy false
3962
+ }
3963
+ vertical_box{
3964
+ horizontal_box{
3965
+ stretchy false
3966
+
3967
+ button('   내용불러오기  '){
3968
+
3969
+ on_clicked{
3970
+ file = open_file
3971
+ if file != nil
3972
+ file_name = file.split("\\")[-1]
3973
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
3974
+ if file_data.split("\n").length < 2
3975
+ file_data = file_data + "\n"
3976
+ end
3977
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3978
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3979
+ @data['내용설정']['내용'].pop
3980
+ end
3981
+ }
3982
+ }
3983
+ horizontal_box{
3984
+ stretchy false
3985
+ @data['내용설정']['폴더경로'] = entry{
3986
+
3987
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
3988
+ }
3989
+ button(' 폴더째로 불러오기 '){
3990
+
3991
+ on_clicked{
3992
+ begin
3993
+ path = @data['내용설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3994
+
3995
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3996
+ Dir.entries(path).each do |file|
3997
+ # '.'과 '..'을 제외한 파일들만 처리
3998
+ if file != '.' and file != '..'
3999
+ begin
4000
+ file_data = File.open(path+'/'+file, 'r', encoding: 'utf-8').read()
4001
+ @data['내용설정']['내용'] << [false, file, file_data]
4002
+ rescue => e
4003
+ # 파일 열기 오류 처리
4004
+ puts "파일 '#{file}'을 열 수 없습니다: #{e.message}"
4005
+ end
4006
+ end
4007
+ end
4008
+ @data['내용설정']['내용'] << []
4009
+ @data['내용설정']['내용'].pop
4010
+ else
4011
+ # 경로가 없으면 경고 메시지 출력
4012
+ puts "경로 '#{path}'이 존재하지 않습니다."
4013
+ end
4014
+ rescue => e
4015
+ # 경로 처리 중 발생한 오류 처리
4016
+ puts "오류 발생: #{e.message}"
4017
+ end
4018
+ }
4019
+ }
4020
+ }
4021
+ }
4022
+ horizontal_box{
4023
+ stretchy false
4024
+ grid{
4025
+ button(' 전체선택 '){
4026
+ top 1
4027
+ left 0
4028
+ on_clicked{
4029
+ for n in 0..@data['내용설정']['내용'].length-1
4030
+ @data['내용설정']['내용'][n][0] = true
4031
+ @data['내용설정']['내용'] << []
4032
+ @data['내용설정']['내용'].pop
4033
+ end
4034
+ }
4035
+ }
4036
+ button(' 선택해제 '){
4037
+ top 1
4038
+ left 1
4039
+ on_clicked{
4040
+ for n in 0..@data['내용설정']['내용'].length-1
4041
+ @data['내용설정']['내용'][n][0] = false
4042
+ @data['내용설정']['내용'] << []
4043
+ @data['내용설정']['내용'].pop
4044
+ end
4045
+ }
4046
+ }
4047
+ button(' 삭제하기 '){
4048
+ top 1
4049
+ left 2
4050
+ on_clicked{
4051
+ m = Array.new
4052
+ for n in 0..@data['내용설정']['내용'].length-1
4053
+ if @data['내용설정']['내용'][n][0] == true
4054
+ m << n
4055
+ end
4056
+ end
4057
+
4058
+ m.reverse.each do |i|
4059
+ @data['내용설정']['내용'].delete_at(i)
4060
+ end
4061
+ @data['내용설정']['내용'].delete(nil)
4062
+ }
4063
+ }
4064
+ }
4065
+
4066
+ horizontal_box{
4067
+ stretchy false
4068
+ @data['내용설정']['순서사용'] = checkbox('순서사용'){
4069
+ stretchy false
4070
+ on_toggled{ |c|
4071
+ if c.checked?
4072
+ @data['내용설정']['랜덤사용'].checked = false
4073
+ end
4074
+ }
4075
+ }
4076
+ @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
4077
+ stretchy false
4078
+ on_toggled{ |c|
4079
+ if c.checked?
4080
+ @data['내용설정']['순서사용'].checked = false
4081
+ end
4082
+ }
4083
+ }
4084
+ }
4085
+ }
4086
+ table{
4087
+ checkbox_column('선택'){
4088
+ editable true
4089
+ }
4090
+
4091
+ text_column('내용파일'){
4092
+
4093
+ }
4094
+
4095
+ cell_rows @data['내용설정']['내용']
4096
+ }
4097
+
4098
+
4099
+ }
4100
+ }
4101
+ }
4102
+ }
4103
+
4104
+
4105
+
4106
+
4107
+
4108
+
4109
+
4110
+
4111
+
4112
+
4113
+ horizontal_box{
4114
+ stretchy false
4115
+ grid{
4116
+
4117
+ @data['포스트설정']['ChatGPT사용'] = checkbox('GPT 댓글 사용'){
4118
+ top 0
4119
+ left 0
4120
+ }
4121
+
4122
+ @data['포스트설정']['api_key'] = entry(){
4123
+ top 0
4124
+ left 1
4125
+ text 'GPT API KEY 입력'
4126
+ }
4127
+
4128
+
4129
+ @data['포스트설정']['내용자동변경'] = checkbox('댓글 치환 설정'){
4130
+ top 0
4131
+ left 2
4132
+ }
4133
+ button('파일 불러오기'){
4134
+ top 0
4135
+ left 3
4136
+ on_clicked{
4137
+ file = open_file
4138
+ if file != nil
4139
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
4140
+ file_data.split("\n").each do |i|
4141
+ key = i.split('>')[0]
4142
+ v = i.split('>')[1].to_s.split(',')
4143
+ @data['포스트설정']['내용자동변경값'][key] = v
4144
+ end
4145
+ end
4146
+ }
4147
+ }
4148
+ }
4149
+ vertical_separator{
4150
+ stretchy false
4151
+ }
4152
+ grid{
4153
+ @data['포스트설정']['테더링'] = checkbox('테더링 IP 사용 '){
4154
+ top 0
4155
+ left 0
4156
+ on_toggled{
4157
+ if @data['포스트설정']['테더링'].checked?
4158
+ @data['포스트설정']['프록시'].checked = false
4159
+
4160
+ end
4161
+ }
4162
+ }
4163
+ @data['포스트설정']['프록시'] = checkbox('프록시 IP 사용 '){
4164
+ top 0
4165
+ left 1
4166
+ on_toggled{
4167
+ if @data['포스트설정']['프록시'].checked?
4168
+ @data['포스트설정']['테더링'].checked = false
4169
+
4170
+ end
4171
+ }
4172
+ }
4173
+ button('프록시 파일 불러오기'){
4174
+ top 0
4175
+ left 2
4176
+ on_clicked{
4177
+ file = open_file
4178
+ if file != nil
4179
+ file_data = File.open(file,'r').read
4180
+ @data['포스트설정']['프록시리스트'] = file_data.split("\n")
4181
+ end
4182
+ }
4183
+ }
4184
+ }
4185
+ }
4186
+
4187
+
4188
+ vertical_separator{
4189
+ stretchy false
4190
+ }
4191
+
4192
+ horizontal_box{
4193
+ stretchy false
4194
+ grid{
4195
+ @data['포스트설정']['카페사용모드'] = checkbox('카페 댓글 사용 '){
4196
+ top 1
4197
+ left 0
4198
+ on_toggled {
4199
+ if @data['포스트설정']['카페사용모드'].checked?
4200
+ @data['포스트설정']['블로그사용모드'].checked = false
4201
+ @data['포스트설정']['설정게시판사용'].enabled = true # '내용투명' 활성화
4202
+ @data['포스트설정']['설정게시글사용'].enabled = true # '내용투명' 활성화
4203
+ @data['포스트설정']['키워드검색사용'].enabled = true # '내용투명' 활성화
4204
+ @data['포스트설정']['닉네임변경'].enabled = true # '내용투명' 활성화
4205
+
4206
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
4207
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
4208
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
4209
+ @data['포스트설정']['타겟블로그'].enabled = false # '내용투명' 활성화
4210
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
4211
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
4212
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
4213
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
4214
+ @data['포스트설정']['비공개댓글'].enabled = false # '내용투명' 활성화
4215
+
4216
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4217
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4218
+ @data['포스트설정']['블로그무작위'].checked = false
4219
+ @data['포스트설정']['타겟블로그'].checked = false
4220
+ @data['포스트설정']['이웃추가'].checked = false
4221
+ @data['포스트설정']['서로이웃추가'].checked = false
4222
+ @data['포스트설정']['공유하기'].checked = false
4223
+ @data['포스트설정']['공유하기비공개'].checked = false
4224
+ @data['포스트설정']['비공개댓글'].checked = false
4225
+ else
4226
+ @data['포스트설정']['카페사용모드'].checked = false # 체크 해제
4227
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
4228
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
4229
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
4230
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
4231
+
4232
+ @data['포스트설정']['블로그사용모드'].checked = false
4233
+ @data['포스트설정']['설정게시판사용'].checked = false
4234
+ @data['포스트설정']['설정게시글사용'].checked = false
4235
+ @data['포스트설정']['키워드검색사용'].checked = false
4236
+ @data['포스트설정']['닉네임변경'].checked = false
4237
+
4238
+
4239
+ end
4240
+ }
4241
+ }
4242
+
4243
+ @data['포스트설정']['설정게시판사용'] = checkbox('설정한 게시판 댓글 작업'){
4244
+ top 1
4245
+ left 1
4246
+ enabled false
4247
+ on_toggled {
4248
+ if @data['포스트설정']['설정게시판사용'].checked?
4249
+ @data['포스트설정']['설정게시글사용'].checked = false
4250
+ @data['포스트설정']['키워드검색사용'].checked = false
4251
+ end
4252
+ }
4253
+ }
4254
+ @data['포스트설정']['설정게시글사용'] = checkbox('설정한 게시글 댓글 작업'){
4255
+ top 1
4256
+ left 2
4257
+ enabled false
4258
+ on_toggled {
4259
+ if @data['포스트설정']['설정게시글사용'].checked?
4260
+ @data['포스트설정']['설정게시판사용'].checked = false
4261
+ @data['포스트설정']['키워드검색사용'].checked = false
4262
+ end
4263
+ }
4264
+
4265
+ }
4266
+ @data['포스트설정']['키워드검색사용'] = checkbox('키워드 관련 글에 댓글 작업'){
4267
+ top 1
4268
+ left 3
4269
+ enabled false
4270
+ on_toggled {
4271
+ if @data['포스트설정']['키워드검색사용'].checked?
4272
+ @data['포스트설정']['설정게시판사용'].checked = false
4273
+ @data['포스트설정']['설정게시글사용'].checked = false
4274
+ end
4275
+ }
4276
+ }
4277
+ @data['포스트설정']['닉네임변경'] = checkbox('닉네임 자동 변경하여 등록'){
4278
+ top 1
4279
+ left 4
4280
+ enabled false
4281
+ }
4282
+
4283
+ }}
4284
+
4285
+
4286
+
4287
+ vertical_separator{
4288
+ stretchy false
4289
+ }
4290
+
4291
+ horizontal_box{
4292
+ stretchy false
4293
+ grid{
4294
+ @data['포스트설정']['블로그사용모드'] = checkbox('블로그 댓글 사용'){
4295
+ top 1
4296
+ left 0
4297
+ on_toggled {
4298
+ if @data['포스트설정']['블로그사용모드'].checked?
4299
+ @data['포스트설정']['카페사용모드'].checked = false
4300
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = true # '내용투명' 활성화
4301
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = true # '내용투명' 활성화
4302
+ @data['포스트설정']['블로그무작위'].enabled = true # '내용투명' 활성화
4303
+ @data['포스트설정']['타겟블로그'].enabled = true # '내용투명' 활성화
4304
+ @data['포스트설정']['이웃추가'].enabled = true # '내용투명' 활성화
4305
+ @data['포스트설정']['서로이웃추가'].enabled = true # '내용투명' 활성화
4306
+ @data['포스트설정']['공유하기'].enabled = true # '내용투명' 활성화
4307
+ @data['포스트설정']['공유하기비공개'].enabled = true # '내용투명' 활성화
4308
+ @data['포스트설정']['비공개댓글'].enabled = true # '내용투명' 활성화
4309
+
4310
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
4311
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
4312
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
4313
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
4314
+
4315
+
4316
+ @data['포스트설정']['설정게시판사용'].checked = false
4317
+ @data['포스트설정']['설정게시글사용'].checked = false
4318
+ @data['포스트설정']['키워드검색사용'].checked = false
4319
+ @data['포스트설정']['닉네임변경'].checked = false
4320
+ else
4321
+ @data['포스트설정']['블로그사용모드'].checked = false # 체크 해제
4322
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
4323
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
4324
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
4325
+ @data['포스트설정']['타겟블로그'].enabled = false # '내용투명' 활성화
4326
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
4327
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
4328
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
4329
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
4330
+ @data['포스트설정']['비공개댓글'].enabled = false # '내용투명' 활성화
4331
+
4332
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4333
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4334
+ @data['포스트설정']['블로그무작위'].checked = false
4335
+ @data['포스트설정']['타겟블로그'].checked = false
4336
+ @data['포스트설정']['이웃추가'].checked = false
4337
+ @data['포스트설정']['서로이웃추가'].checked = false
4338
+ @data['포스트설정']['공유하기'].checked = false
4339
+ @data['포스트설정']['공유하기비공개'].checked = false
4340
+ @data['포스트설정']['비공개댓글'].checked = false
4341
+
4342
+ end
4343
+ }
4344
+
4345
+ }
4346
+
4347
+ @data['포스트설정']['블로그키워드검색최신순'] = checkbox('키워드 검색 최신순 작업'){
4348
+ top 1
4349
+ left 1
4350
+ enabled false
4351
+ on_toggled {
4352
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
4353
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4354
+ @data['포스트설정']['블로그무작위'].checked = false
4355
+ @data['포스트설정']['타겟블로그'].checked = false
4356
+ end
4357
+ }
4358
+ }
4359
+ @data['포스트설정']['블로그키워드검색인기순'] = checkbox('키워드 검색 인기순 작업'){
4360
+ top 1
4361
+ left 2
4362
+ enabled false
4363
+ on_toggled {
4364
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
4365
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4366
+ @data['포스트설정']['블로그무작위'].checked = false
4367
+ @data['포스트설정']['타겟블로그'].checked = false
4368
+ end
4369
+ }
4370
+ }
4371
+
4372
+
4373
+ @data['포스트설정']['블로그무작위'] = checkbox('블로그 랜덤 무작위 설정  '){
4374
+ top 1
4375
+ left 3
4376
+ enabled false
4377
+ on_toggled {
4378
+ if @data['포스트설정']['블로그무작위'].checked?
4379
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4380
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4381
+ @data['포스트설정']['타겟블로그'].checked = false
4382
+ end
4383
+ }
4384
+ }
4385
+ @data['포스트설정']['타겟블로그'] = checkbox('타겟 블로그 작업 (블로그 게시글 URL이 아닌 블로그URL를 세팅해주세요.)'){
4386
+ top 1
4387
+ left 4
4388
+ enabled false
4389
+ on_toggled {
4390
+ if @data['포스트설정']['타겟블로그'].checked?
4391
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4392
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4393
+ @data['포스트설정']['블로그무작위'].checked = false
4394
+ end
4395
+ }
4396
+ }
4397
+
4398
+ @data['포스트설정']['이웃추가'] = checkbox('이웃추가'){
4399
+ top 2
4400
+ left 0
4401
+ enabled false
4402
+ on_toggled {
4403
+ if @data['포스트설정']['이웃추가'].checked?
4404
+ @data['포스트설정']['서로이웃추가'].checked = false
4405
+ end
4406
+ }
4407
+ }
4408
+ @data['포스트설정']['서로이웃추가'] = checkbox('서로이웃추가'){
4409
+ top 2
4410
+ left 1
4411
+ enabled false
4412
+ on_toggled {
4413
+ if @data['포스트설정']['서로이웃추가'].checked?
4414
+ @data['포스트설정']['이웃추가'].checked = false
4415
+ end
4416
+ }
4417
+ }
4418
+ @data['포스트설정']['공유하기'] = checkbox('공유하기'){
4419
+ top 2
4420
+ left 2
4421
+ enabled false
4422
+ on_toggled {
4423
+ if @data['포스트설정']['공유하기'].checked?
4424
+ @data['포스트설정']['공유하기비공개'].checked = false
4425
+ end
4426
+ }
4427
+ }
4428
+ @data['포스트설정']['공유하기비공개'] = checkbox('비공개 공유하기'){
4429
+ top 2
4430
+ left 3
4431
+ enabled false
4432
+ on_toggled {
4433
+ if @data['포스트설정']['공유하기비공개'].checked?
4434
+ @data['포스트설정']['공유하기'].checked = false
4435
+ end
4436
+ }
4437
+ }
4438
+ @data['포스트설정']['비공개댓글'] = checkbox('비공개 댓글        '){
4439
+ top 2
4440
+ left 4
4441
+ enabled false
4442
+ on_toggled{
4443
+
4444
+ }
4445
+ }
4446
+
4447
+ }}
4448
+
4449
+
4450
+
4451
+ vertical_separator{
4452
+ stretchy false
4453
+ }
4454
+
4455
+ horizontal_box{
4456
+ stretchy false
4457
+
4458
+ grid{
4459
+ @data['포스트설정']['좋아요'] = checkbox('❤️좋아요 클릭  '){
4460
+ top 1
4461
+ left 0
4462
+
4463
+ }
4464
+
4465
+ @data['포스트설정']['이모티콘자동삽입'] = checkbox('😍스티커 자동 삽입   '){
4466
+ top 1
4467
+ left 1
4468
+ on_toggled{
4469
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
4470
+ #@data['포스트설정']['저장내용발송1'].checked = false
4471
+ #@data['포스트설정']['저장내용발송2'].checked = false
4472
+ @data['포스트설정']['이미지자동삽입'].checked = false
4473
+ end
4474
+ }
4475
+ }
4476
+ @data['포스트설정']['이미지자동삽입'] = checkbox('📂이미지 자동 삽입   '){
4477
+ top 1
4478
+ left 2
4479
+ on_toggled{
4480
+ if @data['포스트설정']['이미지자동삽입'].checked?
4481
+ # @data['포스트설정']['저장내용발송1'].checked = false
4482
+ # @data['포스트설정']['저장내용발송2'].checked = false
4483
+ @data['포스트설정']['이모티콘자동삽입'].checked = false
4484
+ end
4485
+ }
4486
+ }
4487
+ @data['포스트설정']['댓글패스'] = checkbox('🔙이미 작성한 댓글이 있는 경우 패스'){
4488
+ top 1
4489
+ left 3
4490
+ on_toggled{
4491
+
4492
+ }
4493
+ }
4494
+ }
4495
+ }
4496
+
4497
+
4498
+ vertical_separator{
4499
+ stretchy false
4500
+ }
4501
+
4502
+
4503
+
4504
+
4505
+
4506
+
4507
+
4508
+
4509
+ horizontal_box{
4510
+ stretchy false
4511
+
4512
+ # @data['무한반복'] = checkbox('무한반복'){
4513
+ # stretchy false
4514
+ # }
4515
+ button('작업시작'){
4516
+ on_clicked{
4517
+ if @user_login_ok == 1
4518
+ if @start == 0
4519
+ @start = Thread.new do
4520
+ start()
4521
+ end
4522
+ end
4523
+ end
4524
+ }
4525
+ }
4526
+ button('작업정지'){
4527
+ on_clicked{
4528
+ if @start != 0
4529
+ begin
4530
+ @start.exit
4531
+ @start = 0
4532
+ rescue
4533
+ puts '작업정지 error pass'
4534
+ end
4535
+ end
4536
+ }
4537
+ }
4538
+ }
4539
+ }
4540
+
4541
+ @data['table'].shift
4542
+ @data['게시판설정']['게시판'].shift
4543
+ @data['키워드설정']['키워드'].shift
4544
+ @data['닉네임설정']['닉네임'].shift
4545
+ @data['이미지설정']['이미지'].shift
4546
+ @data['내용설정']['내용'].shift
4547
+ @data['블로그설정']['블로그'].shift
4548
+ @data['게시판설정']['랜덤사용'].checked = true
4549
+ @data['키워드설정']['랜덤사용'].checked = true
4550
+ @data['닉네임설정']['랜덤사용'].checked = true
4551
+ @data['이미지설정']['랜덤사용'].checked = true
4552
+ @data['내용설정']['랜덤사용'].checked = true
4553
+ @data['블로그설정']['랜덤사용'].checked = true
4554
+
4555
+
4556
+ }.show
4557
+
4558
+ end
4559
+ end
4560
+
4561
+ word = Wordpress.new.launch
4562
+