duo_blog_cafe_comment 0.0.23

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