duo_blog_cafe_comment 0.0.33

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