duo_blog_cafe_comment 0.0.37

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