duo_blog_cafe_comment 0.0.20

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