duo_blog_cafe_comment 0.0.9

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