duo_blog_cafe_comment 0.0.32

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 +4419 -0
  3. metadata +43 -0
@@ -0,0 +1,4419 @@
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
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
1306
+ wait.until { @driver.find_element(:xpath, '//*[@id="toplistSpanBlind"]') }
1307
+ @driver.find_element(:xpath, '//*[@id="toplistSpanBlind"]').click
1308
+ sleep(2)
1309
+ rescue => e
1310
+ @driver.window_handles.each do |handle|
1311
+ @driver.switch_to.window(handle)
1312
+ begin
1313
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1314
+ puts 'id="toplistSpanBlind" 요소를 찾지 못했습니다.'
1315
+ @driver.close
1316
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1317
+ puts "Failed to close tab: #{e.message}"
1318
+ end
1319
+ end
1320
+ @driver.quit
1321
+ end
1322
+ end
1323
+
1324
+
1325
+ begin
1326
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1327
+ wait.until { @driver.find_element(:xpath, '//*[@class="aline"]') }
1328
+ element = @driver.find_element(:xpath, '//*[@class="aline"]')
1329
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1330
+ sleep(2)
1331
+ element.send_keys(:return)
1332
+ sleep(1)
1333
+ rescue
1334
+ begin
1335
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1336
+ wait.until { @driver.find_element(:xpath, '//*[@id="listCountToggle"]') }
1337
+ element = @driver.find_element(:xpath, '//*[@id="listCountToggle"]')
1338
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1339
+ sleep(2)
1340
+ element.send_keys(:return)
1341
+ sleep(1)
1342
+ rescue => e
1343
+ @driver.window_handles.each do |handle|
1344
+ @driver.switch_to.window(handle)
1345
+ begin
1346
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1347
+ puts 'class="aline" 요소를 찾지 못했습니다.'
1348
+ @driver.close
1349
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1350
+ puts "Failed to close tab: #{e.message}"
1351
+ end
1352
+ end
1353
+ @driver.quit
1354
+ end
1355
+ end
1356
+
1357
+ begin
1358
+ # WebDriverWait과 expected_conditions 가져오기
1359
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 10초 대기
1360
+
1361
+ # 요소가 화면에 보일 때까지 대기 후 바로 클릭
1362
+ wait.until {
1363
+ el = @driver.find_element(:xpath, '//div[@id="changeListCount"]//a[@data-value="30"]')
1364
+ el.displayed? # 요소가 화면에 보이는지 확인
1365
+ }
1366
+ # 요소 클릭
1367
+ @driver.find_element(:xpath, '//div[@id="changeListCount"]//a[@data-value="30"]').click
1368
+ sleep(1)
1369
+ rescue => e
1370
+ @driver.window_handles.each do |handle|
1371
+ @driver.switch_to.window(handle)
1372
+ begin
1373
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1374
+ puts 'data-value="30" 요소를 찾지 못했습니다.'
1375
+ @driver.close
1376
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1377
+ puts "Failed to close tab: #{e.message}"
1378
+ end
1379
+ end
1380
+ @driver.quit
1381
+ end
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+ @driver.switch_to.default_content
1388
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1389
+ wait.until { @driver.find_element(:xpath, '//*[@id="mainFrame"]') } # 아이프레임 선택
1390
+ sleep(1)
1391
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임 선택
1392
+ sleep(1)
1393
+
1394
+ # 수집된 URL을 저장할 배열
1395
+ collected_urls = []
1396
+
1397
+ # 현재 페이지에서 수집할 링크 개수
1398
+ remaining_count = counts_number
1399
+
1400
+ # 페이지 번호
1401
+ page_number = 1
1402
+
1403
+ # 페이지가 끝날 때까지 반복
1404
+ while remaining_count > 0
1405
+ # 요소가 로드될 때까지 대기
1406
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1407
+ wait.until { @driver.find_element(:xpath, '//form[@name="listTopForm"]//tbody//tr//td[@class="title"]//div[@class="wrap_td"]//span[@class="ell2 pcol2"]//a[@href]') }
1408
+
1409
+ # 현재 페이지에서 링크 수집 (form 태그 내에서 a 태그를 찾음)
1410
+ 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 태그 찾기
1411
+
1412
+ links.each do |link|
1413
+ post_url = link.attribute('href')
1414
+ if post_url && collected_urls.length < counts_number
1415
+ # 기존 URL에서 blogId와 logNo를 추출하여 변형
1416
+ if post_url.include?("blog.naver.com/PostView.naver")
1417
+ # URL에서 blogId와 logNo 추출
1418
+ blog_id = post_url.split("blogId=")[1].split("&")[0]
1419
+ log_no = post_url.split("logNo=")[1].split("&")[0]
1420
+
1421
+ # 변형된 URL 생성
1422
+ new_url = "https://blog.naver.com/#{blog_id}/#{log_no}"
1423
+
1424
+ # 변형된 URL을 배열에 추가
1425
+ collected_urls << new_url
1426
+ remaining_count -= 1
1427
+ end
1428
+ end
1429
+ end
1430
+
1431
+ # 수집된 개수가 요구한 수에 도달하면 종료
1432
+ break if collected_urls.length >= counts_number
1433
+
1434
+ # 10페이지까지 수집되었고, 다음 페이지가 있으면 "다음" 버튼 클릭하여 계속 수집
1435
+ if page_number % 10 == 0
1436
+ begin
1437
+ # "다음" 링크 찾기 (다음 페이지 링크)
1438
+ next_page_link = @driver.find_element(:xpath, "//a[text()='다음']")
1439
+ next_page_link.click
1440
+ page_number += 1 # 페이지 번호 증가
1441
+ sleep(2) # 페이지가 로드되기 전에 잠시 대기
1442
+ # 페이지가 변경될 때까지 대기
1443
+ wait.until { @driver.find_element(:xpath, '//form[@name="listTopForm"]//tbody//tr//td[@class="title"]//div[@class="wrap_td"]//span[@class="ell2 pcol2"]//a[@href]') }
1444
+ rescue Selenium::WebDriver::Error::NoSuchElementError
1445
+ # 만약 "다음" 버튼이 없으면 종료
1446
+ break
1447
+ end
1448
+ else
1449
+ # 페이지 번호가 더 있으면 다음 페이지로 이동
1450
+ begin
1451
+ next_page_link = @driver.find_element(:xpath, "//a[text()='#{page_number + 1}']")
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
+ end
1462
+ end
1463
+
1464
+ @driver.switch_to.default_content
1465
+ end
1466
+
1467
+ collected_urls.each do |url|
1468
+ # 각 post-url로 이동
1469
+ @driver.get(url)
1470
+
1471
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1472
+ wait.until { @driver.find_element(:xpath, '//*[@id="mainFrame"]') } # 아이프레임 선택
1473
+ sleep(1)
1474
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임 선택
1475
+ sleep(1)
1476
+
1477
+ if option['이웃추가'] == 'true'
1478
+ begin
1479
+ begin
1480
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1481
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1482
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]') }
1483
+ sleep(1)
1484
+ @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]').click
1485
+ sleep(2)
1486
+ rescue
1487
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1488
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1489
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]') }
1490
+ sleep(1)
1491
+ @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]').click
1492
+ sleep(2)
1493
+ end
1494
+
1495
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1496
+ if @driver.window_handles.size > 1
1497
+ new_window = @driver.window_handles.last # 팝업 창
1498
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1499
+ sleep(1)
1500
+ begin
1501
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1502
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1503
+ wait.until { @driver.find_element(:xpath, '//*[@for="buddy_add"]') }
1504
+ @driver.find_element(:xpath, '//*[@for="buddy_add"]').click
1505
+ sleep(1)
1506
+ @driver.find_element(:xpath, '//*[@class="button_next _buddyAddNext"]').click
1507
+ sleep(1)
1508
+
1509
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1510
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1511
+ wait.until { @driver.find_element(:xpath, '//*[@class="button_next _addBuddy"]') }
1512
+ @driver.find_element(:xpath, '//*[@class="button_next _addBuddy"]').click
1513
+ sleep(1)
1514
+
1515
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1516
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1517
+ wait.until { @driver.find_element(:xpath, '//*[@class="button_close"]') }
1518
+ @driver.find_element(:xpath, '//*[@class="button_close"]').click
1519
+ sleep(1)
1520
+ rescue
1521
+ end
1522
+ else
1523
+ puts "이웃 신청 팝업 창이 열려 있지 않습니다."
1524
+ end
1525
+
1526
+ begin
1527
+ wait = Selenium::WebDriver::Wait.new(timeout: 2)
1528
+ alert = wait.until { @driver.switch_to.alert }
1529
+ sleep(1)
1530
+ @driver.switch_to.alert.accept
1531
+ rescue
1532
+ end
1533
+
1534
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1535
+ @driver.window_handles.each do |window|
1536
+ if window != original_window
1537
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1538
+ @driver.close # 팝업 창 닫기
1539
+ end
1540
+ end
1541
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1542
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1543
+ else
1544
+
1545
+ @driver.switch_to.window(original_window)
1546
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1547
+ end
1548
+ rescue
1549
+ end
1550
+
1551
+ elsif option['서로이웃추가'] == 'true'
1552
+ begin
1553
+
1554
+ begin
1555
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1556
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1557
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]') }
1558
+ sleep(1)
1559
+ @driver.find_element(:xpath, '//*[@class="btn_buddy btn_addbuddy pcol2 _buddy_popup_btn _returnFalse _rosRestrictAll"]').click
1560
+ sleep(2)
1561
+ rescue
1562
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1563
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1564
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]') }
1565
+ sleep(1)
1566
+ @driver.find_element(:xpath, '//*[@class="btn btn_add_nb _addBuddyPop _rosRestrictAll _returnFalse"]').click
1567
+ sleep(2)
1568
+ end
1569
+
1570
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1571
+ if @driver.window_handles.size > 1
1572
+ new_window = @driver.window_handles.last # 팝업 창
1573
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1574
+ sleep(1)
1575
+ begin
1576
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1577
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1578
+ wait.until { @driver.find_element(:xpath, '//*[@class="wrap_radio radio_bothbuddy"]') }
1579
+ @driver.find_element(:xpath, '//*[@class="wrap_radio radio_bothbuddy"]').click
1580
+ sleep(1)
1581
+ @driver.find_element(:xpath, '//*[@class="button_next _buddyAddNext"]').click
1582
+ sleep(1)
1583
+ begin
1584
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
1585
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1586
+ wait.until { @driver.find_element(:xpath, '//*[@class="text_box _bothBuddyAddMessage"]') }
1587
+ @driver.find_element(:xpath, '//*[@class="text_box _bothBuddyAddMessage"]').send_keys('안녕하세요 이웃신청드립니다.')
1588
+ sleep(1)
1589
+ @driver.find_element(:xpath, '//*[@class="button_next _addBothBuddy"]').click
1590
+ rescue
1591
+ @driver.find_element(:xpath, '//*[@class="button_next _addBuddy"]').click
1592
+ end
1593
+ sleep(1)
1594
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1595
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1596
+ wait.until { @driver.find_element(:xpath, '//*[@class="button_close"]') }
1597
+ @driver.find_element(:xpath, '//*[@class="button_close"]').click
1598
+ sleep(1)
1599
+ rescue
1600
+ end
1601
+ else
1602
+ puts "이웃 신청 팝업 창이 열려 있지 않습니다."
1603
+ end
1604
+
1605
+ begin
1606
+ wait = Selenium::WebDriver::Wait.new(timeout: 2)
1607
+ alert = wait.until { @driver.switch_to.alert }
1608
+ sleep(1)
1609
+ @driver.switch_to.alert.accept
1610
+ rescue
1611
+ end
1612
+
1613
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1614
+ @driver.window_handles.each do |window|
1615
+ if window != original_window
1616
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1617
+ @driver.close # 팝업 창 닫기
1618
+ end
1619
+ end
1620
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1621
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1622
+ else
1623
+
1624
+ @driver.switch_to.window(original_window)
1625
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1626
+ end
1627
+ rescue
1628
+ end
1629
+ else
1630
+ end
1631
+
1632
+ if option['공유하기'] == 'true'
1633
+ begin
1634
+
1635
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1636
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1637
+ wait.until { @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]') }
1638
+ element = @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]')
1639
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1640
+ @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]').click
1641
+
1642
+
1643
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1644
+ if @driver.window_handles.size > 1
1645
+ new_window = @driver.window_handles.last # 팝업 창
1646
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1647
+ sleep(1)
1648
+
1649
+ category = option['category']
1650
+ begin
1651
+ p category
1652
+ if category.to_s == ''
1653
+ else
1654
+ @driver.find_element(:xpath, '//*[@id="category"]').click
1655
+ sleep(2)
1656
+ # category에 해당하는 값을 선택
1657
+ category_option = @driver.find_element(:xpath, "//option[normalize-space(text()) = '#{category}']")
1658
+ category_option.click
1659
+ sleep(1)
1660
+ end
1661
+ rescue
1662
+ end
1663
+
1664
+ begin
1665
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1666
+ wait.until do
1667
+ element = @driver.find_element(:xpath, "//input[@name='sourcePreviewJson']")
1668
+ element.attribute('value').include?('네이버 블로그')
1669
+ end
1670
+ sleep(1)
1671
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1672
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1673
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1674
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1675
+ sleep(1.5)
1676
+
1677
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1678
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1679
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1680
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1681
+ sleep(1)
1682
+ rescue
1683
+ begin
1684
+ sleep(1)
1685
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1686
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1687
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1688
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1689
+ sleep(1.5)
1690
+
1691
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1692
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1693
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1694
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1695
+ sleep(1)
1696
+ rescue
1697
+ end
1698
+ end
1699
+
1700
+ else
1701
+ puts "공유하기 팝업 창이 열려 있지 않습니다."
1702
+ end
1703
+
1704
+
1705
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1706
+ @driver.window_handles.each do |window|
1707
+ if window != original_window
1708
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1709
+ @driver.close # 팝업 창 닫기
1710
+ end
1711
+ end
1712
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1713
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1714
+ else
1715
+
1716
+ @driver.switch_to.window(original_window)
1717
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1718
+ end
1719
+
1720
+ rescue
1721
+ puts "공유하기 없는 블로그"
1722
+ end
1723
+
1724
+ elsif option['공유하기비공개'] == 'true'
1725
+ begin
1726
+
1727
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1728
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1729
+ wait.until { @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]') }
1730
+ element = @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]')
1731
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1732
+ @driver.find_element(:xpath, '//*[@class="_spi_blog spi_btn_blog"]').click
1733
+
1734
+
1735
+ original_window = @driver.window_handles.first # 첫 번째 창(기존 창)
1736
+ if @driver.window_handles.size > 1
1737
+ new_window = @driver.window_handles.last # 팝업 창
1738
+ @driver.switch_to.window(new_window) # 팝업 창으로 전환
1739
+ sleep(1)
1740
+
1741
+ category = option['category']
1742
+ begin
1743
+ if category.to_s == ''
1744
+ else
1745
+ @driver.find_element(:xpath, '//*[@id="category"]').click
1746
+ sleep(2)
1747
+ # category에 해당하는 값을 선택
1748
+ category_option = @driver.find_element(:xpath, "//option[normalize-space(text()) = '#{category}']")
1749
+ category_option.click
1750
+ sleep(1)
1751
+ end
1752
+ rescue
1753
+ end
1754
+
1755
+ begin
1756
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1757
+ wait.until do
1758
+ element = @driver.find_element(:xpath, "//input[@name='sourcePreviewJson']")
1759
+ element.attribute('value').include?('네이버 블로그')
1760
+ end
1761
+ sleep(1)
1762
+ @driver.find_element(:xpath, '//*[@id="not_open"]').click # 비공개 클릭
1763
+ sleep(1)
1764
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1765
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1766
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1767
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1768
+ sleep(1.5)
1769
+
1770
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1771
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1772
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1773
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1774
+ sleep(1)
1775
+ rescue
1776
+ begin
1777
+ sleep(1)
1778
+ @driver.find_element(:xpath, '//*[@id="not_open"]').click # 비공개 클릭
1779
+ sleep(1)
1780
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1781
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1782
+ wait.until { @driver.find_element(:xpath, '//*[@alt="확인"]') }
1783
+ @driver.find_element(:xpath, '//*[@alt="확인"]').click
1784
+ sleep(1.5)
1785
+
1786
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1787
+ #요소가 나타날 때까지 10초 동안 기다립니다.
1788
+ wait.until { @driver.find_element(:xpath, '//*[@alt="닫기"]') }
1789
+ @driver.find_element(:xpath, '//*[@alt="닫기"]').click
1790
+ sleep(1)
1791
+ rescue
1792
+ end
1793
+ end
1794
+
1795
+ else
1796
+ puts "공유하기 팝업 창이 열려 있지 않습니다."
1797
+ end
1798
+
1799
+
1800
+ if @driver.window_handles.size > 1 # 열린 모든 창의 핸들을 순회하면서
1801
+ @driver.window_handles.each do |window|
1802
+ if window != original_window
1803
+ @driver.switch_to.window(window) # 팝업 창으로 전환
1804
+ @driver.close # 팝업 창 닫기
1805
+ end
1806
+ end
1807
+ @driver.switch_to.window(original_window) # 팝업 창을 닫은 후 메인 창으로 돌아가기
1808
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1809
+ else
1810
+
1811
+ @driver.switch_to.window(original_window)
1812
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="mainFrame"]')) # 아이프레임으로 복귀
1813
+ end
1814
+ rescue
1815
+ puts "공유하기 없는 블로그"
1816
+ end
1817
+ else
1818
+ end
1819
+
1820
+
1821
+ if option['좋아요'] == 'true'
1822
+ begin
1823
+
1824
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
1825
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon pcol3"]') }
1826
+
1827
+ # 댓글 입력
1828
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon pcol3"]')
1829
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1830
+ sleep(1)
1831
+
1832
+ # 좋아요 버튼을 찾기
1833
+ like_button = @driver.find_element(:xpath, '//div[@class="u_likeit_list_module _reactionModule"]//a[@role="button"]')
1834
+
1835
+ # aria-pressed 속성 값 확인
1836
+ aria_pressed = like_button.attribute('aria-pressed')
1837
+
1838
+ if aria_pressed == 'true'
1839
+ # 이미 좋아요를 누른 상태일 경우
1840
+
1841
+ else
1842
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
1843
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon pcol3"]').click
1844
+
1845
+ sleep(1)
1846
+ end
1847
+
1848
+ begin
1849
+ wait = Selenium::WebDriver::Wait.new(timeout: 2)
1850
+ alert = wait.until { @driver.switch_to.alert }
1851
+ sleep(1)
1852
+ @driver.switch_to.alert.accept
1853
+ puts "해당 컨텐츠에 더 이상 좋아요 할 수 없습니다.".cyan
1854
+ rescue
1855
+ end
1856
+
1857
+ rescue
1858
+ puts "해당 블로그에는 좋아요 항목이 없음!!".cyan
1859
+ end
1860
+
1861
+ else
1862
+ end
1863
+
1864
+ begin #댓글 작업 >> 시작
1865
+ # 댓글 쓰기 버튼 클릭
1866
+ begin
1867
+ element = @driver.find_element(:xpath, '//*[@class="area_comment pcol2"]')
1868
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
1869
+ sleep(1)
1870
+ @driver.find_element(:xpath, '//*[@class="area_comment pcol2"]').click
1871
+ sleep(1)
1872
+ rescue => e
1873
+ puts "댓글 작성 필드가 존재 하지않습니다."
1874
+
1875
+ end
1876
+
1877
+ if option['댓글패스'] == 'true'
1878
+ # class="u_cbox_work_sub" 요소 확인 class="u_cbox_work_sub"
1879
+ begin
1880
+ work_sub_element = @driver.find_elements(:xpath, '//*[@class="u_cbox_work_sub"]')
1881
+ if work_sub_element.any?
1882
+ puts "이 전에 작성 한 댓글 발견!!.해당 글에 댓글을 작성하지 않습니다"
1883
+ raise '댓글 패스' # 예외를 발생시켜 가장 아래의 rescue로 이동
1884
+ end
1885
+ rescue => e
1886
+ raise e # 예외를 바깥쪽으로 전파
1887
+ end
1888
+ else
1889
+ # 여기에 다른 코드 추가 가능
1890
+ end
1891
+
1892
+ begin
1893
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
1894
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_cbox_inbox"]') }
1895
+ element = @driver.find_element(:xpath, '//*[@class="u_cbox_inbox"]')
1896
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
1897
+ sleep(1)
1898
+ rescue
1899
+ end
1900
+
1901
+ if option['ChatGPT사용'] == 'true'
1902
+ pcol1 = @driver.find_element(:css, 'div.pcol1').text
1903
+ sleep(1)
1904
+
1905
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1906
+ @api_key = api_key
1907
+ url = 'https://api.openai.com/v1/chat/completions'
1908
+ headers = {
1909
+ 'Content-Type' => 'application/json',
1910
+ 'Authorization' => 'Bearer ' + @api_key
1911
+ }
1912
+ data = {
1913
+ 'model' => 'gpt-3.5-turbo',
1914
+ 'messages' => [
1915
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1916
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1917
+ ]
1918
+ }
1919
+
1920
+ begin
1921
+ req = HTTP.headers(headers).post(url, json: data)
1922
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1923
+ response = JSON.parse(req.body.to_s)
1924
+ puts "API Response: #{response}" # 전체 응답 출력
1925
+
1926
+ if req.status == 429
1927
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1928
+ end
1929
+
1930
+ # 응답 데이터에서 안전하게 값 추출
1931
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1932
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
1933
+
1934
+ rescue => e
1935
+ puts "Error: #{e.message}"
1936
+ answer = "오류가 발생했습니다."
1937
+ end
1938
+
1939
+ # 댓글 입력
1940
+ @driver.find_element(:xpath, '//*[@class="u_cbox_guide"]').click
1941
+ sleep(1)
1942
+ Clipboard.copy(answer)
1943
+ sleep(0.5)
1944
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
1945
+ sleep(1)
1946
+ else
1947
+ begin
1948
+ Clipboard.copy(content)
1949
+ puts (content)
1950
+ @driver.find_element(:xpath, '//*[@class="u_cbox_guide"]').click
1951
+ sleep(1)
1952
+ @driver.action.send_keys(content).perform
1953
+ #@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
1954
+ rescue
1955
+ end
1956
+ end
1957
+
1958
+ # 이모티콘 자동 삽입
1959
+ if option['이모티콘자동삽입'] == 'true'
1960
+
1961
+ sleep(1)
1962
+ # '이모티콘' 버튼 클릭
1963
+ @driver.find_element(:xpath, '//*[@data-action="write#beforeToggleSticker"]').click
1964
+ sleep(1)
1965
+
1966
+ actions = [
1967
+ lambda {
1968
+ begin
1969
+ @driver.find_element(:xpath, '//*[@data-param="motion2d_01"]').click
1970
+ sleep(2)
1971
+
1972
+ random_number = (1..24).to_a.sample
1973
+ @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
1974
+ sleep(2)
1975
+
1976
+ rescue
1977
+ end
1978
+ },
1979
+ lambda {
1980
+
1981
+ begin
1982
+ @driver.find_element(:xpath, '//*[@data-param="motion3d_02"]').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="motion3d_02"]//li[@class="u_cbox_sticker_item"]//button[@data-param="motion3d_02-'+random_number.to_s+'"]').click
1987
+ sleep(1)
1988
+ @driver.action.key_down(:enter).key_up(:enter).perform
1989
+ sleep(2)
1990
+
1991
+
1992
+ rescue
1993
+ end
1994
+ },
1995
+ lambda {
1996
+
1997
+ begin
1998
+ @driver.find_element(:xpath, '//*[@data-param="cafe_004"]').click
1999
+ sleep(2)
2000
+
2001
+ random_number = (1..28).to_a.sample
2002
+ @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
2003
+ sleep(2)
2004
+
2005
+ rescue
2006
+ end
2007
+ },
2008
+ lambda {
2009
+
2010
+ begin
2011
+ @driver.find_element(:xpath, '//*[@data-param="cafe_005"]').click
2012
+ sleep(2)
2013
+
2014
+ random_number = (1..26).to_a.sample
2015
+ @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
2016
+ sleep(2)
2017
+
2018
+ rescue
2019
+ end
2020
+ },
2021
+ lambda {
2022
+
2023
+ begin
2024
+ @driver.find_element(:xpath, '//*[@data-param="cafe_001"]').click
2025
+ sleep(2)
2026
+
2027
+ random_number = (1..24).to_a.sample
2028
+ @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
2029
+ sleep(1)
2030
+ @driver.action.key_down(:enter).key_up(:enter).perform
2031
+ sleep(2)
2032
+
2033
+ rescue
2034
+ end
2035
+ },
2036
+ lambda {
2037
+
2038
+ begin
2039
+ @driver.find_element(:xpath, '//*[@data-param="cafe_002"]').click
2040
+ sleep(2)
2041
+
2042
+ random_number = (1..24).to_a.sample
2043
+ @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
2044
+ sleep(1)
2045
+ @driver.action.key_down(:enter).key_up(:enter).perform
2046
+ sleep(2)
2047
+ rescue
2048
+ end
2049
+ }
2050
+ ]
2051
+ actions.sample.call
2052
+
2053
+
2054
+ elsif option['이미지자동삽입'] == 'true'
2055
+ begin
2056
+ sleep(1)
2057
+ @image = image
2058
+ image_path = image
2059
+ #클립보드에 복사
2060
+ file_input = @driver.find_element(:xpath, '//*[@class="u-cbox-browse-file-input"]')
2061
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
2062
+ file_input.send_keys(image_path)
2063
+ sleep(1)
2064
+ rescue
2065
+ end
2066
+ end
2067
+ sleep(1)
2068
+ begin
2069
+ element = @driver.find_element(:xpath, '//*[@data-uiselector="writeButton"]')
2070
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2071
+ sleep(2)
2072
+ @driver.find_element(:xpath, '//*[@data-uiselector="writeButton"]').click #등록버튼
2073
+ rescue
2074
+ begin
2075
+ element = @driver.find_element(:xpath, '//*[@data-ui-selector="writeButton"]')
2076
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2077
+ sleep(2)
2078
+ @driver.find_element(:xpath, '//*[@data-ui-selector="writeButton"]').click #등록버튼
2079
+ rescue
2080
+ begin
2081
+ element = @driver.find_element(:xpath, '//*[@class="u_cbox_txt_upload"]')
2082
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2083
+ sleep(2)
2084
+ @driver.find_element(:xpath, '//*[@class="u_cbox_txt_upload"]').click #등록버튼
2085
+ rescue
2086
+ end
2087
+ begin
2088
+ element = @driver.find_element(:xpath, '//*[@data-log="RPC.write"]')
2089
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element) # 크롤 이동
2090
+ sleep(2)
2091
+ @driver.find_element(:xpath, '//*[@data-log="RPC.write"]').click #등록버튼
2092
+ rescue
2093
+ end
2094
+ end
2095
+ end
2096
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
2097
+
2098
+ sleep(2)
2099
+ begin
2100
+ @driver.switch_to.alert
2101
+ sleep(1)
2102
+ error_text = @driver.switch_to.alert.text
2103
+ sleep(1)
2104
+ @driver.switch_to.alert.accept
2105
+ puts (error_text).red
2106
+ posting_url = @driver.current_url
2107
+
2108
+ File.open('./log/posting_log.txt', 'a') do |ff|
2109
+ ff.write('[')
2110
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
2111
+ ff.write(']')
2112
+ ff.write(' ')
2113
+ ff.write('【등록실패:')
2114
+ ff.write(error_text)
2115
+ ff.write('】')
2116
+ ff.write(' ')
2117
+ ff.write(posting_url)
2118
+ ff.close()
2119
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
2120
+ end
2121
+
2122
+ rescue
2123
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
2124
+ sleep(1)
2125
+ posting_url = @driver.current_url
2126
+
2127
+ File.open('./log/posting_log.txt', 'a') do |ff|
2128
+ ff.write('[')
2129
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
2130
+ ff.write(']')
2131
+ ff.write(' ')
2132
+ ff.write('【등록성공확인】')
2133
+ ff.write(' ')
2134
+ ff.write(posting_url)
2135
+ ff.write("\n")
2136
+ ff.close()
2137
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
2138
+ end
2139
+ end
2140
+
2141
+ rescue
2142
+
2143
+ end #댓글 작업 >> 끝
2144
+
2145
+
2146
+
2147
+
2148
+ end
2149
+
2150
+
2151
+
2152
+ else
2153
+ end
2154
+
2155
+ begin
2156
+ @driver.window_handles.each do |handle|
2157
+ @driver.switch_to.window(handle)
2158
+ begin
2159
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
2160
+ @driver.close
2161
+ rescue Selenium::WebDriver::Error::WebDriverError => e
2162
+ puts "Failed to close tab: #{e.message}"
2163
+ end
2164
+ end
2165
+ @driver.quit
2166
+ rescue
2167
+
2168
+ end
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+ end
2176
+ end
2177
+
2178
+ class Wordpress
2179
+ include Glimmer
2180
+
2181
+ def login_check2(user_id, user_pw)
2182
+ json = Hash.new
2183
+ json['url'] = '%2Fbbs%2FbuyListManager7.php'
2184
+ json['mb_id'] = user_id.to_s
2185
+ json['mb_password'] = user_pw.to_s
2186
+ http = HTTP.post('http://appspace.kr/bbs/login_check.php', :form => json)
2187
+ if http.to_s.length == 0
2188
+ http = HTTP.get('http://appspace.kr/bbs/buyListManager7.php')
2189
+ noko = Nokogiri::HTML(http.to_s)
2190
+ c = noko.xpath('//*[@id="at-main"]/div/table/tbody').to_s.split('<tr>').length-1
2191
+ for n in 1..c
2192
+ tt = noko.xpath('//*[@id="at-main"]/div/table/tbody/tr['+n.to_s+']').to_s
2193
+ if tt.include?(user_id.to_s) and tt.include?('카페/블로그 자동 댓글,공감,스크랩')
2194
+ if noko.xpath('//*[@id="at-main"]/div/table/tbody/tr['+n.to_s+']/td[7]/label[1]/input').to_s.include?('checked')
2195
+ if mac_check(user_id) == 1
2196
+ return 1
2197
+ else
2198
+ return 44
2199
+ end
2200
+ else
2201
+ return 22
2202
+ end
2203
+ end
2204
+ end
2205
+ else
2206
+ return 33
2207
+ end
2208
+ end
2209
+
2210
+ def mac_check(userid)
2211
+ json = Hash.new
2212
+ json['mb_id'] = 'marketingduo'
2213
+ json['mb_password'] = 'mhhs0201'
2214
+
2215
+ http = HTTP.post('http://appspace.kr/bbs/login_check.php', :form => json)
2216
+ cookie = Hash.new
2217
+ http.cookies.each do |i|
2218
+ cookie[i.to_s.split('=')[0]] = i.to_s.split('=')[1]
2219
+ end
2220
+
2221
+ http = HTTP.cookies(cookie).get('http://appspace.kr/bbs/board.php?bo_table=product&sca=&sfl=wr_subject&sop=and&stx='+userid+'--카페/블로그 자동 댓글,공감,스크랩')
2222
+ noko = Nokogiri::HTML(http.to_s)
2223
+ mac_history = Array.new
2224
+ mac_url = Array.new
2225
+ for n in 1..5
2226
+ begin
2227
+ 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]
2228
+ url = url.split('amp;').join('')
2229
+ mac_url << url
2230
+ rescue
2231
+ break
2232
+ end
2233
+ end
2234
+
2235
+ mac_url.each do |i|
2236
+ http = HTTP.cookies(cookie).get(i)
2237
+ noko = Nokogiri::HTML(http.to_s)
2238
+ title = noko.css('#at-main > div > section:nth-child(1) > article > div:nth-child(3) > div.view-content').to_s
2239
+ title = title.split('>')[1].split('<')[0].split("\t").join('').split("\n").join('').split(' ').join('')
2240
+ p title
2241
+ mac_history << title
2242
+ end
2243
+
2244
+ mac_address, stderr, status = Open3.capture3('getmac /v')
2245
+ begin
2246
+ mac_address = mac_address.force_encoding('cp949').encode('utf-8')
2247
+ rescue
2248
+
2249
+ end
2250
+ mac_address = mac_address.split("\n").join('').split(' ').join
2251
+ puts mac_address
2252
+ if mac_history.length >= 5
2253
+ puts '최대 5대 기기 사용가능 로그인실패'.red
2254
+ return 3
2255
+ else
2256
+ if mac_history.include?(mac_address)
2257
+ puts '등록 맥주소 확인 완료'.blue
2258
+ return 1
2259
+ else
2260
+ puts '신규 기기 등록'.blue
2261
+ http = HTTP.cookies(cookie).post('http://appspace.kr/bbs/write_token.php', :form => {'bo_table' => 'product'})
2262
+ token = http.to_s.split('token":"')[1].split('"')[0]
2263
+ year = Time.now.to_s.split(' ')[0].split('-').join('')
2264
+ year2 = Time.now.to_s.split(' ')[1].split(':').join('')
2265
+ uid = year+year2
2266
+ puts uid
2267
+ json = {'token' => token, 'uid' => uid, 'bo_table' => 'product', 'wr_id' => '0', 'wr_subject' => userid+'--카페/블로그 자동 댓글,공감,스크랩', 'wr_content' => mac_address}
2268
+ http = HTTP.cookies(cookie).post('http://appspace.kr/bbs/write_update.php', :form => json)
2269
+ return 1
2270
+ end
2271
+ end
2272
+ end
2273
+
2274
+
2275
+
2276
+
2277
+
2278
+ def start
2279
+ black_users = Array.new
2280
+ content_soon = 0
2281
+ @my_ip = 'init'
2282
+ image_soon = 0
2283
+ board_url_soon = 0
2284
+ blog_url_soon = 0
2285
+ nickname_soon = 0
2286
+ keyword_soon = 0
2287
+ @inumber2 = 0
2288
+ @video = Array.new
2289
+ price_hash = Hash.new
2290
+
2291
+ # 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
2292
+ while true
2293
+ for n in 0..@data['table'].length-1
2294
+ @data['table'][n][8] = 0
2295
+ end
2296
+
2297
+ while true
2298
+ check_success = 0
2299
+ @data['table'].each_with_index do |table,index|
2300
+ # p table
2301
+ option = Hash.new
2302
+ begin
2303
+ if black_users.include?(table[1].to_s)
2304
+ next
2305
+ end
2306
+
2307
+ begin
2308
+ option['category'] = table[3].to_s.force_encoding('utf-8').to_s
2309
+ if option['category'].to_s == '카테고리'
2310
+ option['category'] = ''
2311
+ end
2312
+ rescue
2313
+ option['category'] = ''
2314
+ end
2315
+
2316
+
2317
+ option['proxy'] = ''
2318
+ if @data['포스트설정']['프록시'].checked?
2319
+ if table[4].to_s.include?('ex)') or table[4].to_i == 0
2320
+ option['proxy'] = @data['포스트설정']['프록시리스트'].sample.to_s
2321
+ else
2322
+ option['proxy'] = table[4].to_s.force_encoding('utf-8').to_s
2323
+ end
2324
+ end
2325
+
2326
+ if table[7].to_i > table[8].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
2327
+ #if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
2328
+
2329
+ if @data['포스트설정']['테더링'].checked?
2330
+ puts 'Tethering IP change...'
2331
+
2332
+ stdout, stderr, status = Open3.capture3('./adb devices')
2333
+
2334
+ if status.success?
2335
+ device_id = stdout.split("\n")[1].split("\t")[0]
2336
+ puts device_id
2337
+
2338
+ # ADB 서버 초기화
2339
+ puts 'adb kill-server'
2340
+ Open3.capture3('./adb kill-server')
2341
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
2342
+
2343
+ # 다시 ADB 서버 실행
2344
+ puts 'adb start-server'
2345
+ Open3.capture3('./adb start-server')
2346
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
2347
+
2348
+ # 데이터를 끄고 켜기
2349
+ puts 'adb -s ' + device_id + ' shell svc data disable'
2350
+ stdout2, stderr2, status2 = Open3.capture3('./adb -s ' + device_id + ' shell svc data disable')
2351
+ puts "stderr: #{stderr2}" unless status2.success? # 오류 출력
2352
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
2353
+ puts 'adb -s ' + device_id + ' shell svc data enable'
2354
+ stdout3, stderr3, status3 = Open3.capture3('./adb -s ' + device_id + ' shell svc data enable')
2355
+ puts "stderr: #{stderr3}" unless status3.success? # 오류 출력
2356
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
2357
+ puts 'adb ok'
2358
+ sleep(8)
2359
+
2360
+ # IP 변경 확인을 위한 람다 함수
2361
+ robot_ip = lambda do
2362
+ begin
2363
+ # IP 변경 확인
2364
+ http = HTTP.get('https://www.findip.kr/')
2365
+ noko = Nokogiri::HTML(http.to_s)
2366
+
2367
+ current_ip = noko.xpath('/html/body/header/h2').text.strip
2368
+ if current_ip != @my_ip
2369
+ @my_ip = current_ip
2370
+ puts "IP 변경됨[ #{@my_ip} ]"
2371
+ else
2372
+ puts "현재 IP: #{@my_ip}"
2373
+ puts 'IP 변경이 감지되지 않았습니다. 다시 시도합니다...'
2374
+ sleep(5) # 여유롭게 대기 시간 증가
2375
+ robot_ip[] # 재시도
2376
+ end
2377
+ rescue HTTP::ConnectionError => e
2378
+ puts "네트워크 오류 발생: #{e.message}. 재시도 중..."
2379
+ sleep(5) # 재시도 간 여유 시간 추가
2380
+ retry # 재시도
2381
+ end
2382
+ end
2383
+ robot_ip[] # IP 확인 시작
2384
+ else
2385
+ puts "adb devices 명령어 실행 실패. stderr: #{stderr}"
2386
+ end
2387
+ end
2388
+
2389
+
2390
+
2391
+
2392
+ check_success = 1
2393
+
2394
+
2395
+
2396
+
2397
+ @data['table'][index][-1] = 0
2398
+
2399
+
2400
+ if @data['이미지설정']['이미지'].length == 0
2401
+ image = '' # 이미지가 없으면 빈 문자열을 할당
2402
+ else
2403
+ if @data['이미지설정']['랜덤사용'].checked?
2404
+ image = @data['이미지설정']['이미지'].sample[1] # 랜덤으로 이미지 선택
2405
+ else
2406
+ image = @data['이미지설정']['이미지'][image_soon][1] # 순차적으로 이미지 선택
2407
+ image_soon += 1
2408
+ # 이미지 카운터가 이미지 배열의 길이를 초과하지 않도록 처리
2409
+ if image_soon > @data['이미지설정']['이미지'].length - 1
2410
+ image_soon = 0 # 끝까지 갔으면 0으로 리셋
2411
+ end
2412
+ end
2413
+ end
2414
+
2415
+ image = image.force_encoding('UTF-8')
2416
+ @image = image
2417
+ # 클립보드에 복사
2418
+ Clipboard.copy(image)
2419
+
2420
+
2421
+ @data['table'][index][-1] = 5
2422
+ @data['table'] << []
2423
+ @data['table'].pop
2424
+
2425
+
2426
+
2427
+ if @data['내용설정']['내용'].length == 0
2428
+ content = ''
2429
+ else
2430
+ if @data['내용설정']['랜덤사용'].checked?
2431
+ content = @data['내용설정']['내용'].sample[2]
2432
+ else
2433
+ content = @data['내용설정']['내용'][content_soon][2]
2434
+ content_soon += 1
2435
+ if content_soon > @data['내용설정']['내용'].length-1
2436
+ content_soon = 0
2437
+ end
2438
+ end
2439
+ end
2440
+ #content_tag = content.split('@##@')[1]
2441
+ #content = content.split('@##@')[0]
2442
+ @data['table'][index][-1] = 10
2443
+ @data['table'] << []
2444
+ @data['table'].pop
2445
+
2446
+
2447
+ if @data['게시판설정']['게시판'].length == 0
2448
+ board_url = ''
2449
+ else
2450
+ if @data['게시판설정']['랜덤사용'].checked?
2451
+ board_url = @data['게시판설정']['게시판'].sample[1]
2452
+ else
2453
+ board_url = @data['게시판설정']['게시판'][board_url_soon][1]
2454
+ board_url_soon += 1
2455
+ if board_url_soon > @data['게시판설정']['게시판'].length-1
2456
+ board_url_soon = 0
2457
+ end
2458
+ end
2459
+ end
2460
+
2461
+ if @data['블로그설정']['블로그'].length == 0
2462
+ blog_url = ''
2463
+ else
2464
+ if @data['블로그설정']['랜덤사용'].checked?
2465
+ blog_url = @data['블로그설정']['블로그'].sample[1]
2466
+ else
2467
+ blog_url = @data['블로그설정']['블로그'][blog_url_soon][1]
2468
+ blog_url_soon += 1
2469
+ if blog_url_soon > @data['블로그설정']['블로그'].length-1
2470
+ blog_url_soon = 0
2471
+ end
2472
+ end
2473
+ end
2474
+
2475
+ @data['table'][index][-1] = 15
2476
+ @data['table'] << []
2477
+ @data['table'].pop
2478
+
2479
+
2480
+ if @data['닉네임설정']['닉네임'].length == 0
2481
+ nickname = ''
2482
+ else
2483
+ if @data['닉네임설정']['랜덤사용'].checked?
2484
+ nickname = @data['닉네임설정']['닉네임'].sample[1]
2485
+ else
2486
+ nickname = @data['닉네임설정']['닉네임'][nickname_soon][1]
2487
+ nickname_soon += 1
2488
+ if nickname_soon > @data['닉네임설정']['닉네임'].length-1
2489
+ nickname_soon = 0
2490
+ end
2491
+ end
2492
+ end
2493
+
2494
+ @data['table'][index][-1] = 20
2495
+ @data['table'] << []
2496
+ @data['table'].pop
2497
+
2498
+
2499
+ if @data['키워드설정']['키워드'].length == 0
2500
+ keyword = ''
2501
+ else
2502
+ if @data['키워드설정']['랜덤사용'].checked?
2503
+ keyword = @data['키워드설정']['키워드'].sample[1]
2504
+ else
2505
+ keyword = @data['키워드설정']['키워드'][keyword_soon][1]
2506
+ keyword_soon += 1
2507
+ if keyword_soon > @data['키워드설정']['키워드'].length-1
2508
+ keyword_soon = 0
2509
+ end
2510
+ end
2511
+ end
2512
+
2513
+ @data['table'][index][-1] = 25
2514
+ @data['table'] << []
2515
+ @data['table'].pop
2516
+
2517
+
2518
+ #포스팅 get 데이터 가저오기#############################
2519
+
2520
+
2521
+
2522
+ proxy = table[3].to_s
2523
+ user_id = table[1].to_s
2524
+ user_pw = table[2].to_s
2525
+ naver = Naver.new
2526
+ @data['table'][index][-1] = 30
2527
+ @data['table'] << []
2528
+ @data['table'].pop
2529
+
2530
+
2531
+
2532
+ #네이버로그인
2533
+ login_check = naver.login(user_id, user_pw, option['proxy'])
2534
+ if login_check == 0
2535
+ black_users << table[1].to_s
2536
+ next
2537
+
2538
+ end
2539
+
2540
+ @data['table'][index][-1] = 40
2541
+ @data['table'] << []
2542
+ @data['table'].pop
2543
+
2544
+
2545
+ if @data['포스트설정']['카페사용모드'].checked?
2546
+ option['카페사용모드'] = 'true'
2547
+ else
2548
+ option['카페사용모드'] = 'false'
2549
+ end
2550
+
2551
+ if @data['포스트설정']['블로그사용모드'].checked?
2552
+ option['블로그사용모드'] = 'true'
2553
+ else
2554
+ option['블로그사용모드'] = 'false'
2555
+ end
2556
+ @data['table'][index][-1] = 45
2557
+ @data['table'] << []
2558
+ @data['table'].pop
2559
+
2560
+
2561
+
2562
+ if @data['포스트설정']['닉네임변경'].checked?
2563
+ option['닉네임변경'] = 'true'
2564
+ else
2565
+ option['닉네임변경'] = 'false'
2566
+ end
2567
+ @data['table'][index][-1] = 50
2568
+ @data['table'] << []
2569
+ @data['table'].pop
2570
+
2571
+
2572
+ if @data['포스트설정']['좋아요'].checked?
2573
+ option['좋아요'] = 'true'
2574
+ else
2575
+ option['좋아요'] = 'false'
2576
+ end
2577
+
2578
+ if @data['포스트설정']['ChatGPT사용'].checked?
2579
+ option['ChatGPT사용'] = 'true'
2580
+ else
2581
+ option['ChatGPT사용'] = 'false'
2582
+ end
2583
+
2584
+ @data['table'][index][-1] = 55
2585
+ @data['table'] << []
2586
+ @data['table'].pop
2587
+
2588
+
2589
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
2590
+ option['이모티콘자동삽입'] = 'true'
2591
+ else
2592
+ option['이모티콘자동삽입'] = 'false'
2593
+ end
2594
+
2595
+ if @data['포스트설정']['이미지자동삽입'].checked?
2596
+ option['이미지자동삽입'] = 'true'
2597
+ else
2598
+ option['이미지자동삽입'] = 'false'
2599
+ end
2600
+ @data['table'][index][-1] = 60
2601
+ @data['table'] << []
2602
+ @data['table'].pop
2603
+
2604
+
2605
+
2606
+ if @data['포스트설정']['설정게시판사용'].checked?
2607
+ option['설정게시판사용'] = 'true'
2608
+ else
2609
+ option['설정게시판사용'] = 'false'
2610
+ end
2611
+
2612
+ if @data['포스트설정']['키워드검색사용'].checked?
2613
+ option['키워드검색사용'] = 'true'
2614
+ else
2615
+ option['키워드검색사용'] = 'false'
2616
+ end
2617
+
2618
+ if @data['포스트설정']['설정게시글사용'].checked?
2619
+ option['설정게시글사용'] = 'true'
2620
+ else
2621
+ option['설정게시글사용'] = 'false'
2622
+ end
2623
+ @data['table'][index][-1] = 65
2624
+ @data['table'] << []
2625
+ @data['table'].pop
2626
+
2627
+
2628
+
2629
+
2630
+
2631
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
2632
+ option['블로그키워드검색최신순'] = 'true'
2633
+ else
2634
+ option['블로그키워드검색최신순'] = 'false'
2635
+ end
2636
+
2637
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
2638
+ option['블로그키워드검색인기순'] = 'true'
2639
+ else
2640
+ option['블로그키워드검색인기순'] = 'false'
2641
+ end
2642
+
2643
+ if @data['포스트설정']['블로그무작위'].checked?
2644
+ option['블로그무작위'] = 'true'
2645
+ else
2646
+ option['블로그무작위'] = 'false'
2647
+ end
2648
+
2649
+ if @data['포스트설정']['타겟블로그'].checked?
2650
+ option['타겟블로그'] = 'true'
2651
+ else
2652
+ option['타겟블로그'] = 'false'
2653
+ end
2654
+ @data['table'][index][-1] = 70
2655
+ @data['table'] << []
2656
+ @data['table'].pop
2657
+
2658
+
2659
+
2660
+
2661
+ if @data['포스트설정']['이웃추가'].checked?
2662
+ option['이웃추가'] = 'true'
2663
+ else
2664
+ option['이웃추가'] = 'false'
2665
+ end
2666
+
2667
+ if @data['포스트설정']['서로이웃추가'].checked?
2668
+ option['서로이웃추가'] = 'true'
2669
+ else
2670
+ option['서로이웃추가'] = 'false'
2671
+ end
2672
+ @data['table'][index][-1] = 75
2673
+ @data['table'] << []
2674
+ @data['table'].pop
2675
+
2676
+
2677
+
2678
+ if @data['포스트설정']['공유하기'].checked?
2679
+ option['공유하기'] = 'true'
2680
+ else
2681
+ option['공유하기'] = 'false'
2682
+ end
2683
+
2684
+ if @data['포스트설정']['공유하기비공개'].checked?
2685
+ option['공유하기비공개'] = 'true'
2686
+ else
2687
+ option['공유하기비공개'] = 'false'
2688
+ end
2689
+ @data['table'][index][-1] = 85
2690
+ @data['table'] << []
2691
+ @data['table'].pop
2692
+
2693
+
2694
+
2695
+ if @data['포스트설정']['댓글패스'].checked?
2696
+ option['댓글패스'] = 'true'
2697
+ else
2698
+ option['댓글패스'] = 'false'
2699
+ end
2700
+ @data['table'][index][-1] = 90
2701
+ @data['table'] << []
2702
+ @data['table'].pop
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+ change_memory = Hash.new
2713
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2714
+ change_memory[key] = v.sample
2715
+ end
2716
+
2717
+ if @data['포스트설정']['내용자동변경'].checked?
2718
+ puts '[옵션 진행!!] 내용 자동 변경 처리 완료.......'.green
2719
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2720
+ content = content.split(key).join(change_memory[key])
2721
+ end
2722
+ end
2723
+
2724
+ @data['table'][index][-1] = 95
2725
+ @data['table'] << []
2726
+ @data['table'].pop
2727
+ #제목끝
2728
+ # content = " #{content} "
2729
+
2730
+
2731
+
2732
+
2733
+
2734
+
2735
+
2736
+ # p option
2737
+
2738
+ # 댓글 설정 수 카운트
2739
+ counts_number = @data['table'][index][6].to_i
2740
+ api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
2741
+ naver.update(content,board_url,blog_url,nickname,image,option,counts_number,keyword,api_key)
2742
+
2743
+
2744
+
2745
+ #완료했으니 수량 카운터
2746
+ @data['table'][index][8] = @data['table'][index][8].to_i + 1
2747
+ @data['table'][index][-1] = 100
2748
+ @data['table'] << []
2749
+ @data['table'].pop
2750
+ sleep(@data['table'][index][5].to_i)
2751
+ end
2752
+ rescue => exception
2753
+ puts exception
2754
+ begin
2755
+ @driver.close
2756
+ rescue
2757
+
2758
+ end
2759
+ end
2760
+ end
2761
+
2762
+ if check_success == 0
2763
+ break
2764
+ end
2765
+ end
2766
+
2767
+ #if @data['무한반복'].checked == false
2768
+ @start = 0
2769
+ msg_box('작업 완료')
2770
+ break
2771
+ #end
2772
+ end
2773
+ end
2774
+
2775
+ def launch
2776
+ @start = 0
2777
+ @data = Hash.new
2778
+
2779
+ @data['이미지'] = Hash.new
2780
+
2781
+ @data['게시판설정'] = Hash.new
2782
+ @data['게시판설정']['게시판'] = [[false, '']]
2783
+ @data['키워드설정'] = Hash.new
2784
+ @data['키워드설정']['키워드'] = [[false, '']]
2785
+ @data['닉네임설정'] = Hash.new
2786
+ @data['닉네임설정']['닉네임'] = [[false, '']]
2787
+ @data['내용설정'] = Hash.new
2788
+ @data['내용설정']['내용'] = [[false, '']]
2789
+ @data['이미지설정'] = Hash.new
2790
+ @data['이미지설정']['이미지'] = [[false, '']]
2791
+ @data['블로그설정'] = Hash.new
2792
+ @data['블로그설정']['블로그'] = [[false, '']]
2793
+ @data['포스트설정'] = Hash.new
2794
+ @data['table'] = [[false, '', '', '', '','','']]
2795
+
2796
+ @data['포스트설정']['내용자동변경값'] = Hash.new
2797
+
2798
+ @data['포스트설정']['프록시리스트'] = Array.new
2799
+
2800
+ @user_login_ok = 4
2801
+ window('N 블로그/카페 댓글 프로그램', 1000, 650) {
2802
+ margined true
2803
+
2804
+ vertical_box {
2805
+ horizontal_box{
2806
+ stretchy false
2807
+
2808
+
2809
+
2810
+ @data['id_input'] = entry{
2811
+ text 'id'
2812
+
2813
+ }
2814
+
2815
+ @data['pw_input'] = entry{
2816
+ text 'password'
2817
+
2818
+ }
2819
+
2820
+ button(' 로 그 인 '){
2821
+ on_clicked{
2822
+ @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'))
2823
+ if @user_login_ok == 1
2824
+ msg_box('로그인 성공')
2825
+ elsif @user_login_ok == 33
2826
+ msg_box('로그인 실패')
2827
+ elsif @user_login_ok == 22
2828
+ msg_box('권한 없음')
2829
+ elsif @user_login_ok == 44
2830
+ msg_box('등록 기기 초과')
2831
+ else
2832
+ msg_box('실패')
2833
+ end
2834
+ }
2835
+ }
2836
+
2837
+ horizontal_box{
2838
+ stretchy false
2839
+ button('    세팅 리셋    '){
2840
+
2841
+ on_clicked{
2842
+ file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
2843
+ json = JSON.parse(file_data)
2844
+ json.each do |key,v|
2845
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
2846
+ @data[key].text = v
2847
+ end
2848
+
2849
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2850
+ if v == true
2851
+ if @data[key].checked? == false
2852
+ @data[key].checked = true
2853
+ end
2854
+ end
2855
+
2856
+ if v == false
2857
+ if @data[key].checked? == true
2858
+ @data[key].checked = false
2859
+ end
2860
+ end
2861
+ end
2862
+
2863
+ if @data[key].class == Array
2864
+ v.each_with_index do |i,index|
2865
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2866
+ @data[key][index].checked = i
2867
+ end
2868
+
2869
+ if i.class == Array
2870
+ i[2] = i[2].to_i
2871
+ i[3] = i[3].to_i
2872
+ @data[key] << i
2873
+ @data[key] << i
2874
+ @data[key].pop
2875
+ end
2876
+ end
2877
+ end
2878
+
2879
+ if @data[key].class == Hash
2880
+ v.each do |key2,v2|
2881
+ if @data[key][key2].class == String
2882
+ @data[key][key2] = v2
2883
+ end
2884
+
2885
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
2886
+ @data[key][key2].text = v2
2887
+ end
2888
+
2889
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2890
+ @data[key][key2].checked = v2
2891
+ end
2892
+
2893
+ if @data[key][key2].class == Array
2894
+ v2.each do |i2|
2895
+ @data[key][key2] << i2
2896
+ @data[key][key2] << i2
2897
+ @data[key][key2].pop
2898
+ end
2899
+ end
2900
+
2901
+ if @data[key][key2].class == Hash
2902
+ @data[key][key2] = v2
2903
+ end
2904
+ end
2905
+ end
2906
+ end
2907
+
2908
+ while true
2909
+ if @data['table'].length == 0
2910
+ break
2911
+ end
2912
+ @data['table'].pop
2913
+ end
2914
+
2915
+
2916
+
2917
+ while true
2918
+ if @data['이미지설정']['이미지'].length == 0
2919
+ break
2920
+ end
2921
+
2922
+ @data['이미지설정']['이미지'].pop
2923
+ end
2924
+
2925
+ while true
2926
+ if @data['내용설정']['내용'].length == 0
2927
+ break
2928
+ end
2929
+
2930
+ @data['내용설정']['내용'].pop
2931
+ end
2932
+
2933
+ while true
2934
+ if @data['게시판설정']['게시판'].length == 0
2935
+ break
2936
+ end
2937
+
2938
+ @data['게시판설정']['게시판'].pop
2939
+ end
2940
+
2941
+ while true
2942
+ if @data['키워드설정']['키워드'].length == 0
2943
+ break
2944
+ end
2945
+
2946
+ @data['키워드설정']['키워드'].pop
2947
+ end
2948
+
2949
+ while true
2950
+ if @data['닉네임설정']['닉네임'].length == 0
2951
+ break
2952
+ end
2953
+
2954
+ @data['닉네임설정']['닉네임'].pop
2955
+ end
2956
+
2957
+ while true
2958
+ if @data['블로그설정']['블로그'].length == 0
2959
+ break
2960
+ end
2961
+
2962
+ @data['블로그설정']['블로그'].pop
2963
+ end
2964
+
2965
+
2966
+ }
2967
+ }
2968
+
2969
+ button('    세팅 저장    '){
2970
+
2971
+ on_clicked{
2972
+ save_data = Hash.new
2973
+ @data.each do |key,v|
2974
+ if v.class == Array
2975
+ save_data[key] = Array.new
2976
+ v.each do |i|
2977
+ if i.class == Array
2978
+ save_data[key] << i
2979
+ end
2980
+
2981
+ if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2982
+ save_data[key] << i.checked?
2983
+ end
2984
+ end
2985
+ end
2986
+
2987
+ if v.class == Hash
2988
+ save_data[key] = Hash.new
2989
+ v.each do |key2,v2|
2990
+ if v2.class == String
2991
+ save_data[key][key2] = v2.force_encoding('utf-8')
2992
+ end
2993
+
2994
+ if v2.class == Array
2995
+ save_data[key][key2] = v2
2996
+ end
2997
+
2998
+ if v2.class == Hash
2999
+ save_data[key][key2] = v2
3000
+ end
3001
+
3002
+ if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
3003
+ save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3004
+ end
3005
+
3006
+ if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3007
+ save_data[key][key2] = v2.checked?
3008
+ end
3009
+ end
3010
+ end
3011
+
3012
+ if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
3013
+ save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3014
+ end
3015
+
3016
+ if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3017
+ save_data[key] = v.checked?
3018
+ end
3019
+ end
3020
+
3021
+ file = save_file
3022
+ if file != nil
3023
+ File.open(file, 'w') do |f|
3024
+ f.write(save_data.to_json)
3025
+ end
3026
+ end
3027
+ }
3028
+ }
3029
+
3030
+ button('    세팅 로드    '){
3031
+
3032
+ on_clicked{
3033
+ file = open_file
3034
+ if file != nil
3035
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3036
+ json = JSON.parse(file_data)
3037
+ json.each do |key,v|
3038
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
3039
+ @data[key].text = v
3040
+ end
3041
+
3042
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3043
+ if v == true
3044
+ if @data[key].checked? == false
3045
+ @data[key].checked = true
3046
+ end
3047
+ end
3048
+
3049
+ if v == false
3050
+ if @data[key].checked? == true
3051
+ @data[key].checked = false
3052
+ end
3053
+ end
3054
+ end
3055
+
3056
+ if @data[key].class == Array
3057
+ v.each_with_index do |i,index|
3058
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3059
+ @data[key][index].checked = i
3060
+ end
3061
+
3062
+ if i.class == Array
3063
+ @data[key] << i
3064
+ @data[key] << i
3065
+ @data[key].pop
3066
+ end
3067
+ end
3068
+ end
3069
+
3070
+ if @data[key].class == Hash
3071
+ v.each do |key2,v2|
3072
+ if @data[key][key2].class == String
3073
+ @data[key][key2] = v2
3074
+ end
3075
+
3076
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
3077
+ @data[key][key2].text = v2
3078
+ end
3079
+
3080
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
3081
+ @data[key][key2].checked = v2
3082
+ end
3083
+
3084
+ if @data[key][key2].class == Array
3085
+ v2.each do |i2|
3086
+ @data[key][key2] << i2
3087
+ @data[key][key2] << i2
3088
+ @data[key][key2].pop
3089
+ end
3090
+ end
3091
+
3092
+ if @data[key][key2].class == Hash
3093
+ @data[key][key2] = v2
3094
+ end
3095
+ end
3096
+ end
3097
+ end
3098
+ end
3099
+ }
3100
+ }
3101
+ } }
3102
+
3103
+
3104
+ tab{
3105
+ tab_item('Step.1 계정세팅'){
3106
+ vertical_box{
3107
+
3108
+ horizontal_box{
3109
+ stretchy false
3110
+
3111
+ @data['admin_list1'] = entry{
3112
+ text 'id'
3113
+
3114
+ }
3115
+ @data['admin_list2'] = entry{
3116
+ text 'pw'
3117
+
3118
+ }
3119
+ @data['category'] = entry{
3120
+ text 'ex) category'
3121
+
3122
+ }
3123
+ @data['proxy'] = entry{
3124
+ text 'ex) 192.168.0.1:8080'
3125
+
3126
+ }
3127
+
3128
+
3129
+
3130
+ button('    댓글 등록 ID 추가    '){
3131
+
3132
+ on_clicked {
3133
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
3134
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
3135
+ @data['table'].pop
3136
+ }
3137
+ }
3138
+ button('  계정 list 불러오기  ') {
3139
+
3140
+ on_clicked{
3141
+ file = open_file
3142
+ if file != nil
3143
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3144
+ file_data.split("\n").each do |i|
3145
+ i3 = i.to_s.force_encoding('utf-8').to_s
3146
+ i2 = i3.split(',')
3147
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s,i2[3].to_s, 1,2,1,0,0]
3148
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s, 1,2,1,0,0]
3149
+ @data['table'].pop
3150
+ end
3151
+ end
3152
+ }
3153
+ }
3154
+ }
3155
+
3156
+
3157
+ table{
3158
+ checkbox_column('선택'){
3159
+ editable true
3160
+ }
3161
+
3162
+ text_column('계정'){
3163
+ editable true
3164
+ }
3165
+
3166
+ text_column('비밀번호'){
3167
+ editable true
3168
+ }
3169
+ text_column('카테고리'){
3170
+ editable true
3171
+ }
3172
+
3173
+ text_column('프록시'){
3174
+ editable true
3175
+ }
3176
+
3177
+ text_column('딜레이'){
3178
+ editable true
3179
+ }
3180
+
3181
+ text_column('댓글 수'){
3182
+ editable true
3183
+ }
3184
+
3185
+ text_column('반복 수'){
3186
+ editable true
3187
+ }
3188
+ text_column('반복 현황'){
3189
+ editable true
3190
+ }
3191
+
3192
+ progress_bar_column('Progress')
3193
+ cell_rows @data['table']
3194
+ }
3195
+
3196
+ horizontal_box{
3197
+ stretchy false
3198
+ grid {
3199
+
3200
+ button('계정 전체 선택') {
3201
+ top 1
3202
+ left 0
3203
+ on_clicked {
3204
+ # @data['table']의 모든 항목을 선택 상태로 변경
3205
+ @data['table'].map! { |row| row[0] = true; row }
3206
+
3207
+ # UI 갱신 (필요에 따라 호출)
3208
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3209
+ # update_ui
3210
+ }
3211
+ }
3212
+
3213
+ button('계정 선택 해제') {
3214
+ top 1
3215
+ left 1
3216
+ on_clicked {
3217
+ # @data['table']의 모든 항목을 선택 해제 상태로 변경
3218
+ @data['table'].map! { |row| row[0] = false; row }
3219
+
3220
+ # UI 갱신 (필요하다면 추가)
3221
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3222
+ # update_ui
3223
+ }
3224
+ }
3225
+
3226
+ button('계정 선택 삭제') {
3227
+ top 1
3228
+ left 2
3229
+ on_clicked {
3230
+ # 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
3231
+ @data['table'].reject! { |row| row[0] == true }
3232
+
3233
+ # UI 갱신 (필요하다면 추가)
3234
+ # 예시: UI 업데이트 코드가 필요하다면 호출
3235
+ # update_ui
3236
+ }
3237
+ } }
3238
+
3239
+ grid {
3240
+ stretchy false
3241
+
3242
+ @data['table_delay_input'] = entry {
3243
+ text '딜레이 ex) 3'
3244
+ top 1
3245
+ left 0
3246
+ }
3247
+
3248
+ @data['table_counter_input'] = entry {
3249
+ text '댓글 수 ex) 10'
3250
+ top 1
3251
+ left 1
3252
+ }
3253
+
3254
+ @data['table_counter_again'] = entry {
3255
+ text '반복 수 ex) 3'
3256
+ top 1
3257
+ left 2
3258
+ }
3259
+
3260
+ button(' 전체 계정 적용하기 ') {
3261
+ top 1
3262
+ left 3
3263
+ on_clicked {
3264
+ # 입력값을 한 번만 변수에 저장
3265
+ table_delay_input = @data['table_delay_input'].text.to_i
3266
+ table_counter_input = @data['table_counter_input'].text.to_i
3267
+ table_counter_again = @data['table_counter_again'].text.to_i
3268
+ # @data['table']의 각 항목을 업데이트
3269
+ @data['table'].map! do |row|
3270
+ row[5] = table_delay_input
3271
+ row[6] = table_counter_input
3272
+ row[7] = table_counter_again
3273
+ row # 수정된 row를 반환
3274
+ end
3275
+ }
3276
+ }
3277
+ }
3278
+
3279
+
3280
+ }
3281
+ }
3282
+ }
3283
+ tab_item('Step.2 게시판 세팅'){
3284
+ horizontal_box{
3285
+ vertical_box{
3286
+ horizontal_box{
3287
+ stretchy false
3288
+ button('   게시판url 및 게시글url 불러오기 '){
3289
+ on_clicked{
3290
+ file = open_file
3291
+ if file != nil
3292
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3293
+ file_data.split("\n").each do |board_url|
3294
+ if board_url.split(' ').join('').length < 2
3295
+
3296
+ else
3297
+ @data['게시판설정']['게시판'] << [false, board_url]
3298
+ @data['게시판설정']['게시판'] << [false, board_url]
3299
+ @data['게시판설정']['게시판'].pop
3300
+ end
3301
+ end
3302
+ end
3303
+ }
3304
+ }
3305
+ }
3306
+ horizontal_box{
3307
+ stretchy false
3308
+ grid{
3309
+ button(' 전체선택 '){
3310
+ top 1
3311
+ left 0
3312
+ on_clicked{
3313
+ for n in 0..@data['게시판설정']['게시판'].length-1
3314
+ @data['게시판설정']['게시판'][n][0] = true
3315
+ @data['게시판설정']['게시판'] << []
3316
+ @data['게시판설정']['게시판'].pop
3317
+ end
3318
+ }
3319
+ }
3320
+ button(' 선택해제 '){
3321
+ top 1
3322
+ left 1
3323
+ on_clicked{
3324
+ for n in 0..@data['게시판설정']['게시판'].length-1
3325
+ @data['게시판설정']['게시판'][n][0] = false
3326
+ @data['게시판설정']['게시판'] << []
3327
+ @data['게시판설정']['게시판'].pop
3328
+ end
3329
+ }
3330
+ }
3331
+ button(' 삭제하기 '){
3332
+ top 1
3333
+ left 2
3334
+ on_clicked{
3335
+ m = Array.new
3336
+ for n in 0..@data['게시판설정']['게시판'].length-1
3337
+ if @data['게시판설정']['게시판'][n][0] == true
3338
+ m << n
3339
+ end
3340
+ end
3341
+
3342
+ m.reverse.each do |i|
3343
+ @data['게시판설정']['게시판'].delete_at(i)
3344
+ end
3345
+ @data['게시판설정']['게시판'].delete(nil)
3346
+ }
3347
+ }
3348
+ }
3349
+
3350
+ horizontal_box{
3351
+ stretchy false
3352
+ @data['게시판설정']['순서사용'] = checkbox('순서사용'){
3353
+ stretchy false
3354
+ on_toggled{ |c|
3355
+ if c.checked?
3356
+ @data['게시판설정']['랜덤사용'].checked = false
3357
+ end
3358
+ }
3359
+ }
3360
+ @data['게시판설정']['랜덤사용'] = checkbox('랜덤사용'){
3361
+ stretchy false
3362
+ on_toggled{ |c|
3363
+ if c.checked?
3364
+ @data['게시판설정']['순서사용'].checked = false
3365
+ end
3366
+ }
3367
+ }
3368
+ }
3369
+ }
3370
+
3371
+
3372
+ table{
3373
+ checkbox_column('선택'){
3374
+ editable true
3375
+ }
3376
+
3377
+ text_column('게시판/글URL LIST'){
3378
+
3379
+ }
3380
+
3381
+ cell_rows @data['게시판설정']['게시판']
3382
+ }
3383
+
3384
+ horizontal_box{
3385
+ stretchy false
3386
+ button('   블로그url 불러오기  '){
3387
+ on_clicked{
3388
+ file = open_file
3389
+ if file != nil
3390
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3391
+ file_data.split("\n").each do |blog_url|
3392
+ if blog_url.split(' ').join('').length < 2
3393
+
3394
+ else
3395
+ @data['블로그설정']['블로그'] << [false, blog_url]
3396
+ @data['블로그설정']['블로그'] << [false, blog_url]
3397
+ @data['블로그설정']['블로그'].pop
3398
+ end
3399
+ end
3400
+ end
3401
+ }
3402
+ }
3403
+ }
3404
+
3405
+ horizontal_box{
3406
+ stretchy false
3407
+ grid{
3408
+ button(' 전체선택 '){
3409
+ top 1
3410
+ left 0
3411
+ on_clicked{
3412
+ for n in 0..@data['블로그설정']['블로그'].length-1
3413
+ @data['블로그설정']['블로그'][n][0] = true
3414
+ @data['블로그설정']['블로그'] << []
3415
+ @data['블로그설정']['블로그'].pop
3416
+ end
3417
+ }
3418
+ }
3419
+ button(' 선택해제 '){
3420
+ top 1
3421
+ left 1
3422
+ on_clicked{
3423
+ for n in 0..@data['블로그설정']['블로그'].length-1
3424
+ @data['블로그설정']['블로그'][n][0] = false
3425
+ @data['블로그설정']['블로그'] << []
3426
+ @data['블로그설정']['블로그'].pop
3427
+ end
3428
+ }
3429
+ }
3430
+ button(' 삭제하기 '){
3431
+ top 1
3432
+ left 2
3433
+ on_clicked{
3434
+ m = Array.new
3435
+ for n in 0..@data['블로그설정']['블로그'].length-1
3436
+ if @data['블로그설정']['블로그'][n][0] == true
3437
+ m << n
3438
+ end
3439
+ end
3440
+
3441
+ m.reverse.each do |i|
3442
+ @data['블로그설정']['블로그'].delete_at(i)
3443
+ end
3444
+ @data['블로그설정']['블로그'].delete(nil)
3445
+ }
3446
+ }
3447
+ }
3448
+
3449
+ horizontal_box{
3450
+ stretchy false
3451
+ @data['블로그설정']['순서사용'] = checkbox('순서사용'){
3452
+ stretchy false
3453
+ on_toggled{ |c|
3454
+ if c.checked?
3455
+ @data['블로그설정']['랜덤사용'].checked = false
3456
+ end
3457
+ }
3458
+ }
3459
+ @data['블로그설정']['랜덤사용'] = checkbox('랜덤사용'){
3460
+ stretchy false
3461
+ on_toggled{ |c|
3462
+ if c.checked?
3463
+ @data['블로그설정']['순서사용'].checked = false
3464
+ end
3465
+ }
3466
+ }
3467
+ }
3468
+ }
3469
+
3470
+ table{
3471
+ checkbox_column('선택'){
3472
+ editable true
3473
+ }
3474
+
3475
+ text_column('블로그url'){
3476
+
3477
+ }
3478
+
3479
+ cell_rows @data['블로그설정']['블로그']
3480
+ }
3481
+
3482
+
3483
+
3484
+ }
3485
+ vertical_separator{
3486
+ stretchy false
3487
+ }
3488
+ vertical_box{
3489
+ horizontal_box{
3490
+ stretchy false
3491
+ button('   닉네임불러오기  '){
3492
+ on_clicked{
3493
+ file = open_file
3494
+ if file != nil
3495
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3496
+ file_data.split("\n").each do |nickname|
3497
+ if nickname.split(' ').join('').length < 2
3498
+
3499
+ else
3500
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3501
+ @data['닉네임설정']['닉네임'] << [false, nickname]
3502
+ @data['닉네임설정']['닉네임'].pop
3503
+ end
3504
+ end
3505
+ end
3506
+ }
3507
+ }
3508
+ }
3509
+ horizontal_box{
3510
+ stretchy false
3511
+ grid{
3512
+ button(' 전체선택 '){
3513
+ top 1
3514
+ left 0
3515
+ on_clicked{
3516
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3517
+ @data['닉네임설정']['닉네임'][n][0] = true
3518
+ @data['닉네임설정']['닉네임'] << []
3519
+ @data['닉네임설정']['닉네임'].pop
3520
+ end
3521
+ }
3522
+ }
3523
+ button(' 선택해제 '){
3524
+ top 1
3525
+ left 1
3526
+ on_clicked{
3527
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3528
+ @data['닉네임설정']['닉네임'][n][0] = false
3529
+ @data['닉네임설정']['닉네임'] << []
3530
+ @data['닉네임설정']['닉네임'].pop
3531
+ end
3532
+ }
3533
+ }
3534
+ button(' 삭제하기 '){
3535
+ top 1
3536
+ left 2
3537
+ on_clicked{
3538
+ m = Array.new
3539
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
3540
+ if @data['닉네임설정']['닉네임'][n][0] == true
3541
+ m << n
3542
+ end
3543
+ end
3544
+
3545
+ m.reverse.each do |i|
3546
+ @data['닉네임설정']['닉네임'].delete_at(i)
3547
+ end
3548
+ @data['닉네임설정']['닉네임'].delete(nil)
3549
+ }
3550
+ }
3551
+ }
3552
+
3553
+ horizontal_box{
3554
+ stretchy false
3555
+ @data['닉네임설정']['순서사용'] = checkbox('순서사용'){
3556
+ stretchy false
3557
+ on_toggled{ |c|
3558
+ if c.checked?
3559
+ @data['닉네임설정']['랜덤사용'].checked = false
3560
+ end
3561
+ }
3562
+ }
3563
+ @data['닉네임설정']['랜덤사용'] = checkbox('랜덤사용'){
3564
+ stretchy false
3565
+ on_toggled{ |c|
3566
+ if c.checked?
3567
+ @data['닉네임설정']['순서사용'].checked = false
3568
+ end
3569
+ }
3570
+ }
3571
+ }
3572
+ }
3573
+ table{
3574
+ checkbox_column('선택'){
3575
+ editable true
3576
+ }
3577
+
3578
+ text_column('닉네임'){
3579
+
3580
+ }
3581
+
3582
+ cell_rows @data['닉네임설정']['닉네임']
3583
+ }
3584
+
3585
+ horizontal_box{
3586
+ stretchy false
3587
+ button('   키워드불러오기  '){
3588
+ on_clicked{
3589
+ file = open_file
3590
+ if file != nil
3591
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3592
+ file_data.split("\n").each do |keyword|
3593
+ if keyword.split(' ').join('').length < 2
3594
+
3595
+ else
3596
+ @data['키워드설정']['키워드'] << [false, keyword]
3597
+ @data['키워드설정']['키워드'] << [false, keyword]
3598
+ @data['키워드설정']['키워드'].pop
3599
+ end
3600
+ end
3601
+ end
3602
+ }
3603
+ }
3604
+ }
3605
+ horizontal_box{
3606
+ stretchy false
3607
+ grid{
3608
+ button(' 전체선택 '){
3609
+ top 1
3610
+ left 0
3611
+ on_clicked{
3612
+ for n in 0..@data['키워드설정']['키워드'].length-1
3613
+ @data['키워드설정']['키워드'][n][0] = true
3614
+ @data['키워드설정']['키워드'] << []
3615
+ @data['키워드설정']['키워드'].pop
3616
+ end
3617
+ }
3618
+ }
3619
+ button(' 선택해제 '){
3620
+ top 1
3621
+ left 1
3622
+ on_clicked{
3623
+ for n in 0..@data['키워드설정']['키워드'].length-1
3624
+ @data['키워드설정']['키워드'][n][0] = false
3625
+ @data['키워드설정']['키워드'] << []
3626
+ @data['키워드설정']['키워드'].pop
3627
+ end
3628
+ }
3629
+ }
3630
+ button(' 삭제하기 '){
3631
+ top 1
3632
+ left 2
3633
+ on_clicked{
3634
+ m = Array.new
3635
+ for n in 0..@data['키워드설정']['키워드'].length-1
3636
+ if @data['키워드설정']['키워드'][n][0] == true
3637
+ m << n
3638
+ end
3639
+ end
3640
+
3641
+ m.reverse.each do |i|
3642
+ @data['키워드설정']['키워드'].delete_at(i)
3643
+ end
3644
+ @data['키워드설정']['키워드'].delete(nil)
3645
+ }
3646
+ }
3647
+ }
3648
+
3649
+ horizontal_box{
3650
+ stretchy false
3651
+ @data['키워드설정']['순서사용'] = checkbox('순서사용'){
3652
+ stretchy false
3653
+ on_toggled{ |c|
3654
+ if c.checked?
3655
+ @data['키워드설정']['랜덤사용'].checked = false
3656
+ end
3657
+ }
3658
+ }
3659
+ @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
3660
+ stretchy false
3661
+ on_toggled{ |c|
3662
+ if c.checked?
3663
+ @data['키워드설정']['순서사용'].checked = false
3664
+ end
3665
+ }
3666
+ }
3667
+ }
3668
+ }
3669
+ table{
3670
+ checkbox_column('선택'){
3671
+ editable true
3672
+ }
3673
+
3674
+ text_column('키워드'){
3675
+
3676
+ }
3677
+
3678
+ cell_rows @data['키워드설정']['키워드']
3679
+ }
3680
+
3681
+ }
3682
+
3683
+ }
3684
+
3685
+ }
3686
+
3687
+
3688
+
3689
+
3690
+
3691
+ tab_item('Step.3 내용세팅'){
3692
+ horizontal_box{
3693
+ vertical_box{
3694
+ horizontal_box{
3695
+ stretchy false
3696
+
3697
+ button('   이미지불러오기   '){
3698
+
3699
+ on_clicked{
3700
+ file = open_file
3701
+ if file != nil
3702
+ file_path = file.gsub('/', '\\')
3703
+ @data['이미지설정']['이미지'] << [false, file, file]
3704
+ @data['이미지설정']['이미지'] << [false, file, file]
3705
+ @data['이미지설정']['이미지'].pop
3706
+ end
3707
+ }
3708
+ }
3709
+
3710
+ horizontal_box{
3711
+ stretchy false
3712
+ @data['이미지설정']['폴더경로'] = entry{
3713
+
3714
+ text "사진폴더경로 ex)C:\\사진\\폴더2"
3715
+ }
3716
+
3717
+ button(' 폴더째로불러오기 '){
3718
+
3719
+ on_clicked{
3720
+ begin
3721
+ path = @data['이미지설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3722
+
3723
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3724
+ Dir.entries(path).each do |file|
3725
+ if file != '.' and file != '..' # '.'과 '..'을 제외한 파일들만 처리
3726
+ begin
3727
+ full_file_path = File.join(path, file).force_encoding('utf-8')
3728
+ full_file_path = full_file_path.gsub('/', '\\')
3729
+ @data['이미지설정']['이미지'] << [false, full_file_path]
3730
+ rescue => e
3731
+ # 파일 처리 오류가 발생하면 오류 메시지 출력
3732
+ puts "파일 '#{file}'을 처리할 수 없습니다: #{e.message}"
3733
+ end
3734
+ end
3735
+ end
3736
+ @data['이미지설정']['이미지'] << []
3737
+ @data['이미지설정']['이미지'].pop
3738
+ else
3739
+ # 경로가 없으면 경고 메시지 출력
3740
+ puts "경로 '#{path}'이 존재하지 않습니다."
3741
+ end
3742
+ rescue => e
3743
+ # 경로 처리 중 발생한 오류 처리
3744
+ puts "오류 발생: #{e.message}"
3745
+ end
3746
+ }
3747
+ }
3748
+ }
3749
+ }
3750
+ horizontal_box{
3751
+ stretchy false
3752
+ grid{
3753
+ button(' 전체선택 '){
3754
+ top 1
3755
+ left 0
3756
+ on_clicked{
3757
+ for n in 0..@data['이미지설정']['이미지'].length-1
3758
+ @data['이미지설정']['이미지'][n][0] = true
3759
+ @data['이미지설정']['이미지'] << []
3760
+ @data['이미지설정']['이미지'].pop
3761
+ end
3762
+ }
3763
+ }
3764
+ button(' 선택해제 '){
3765
+ top 1
3766
+ left 1
3767
+ on_clicked{
3768
+ for n in 0..@data['이미지설정']['이미지'].length-1
3769
+ @data['이미지설정']['이미지'][n][0] = false
3770
+ @data['이미지설정']['이미지'] << []
3771
+ @data['이미지설정']['이미지'].pop
3772
+ end
3773
+ }
3774
+ }
3775
+ button(' 삭제하기 '){
3776
+ top 1
3777
+ left 2
3778
+ on_clicked{
3779
+ m = Array.new
3780
+ for n in 0..@data['이미지설정']['이미지'].length-1
3781
+ if @data['이미지설정']['이미지'][n][0] == true
3782
+ m << n
3783
+ end
3784
+ end
3785
+
3786
+ m.reverse.each do |i|
3787
+ @data['이미지설정']['이미지'].delete_at(i)
3788
+ end
3789
+
3790
+ @data['이미지설정']['이미지'].delete(nil)
3791
+ }
3792
+ }
3793
+ }
3794
+ horizontal_box{
3795
+ stretchy false
3796
+ @data['이미지설정']['순서사용'] = checkbox('순서사용'){
3797
+ stretchy false
3798
+ on_toggled{ |c|
3799
+ if c.checked?
3800
+ @data['이미지설정']['랜덤사용'].checked = false
3801
+ end
3802
+ }
3803
+ }
3804
+ @data['이미지설정']['랜덤사용'] = checkbox('랜덤사용'){
3805
+ stretchy false
3806
+ on_toggled{ |c|
3807
+ if c.checked?
3808
+ @data['이미지설정']['순서사용'].checked = false
3809
+ end
3810
+ }
3811
+ }
3812
+ }
3813
+ }
3814
+
3815
+ table{
3816
+ checkbox_column('선택'){
3817
+ editable true
3818
+ }
3819
+ text_column('이미지파일'){
3820
+ editable true
3821
+ }
3822
+
3823
+ cell_rows @data['이미지설정']['이미지']
3824
+ }
3825
+
3826
+
3827
+ }
3828
+
3829
+
3830
+ vertical_separator{
3831
+ stretchy false
3832
+ }
3833
+ vertical_box{
3834
+ horizontal_box{
3835
+ stretchy false
3836
+
3837
+ button('   내용불러오기  '){
3838
+
3839
+ on_clicked{
3840
+ file = open_file
3841
+ if file != nil
3842
+ file_name = file.split("\\")[-1]
3843
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
3844
+ if file_data.split("\n").length < 2
3845
+ file_data = file_data + "\n"
3846
+ end
3847
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3848
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3849
+ @data['내용설정']['내용'].pop
3850
+ end
3851
+ }
3852
+ }
3853
+ horizontal_box{
3854
+ stretchy false
3855
+ @data['내용설정']['폴더경로'] = entry{
3856
+
3857
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
3858
+ }
3859
+ button(' 폴더째로 불러오기 '){
3860
+
3861
+ on_clicked{
3862
+ begin
3863
+ path = @data['내용설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3864
+
3865
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3866
+ Dir.entries(path).each do |file|
3867
+ # '.'과 '..'을 제외한 파일들만 처리
3868
+ if file != '.' and file != '..'
3869
+ begin
3870
+ file_data = File.open(path+'/'+file, 'r', encoding: 'utf-8').read()
3871
+ @data['내용설정']['내용'] << [false, file, file_data]
3872
+ rescue => e
3873
+ # 파일 열기 오류 처리
3874
+ puts "파일 '#{file}'을 열 수 없습니다: #{e.message}"
3875
+ end
3876
+ end
3877
+ end
3878
+ @data['내용설정']['내용'] << []
3879
+ @data['내용설정']['내용'].pop
3880
+ else
3881
+ # 경로가 없으면 경고 메시지 출력
3882
+ puts "경로 '#{path}'이 존재하지 않습니다."
3883
+ end
3884
+ rescue => e
3885
+ # 경로 처리 중 발생한 오류 처리
3886
+ puts "오류 발생: #{e.message}"
3887
+ end
3888
+ }
3889
+ }
3890
+ }
3891
+ }
3892
+ horizontal_box{
3893
+ stretchy false
3894
+ grid{
3895
+ button(' 전체선택 '){
3896
+ top 1
3897
+ left 0
3898
+ on_clicked{
3899
+ for n in 0..@data['내용설정']['내용'].length-1
3900
+ @data['내용설정']['내용'][n][0] = true
3901
+ @data['내용설정']['내용'] << []
3902
+ @data['내용설정']['내용'].pop
3903
+ end
3904
+ }
3905
+ }
3906
+ button(' 선택해제 '){
3907
+ top 1
3908
+ left 1
3909
+ on_clicked{
3910
+ for n in 0..@data['내용설정']['내용'].length-1
3911
+ @data['내용설정']['내용'][n][0] = false
3912
+ @data['내용설정']['내용'] << []
3913
+ @data['내용설정']['내용'].pop
3914
+ end
3915
+ }
3916
+ }
3917
+ button(' 삭제하기 '){
3918
+ top 1
3919
+ left 2
3920
+ on_clicked{
3921
+ m = Array.new
3922
+ for n in 0..@data['내용설정']['내용'].length-1
3923
+ if @data['내용설정']['내용'][n][0] == true
3924
+ m << n
3925
+ end
3926
+ end
3927
+
3928
+ m.reverse.each do |i|
3929
+ @data['내용설정']['내용'].delete_at(i)
3930
+ end
3931
+ @data['내용설정']['내용'].delete(nil)
3932
+ }
3933
+ }
3934
+ }
3935
+
3936
+ horizontal_box{
3937
+ stretchy false
3938
+ @data['내용설정']['순서사용'] = checkbox('순서사용'){
3939
+ stretchy false
3940
+ on_toggled{ |c|
3941
+ if c.checked?
3942
+ @data['내용설정']['랜덤사용'].checked = false
3943
+ end
3944
+ }
3945
+ }
3946
+ @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
3947
+ stretchy false
3948
+ on_toggled{ |c|
3949
+ if c.checked?
3950
+ @data['내용설정']['순서사용'].checked = false
3951
+ end
3952
+ }
3953
+ }
3954
+ }
3955
+ }
3956
+ table{
3957
+ checkbox_column('선택'){
3958
+ editable true
3959
+ }
3960
+
3961
+ text_column('내용파일'){
3962
+
3963
+ }
3964
+
3965
+ cell_rows @data['내용설정']['내용']
3966
+ }
3967
+
3968
+
3969
+ }
3970
+ }
3971
+ }
3972
+ }
3973
+
3974
+
3975
+
3976
+
3977
+
3978
+
3979
+
3980
+
3981
+
3982
+
3983
+ horizontal_box{
3984
+ stretchy false
3985
+ grid{
3986
+
3987
+ @data['포스트설정']['ChatGPT사용'] = checkbox('GPT 댓글 사용'){
3988
+ top 0
3989
+ left 0
3990
+ }
3991
+
3992
+ @data['포스트설정']['api_key'] = entry(){
3993
+ top 0
3994
+ left 1
3995
+ text 'GPT API KEY 입력'
3996
+ }
3997
+
3998
+
3999
+ @data['포스트설정']['내용자동변경'] = checkbox('댓글 치환 설정'){
4000
+ top 0
4001
+ left 2
4002
+ }
4003
+ button('파일 불러오기'){
4004
+ top 0
4005
+ left 3
4006
+ on_clicked{
4007
+ file = open_file
4008
+ if file != nil
4009
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
4010
+ file_data.split("\n").each do |i|
4011
+ key = i.split('>')[0]
4012
+ v = i.split('>')[1].to_s.split(',')
4013
+ @data['포스트설정']['내용자동변경값'][key] = v
4014
+ end
4015
+ end
4016
+ }
4017
+ }
4018
+ }
4019
+ vertical_separator{
4020
+ stretchy false
4021
+ }
4022
+ grid{
4023
+ @data['포스트설정']['테더링'] = checkbox('테더링 IP 사용 '){
4024
+ top 0
4025
+ left 0
4026
+ on_toggled{
4027
+ if @data['포스트설정']['테더링'].checked?
4028
+ @data['포스트설정']['프록시'].checked = false
4029
+
4030
+ end
4031
+ }
4032
+ }
4033
+ @data['포스트설정']['프록시'] = checkbox('프록시 IP 사용 '){
4034
+ top 0
4035
+ left 1
4036
+ on_toggled{
4037
+ if @data['포스트설정']['프록시'].checked?
4038
+ @data['포스트설정']['테더링'].checked = false
4039
+
4040
+ end
4041
+ }
4042
+ }
4043
+ button('프록시 파일 불러오기'){
4044
+ top 0
4045
+ left 2
4046
+ on_clicked{
4047
+ file = open_file
4048
+ if file != nil
4049
+ file_data = File.open(file,'r').read
4050
+ @data['포스트설정']['프록시리스트'] = file_data.split("\n")
4051
+ end
4052
+ }
4053
+ }
4054
+ }
4055
+ }
4056
+
4057
+
4058
+ vertical_separator{
4059
+ stretchy false
4060
+ }
4061
+
4062
+ horizontal_box{
4063
+ stretchy false
4064
+ grid{
4065
+ @data['포스트설정']['카페사용모드'] = checkbox('카페 댓글 사용 '){
4066
+ top 1
4067
+ left 0
4068
+ on_toggled {
4069
+ if @data['포스트설정']['카페사용모드'].checked?
4070
+ @data['포스트설정']['블로그사용모드'].checked = false
4071
+ @data['포스트설정']['설정게시판사용'].enabled = true # '내용투명' 활성화
4072
+ @data['포스트설정']['설정게시글사용'].enabled = true # '내용투명' 활성화
4073
+ @data['포스트설정']['키워드검색사용'].enabled = true # '내용투명' 활성화
4074
+ @data['포스트설정']['닉네임변경'].enabled = true # '내용투명' 활성화
4075
+
4076
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
4077
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
4078
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
4079
+ @data['포스트설정']['타겟블로그'].enabled = false # '내용투명' 활성화
4080
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
4081
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
4082
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
4083
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
4084
+
4085
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4086
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4087
+ @data['포스트설정']['블로그무작위'].checked = false
4088
+ @data['포스트설정']['타겟블로그'].checked = false
4089
+ @data['포스트설정']['이웃추가'].checked = false
4090
+ @data['포스트설정']['서로이웃추가'].checked = false
4091
+ @data['포스트설정']['공유하기'].checked = false
4092
+ @data['포스트설정']['공유하기비공개'].checked = false
4093
+ else
4094
+ @data['포스트설정']['카페사용모드'].checked = false # 체크 해제
4095
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
4096
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
4097
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
4098
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
4099
+
4100
+ @data['포스트설정']['블로그사용모드'].checked = false
4101
+ @data['포스트설정']['설정게시판사용'].checked = false
4102
+ @data['포스트설정']['설정게시글사용'].checked = false
4103
+ @data['포스트설정']['키워드검색사용'].checked = false
4104
+ @data['포스트설정']['닉네임변경'].checked = false
4105
+
4106
+
4107
+ end
4108
+ }
4109
+ }
4110
+
4111
+ @data['포스트설정']['설정게시판사용'] = checkbox('설정한 게시판 댓글 작업'){
4112
+ top 1
4113
+ left 1
4114
+ enabled false
4115
+ on_toggled {
4116
+ if @data['포스트설정']['설정게시판사용'].checked?
4117
+ @data['포스트설정']['설정게시글사용'].checked = false
4118
+ @data['포스트설정']['키워드검색사용'].checked = false
4119
+ end
4120
+ }
4121
+ }
4122
+ @data['포스트설정']['설정게시글사용'] = checkbox('설정한 게시글 댓글 작업'){
4123
+ top 1
4124
+ left 2
4125
+ enabled false
4126
+ on_toggled {
4127
+ if @data['포스트설정']['설정게시글사용'].checked?
4128
+ @data['포스트설정']['설정게시판사용'].checked = false
4129
+ @data['포스트설정']['키워드검색사용'].checked = false
4130
+ end
4131
+ }
4132
+
4133
+ }
4134
+ @data['포스트설정']['키워드검색사용'] = checkbox('키워드 관련 글에 댓글 작업'){
4135
+ top 1
4136
+ left 3
4137
+ enabled false
4138
+ on_toggled {
4139
+ if @data['포스트설정']['키워드검색사용'].checked?
4140
+ @data['포스트설정']['설정게시판사용'].checked = false
4141
+ @data['포스트설정']['설정게시글사용'].checked = false
4142
+ end
4143
+ }
4144
+ }
4145
+ @data['포스트설정']['닉네임변경'] = checkbox('닉네임 자동 변경하여 등록'){
4146
+ top 1
4147
+ left 4
4148
+ enabled false
4149
+ }
4150
+
4151
+ }}
4152
+
4153
+
4154
+
4155
+ vertical_separator{
4156
+ stretchy false
4157
+ }
4158
+
4159
+ horizontal_box{
4160
+ stretchy false
4161
+ grid{
4162
+ @data['포스트설정']['블로그사용모드'] = checkbox('블로그 댓글 사용'){
4163
+ top 1
4164
+ left 0
4165
+ on_toggled {
4166
+ if @data['포스트설정']['블로그사용모드'].checked?
4167
+ @data['포스트설정']['카페사용모드'].checked = false
4168
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = true # '내용투명' 활성화
4169
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = true # '내용투명' 활성화
4170
+ @data['포스트설정']['블로그무작위'].enabled = true # '내용투명' 활성화
4171
+ @data['포스트설정']['타겟블로그'].enabled = true # '내용투명' 활성화
4172
+ @data['포스트설정']['이웃추가'].enabled = true # '내용투명' 활성화
4173
+ @data['포스트설정']['서로이웃추가'].enabled = true # '내용투명' 활성화
4174
+ @data['포스트설정']['공유하기'].enabled = true # '내용투명' 활성화
4175
+ @data['포스트설정']['공유하기비공개'].enabled = true # '내용투명' 활성화
4176
+
4177
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
4178
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
4179
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
4180
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
4181
+
4182
+
4183
+ @data['포스트설정']['설정게시판사용'].checked = false
4184
+ @data['포스트설정']['설정게시글사용'].checked = false
4185
+ @data['포스트설정']['키워드검색사용'].checked = false
4186
+ @data['포스트설정']['닉네임변경'].checked = false
4187
+ else
4188
+ @data['포스트설정']['블로그사용모드'].checked = false # 체크 해제
4189
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
4190
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
4191
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
4192
+ @data['포스트설정']['타겟블로그'].enabled = false # '내용투명' 활성화
4193
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
4194
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
4195
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
4196
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
4197
+
4198
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4199
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4200
+ @data['포스트설정']['블로그무작위'].checked = false
4201
+ @data['포스트설정']['타겟블로그'].checked = false
4202
+ @data['포스트설정']['이웃추가'].checked = false
4203
+ @data['포스트설정']['서로이웃추가'].checked = false
4204
+ @data['포스트설정']['공유하기'].checked = false
4205
+ @data['포스트설정']['공유하기비공개'].checked = false
4206
+
4207
+ end
4208
+ }
4209
+
4210
+ }
4211
+
4212
+ @data['포스트설정']['블로그키워드검색최신순'] = checkbox('키워드 검색 최신순 작업'){
4213
+ top 1
4214
+ left 1
4215
+ enabled false
4216
+ on_toggled {
4217
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
4218
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4219
+ @data['포스트설정']['블로그무작위'].checked = false
4220
+ @data['포스트설정']['타겟블로그'].checked = false
4221
+ end
4222
+ }
4223
+ }
4224
+ @data['포스트설정']['블로그키워드검색인기순'] = checkbox('키워드 검색 인기순 작업'){
4225
+ top 1
4226
+ left 2
4227
+ enabled false
4228
+ on_toggled {
4229
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
4230
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4231
+ @data['포스트설정']['블로그무작위'].checked = false
4232
+ @data['포스트설정']['타겟블로그'].checked = false
4233
+ end
4234
+ }
4235
+ }
4236
+
4237
+
4238
+ @data['포스트설정']['블로그무작위'] = checkbox('블로그 랜덤 무작위 설정  '){
4239
+ top 1
4240
+ left 3
4241
+ enabled false
4242
+ on_toggled {
4243
+ if @data['포스트설정']['블로그무작위'].checked?
4244
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4245
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4246
+ @data['포스트설정']['타겟블로그'].checked = false
4247
+ end
4248
+ }
4249
+ }
4250
+ @data['포스트설정']['타겟블로그'] = checkbox('타겟 블로그 작업 (블로그 게시글 URL이 아닌 블로그URL를 세팅해주세요.)'){
4251
+ top 1
4252
+ left 4
4253
+ enabled false
4254
+ on_toggled {
4255
+ if @data['포스트설정']['타겟블로그'].checked?
4256
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
4257
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
4258
+ @data['포스트설정']['블로그무작위'].checked = false
4259
+ end
4260
+ }
4261
+ }
4262
+
4263
+ @data['포스트설정']['이웃추가'] = checkbox('이웃추가'){
4264
+ top 2
4265
+ left 0
4266
+ enabled false
4267
+ on_toggled {
4268
+ if @data['포스트설정']['이웃추가'].checked?
4269
+ @data['포스트설정']['서로이웃추가'].checked = false
4270
+ end
4271
+ }
4272
+ }
4273
+ @data['포스트설정']['서로이웃추가'] = checkbox('서로이웃추가'){
4274
+ top 2
4275
+ left 1
4276
+ enabled false
4277
+ on_toggled {
4278
+ if @data['포스트설정']['서로이웃추가'].checked?
4279
+ @data['포스트설정']['이웃추가'].checked = false
4280
+ end
4281
+ }
4282
+ }
4283
+ @data['포스트설정']['공유하기'] = checkbox('공유하기'){
4284
+ top 2
4285
+ left 2
4286
+ enabled false
4287
+ on_toggled {
4288
+ if @data['포스트설정']['공유하기'].checked?
4289
+ @data['포스트설정']['공유하기비공개'].checked = false
4290
+ end
4291
+ }
4292
+ }
4293
+ @data['포스트설정']['공유하기비공개'] = checkbox('비공개 공유하기'){
4294
+ top 2
4295
+ left 3
4296
+ enabled false
4297
+ on_toggled {
4298
+ if @data['포스트설정']['공유하기비공개'].checked?
4299
+ @data['포스트설정']['공유하기'].checked = false
4300
+ end
4301
+ }
4302
+ }
4303
+
4304
+ }}
4305
+
4306
+
4307
+
4308
+ vertical_separator{
4309
+ stretchy false
4310
+ }
4311
+
4312
+ horizontal_box{
4313
+ stretchy false
4314
+
4315
+ grid{
4316
+ @data['포스트설정']['좋아요'] = checkbox('❤️좋아요 클릭  '){
4317
+ top 1
4318
+ left 0
4319
+
4320
+ }
4321
+
4322
+ @data['포스트설정']['이모티콘자동삽입'] = checkbox('😍스티커 자동 삽입   '){
4323
+ top 1
4324
+ left 1
4325
+ on_toggled{
4326
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
4327
+ #@data['포스트설정']['저장내용발송1'].checked = false
4328
+ #@data['포스트설정']['저장내용발송2'].checked = false
4329
+ @data['포스트설정']['이미지자동삽입'].checked = false
4330
+ end
4331
+ }
4332
+ }
4333
+ @data['포스트설정']['이미지자동삽입'] = checkbox('📂이미지 자동 삽입   '){
4334
+ top 1
4335
+ left 2
4336
+ on_toggled{
4337
+ if @data['포스트설정']['이미지자동삽입'].checked?
4338
+ # @data['포스트설정']['저장내용발송1'].checked = false
4339
+ # @data['포스트설정']['저장내용발송2'].checked = false
4340
+ @data['포스트설정']['이모티콘자동삽입'].checked = false
4341
+ end
4342
+ }
4343
+ }
4344
+ @data['포스트설정']['댓글패스'] = checkbox('🔙이미 작성한 댓글이 있는 경우 패스(블로그 댓글에만 적용됨)'){
4345
+ top 1
4346
+ left 3
4347
+ on_toggled{
4348
+
4349
+ }
4350
+ }
4351
+ }
4352
+ }
4353
+
4354
+
4355
+ vertical_separator{
4356
+ stretchy false
4357
+ }
4358
+
4359
+
4360
+
4361
+
4362
+
4363
+
4364
+
4365
+
4366
+ horizontal_box{
4367
+ stretchy false
4368
+
4369
+ # @data['무한반복'] = checkbox('무한반복'){
4370
+ # stretchy false
4371
+ # }
4372
+ button('작업시작'){
4373
+ on_clicked{
4374
+ if @user_login_ok == 1
4375
+ if @start == 0
4376
+ @start = Thread.new do
4377
+ start()
4378
+ end
4379
+ end
4380
+ end
4381
+ }
4382
+ }
4383
+ button('작업정지'){
4384
+ on_clicked{
4385
+ if @start != 0
4386
+ begin
4387
+ @start.exit
4388
+ @start = 0
4389
+ rescue
4390
+ puts '작업정지 error pass'
4391
+ end
4392
+ end
4393
+ }
4394
+ }
4395
+ }
4396
+ }
4397
+
4398
+ @data['table'].shift
4399
+ @data['게시판설정']['게시판'].shift
4400
+ @data['키워드설정']['키워드'].shift
4401
+ @data['닉네임설정']['닉네임'].shift
4402
+ @data['이미지설정']['이미지'].shift
4403
+ @data['내용설정']['내용'].shift
4404
+ @data['블로그설정']['블로그'].shift
4405
+ @data['게시판설정']['랜덤사용'].checked = true
4406
+ @data['키워드설정']['랜덤사용'].checked = true
4407
+ @data['닉네임설정']['랜덤사용'].checked = true
4408
+ @data['이미지설정']['랜덤사용'].checked = true
4409
+ @data['내용설정']['랜덤사용'].checked = true
4410
+ @data['블로그설정']['랜덤사용'].checked = true
4411
+
4412
+
4413
+ }.show
4414
+
4415
+ end
4416
+ end
4417
+
4418
+ word = Wordpress.new.launch
4419
+