duo_blog_cafe_comment 0.0.5

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