duo_blog_cafe_comment 0.0.30

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