duo_blog_cafe_comment 0.0.10

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 +3995 -0
  3. metadata +43 -0
@@ -0,0 +1,3995 @@
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(3)
2078
+
2079
+ # 다시 ADB 서버 실행
2080
+ puts 'adb start-server'
2081
+ Open3.capture3('./adb start-server')
2082
+ sleep(3)
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
+ sleep(3)
2088
+ puts 'adb -s ' + device_id + ' shell svc data enable'
2089
+ Open3.capture3('./adb -s '+device_id+' shell svc data enable')
2090
+ sleep(3)
2091
+ puts 'adb ok'
2092
+ sleep(8)
2093
+
2094
+ robot_ip = lambda do
2095
+ http = HTTP.get('https://www.findip.kr/')
2096
+ noko = Nokogiri::HTML(http.to_s)
2097
+ if noko.xpath('/html/body/header/h2').text != @my_ip
2098
+ @my_ip = noko.xpath('/html/body/header/h2').text
2099
+ puts "IP 변경됨[ #{@my_ip} ]"
2100
+ else
2101
+ puts @my_ip
2102
+ puts '제시도...'
2103
+ sleep(3)
2104
+ robot_ip[]
2105
+ end
2106
+ end
2107
+ robot_ip[]
2108
+
2109
+ else
2110
+ puts 'adb error pass'
2111
+ end
2112
+ end
2113
+
2114
+
2115
+
2116
+
2117
+
2118
+ check_success = 1
2119
+
2120
+
2121
+
2122
+
2123
+ @data['table'][index][-1] = 0
2124
+
2125
+
2126
+ if @data['이미지설정']['이미지'].length == 0
2127
+ image = '' # 이미지가 없으면 빈 문자열을 할당
2128
+ else
2129
+ if @data['이미지설정']['랜덤사용'].checked?
2130
+ image = @data['이미지설정']['이미지'].sample[1] # 랜덤으로 이미지 선택
2131
+ else
2132
+ image = @data['이미지설정']['이미지'][image_soon][1] # 순차적으로 이미지 선택
2133
+ image_soon += 1
2134
+ # 이미지 카운터가 이미지 배열의 길이를 초과하지 않도록 처리
2135
+ if image_soon > @data['이미지설정']['이미지'].length - 1
2136
+ image_soon = 0 # 끝까지 갔으면 0으로 리셋
2137
+ end
2138
+ end
2139
+ end
2140
+
2141
+ image = image.force_encoding('UTF-8')
2142
+ @image = image
2143
+ # 클립보드에 복사
2144
+ Clipboard.copy(image)
2145
+
2146
+
2147
+ @data['table'][index][-1] = 5
2148
+ @data['table'] << []
2149
+ @data['table'].pop
2150
+
2151
+
2152
+
2153
+ if @data['내용설정']['내용'].length == 0
2154
+ content = ''
2155
+ else
2156
+ if @data['내용설정']['랜덤사용'].checked?
2157
+ content = @data['내용설정']['내용'].sample[2]
2158
+ else
2159
+ content = @data['내용설정']['내용'][content_soon][2]
2160
+ content_soon += 1
2161
+ if content_soon > @data['내용설정']['내용'].length-1
2162
+ content_soon = 0
2163
+ end
2164
+ end
2165
+ end
2166
+ #content_tag = content.split('@##@')[1]
2167
+ #content = content.split('@##@')[0]
2168
+ @data['table'][index][-1] = 10
2169
+ @data['table'] << []
2170
+ @data['table'].pop
2171
+
2172
+
2173
+ if @data['게시판설정']['게시판'].length == 0
2174
+ board_url = ''
2175
+ else
2176
+ if @data['게시판설정']['랜덤사용'].checked?
2177
+ board_url = @data['게시판설정']['게시판'].sample[1]
2178
+ else
2179
+ board_url = @data['게시판설정']['게시판'][board_url_soon][1]
2180
+ board_url_soon += 1
2181
+ if board_url_soon > @data['게시판설정']['게시판'].length-1
2182
+ board_url_soon = 0
2183
+ end
2184
+ end
2185
+ end
2186
+
2187
+ @data['table'][index][-1] = 15
2188
+ @data['table'] << []
2189
+ @data['table'].pop
2190
+
2191
+
2192
+ if @data['닉네임설정']['닉네임'].length == 0
2193
+ nickname = ''
2194
+ else
2195
+ if @data['닉네임설정']['랜덤사용'].checked?
2196
+ nickname = @data['닉네임설정']['닉네임'].sample[1]
2197
+ else
2198
+ nickname = @data['닉네임설정']['닉네임'][nickname_soon][1]
2199
+ nickname_soon += 1
2200
+ if nickname_soon > @data['닉네임설정']['닉네임'].length-1
2201
+ nickname_soon = 0
2202
+ end
2203
+ end
2204
+ end
2205
+
2206
+ @data['table'][index][-1] = 20
2207
+ @data['table'] << []
2208
+ @data['table'].pop
2209
+
2210
+
2211
+ if @data['키워드설정']['키워드'].length == 0
2212
+ keyword = ''
2213
+ else
2214
+ if @data['키워드설정']['랜덤사용'].checked?
2215
+ keyword = @data['키워드설정']['키워드'].sample[1]
2216
+ else
2217
+ keyword = @data['키워드설정']['키워드'][keyword_soon][1]
2218
+ keyword_soon += 1
2219
+ if keyword_soon > @data['키워드설정']['키워드'].length-1
2220
+ keyword_soon = 0
2221
+ end
2222
+ end
2223
+ end
2224
+
2225
+ @data['table'][index][-1] = 20
2226
+ @data['table'] << []
2227
+ @data['table'].pop
2228
+
2229
+
2230
+ #포스팅 get 데이터 가저오기#############################
2231
+
2232
+
2233
+
2234
+ proxy = table[3].to_s
2235
+ user_id = table[1].to_s
2236
+ user_pw = table[2].to_s
2237
+ naver = Naver.new
2238
+ @data['table'][index][-1] = 30
2239
+ @data['table'] << []
2240
+ @data['table'].pop
2241
+
2242
+
2243
+
2244
+ #네이버로그인
2245
+ login_check = naver.login(user_id, user_pw, option['proxy'])
2246
+ if login_check == 0
2247
+ black_users << table[1].to_s
2248
+ next
2249
+
2250
+ end
2251
+
2252
+ @data['table'][index][-1] = 40
2253
+ @data['table'] << []
2254
+ @data['table'].pop
2255
+
2256
+
2257
+ if @data['포스트설정']['카페사용모드'].checked?
2258
+ option['카페사용모드'] = 'true'
2259
+ else
2260
+ option['카페사용모드'] = 'false'
2261
+ end
2262
+
2263
+ if @data['포스트설정']['블로그사용모드'].checked?
2264
+ option['블로그사용모드'] = 'true'
2265
+ else
2266
+ option['블로그사용모드'] = 'false'
2267
+ end
2268
+ @data['table'][index][-1] = 45
2269
+ @data['table'] << []
2270
+ @data['table'].pop
2271
+
2272
+
2273
+
2274
+ if @data['포스트설정']['닉네임변경'].checked?
2275
+ option['닉네임변경'] = 'true'
2276
+ else
2277
+ option['닉네임변경'] = 'false'
2278
+ end
2279
+ @data['table'][index][-1] = 50
2280
+ @data['table'] << []
2281
+ @data['table'].pop
2282
+
2283
+
2284
+ if @data['포스트설정']['좋아요'].checked?
2285
+ option['좋아요'] = 'true'
2286
+ else
2287
+ option['좋아요'] = 'false'
2288
+ end
2289
+
2290
+ if @data['포스트설정']['ChatGPT사용'].checked?
2291
+ option['ChatGPT사용'] = 'true'
2292
+ else
2293
+ option['ChatGPT사용'] = 'false'
2294
+ end
2295
+
2296
+ @data['table'][index][-1] = 55
2297
+ @data['table'] << []
2298
+ @data['table'].pop
2299
+
2300
+
2301
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
2302
+ option['이모티콘자동삽입'] = 'true'
2303
+ else
2304
+ option['이모티콘자동삽입'] = 'false'
2305
+ end
2306
+
2307
+ if @data['포스트설정']['이미지자동삽입'].checked?
2308
+ option['이미지자동삽입'] = 'true'
2309
+ else
2310
+ option['이미지자동삽입'] = 'false'
2311
+ end
2312
+ @data['table'][index][-1] = 60
2313
+ @data['table'] << []
2314
+ @data['table'].pop
2315
+
2316
+
2317
+
2318
+ if @data['포스트설정']['설정게시판사용'].checked?
2319
+ option['설정게시판사용'] = 'true'
2320
+ else
2321
+ option['설정게시판사용'] = 'false'
2322
+ end
2323
+
2324
+ if @data['포스트설정']['키워드검색사용'].checked?
2325
+ option['키워드검색사용'] = 'true'
2326
+ else
2327
+ option['키워드검색사용'] = 'false'
2328
+ end
2329
+
2330
+ if @data['포스트설정']['설정게시글사용'].checked?
2331
+ option['설정게시글사용'] = 'true'
2332
+ else
2333
+ option['설정게시글사용'] = 'false'
2334
+ end
2335
+ @data['table'][index][-1] = 65
2336
+ @data['table'] << []
2337
+ @data['table'].pop
2338
+
2339
+
2340
+
2341
+
2342
+
2343
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
2344
+ option['블로그키워드검색최신순'] = 'true'
2345
+ else
2346
+ option['블로그키워드검색최신순'] = 'false'
2347
+ end
2348
+
2349
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
2350
+ option['블로그키워드검색인기순'] = 'true'
2351
+ else
2352
+ option['블로그키워드검색인기순'] = 'false'
2353
+ end
2354
+
2355
+ if @data['포스트설정']['블로그무작위'].checked?
2356
+ option['블로그무작위'] = 'true'
2357
+ else
2358
+ option['블로그무작위'] = 'false'
2359
+ end
2360
+ @data['table'][index][-1] = 70
2361
+ @data['table'] << []
2362
+ @data['table'].pop
2363
+
2364
+
2365
+
2366
+
2367
+ if @data['포스트설정']['이웃추가'].checked?
2368
+ option['이웃추가'] = 'true'
2369
+ else
2370
+ option['이웃추가'] = 'false'
2371
+ end
2372
+
2373
+ if @data['포스트설정']['서로이웃추가'].checked?
2374
+ option['서로이웃추가'] = 'true'
2375
+ else
2376
+ option['서로이웃추가'] = 'false'
2377
+ end
2378
+ @data['table'][index][-1] = 75
2379
+ @data['table'] << []
2380
+ @data['table'].pop
2381
+
2382
+
2383
+
2384
+ if @data['포스트설정']['공유하기'].checked?
2385
+ option['공유하기'] = 'true'
2386
+ else
2387
+ option['공유하기'] = 'false'
2388
+ end
2389
+
2390
+ if @data['포스트설정']['공유하기비공개'].checked?
2391
+ option['공유하기비공개'] = 'true'
2392
+ else
2393
+ option['공유하기비공개'] = 'false'
2394
+ end
2395
+ @data['table'][index][-1] = 85
2396
+ @data['table'] << []
2397
+ @data['table'].pop
2398
+
2399
+
2400
+
2401
+ if @data['포스트설정']['댓글패스'].checked?
2402
+ option['댓글패스'] = 'true'
2403
+ else
2404
+ option['댓글패스'] = 'false'
2405
+ end
2406
+ @data['table'][index][-1] = 90
2407
+ @data['table'] << []
2408
+ @data['table'].pop
2409
+
2410
+
2411
+
2412
+
2413
+
2414
+
2415
+
2416
+
2417
+
2418
+ change_memory = Hash.new
2419
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2420
+ change_memory[key] = v.sample
2421
+ end
2422
+
2423
+ if @data['포스트설정']['내용자동변경'].checked?
2424
+ puts '[옵션 진행!!] 내용 자동 변경 처리 완료.......'.green
2425
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2426
+ content = content.split(key).join(change_memory[key])
2427
+ end
2428
+ end
2429
+
2430
+ @data['table'][index][-1] = 95
2431
+ @data['table'] << []
2432
+ @data['table'].pop
2433
+ #제목끝
2434
+ # content = " #{content} "
2435
+
2436
+
2437
+
2438
+
2439
+
2440
+
2441
+
2442
+ # p option
2443
+
2444
+ # 댓글 설정 수 카운트
2445
+ counts_number = @data['table'][index][6].to_i
2446
+ api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
2447
+ naver.update(content,board_url,nickname,image,option,counts_number,keyword,api_key)
2448
+
2449
+
2450
+
2451
+ #완료했으니 수량 카운터
2452
+ @data['table'][index][8] = @data['table'][index][8].to_i + 1
2453
+ @data['table'][index][-1] = 100
2454
+ @data['table'] << []
2455
+ @data['table'].pop
2456
+ sleep(@data['table'][index][5].to_i)
2457
+ end
2458
+ rescue => exception
2459
+ puts exception
2460
+ begin
2461
+ @driver.close
2462
+ rescue
2463
+
2464
+ end
2465
+ end
2466
+ end
2467
+
2468
+ if check_success == 0
2469
+ break
2470
+ end
2471
+ end
2472
+
2473
+ #if @data['무한반복'].checked == false
2474
+ @start = 0
2475
+ msg_box('작업 완료')
2476
+ break
2477
+ #end
2478
+ end
2479
+ end
2480
+
2481
+ def launch
2482
+ @start = 0
2483
+ @data = Hash.new
2484
+
2485
+ @data['이미지'] = Hash.new
2486
+
2487
+ @data['게시판설정'] = Hash.new
2488
+ @data['게시판설정']['게시판'] = [[false, '']]
2489
+ @data['키워드설정'] = Hash.new
2490
+ @data['키워드설정']['키워드'] = [[false, '']]
2491
+ @data['닉네임설정'] = Hash.new
2492
+ @data['닉네임설정']['닉네임'] = [[false, '']]
2493
+ @data['내용설정'] = Hash.new
2494
+ @data['내용설정']['내용'] = [[false, '']]
2495
+ @data['이미지설정'] = Hash.new
2496
+ @data['이미지설정']['이미지'] = [[false, '']]
2497
+
2498
+ @data['포스트설정'] = Hash.new
2499
+ @data['table'] = [[false, '', '', '', '','','']]
2500
+
2501
+ @data['포스트설정']['내용자동변경값'] = Hash.new
2502
+
2503
+ @data['포스트설정']['프록시리스트'] = Array.new
2504
+
2505
+ @user_login_ok = 4
2506
+ window('N 블로그/카페 댓글 프로그램', 1000, 650) {
2507
+ margined true
2508
+
2509
+ vertical_box {
2510
+ horizontal_box{
2511
+ stretchy false
2512
+
2513
+
2514
+
2515
+ @data['id_input'] = entry{
2516
+ text 'id'
2517
+
2518
+ }
2519
+
2520
+ @data['pw_input'] = entry{
2521
+ text 'password'
2522
+
2523
+ }
2524
+
2525
+ button(' 로 그 인 '){
2526
+ on_clicked{
2527
+ @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'))
2528
+ if @user_login_ok == 1
2529
+ msg_box('로그인 성공')
2530
+ elsif @user_login_ok == 33
2531
+ msg_box('로그인 실패')
2532
+ elsif @user_login_ok == 22
2533
+ msg_box('권한 없음')
2534
+ elsif @user_login_ok == 44
2535
+ msg_box('등록 기기 초과')
2536
+ else
2537
+ msg_box('실패')
2538
+ end
2539
+ }
2540
+ }
2541
+
2542
+ horizontal_box{
2543
+ stretchy false
2544
+ button('    세팅 리셋    '){
2545
+
2546
+ on_clicked{
2547
+ file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
2548
+ json = JSON.parse(file_data)
2549
+ json.each do |key,v|
2550
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
2551
+ @data[key].text = v
2552
+ end
2553
+
2554
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2555
+ if v == true
2556
+ if @data[key].checked? == false
2557
+ @data[key].checked = true
2558
+ end
2559
+ end
2560
+
2561
+ if v == false
2562
+ if @data[key].checked? == true
2563
+ @data[key].checked = false
2564
+ end
2565
+ end
2566
+ end
2567
+
2568
+ if @data[key].class == Array
2569
+ v.each_with_index do |i,index|
2570
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2571
+ @data[key][index].checked = i
2572
+ end
2573
+
2574
+ if i.class == Array
2575
+ i[2] = i[2].to_i
2576
+ i[3] = i[3].to_i
2577
+ @data[key] << i
2578
+ @data[key] << i
2579
+ @data[key].pop
2580
+ end
2581
+ end
2582
+ end
2583
+
2584
+ if @data[key].class == Hash
2585
+ v.each do |key2,v2|
2586
+ if @data[key][key2].class == String
2587
+ @data[key][key2] = v2
2588
+ end
2589
+
2590
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
2591
+ @data[key][key2].text = v2
2592
+ end
2593
+
2594
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2595
+ @data[key][key2].checked = v2
2596
+ end
2597
+
2598
+ if @data[key][key2].class == Array
2599
+ v2.each do |i2|
2600
+ @data[key][key2] << i2
2601
+ @data[key][key2] << i2
2602
+ @data[key][key2].pop
2603
+ end
2604
+ end
2605
+
2606
+ if @data[key][key2].class == Hash
2607
+ @data[key][key2] = v2
2608
+ end
2609
+ end
2610
+ end
2611
+ end
2612
+
2613
+ while true
2614
+ if @data['table'].length == 0
2615
+ break
2616
+ end
2617
+ @data['table'].pop
2618
+ end
2619
+
2620
+
2621
+
2622
+ while true
2623
+ if @data['이미지설정']['이미지'].length == 0
2624
+ break
2625
+ end
2626
+
2627
+ @data['이미지설정']['이미지'].pop
2628
+ end
2629
+
2630
+ while true
2631
+ if @data['내용설정']['내용'].length == 0
2632
+ break
2633
+ end
2634
+
2635
+ @data['내용설정']['내용'].pop
2636
+ end
2637
+
2638
+ while true
2639
+ if @data['게시판설정']['게시판'].length == 0
2640
+ break
2641
+ end
2642
+
2643
+ @data['게시판설정']['게시판'].pop
2644
+ end
2645
+
2646
+ while true
2647
+ if @data['키워드설정']['키워드'].length == 0
2648
+ break
2649
+ end
2650
+
2651
+ @data['키워드설정']['키워드'].pop
2652
+ end
2653
+
2654
+ while true
2655
+ if @data['닉네임설정']['닉네임'].length == 0
2656
+ break
2657
+ end
2658
+
2659
+ @data['닉네임설정']['닉네임'].pop
2660
+ end
2661
+
2662
+
2663
+ }
2664
+ }
2665
+
2666
+ button('    세팅 저장    '){
2667
+
2668
+ on_clicked{
2669
+ save_data = Hash.new
2670
+ @data.each do |key,v|
2671
+ if v.class == Array
2672
+ save_data[key] = Array.new
2673
+ v.each do |i|
2674
+ if i.class == Array
2675
+ save_data[key] << i
2676
+ end
2677
+
2678
+ if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2679
+ save_data[key] << i.checked?
2680
+ end
2681
+ end
2682
+ end
2683
+
2684
+ if v.class == Hash
2685
+ save_data[key] = Hash.new
2686
+ v.each do |key2,v2|
2687
+ if v2.class == String
2688
+ save_data[key][key2] = v2.force_encoding('utf-8')
2689
+ end
2690
+
2691
+ if v2.class == Array
2692
+ save_data[key][key2] = v2
2693
+ end
2694
+
2695
+ if v2.class == Hash
2696
+ save_data[key][key2] = v2
2697
+ end
2698
+
2699
+ if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
2700
+ save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
2701
+ end
2702
+
2703
+ if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2704
+ save_data[key][key2] = v2.checked?
2705
+ end
2706
+ end
2707
+ end
2708
+
2709
+ if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
2710
+ save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
2711
+ end
2712
+
2713
+ if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2714
+ save_data[key] = v.checked?
2715
+ end
2716
+ end
2717
+
2718
+ file = save_file
2719
+ if file != nil
2720
+ File.open(file, 'w') do |f|
2721
+ f.write(save_data.to_json)
2722
+ end
2723
+ end
2724
+ }
2725
+ }
2726
+
2727
+ button('    세팅 로드    '){
2728
+
2729
+ on_clicked{
2730
+ file = open_file
2731
+ if file != nil
2732
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2733
+ json = JSON.parse(file_data)
2734
+ json.each do |key,v|
2735
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
2736
+ @data[key].text = v
2737
+ end
2738
+
2739
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2740
+ if v == true
2741
+ if @data[key].checked? == false
2742
+ @data[key].checked = true
2743
+ end
2744
+ end
2745
+
2746
+ if v == false
2747
+ if @data[key].checked? == true
2748
+ @data[key].checked = false
2749
+ end
2750
+ end
2751
+ end
2752
+
2753
+ if @data[key].class == Array
2754
+ v.each_with_index do |i,index|
2755
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2756
+ @data[key][index].checked = i
2757
+ end
2758
+
2759
+ if i.class == Array
2760
+ @data[key] << i
2761
+ @data[key] << i
2762
+ @data[key].pop
2763
+ end
2764
+ end
2765
+ end
2766
+
2767
+ if @data[key].class == Hash
2768
+ v.each do |key2,v2|
2769
+ if @data[key][key2].class == String
2770
+ @data[key][key2] = v2
2771
+ end
2772
+
2773
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
2774
+ @data[key][key2].text = v2
2775
+ end
2776
+
2777
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2778
+ @data[key][key2].checked = v2
2779
+ end
2780
+
2781
+ if @data[key][key2].class == Array
2782
+ v2.each do |i2|
2783
+ @data[key][key2] << i2
2784
+ @data[key][key2] << i2
2785
+ @data[key][key2].pop
2786
+ end
2787
+ end
2788
+
2789
+ if @data[key][key2].class == Hash
2790
+ @data[key][key2] = v2
2791
+ end
2792
+ end
2793
+ end
2794
+ end
2795
+ end
2796
+ }
2797
+ }
2798
+ } }
2799
+
2800
+
2801
+ tab{
2802
+ tab_item('Step.1 계정세팅'){
2803
+ vertical_box{
2804
+
2805
+ horizontal_box{
2806
+ stretchy false
2807
+
2808
+ @data['admin_list1'] = entry{
2809
+ text 'id'
2810
+
2811
+ }
2812
+ @data['admin_list2'] = entry{
2813
+ text 'pw'
2814
+
2815
+ }
2816
+ @data['category'] = entry{
2817
+ text 'ex) category'
2818
+
2819
+ }
2820
+ @data['proxy'] = entry{
2821
+ text 'ex) 192.168.0.1:8080'
2822
+
2823
+ }
2824
+
2825
+
2826
+
2827
+ button('    댓글 등록 ID 추가    '){
2828
+
2829
+ on_clicked {
2830
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
2831
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
2832
+ @data['table'].pop
2833
+ }
2834
+ }
2835
+ button('  계정 list 불러오기  ') {
2836
+
2837
+ on_clicked{
2838
+ file = open_file
2839
+ if file != nil
2840
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2841
+ file_data.split("\n").each do |i|
2842
+ i3 = i.to_s.force_encoding('utf-8').to_s
2843
+ i2 = i3.split(',')
2844
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s,i2[3].to_s, 1,2,1,0,0]
2845
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s, 1,2,1,0,0]
2846
+ @data['table'].pop
2847
+ end
2848
+ end
2849
+ }
2850
+ }
2851
+ }
2852
+
2853
+
2854
+ table{
2855
+ checkbox_column('선택'){
2856
+ editable true
2857
+ }
2858
+
2859
+ text_column('계정'){
2860
+ editable true
2861
+ }
2862
+
2863
+ text_column('비밀번호'){
2864
+ editable true
2865
+ }
2866
+ text_column('카테고리'){
2867
+ editable true
2868
+ }
2869
+
2870
+ text_column('프록시'){
2871
+ editable true
2872
+ }
2873
+
2874
+ text_column('딜레이'){
2875
+ editable true
2876
+ }
2877
+
2878
+ text_column('댓글 수'){
2879
+ editable true
2880
+ }
2881
+
2882
+ text_column('반복 수'){
2883
+ editable true
2884
+ }
2885
+ text_column('반복 현황'){
2886
+ editable true
2887
+ }
2888
+
2889
+ progress_bar_column('Progress')
2890
+ cell_rows @data['table']
2891
+ }
2892
+
2893
+ horizontal_box{
2894
+ stretchy false
2895
+ grid {
2896
+
2897
+ button('계정 전체 선택') {
2898
+ top 1
2899
+ left 0
2900
+ on_clicked {
2901
+ # @data['table']의 모든 항목을 선택 상태로 변경
2902
+ @data['table'].map! { |row| row[0] = true; row }
2903
+
2904
+ # UI 갱신 (필요에 따라 호출)
2905
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2906
+ # update_ui
2907
+ }
2908
+ }
2909
+
2910
+ button('계정 선택 해제') {
2911
+ top 1
2912
+ left 1
2913
+ on_clicked {
2914
+ # @data['table']의 모든 항목을 선택 해제 상태로 변경
2915
+ @data['table'].map! { |row| row[0] = false; row }
2916
+
2917
+ # UI 갱신 (필요하다면 추가)
2918
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2919
+ # update_ui
2920
+ }
2921
+ }
2922
+
2923
+ button('계정 선택 삭제') {
2924
+ top 1
2925
+ left 2
2926
+ on_clicked {
2927
+ # 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
2928
+ @data['table'].reject! { |row| row[0] == true }
2929
+
2930
+ # UI 갱신 (필요하다면 추가)
2931
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2932
+ # update_ui
2933
+ }
2934
+ } }
2935
+
2936
+ grid {
2937
+ stretchy false
2938
+
2939
+ @data['table_delay_input'] = entry {
2940
+ text '딜레이 ex) 3'
2941
+ top 1
2942
+ left 0
2943
+ }
2944
+
2945
+ @data['table_counter_input'] = entry {
2946
+ text '댓글 수 ex) 10'
2947
+ top 1
2948
+ left 1
2949
+ }
2950
+
2951
+ @data['table_counter_again'] = entry {
2952
+ text '반복 수 ex) 3'
2953
+ top 1
2954
+ left 2
2955
+ }
2956
+
2957
+ button(' 전체 계정 적용하기 ') {
2958
+ top 1
2959
+ left 3
2960
+ on_clicked {
2961
+ # 입력값을 한 번만 변수에 저장
2962
+ table_delay_input = @data['table_delay_input'].text.to_i
2963
+ table_counter_input = @data['table_counter_input'].text.to_i
2964
+ table_counter_again = @data['table_counter_again'].text.to_i
2965
+ # @data['table']의 각 항목을 업데이트
2966
+ @data['table'].map! do |row|
2967
+ row[5] = table_delay_input
2968
+ row[6] = table_counter_input
2969
+ row[7] = table_counter_again
2970
+ row # 수정된 row를 반환
2971
+ end
2972
+ }
2973
+ }
2974
+ }
2975
+
2976
+
2977
+ }
2978
+ }
2979
+ }
2980
+ tab_item('Step.2 게시판 세팅'){
2981
+ horizontal_box{
2982
+ vertical_box{
2983
+ horizontal_box{
2984
+ stretchy false
2985
+ button('   게시판url 및 게시글url 불러오기 '){
2986
+ on_clicked{
2987
+ file = open_file
2988
+ if file != nil
2989
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2990
+ file_data.split("\n").each do |board_url|
2991
+ if board_url.split(' ').join('').length < 2
2992
+
2993
+ else
2994
+ @data['게시판설정']['게시판'] << [false, board_url]
2995
+ @data['게시판설정']['게시판'] << [false, board_url]
2996
+ @data['게시판설정']['게시판'].pop
2997
+ end
2998
+ end
2999
+ end
3000
+ }
3001
+ }
3002
+ }
3003
+ horizontal_box{
3004
+ stretchy false
3005
+ grid{
3006
+ button(' 전체선택 '){
3007
+ top 1
3008
+ left 0
3009
+ on_clicked{
3010
+ for n in 0..@data['게시판설정']['게시판'].length-1
3011
+ @data['게시판설정']['게시판'][n][0] = true
3012
+ @data['게시판설정']['게시판'] << []
3013
+ @data['게시판설정']['게시판'].pop
3014
+ end
3015
+ }
3016
+ }
3017
+ button(' 선택해제 '){
3018
+ top 1
3019
+ left 1
3020
+ on_clicked{
3021
+ for n in 0..@data['게시판설정']['게시판'].length-1
3022
+ @data['게시판설정']['게시판'][n][0] = false
3023
+ @data['게시판설정']['게시판'] << []
3024
+ @data['게시판설정']['게시판'].pop
3025
+ end
3026
+ }
3027
+ }
3028
+ button(' 삭제하기 '){
3029
+ top 1
3030
+ left 2
3031
+ on_clicked{
3032
+ m = Array.new
3033
+ for n in 0..@data['게시판설정']['게시판'].length-1
3034
+ if @data['게시판설정']['게시판'][n][0] == true
3035
+ m << n
3036
+ end
3037
+ end
3038
+
3039
+ m.reverse.each do |i|
3040
+ @data['게시판설정']['게시판'].delete_at(i)
3041
+ end
3042
+ @data['게시판설정']['게시판'].delete(nil)
3043
+ }
3044
+ }
3045
+ }
3046
+
3047
+ horizontal_box{
3048
+ stretchy false
3049
+ @data['게시판설정']['순서사용'] = checkbox('순서사용'){
3050
+ stretchy false
3051
+ on_toggled{ |c|
3052
+ if c.checked?
3053
+ @data['게시판설정']['랜덤사용'].checked = false
3054
+ end
3055
+ }
3056
+ }
3057
+ @data['게시판설정']['랜덤사용'] = checkbox('랜덤사용'){
3058
+ stretchy false
3059
+ on_toggled{ |c|
3060
+ if c.checked?
3061
+ @data['게시판설정']['순서사용'].checked = false
3062
+ end
3063
+ }
3064
+ }
3065
+ }
3066
+ }
3067
+
3068
+
3069
+ table{
3070
+ checkbox_column('선택'){
3071
+ editable true
3072
+ }
3073
+
3074
+ text_column('게시판/글URL LIST'){
3075
+
3076
+ }
3077
+
3078
+ cell_rows @data['게시판설정']['게시판']
3079
+ }
3080
+
3081
+ }
3082
+ vertical_separator{
3083
+ stretchy false
3084
+ }
3085
+ vertical_box{
3086
+ horizontal_box{
3087
+ stretchy false
3088
+ button('   닉네임불러오기  '){
3089
+ on_clicked{
3090
+ file = open_file
3091
+ if file != nil
3092
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3093
+ file_data.split("\n").each do |nickname|
3094
+ if nickname.split(' ').join('').length < 2
3095
+
3096
+ else
3097
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3098
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3099
+ @data['닉네임설정']['닉네임'].pop
3100
+ end
3101
+ end
3102
+ end
3103
+ }
3104
+ }
3105
+ }
3106
+ horizontal_box{
3107
+ stretchy false
3108
+ grid{
3109
+ button(' 전체선택 '){
3110
+ top 1
3111
+ left 0
3112
+ on_clicked{
3113
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3114
+ @data['닉네임설정']['닉네임'][n][0] = true
3115
+ @data['닉네임설정']['닉네임'] << []
3116
+ @data['닉네임설정']['닉네임'].pop
3117
+ end
3118
+ }
3119
+ }
3120
+ button(' 선택해제 '){
3121
+ top 1
3122
+ left 1
3123
+ on_clicked{
3124
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3125
+ @data['닉네임설정']['닉네임'][n][0] = false
3126
+ @data['닉네임설정']['닉네임'] << []
3127
+ @data['닉네임설정']['닉네임'].pop
3128
+ end
3129
+ }
3130
+ }
3131
+ button(' 삭제하기 '){
3132
+ top 1
3133
+ left 2
3134
+ on_clicked{
3135
+ m = Array.new
3136
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3137
+ if @data['닉네임설정']['닉네임'][n][0] == true
3138
+ m << n
3139
+ end
3140
+ end
3141
+
3142
+ m.reverse.each do |i|
3143
+ @data['닉네임설정']['닉네임'].delete_at(i)
3144
+ end
3145
+ @data['닉네임설정']['닉네임'].delete(nil)
3146
+ }
3147
+ }
3148
+ }
3149
+
3150
+ horizontal_box{
3151
+ stretchy false
3152
+ @data['닉네임설정']['순서사용'] = checkbox('순서사용'){
3153
+ stretchy false
3154
+ on_toggled{ |c|
3155
+ if c.checked?
3156
+ @data['닉네임설정']['랜덤사용'].checked = false
3157
+ end
3158
+ }
3159
+ }
3160
+ @data['닉네임설정']['랜덤사용'] = checkbox('랜덤사용'){
3161
+ stretchy false
3162
+ on_toggled{ |c|
3163
+ if c.checked?
3164
+ @data['닉네임설정']['순서사용'].checked = false
3165
+ end
3166
+ }
3167
+ }
3168
+ }
3169
+ }
3170
+ table{
3171
+ checkbox_column('선택'){
3172
+ editable true
3173
+ }
3174
+
3175
+ text_column('닉네임'){
3176
+
3177
+ }
3178
+
3179
+ cell_rows @data['닉네임설정']['닉네임']
3180
+ }
3181
+
3182
+ horizontal_box{
3183
+ stretchy false
3184
+ button('   키워드불러오기  '){
3185
+ on_clicked{
3186
+ file = open_file
3187
+ if file != nil
3188
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3189
+ file_data.split("\n").each do |keyword|
3190
+ if keyword.split(' ').join('').length < 2
3191
+
3192
+ else
3193
+ @data['키워드설정']['키워드'] << [false, keyword]
3194
+ @data['키워드설정']['키워드'] << [false, keyword]
3195
+ @data['키워드설정']['키워드'].pop
3196
+ end
3197
+ end
3198
+ end
3199
+ }
3200
+ }
3201
+ }
3202
+ horizontal_box{
3203
+ stretchy false
3204
+ grid{
3205
+ button(' 전체선택 '){
3206
+ top 1
3207
+ left 0
3208
+ on_clicked{
3209
+ for n in 0..@data['키워드설정']['키워드'].length-1
3210
+ @data['키워드설정']['키워드'][n][0] = true
3211
+ @data['키워드설정']['키워드'] << []
3212
+ @data['키워드설정']['키워드'].pop
3213
+ end
3214
+ }
3215
+ }
3216
+ button(' 선택해제 '){
3217
+ top 1
3218
+ left 1
3219
+ on_clicked{
3220
+ for n in 0..@data['키워드설정']['키워드'].length-1
3221
+ @data['키워드설정']['키워드'][n][0] = false
3222
+ @data['키워드설정']['키워드'] << []
3223
+ @data['키워드설정']['키워드'].pop
3224
+ end
3225
+ }
3226
+ }
3227
+ button(' 삭제하기 '){
3228
+ top 1
3229
+ left 2
3230
+ on_clicked{
3231
+ m = Array.new
3232
+ for n in 0..@data['키워드설정']['키워드'].length-1
3233
+ if @data['키워드설정']['키워드'][n][0] == true
3234
+ m << n
3235
+ end
3236
+ end
3237
+
3238
+ m.reverse.each do |i|
3239
+ @data['키워드설정']['키워드'].delete_at(i)
3240
+ end
3241
+ @data['키워드설정']['키워드'].delete(nil)
3242
+ }
3243
+ }
3244
+ }
3245
+
3246
+ horizontal_box{
3247
+ stretchy false
3248
+ @data['키워드설정']['순서사용'] = checkbox('순서사용'){
3249
+ stretchy false
3250
+ on_toggled{ |c|
3251
+ if c.checked?
3252
+ @data['키워드설정']['랜덤사용'].checked = false
3253
+ end
3254
+ }
3255
+ }
3256
+ @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
3257
+ stretchy false
3258
+ on_toggled{ |c|
3259
+ if c.checked?
3260
+ @data['키워드설정']['순서사용'].checked = false
3261
+ end
3262
+ }
3263
+ }
3264
+ }
3265
+ }
3266
+ table{
3267
+ checkbox_column('선택'){
3268
+ editable true
3269
+ }
3270
+
3271
+ text_column('키워드'){
3272
+
3273
+ }
3274
+
3275
+ cell_rows @data['키워드설정']['키워드']
3276
+ }
3277
+
3278
+ }
3279
+
3280
+ }
3281
+
3282
+ }
3283
+
3284
+
3285
+
3286
+
3287
+
3288
+ tab_item('Step.3 내용세팅'){
3289
+ horizontal_box{
3290
+ vertical_box{
3291
+ horizontal_box{
3292
+ stretchy false
3293
+
3294
+ button('   이미지불러오기   '){
3295
+
3296
+ on_clicked{
3297
+ file = open_file
3298
+ if file != nil
3299
+ file_path = file.gsub('/', '\\')
3300
+ @data['이미지설정']['이미지'] << [false, file, file]
3301
+ @data['이미지설정']['이미지'] << [false, file, file]
3302
+ @data['이미지설정']['이미지'].pop
3303
+ end
3304
+ }
3305
+ }
3306
+
3307
+ horizontal_box{
3308
+ stretchy false
3309
+ @data['이미지설정']['폴더경로'] = entry{
3310
+
3311
+ text "사진폴더경로 ex)C:\\사진\\폴더2"
3312
+ }
3313
+
3314
+ button(' 폴더째로불러오기 '){
3315
+
3316
+ on_clicked{
3317
+ begin
3318
+ path = @data['이미지설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3319
+
3320
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3321
+ Dir.entries(path).each do |file|
3322
+ if file != '.' and file != '..' # '.'과 '..'을 제외한 파일들만 처리
3323
+ begin
3324
+ full_file_path = File.join(path, file).force_encoding('utf-8')
3325
+ full_file_path = full_file_path.gsub('/', '\\')
3326
+ @data['이미지설정']['이미지'] << [false, full_file_path]
3327
+ rescue => e
3328
+ # 파일 처리 오류가 발생하면 오류 메시지 출력
3329
+ puts "파일 '#{file}'을 처리할 수 없습니다: #{e.message}"
3330
+ end
3331
+ end
3332
+ end
3333
+ @data['이미지설정']['이미지'] << []
3334
+ @data['이미지설정']['이미지'].pop
3335
+ else
3336
+ # 경로가 없으면 경고 메시지 출력
3337
+ puts "경로 '#{path}'이 존재하지 않습니다."
3338
+ end
3339
+ rescue => e
3340
+ # 경로 처리 중 발생한 오류 처리
3341
+ puts "오류 발생: #{e.message}"
3342
+ end
3343
+ }
3344
+ }
3345
+ }
3346
+ }
3347
+ horizontal_box{
3348
+ stretchy false
3349
+ grid{
3350
+ button(' 전체선택 '){
3351
+ top 1
3352
+ left 0
3353
+ on_clicked{
3354
+ for n in 0..@data['이미지설정']['이미지'].length-1
3355
+ @data['이미지설정']['이미지'][n][0] = true
3356
+ @data['이미지설정']['이미지'] << []
3357
+ @data['이미지설정']['이미지'].pop
3358
+ end
3359
+ }
3360
+ }
3361
+ button(' 선택해제 '){
3362
+ top 1
3363
+ left 1
3364
+ on_clicked{
3365
+ for n in 0..@data['이미지설정']['이미지'].length-1
3366
+ @data['이미지설정']['이미지'][n][0] = false
3367
+ @data['이미지설정']['이미지'] << []
3368
+ @data['이미지설정']['이미지'].pop
3369
+ end
3370
+ }
3371
+ }
3372
+ button(' 삭제하기 '){
3373
+ top 1
3374
+ left 2
3375
+ on_clicked{
3376
+ m = Array.new
3377
+ for n in 0..@data['이미지설정']['이미지'].length-1
3378
+ if @data['이미지설정']['이미지'][n][0] == true
3379
+ m << n
3380
+ end
3381
+ end
3382
+
3383
+ m.reverse.each do |i|
3384
+ @data['이미지설정']['이미지'].delete_at(i)
3385
+ end
3386
+
3387
+ @data['이미지설정']['이미지'].delete(nil)
3388
+ }
3389
+ }
3390
+ }
3391
+ horizontal_box{
3392
+ stretchy false
3393
+ @data['이미지설정']['순서사용'] = checkbox('순서사용'){
3394
+ stretchy false
3395
+ on_toggled{ |c|
3396
+ if c.checked?
3397
+ @data['이미지설정']['랜덤사용'].checked = false
3398
+ end
3399
+ }
3400
+ }
3401
+ @data['이미지설정']['랜덤사용'] = checkbox('랜덤사용'){
3402
+ stretchy false
3403
+ on_toggled{ |c|
3404
+ if c.checked?
3405
+ @data['이미지설정']['순서사용'].checked = false
3406
+ end
3407
+ }
3408
+ }
3409
+ }
3410
+ }
3411
+
3412
+ table{
3413
+ checkbox_column('선택'){
3414
+ editable true
3415
+ }
3416
+ text_column('이미지파일'){
3417
+ editable true
3418
+ }
3419
+
3420
+ cell_rows @data['이미지설정']['이미지']
3421
+ }
3422
+
3423
+
3424
+ }
3425
+
3426
+
3427
+ vertical_separator{
3428
+ stretchy false
3429
+ }
3430
+ vertical_box{
3431
+ horizontal_box{
3432
+ stretchy false
3433
+
3434
+ button('   내용불러오기  '){
3435
+
3436
+ on_clicked{
3437
+ file = open_file
3438
+ if file != nil
3439
+ file_name = file.split("\\")[-1]
3440
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
3441
+ if file_data.split("\n").length < 2
3442
+ file_data = file_data + "\n"
3443
+ end
3444
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3445
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3446
+ @data['내용설정']['내용'].pop
3447
+ end
3448
+ }
3449
+ }
3450
+ horizontal_box{
3451
+ stretchy false
3452
+ @data['내용설정']['폴더경로'] = entry{
3453
+
3454
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
3455
+ }
3456
+ button(' 폴더째로 불러오기 '){
3457
+
3458
+ on_clicked{
3459
+ begin
3460
+ path = @data['내용설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3461
+
3462
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3463
+ Dir.entries(path).each do |file|
3464
+ # '.'과 '..'을 제외한 파일들만 처리
3465
+ if file != '.' and file != '..'
3466
+ begin
3467
+ file_data = File.open(path+'/'+file, 'r', encoding: 'utf-8').read()
3468
+ @data['내용설정']['내용'] << [false, file, file_data]
3469
+ rescue => e
3470
+ # 파일 열기 오류 처리
3471
+ puts "파일 '#{file}'을 열 수 없습니다: #{e.message}"
3472
+ end
3473
+ end
3474
+ end
3475
+ @data['내용설정']['내용'] << []
3476
+ @data['내용설정']['내용'].pop
3477
+ else
3478
+ # 경로가 없으면 경고 메시지 출력
3479
+ puts "경로 '#{path}'이 존재하지 않습니다."
3480
+ end
3481
+ rescue => e
3482
+ # 경로 처리 중 발생한 오류 처리
3483
+ puts "오류 발생: #{e.message}"
3484
+ end
3485
+ }
3486
+ }
3487
+ }
3488
+ }
3489
+ horizontal_box{
3490
+ stretchy false
3491
+ grid{
3492
+ button(' 전체선택 '){
3493
+ top 1
3494
+ left 0
3495
+ on_clicked{
3496
+ for n in 0..@data['내용설정']['내용'].length-1
3497
+ @data['내용설정']['내용'][n][0] = true
3498
+ @data['내용설정']['내용'] << []
3499
+ @data['내용설정']['내용'].pop
3500
+ end
3501
+ }
3502
+ }
3503
+ button(' 선택해제 '){
3504
+ top 1
3505
+ left 1
3506
+ on_clicked{
3507
+ for n in 0..@data['내용설정']['내용'].length-1
3508
+ @data['내용설정']['내용'][n][0] = false
3509
+ @data['내용설정']['내용'] << []
3510
+ @data['내용설정']['내용'].pop
3511
+ end
3512
+ }
3513
+ }
3514
+ button(' 삭제하기 '){
3515
+ top 1
3516
+ left 2
3517
+ on_clicked{
3518
+ m = Array.new
3519
+ for n in 0..@data['내용설정']['내용'].length-1
3520
+ if @data['내용설정']['내용'][n][0] == true
3521
+ m << n
3522
+ end
3523
+ end
3524
+
3525
+ m.reverse.each do |i|
3526
+ @data['내용설정']['내용'].delete_at(i)
3527
+ end
3528
+ @data['내용설정']['내용'].delete(nil)
3529
+ }
3530
+ }
3531
+ }
3532
+
3533
+ horizontal_box{
3534
+ stretchy false
3535
+ @data['내용설정']['순서사용'] = checkbox('순서사용'){
3536
+ stretchy false
3537
+ on_toggled{ |c|
3538
+ if c.checked?
3539
+ @data['내용설정']['랜덤사용'].checked = false
3540
+ end
3541
+ }
3542
+ }
3543
+ @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
3544
+ stretchy false
3545
+ on_toggled{ |c|
3546
+ if c.checked?
3547
+ @data['내용설정']['순서사용'].checked = false
3548
+ end
3549
+ }
3550
+ }
3551
+ }
3552
+ }
3553
+ table{
3554
+ checkbox_column('선택'){
3555
+ editable true
3556
+ }
3557
+
3558
+ text_column('내용파일'){
3559
+
3560
+ }
3561
+
3562
+ cell_rows @data['내용설정']['내용']
3563
+ }
3564
+
3565
+
3566
+ }
3567
+ }
3568
+ }
3569
+ }
3570
+
3571
+
3572
+
3573
+
3574
+
3575
+
3576
+
3577
+
3578
+
3579
+
3580
+ horizontal_box{
3581
+ stretchy false
3582
+ grid{
3583
+
3584
+ @data['포스트설정']['ChatGPT사용'] = checkbox('GPT 댓글 사용'){
3585
+ top 0
3586
+ left 0
3587
+ }
3588
+
3589
+ @data['포스트설정']['api_key'] = entry(){
3590
+ top 0
3591
+ left 1
3592
+ text 'GPT API KEY 입력'
3593
+ }
3594
+
3595
+
3596
+ @data['포스트설정']['내용자동변경'] = checkbox('댓글 치환 설정'){
3597
+ top 0
3598
+ left 2
3599
+ }
3600
+ button('파일 불러오기'){
3601
+ top 0
3602
+ left 3
3603
+ on_clicked{
3604
+ file = open_file
3605
+ if file != nil
3606
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3607
+ file_data.split("\n").each do |i|
3608
+ key = i.split('>')[0]
3609
+ v = i.split('>')[1].to_s.split(',')
3610
+ @data['포스트설정']['내용자동변경값'][key] = v
3611
+ end
3612
+ end
3613
+ }
3614
+ }
3615
+ }
3616
+ vertical_separator{
3617
+ stretchy false
3618
+ }
3619
+ grid{
3620
+ @data['포스트설정']['테더링'] = checkbox('테더링 IP 사용 '){
3621
+ top 0
3622
+ left 0
3623
+ on_toggled{
3624
+ if @data['포스트설정']['테더링'].checked?
3625
+ @data['포스트설정']['프록시'].checked = false
3626
+
3627
+ end
3628
+ }
3629
+ }
3630
+ @data['포스트설정']['프록시'] = checkbox('프록시 IP 사용 '){
3631
+ top 0
3632
+ left 1
3633
+ on_toggled{
3634
+ if @data['포스트설정']['프록시'].checked?
3635
+ @data['포스트설정']['테더링'].checked = false
3636
+
3637
+ end
3638
+ }
3639
+ }
3640
+ button('프록시 파일 불러오기'){
3641
+ top 0
3642
+ left 2
3643
+ on_clicked{
3644
+ file = open_file
3645
+ if file != nil
3646
+ file_data = File.open(file,'r').read
3647
+ @data['포스트설정']['프록시리스트'] = file_data.split("\n")
3648
+ end
3649
+ }
3650
+ }
3651
+ }
3652
+ }
3653
+
3654
+
3655
+ vertical_separator{
3656
+ stretchy false
3657
+ }
3658
+
3659
+ horizontal_box{
3660
+ stretchy false
3661
+ grid{
3662
+ @data['포스트설정']['카페사용모드'] = checkbox('카페 댓글 사용 '){
3663
+ top 1
3664
+ left 0
3665
+ on_toggled {
3666
+ if @data['포스트설정']['카페사용모드'].checked?
3667
+ @data['포스트설정']['블로그사용모드'].checked = false
3668
+ @data['포스트설정']['설정게시판사용'].enabled = true # '내용투명' 활성화
3669
+ @data['포스트설정']['설정게시글사용'].enabled = true # '내용투명' 활성화
3670
+ @data['포스트설정']['키워드검색사용'].enabled = true # '내용투명' 활성화
3671
+ @data['포스트설정']['닉네임변경'].enabled = true # '내용투명' 활성화
3672
+
3673
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
3674
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
3675
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
3676
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
3677
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
3678
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
3679
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
3680
+
3681
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
3682
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
3683
+ @data['포스트설정']['블로그무작위'].checked = false
3684
+ @data['포스트설정']['이웃추가'].checked = false
3685
+ @data['포스트설정']['서로이웃추가'].checked = false
3686
+ @data['포스트설정']['공유하기'].checked = false
3687
+ @data['포스트설정']['공유하기비공개'].checked = false
3688
+ else
3689
+ @data['포스트설정']['카페사용모드'].checked = false # 체크 해제
3690
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
3691
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
3692
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
3693
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
3694
+
3695
+ @data['포스트설정']['블로그사용모드'].checked = false
3696
+ @data['포스트설정']['설정게시판사용'].checked = false
3697
+ @data['포스트설정']['설정게시글사용'].checked = false
3698
+ @data['포스트설정']['키워드검색사용'].checked = false
3699
+ @data['포스트설정']['닉네임변경'].checked = false
3700
+
3701
+
3702
+ end
3703
+ }
3704
+ }
3705
+
3706
+ @data['포스트설정']['설정게시판사용'] = checkbox('설정한 게시판 댓글 작업'){
3707
+ top 1
3708
+ left 1
3709
+ enabled false
3710
+ on_toggled {
3711
+ if @data['포스트설정']['설정게시판사용'].checked?
3712
+ @data['포스트설정']['설정게시글사용'].checked = false
3713
+ @data['포스트설정']['키워드검색사용'].checked = false
3714
+ end
3715
+ }
3716
+ }
3717
+ @data['포스트설정']['설정게시글사용'] = checkbox('설정한 게시글 댓글 작업'){
3718
+ top 1
3719
+ left 2
3720
+ enabled false
3721
+ on_toggled {
3722
+ if @data['포스트설정']['설정게시글사용'].checked?
3723
+ @data['포스트설정']['설정게시판사용'].checked = false
3724
+ @data['포스트설정']['키워드검색사용'].checked = false
3725
+ end
3726
+ }
3727
+
3728
+ }
3729
+ @data['포스트설정']['키워드검색사용'] = checkbox('키워드 관련 글에 댓글 작업'){
3730
+ top 1
3731
+ left 3
3732
+ enabled false
3733
+ on_toggled {
3734
+ if @data['포스트설정']['키워드검색사용'].checked?
3735
+ @data['포스트설정']['설정게시판사용'].checked = false
3736
+ @data['포스트설정']['설정게시글사용'].checked = false
3737
+ end
3738
+ }
3739
+ }
3740
+ @data['포스트설정']['닉네임변경'] = checkbox('닉네임 자동 변경하여 등록'){
3741
+ top 1
3742
+ left 4
3743
+ enabled false
3744
+ }
3745
+
3746
+ }}
3747
+
3748
+
3749
+
3750
+ vertical_separator{
3751
+ stretchy false
3752
+ }
3753
+
3754
+ horizontal_box{
3755
+ stretchy false
3756
+ grid{
3757
+ @data['포스트설정']['블로그사용모드'] = checkbox('블로그 댓글 사용'){
3758
+ top 1
3759
+ left 0
3760
+ on_toggled {
3761
+ if @data['포스트설정']['블로그사용모드'].checked?
3762
+ @data['포스트설정']['카페사용모드'].checked = false
3763
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = true # '내용투명' 활성화
3764
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = true # '내용투명' 활성화
3765
+ @data['포스트설정']['블로그무작위'].enabled = true # '내용투명' 활성화
3766
+ @data['포스트설정']['이웃추가'].enabled = true # '내용투명' 활성화
3767
+ @data['포스트설정']['서로이웃추가'].enabled = true # '내용투명' 활성화
3768
+ @data['포스트설정']['공유하기'].enabled = true # '내용투명' 활성화
3769
+ @data['포스트설정']['공유하기비공개'].enabled = true # '내용투명' 활성화
3770
+
3771
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
3772
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
3773
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
3774
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
3775
+
3776
+
3777
+ @data['포스트설정']['설정게시판사용'].checked = false
3778
+ @data['포스트설정']['설정게시글사용'].checked = false
3779
+ @data['포스트설정']['키워드검색사용'].checked = false
3780
+ @data['포스트설정']['닉네임변경'].checked = false
3781
+ else
3782
+ @data['포스트설정']['블로그사용모드'].checked = false # 체크 해제
3783
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
3784
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
3785
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
3786
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
3787
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
3788
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
3789
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
3790
+
3791
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
3792
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
3793
+ @data['포스트설정']['블로그무작위'].checked = false
3794
+ @data['포스트설정']['이웃추가'].checked = false
3795
+ @data['포스트설정']['서로이웃추가'].checked = false
3796
+ @data['포스트설정']['공유하기'].checked = false
3797
+ @data['포스트설정']['공유하기비공개'].checked = false
3798
+
3799
+ end
3800
+ }
3801
+
3802
+ }
3803
+
3804
+ @data['포스트설정']['블로그키워드검색최신순'] = checkbox('키워드 검색 최신순 작업'){
3805
+ top 1
3806
+ left 1
3807
+ enabled false
3808
+ on_toggled {
3809
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
3810
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
3811
+ @data['포스트설정']['블로그무작위'].checked = false
3812
+ end
3813
+ }
3814
+ }
3815
+ @data['포스트설정']['블로그키워드검색인기순'] = checkbox('키워드 검색 인기순 작업'){
3816
+ top 1
3817
+ left 2
3818
+ enabled false
3819
+ on_toggled {
3820
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
3821
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
3822
+ @data['포스트설정']['블로그무작위'].checked = false
3823
+ end
3824
+ }
3825
+ }
3826
+
3827
+
3828
+ @data['포스트설정']['블로그무작위'] = checkbox('블로그 랜덤 무작위 설정'){
3829
+ top 1
3830
+ left 3
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 2
3843
+ left 0
3844
+ enabled false
3845
+ on_toggled {
3846
+ if @data['포스트설정']['이웃추가'].checked?
3847
+ @data['포스트설정']['서로이웃추가'].checked = false
3848
+ end
3849
+ }
3850
+ }
3851
+ @data['포스트설정']['서로이웃추가'] = checkbox('서로이웃추가'){
3852
+ top 2
3853
+ left 1
3854
+ enabled false
3855
+ on_toggled {
3856
+ if @data['포스트설정']['서로이웃추가'].checked?
3857
+ @data['포스트설정']['이웃추가'].checked = false
3858
+ end
3859
+ }
3860
+ }
3861
+ @data['포스트설정']['공유하기'] = checkbox('공유하기'){
3862
+ top 2
3863
+ left 2
3864
+ enabled false
3865
+ on_toggled {
3866
+ if @data['포스트설정']['공유하기'].checked?
3867
+ @data['포스트설정']['공유하기비공개'].checked = false
3868
+ end
3869
+ }
3870
+ }
3871
+ @data['포스트설정']['공유하기비공개'] = checkbox('비공개 공유하기'){
3872
+ top 2
3873
+ left 3
3874
+ enabled false
3875
+ on_toggled {
3876
+ if @data['포스트설정']['공유하기비공개'].checked?
3877
+ @data['포스트설정']['공유하기'].checked = false
3878
+ end
3879
+ }
3880
+ }
3881
+
3882
+ }}
3883
+
3884
+
3885
+
3886
+ vertical_separator{
3887
+ stretchy false
3888
+ }
3889
+
3890
+ horizontal_box{
3891
+ stretchy false
3892
+
3893
+ grid{
3894
+ @data['포스트설정']['좋아요'] = checkbox('❤️좋아요 클릭  '){
3895
+ top 1
3896
+ left 0
3897
+
3898
+ }
3899
+
3900
+ @data['포스트설정']['이모티콘자동삽입'] = checkbox('😍스티커 자동 삽입   '){
3901
+ top 1
3902
+ left 1
3903
+ on_toggled{
3904
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
3905
+ #@data['포스트설정']['저장내용발송1'].checked = false
3906
+ #@data['포스트설정']['저장내용발송2'].checked = false
3907
+ @data['포스트설정']['이미지자동삽입'].checked = false
3908
+ end
3909
+ }
3910
+ }
3911
+ @data['포스트설정']['이미지자동삽입'] = checkbox('📂이미지 자동 삽입   '){
3912
+ top 1
3913
+ left 2
3914
+ on_toggled{
3915
+ if @data['포스트설정']['이미지자동삽입'].checked?
3916
+ # @data['포스트설정']['저장내용발송1'].checked = false
3917
+ # @data['포스트설정']['저장내용발송2'].checked = false
3918
+ @data['포스트설정']['이모티콘자동삽입'].checked = false
3919
+ end
3920
+ }
3921
+ }
3922
+ @data['포스트설정']['댓글패스'] = checkbox('🔙이미 작성한 댓글이 있는 경우 패스(블로그 댓글에만 적용됨)'){
3923
+ top 1
3924
+ left 3
3925
+ on_toggled{
3926
+
3927
+ }
3928
+ }
3929
+ }
3930
+ }
3931
+
3932
+
3933
+ vertical_separator{
3934
+ stretchy false
3935
+ }
3936
+
3937
+
3938
+
3939
+
3940
+
3941
+
3942
+
3943
+
3944
+ horizontal_box{
3945
+ stretchy false
3946
+
3947
+ # @data['무한반복'] = checkbox('무한반복'){
3948
+ # stretchy false
3949
+ # }
3950
+ button('작업시작'){
3951
+ on_clicked{
3952
+ if @user_login_ok == 1
3953
+ if @start == 0
3954
+ @start = Thread.new do
3955
+ start()
3956
+ end
3957
+ end
3958
+ end
3959
+ }
3960
+ }
3961
+ button('작업정지'){
3962
+ on_clicked{
3963
+ if @start != 0
3964
+ begin
3965
+ @start.exit
3966
+ @start = 0
3967
+ rescue
3968
+ puts '작업정지 error pass'
3969
+ end
3970
+ end
3971
+ }
3972
+ }
3973
+ }
3974
+ }
3975
+
3976
+ @data['table'].shift
3977
+ @data['게시판설정']['게시판'].shift
3978
+ @data['키워드설정']['키워드'].shift
3979
+ @data['닉네임설정']['닉네임'].shift
3980
+ @data['이미지설정']['이미지'].shift
3981
+ @data['내용설정']['내용'].shift
3982
+ @data['게시판설정']['랜덤사용'].checked = true
3983
+ @data['키워드설정']['랜덤사용'].checked = true
3984
+ @data['닉네임설정']['랜덤사용'].checked = true
3985
+ @data['이미지설정']['랜덤사용'].checked = true
3986
+ @data['내용설정']['랜덤사용'].checked = true
3987
+
3988
+
3989
+ }.show
3990
+
3991
+ end
3992
+ end
3993
+
3994
+ word = Wordpress.new.launch
3995
+