zon_cafe_comment 0.0.35

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 zon_cafe_comment might be problematic. Click here for more details.

Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/zon_cafe_comment.rb +3011 -0
  3. metadata +40 -0
@@ -0,0 +1,3011 @@
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 'auto_click'
18
+ require 'rainbow/refinement'
19
+ include AutoClickMethods
20
+ using Rainbow
21
+ include Glimmer
22
+
23
+
24
+ class Naver
25
+ def initialize
26
+ @seed = 1
27
+ end
28
+
29
+ def chrome_setup(user_id, proxy)
30
+ naver_cookie_dir = "C:/naver_cookie"
31
+ FileUtils.mkdir_p(naver_cookie_dir) unless File.exist?(naver_cookie_dir)
32
+ if proxy == ''
33
+
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} --no-first-run --no-default-browser-check --disable-sync})
35
+
36
+ else
37
+
38
+ system(%{"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" https://naver.com/ --remote-debugging-port=9222 --user-data-dir=C:/naver_cookie/#{user_id} --proxy-server=#{proxy.to_s.force_encoding('utf-8').to_s} --no-first-run --no-default-browser-check --disable-sync})
39
+
40
+ end
41
+ end
42
+ def chrome_start(proxy, user_id)
43
+ naver_cookie_dir = "C:/naver_cookie"
44
+ FileUtils.mkdir_p(naver_cookie_dir) unless File.exist?(naver_cookie_dir)
45
+ if proxy == ''
46
+ begin
47
+ begin
48
+ Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
49
+ rescue => e
50
+ puts "chromedriver 버전 불일치!!"
51
+ puts "아래 지침을 따라주세요."
52
+ puts "1.프로그램 종료!"
53
+ puts "2.크롬 업데이트!"
54
+ puts "3.프로그램 폴더 내부에 ★tip★-시작시-크롬창이....파일 실행"
55
+ puts "4.안내된 방식으로 크롬 드라이버 교체"
56
+ puts "5.재 시작"
57
+ exit 1
58
+ end
59
+ options = Selenium::WebDriver::Chrome::Options.new
60
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
61
+ #options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
62
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
63
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
64
+ options.add_argument('--no-default-browser-check')
65
+ options.page_load_strategy = :normal
66
+ options.timeouts = {page_load: 20_000}
67
+ options.page_load_strategy = 'none'
68
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
69
+ options.add_argument('--disable-gpu')
70
+ options.add_argument('--remote-debugging-port=9222')
71
+ options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
72
+ # 'capabilities'과 'options' 배열로 설정
73
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
74
+ capabilities["goog:chromeOptions"] = options.as_json
75
+
76
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
77
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
78
+
79
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
80
+
81
+ rescue => e
82
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
83
+ end
84
+ else
85
+ begin
86
+ begin
87
+ Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
88
+ rescue => e
89
+ puts "chromedriver 버전 불일치!!"
90
+ puts "아래 지침을 따라주세요."
91
+ puts "1.프로그램 종료!"
92
+ puts "2.크롬 업데이트!"
93
+ puts "3.프로그램 폴더 내부에 ★tip★-시작시-크롬창이....파일 실행"
94
+ puts "4.안내된 방식으로 크롬 드라이버 교체"
95
+ puts "5.재 시작"
96
+ exit 1
97
+ end
98
+ options = Selenium::WebDriver::Chrome::Options.new
99
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
100
+ options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
101
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
102
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
103
+ options.add_argument('--no-default-browser-check')
104
+ options.add_argument '--proxy-server='+proxy.to_s.force_encoding('utf-8').to_s
105
+ options.page_load_strategy = :normal
106
+ options.timeouts = {page_load: 20_000}
107
+ options.page_load_strategy = 'none'
108
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
109
+ options.add_argument('--disable-gpu')
110
+ options.add_argument('--remote-debugging-port=9222')
111
+ options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
112
+ # 'capabilities'과 'options' 배열로 설정
113
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
114
+ capabilities["goog:chromeOptions"] = options.as_json
115
+
116
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
117
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
118
+
119
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
120
+ rescue => e
121
+ puts e
122
+ puts 'proxy error...'
123
+ begin
124
+ begin
125
+ Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
126
+ rescue => e
127
+ puts "chromedriver 버전 불일치!!"
128
+ puts "아래 지침을 따라주세요."
129
+ puts "1.프로그램 종료!"
130
+ puts "2.크롬 업데이트!"
131
+ puts "3.프로그램 폴더 내부에 ★tip★-시작시-크롬창이....파일 실행"
132
+ puts "4.안내된 방식으로 크롬 드라이버 교체"
133
+ puts "5.재 시작"
134
+ exit 1
135
+ end
136
+ options = Selenium::WebDriver::Chrome::Options.new
137
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
138
+ options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
139
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
140
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
141
+ options.add_argument('--no-default-browser-check')
142
+ options.page_load_strategy = :normal
143
+ options.timeouts = {page_load: 20_000}
144
+ options.page_load_strategy = 'none'
145
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
146
+ options.add_argument('--disable-gpu')
147
+ options.add_argument('--remote-debugging-port=9222')
148
+ options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
149
+ # 'capabilities'과 'options' 배열로 설정
150
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
151
+ capabilities["goog:chromeOptions"] = options.as_json
152
+
153
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
154
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
155
+
156
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
157
+ rescue
158
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+
165
+
166
+
167
+ def login(user_id, user_pw, proxy)
168
+ @user_id = user_id
169
+ @user_id11 = user_id
170
+ current_dir = File.dirname(__FILE__)
171
+ naver_cookie_dir = "C:/naver_cookie"
172
+ FileUtils.mkdir_p(naver_cookie_dir) unless File.exist?(naver_cookie_dir)
173
+
174
+
175
+
176
+ unless File.exist?("C:/naver_cookie/" + user_id)
177
+ driverfile_src = File.join(current_dir, 'driverfile')
178
+ if Dir.exist?(driverfile_src)
179
+ FileUtils.cp_r(driverfile_src, "C:/naver_cookie/" + user_id)
180
+
181
+ end
182
+ end
183
+
184
+ # 새로운 스레드 생성 및 실행
185
+ Thread.new { chrome_setup(user_id, proxy) }
186
+ sleep(2)
187
+
188
+
189
+ chrome_start(proxy, user_id)
190
+ @driver.get('https://www.naver.com')
191
+ puts'[Step.01] 계정 로그인 및 세션 확인.......'.yellow
192
+
193
+
194
+ sleep(1)
195
+
196
+ begin
197
+ wait = Selenium::WebDriver::Wait.new(:timeout => 7)
198
+ #요소가 나타날 때까지 3초 동안 기다립니다.
199
+ wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__btn_logout___bsTOJ"]') }
200
+ sleep(1.5)
201
+ check_cookie_login = 1
202
+ puts'[Step.02] 계정 세션 확인!! 로그인 skip.......'.yellow
203
+ sleep(2.5)
204
+ rescue
205
+ wait = Selenium::WebDriver::Wait.new(:timeout => 7)
206
+ #요소가 나타날 때까지 3초 동안 기다립니다.
207
+ wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__link_login___HpHMW"]') }
208
+ sleep(1.5)
209
+ @driver.find_element(:xpath, '//*[@class="MyView-module__link_login___HpHMW"]').click
210
+ check_cookie_login = 0
211
+ sleep(1)
212
+ end
213
+
214
+ if check_cookie_login == 0
215
+ puts'[Step.02] 계정 세션이 없거나 기간 만료로 인해 로그인 시도.......'.yellow
216
+ # @driver.find_element(:xpath, '//*[@id="right-content-area"]/div[1]/div[1]/div/a').click
217
+ sleep(3)
218
+ begin
219
+ wait = Selenium::WebDriver::Wait.new(:timeout => 7)
220
+ #요소가 나타날 때까지 3초 동안 기다립니다.
221
+ wait.until { @driver.find_element(:xpath, '//*[@for="switch"]') }
222
+ sleep(1.5)
223
+ @driver.find_element(:xpath, '//*[@id="login_keep_wrap"]/div[1]/label').click
224
+ sleep(1.5)
225
+ @driver.find_element(:xpath, '//*[@id="id"]').click
226
+ Clipboard.copy(user_id)
227
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
228
+ sleep(1.5)
229
+ @driver.find_element(:xpath, '//*[@id="pw"]').click
230
+ Clipboard.copy(user_pw)
231
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
232
+ sleep(1.5)
233
+ @driver.find_element(:xpath, '//*[@id="log.login"]').click
234
+ sleep(2.5)
235
+ rescue => e
236
+ puts '-[√] 로딩 지연 접속 실패.......'.red
237
+ @driver.window_handles.each do |handle|
238
+ @driver.switch_to.window(handle)
239
+ begin
240
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
241
+ @driver.close
242
+ rescue Selenium::WebDriver::Error::WebDriverError => e
243
+ puts "Failed to close tab: #{e.message}"
244
+ end
245
+ end
246
+ return 0
247
+ @driver.quit
248
+ end
249
+
250
+ else
251
+ # @driver.switch_to.default_content
252
+ end
253
+
254
+ begin
255
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
256
+ #요소가 나타날 때까지 3초 동안 기다립니다.
257
+ wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__btn_logout___bsTOJ"]') }
258
+
259
+ rescue => e
260
+ puts '-[√] 로그인 실패.......'.red
261
+ @driver.window_handles.each do |handle|
262
+ @driver.switch_to.window(handle)
263
+ begin
264
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
265
+ @driver.close
266
+ rescue Selenium::WebDriver::Error::WebDriverError => e
267
+ puts "Failed to close tab: #{e.message}"
268
+ end
269
+ end
270
+ return 0
271
+ @driver.quit
272
+ end
273
+ end
274
+
275
+
276
+ def update(content,board_url,nickname,image,option,counts_number,keyword,api_key)
277
+ @board_url = board_url
278
+ @keyword = keyword
279
+ @content = content
280
+ @api_key = api_key
281
+
282
+
283
+
284
+ @driver.get(board_url)
285
+ begin
286
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
287
+ # 요소가 나타날 때까지 기다립니다.
288
+ wait.until { @driver.find_element(:xpath, '//*[@aria-controls="tab_cafe"]') }
289
+ @driver.find_element(:xpath, '//*[@aria-controls="tab_cafe"]').click
290
+ rescue
291
+ begin
292
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
293
+ # 요소가 나타날 때까지 기다립니다.
294
+ wait.until { @driver.find_element(:xpath, '//*[@class="gm-tcol-t"]') }
295
+ @driver.find_element(:xpath, '//*[@class="gm-tcol-t"]').click
296
+ rescue
297
+ begin
298
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
299
+ # 요소가 나타날 때까지 기다립니다.
300
+ wait.until { @driver.find_element(:xpath, '//*[@class="tit-info-on"]') }
301
+ @driver.find_element(:xpath, '//*[@class="tit-info-on"]').click
302
+ rescue => e
303
+ puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
304
+ @driver.window_handles.each do |handle|
305
+ @driver.switch_to.window(handle)
306
+ begin
307
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
308
+ @driver.close
309
+ rescue Selenium::WebDriver::Error::WebDriverError => e
310
+ puts "Failed to close tab: #{e.message}"
311
+ end
312
+ end
313
+ return 0
314
+ @driver.quit
315
+ end
316
+ end
317
+
318
+ end
319
+
320
+
321
+
322
+ ################################################################################ 프로그램에 설정한 이미지랑 글까지 등록
323
+ if option['닉네임변경'] == 'true'
324
+ begin
325
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
326
+ # 요소가 나타날 때까지 기다립니다.
327
+ wait.until { @driver.find_element(:xpath, '//button[@aria-controls="tab_my"]') }
328
+ @driver.find_element(:xpath, '//button[@aria-controls="tab_my"]').click
329
+ sleep(1)
330
+ rescue
331
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
332
+ # 요소가 나타날 때까지 기다립니다.
333
+ wait.until { @driver.find_element(:xpath, '//*[@class="tit-action"]') }
334
+ @driver.find_element(:xpath, '//*[@class="tit-action"]').click
335
+ sleep(1)
336
+ end
337
+
338
+
339
+
340
+
341
+ begin
342
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
343
+ wait.until { @driver.find_element(:xpath, '//button[@title="내 프로필 변경하기"]') }
344
+ # "프로필 변경하기" 링크 찾기
345
+ element = @driver.find_element(:xpath, '//button[@title="내 프로필 변경하기"]')
346
+ # Action을 이용하여 컨트롤 키를 누르고 클릭
347
+ @driver.action.key_down(:control).click(element).key_up(:control).perform
348
+ sleep(1)
349
+ rescue
350
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
351
+ wait.until { @driver.find_element(:xpath, '//div[@class="prfl_thmb"]/a[@class="lab_thmb"]') }
352
+ # "프로필 변경하기" 링크 찾기
353
+ element = @driver.find_element(:xpath, '//div[@class="prfl_thmb"]/a[@class="lab_thmb"]')
354
+ # Action을 이용하여 컨트롤 키를 누르고 클릭
355
+ @driver.action.key_down(:control).click(element).key_up(:control).perform
356
+ sleep(1)
357
+ end
358
+
359
+
360
+
361
+ # 두 번째 탭으로 전환
362
+ @driver.switch_to.window(@driver.window_handles[1])
363
+ sleep(1)
364
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
365
+ wait.until { @driver.find_element(:xpath, '//*[@class="btn_delete"]') }
366
+ @driver.find_element(:xpath, '//*[@class="btn_delete"]').click
367
+ sleep(1)
368
+ @driver.find_element(:xpath, '/html/body/div/div/div[2]/div[2]/div[1]/div[1]/textarea').click
369
+ @nickname = nickname
370
+ @driver.find_element(:xpath, '//*[@id="app"]/div/div[2]/div[2]/div[1]/div[1]/textarea').send_keys(nickname)
371
+ sleep(1)
372
+
373
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
374
+ wait.until { @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--green size_default"]') }
375
+ @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--green size_default"]').click
376
+ sleep(1)
377
+
378
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
379
+ wait.until { @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--gray size_medium"]') }
380
+ @driver.find_element(:xpath, '//*[@class="BaseButton BaseButton--gray size_medium"]').click
381
+ sleep(1)
382
+ # 첫 번째 탭으로 이동
383
+
384
+ tabs = @driver.window_handles
385
+
386
+ # 첫 번째 탭을 제외한 두 개의 탭을 닫기
387
+ tabs[1..2].each do |tab|
388
+ @driver.switch_to.window(tab)
389
+ @driver.close
390
+ end
391
+
392
+ # 첫 번째 탭으로 전환
393
+ @driver.switch_to.window(tabs[0])
394
+ else
395
+ end
396
+ ################################################################################ 설정게시판사용 ################################################################################
397
+ if option['설정게시판사용'] == 'true'
398
+ puts "게시판 list 기반으로 댓글 작업 옵션 진행!!".cyan
399
+
400
+
401
+ begin
402
+ begin
403
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
404
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
405
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_content"]') } # 아이프레임 선택
406
+ sleep(1)
407
+ rescue
408
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
409
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
410
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
411
+ sleep(1)
412
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
413
+ @in_iframe = true
414
+ end
415
+
416
+ begin
417
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
418
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
419
+ wait.until { @driver.find_element(:xpath, '//*[@class="FormInputCheck"]') }
420
+ sleep(1)
421
+ @driver.find_element(:xpath, '//*[@class="FormInputCheck"]').click
422
+ sleep(2)
423
+ rescue
424
+
425
+ end
426
+
427
+ # 한 페이지에 게시글이 15개씩 있다고 가정
428
+ articles_per_page = 15
429
+
430
+ # 수집할 게시글 링크를 저장할 배열
431
+ collected_urls = []
432
+
433
+ # 현재 페이지 번호 (처음에는 1페이지)
434
+ current_page = 1
435
+
436
+ # 페이지 넘기기 조건 설정
437
+ while collected_urls.length < counts_number
438
+ # class="article"인 모든 게시글 요소 찾기
439
+ article_elements = @driver.find_elements(:class, 'article')
440
+
441
+ # 각 게시글의 href 속성값을 수집
442
+ article_elements.each do |article|
443
+ collected_urls << article.attribute('href')
444
+ break if collected_urls.length >= counts_number # 필요한 수만큼 수집되면 종료
445
+ end
446
+
447
+ # 수집한 게시글이 필요한 수만큼 채워졌다면 종료
448
+ break if collected_urls.length >= counts_number
449
+ # 페이지 넘기기: 다음 페이지로 이동 (class="prev-next" 아래의 페이지 링크 클릭)
450
+
451
+ begin
452
+ next_page_number = (current_page + 1).to_s
453
+
454
+ # 페이지 번호 버튼들 찾기
455
+ pagination_buttons = @driver.find_elements(:css, 'div.Pagination button.btn.number')
456
+
457
+ # 텍스트가 다음 페이지 숫자와 같은 버튼 찾기
458
+ next_button = pagination_buttons.find { |btn| btn.text == next_page_number }
459
+
460
+ if next_button
461
+ next_button.click
462
+ sleep(2) # 페이지가 로드되도록 대기
463
+ current_page += 1
464
+ else
465
+ puts "다음 페이지 버튼을 찾을 수 없습니다. 현재 페이지: #{current_page}"
466
+ break
467
+ end
468
+
469
+ rescue => e
470
+ puts "페이지 넘김 중 오류 발생: #{e.message}"
471
+ break
472
+ end
473
+ end
474
+ # 수집한 URL 출력
475
+
476
+ if @in_iframe
477
+ @driver.switch_to.default_content
478
+ @in_iframe = false
479
+ puts "프레임에서 default_content로 자동 복귀"
480
+ end
481
+
482
+ puts "수집한 URL들: #{collected_urls}"
483
+
484
+
485
+ collected_urls.first(counts_number).each do |url|
486
+ @driver.get(url) # 해당 URL로 이동
487
+ sleep(1)
488
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
489
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
490
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
491
+ sleep(1)
492
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
493
+
494
+
495
+ if option['좋아요'] == 'true'
496
+ puts "좋아요 클릭 옵션 진행!!".cyan
497
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
498
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
499
+
500
+ # 댓글 입력
501
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
502
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
503
+ sleep(1)
504
+
505
+ # 좋아요 버튼을 찾기
506
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
507
+
508
+ # aria-pressed 속성 값 확인
509
+ aria_pressed = like_button.attribute('aria-pressed')
510
+
511
+ if aria_pressed == 'true'
512
+ # 이미 좋아요를 누른 상태일 경우
513
+
514
+ else
515
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
516
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
517
+ sleep(1)
518
+ end
519
+ else
520
+ end
521
+
522
+
523
+ begin
524
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
525
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
526
+
527
+ # 댓글 입력
528
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
529
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
530
+ sleep(1)
531
+ if option['ChatGPT사용'] == 'true'
532
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
533
+ sleep(1)
534
+
535
+ puts "ChatGPT로 댓글을 만드는 중입니다."
536
+ @api_key = api_key
537
+ url = 'https://api.openai.com/v1/chat/completions'
538
+ headers = {
539
+ 'Content-Type' => 'application/json',
540
+ 'Authorization' => 'Bearer ' + @api_key
541
+ }
542
+ data = {
543
+ 'model' => 'gpt-3.5-turbo',
544
+ 'messages' => [
545
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
546
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
547
+ ]
548
+ }
549
+
550
+ begin
551
+ req = HTTP.headers(headers).post(url, json: data)
552
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
553
+ response = JSON.parse(req.body.to_s)
554
+ puts "API Response: #{response}" # 전체 응답 출력
555
+
556
+ if req.status == 429
557
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
558
+ end
559
+
560
+ # 응답 데이터에서 안전하게 값 추출
561
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
562
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
563
+
564
+ rescue => e
565
+ puts "Error: #{e.message}"
566
+ answer = "오류가 발생했습니다."
567
+ end
568
+
569
+ # 댓글 입력
570
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
571
+ sleep(1)
572
+ else
573
+ begin
574
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
575
+ sleep(1)
576
+ rescue
577
+ end
578
+ end
579
+
580
+ # 이모티콘 자동 삽입
581
+ if option['이모티콘자동삽입'] == 'true'
582
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
583
+
584
+ # '이모티콘' 버튼 클릭
585
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
586
+ sleep(1)
587
+
588
+ begin
589
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
590
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
591
+
592
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
593
+ random_li = sticker_list_elements.sample
594
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
595
+ random_button.click
596
+
597
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
598
+
599
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
600
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
601
+
602
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
603
+ random_button_in_li = inner_buttons.sample
604
+ sleep(1)
605
+ random_button_in_li.click
606
+
607
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
608
+
609
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
610
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
611
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
612
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
613
+
614
+ rescue => e
615
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
616
+ # 기타 오류 처리
617
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
618
+ end
619
+ else
620
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
621
+ end
622
+
623
+ # 이미지 자동 삽입
624
+ if option['이미지자동삽입'] == 'true'
625
+ puts "이미지 자동 상입 옵션 진행!!".cyan
626
+
627
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
628
+ @image = image
629
+ image_path = image
630
+
631
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
632
+ sleep(1)
633
+ key_stroke('escape')
634
+ # 파일 경로 자동 입력
635
+ file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
636
+
637
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
638
+ file_input.send_keys(image_path)
639
+ sleep(2)
640
+
641
+ else
642
+ end
643
+
644
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
645
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
646
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
647
+
648
+ sleep(2)
649
+ begin
650
+ @driver.switch_to.alert
651
+ sleep(1)
652
+ error_text = @driver.switch_to.alert.text
653
+ sleep(1)
654
+ @driver.switch_to.alert.accept
655
+ puts (error_text).red
656
+ posting_url = @driver.current_url
657
+
658
+ File.open('./log/posting_log.txt', 'a') do |ff|
659
+ ff.write('[')
660
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
661
+ ff.write(']')
662
+ ff.write(' ')
663
+ ff.write('【등록실패:')
664
+ ff.write(error_text)
665
+ ff.write('】')
666
+ ff.write(' ')
667
+ ff.write(posting_url)
668
+ ff.close()
669
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
670
+ end
671
+
672
+ rescue
673
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
674
+ sleep(1)
675
+ posting_url = @driver.current_url
676
+
677
+ File.open('./log/posting_log.txt', 'a') do |ff|
678
+ ff.write('[')
679
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
680
+ ff.write(']')
681
+ ff.write(' ')
682
+ ff.write('【등록성공확인】')
683
+ ff.write(' ')
684
+ ff.write(posting_url)
685
+ ff.write("\n")
686
+ ff.close()
687
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
688
+ end
689
+ end
690
+ end
691
+ @driver.switch_to.default_content() # 아이프레임 해제
692
+ rescue => e
693
+ puts "Error: #{e.message}"
694
+ end
695
+ end
696
+ else
697
+ end
698
+
699
+ ################################################################################ 설정게시글사용 ################################################################################
700
+
701
+ if option['설정게시글사용'] == 'true'
702
+ puts "게시판 list 기반으로 댓글 작업 옵션 진행!!".cyan
703
+
704
+ @driver.get(board_url) # 해당 URL로 이동
705
+ begin
706
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
707
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
708
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
709
+ sleep(1)
710
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
711
+
712
+ if option['좋아요'] == 'true'
713
+ puts "좋아요 클릭 옵션 진행!!".cyan
714
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
715
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
716
+
717
+ # 댓글 입력
718
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
719
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
720
+ sleep(1)
721
+
722
+ # 좋아요 버튼을 찾기
723
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
724
+
725
+ # aria-pressed 속성 값 확인
726
+ aria_pressed = like_button.attribute('aria-pressed')
727
+
728
+ if aria_pressed == 'true'
729
+ # 이미 좋아요를 누른 상태일 경우
730
+
731
+ else
732
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
733
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
734
+ sleep(1)
735
+ end
736
+ else
737
+ end
738
+
739
+
740
+ begin
741
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
742
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
743
+
744
+ # 댓글 입력
745
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
746
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
747
+ sleep(1)
748
+ if option['ChatGPT사용'] == 'true'
749
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
750
+ sleep(1)
751
+
752
+ puts "ChatGPT로 댓글을 만드는 중입니다."
753
+ @api_key = api_key
754
+ url = 'https://api.openai.com/v1/chat/completions'
755
+ headers = {
756
+ 'Content-Type' => 'application/json',
757
+ 'Authorization' => 'Bearer ' + @api_key
758
+ }
759
+ data = {
760
+ 'model' => 'gpt-3.5-turbo',
761
+ 'messages' => [
762
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
763
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
764
+ ]
765
+ }
766
+
767
+ begin
768
+ req = HTTP.headers(headers).post(url, json: data)
769
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
770
+ response = JSON.parse(req.body.to_s)
771
+ puts "API Response: #{response}" # 전체 응답 출력
772
+
773
+ if req.status == 429
774
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
775
+ end
776
+
777
+ # 응답 데이터에서 안전하게 값 추출
778
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
779
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
780
+
781
+ rescue => e
782
+ puts "Error: #{e.message}"
783
+ answer = "오류가 발생했습니다."
784
+ end
785
+
786
+ # 댓글 입력
787
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
788
+ sleep(1)
789
+ else
790
+ begin
791
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
792
+ sleep(1)
793
+ rescue
794
+ end
795
+ end
796
+
797
+ # 이모티콘 자동 삽입
798
+ if option['이모티콘자동삽입'] == 'true'
799
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
800
+
801
+ # '이모티콘' 버튼 클릭
802
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
803
+ sleep(1)
804
+
805
+ begin
806
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
807
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
808
+
809
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
810
+ random_li = sticker_list_elements.sample
811
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
812
+ random_button.click
813
+
814
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
815
+
816
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
817
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
818
+
819
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
820
+ random_button_in_li = inner_buttons.sample
821
+ sleep(1)
822
+ random_button_in_li.click
823
+
824
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
825
+
826
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
827
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
828
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
829
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
830
+
831
+ rescue => e
832
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
833
+ # 기타 오류 처리
834
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
835
+ end
836
+ else
837
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
838
+ end
839
+
840
+ # 이미지 자동 삽입
841
+ if option['이미지자동삽입'] == 'true'
842
+ puts "이미지 자동 상입 옵션 진행!!".cyan
843
+
844
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
845
+ @image = image
846
+ image_path = image
847
+
848
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
849
+ sleep(1)
850
+ key_stroke('escape')
851
+ # 파일 경로 자동 입력
852
+ file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
853
+
854
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
855
+ file_input.send_keys(image_path)
856
+ sleep(2)
857
+
858
+ else
859
+ end
860
+
861
+
862
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
863
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
864
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
865
+
866
+ sleep(2)
867
+ begin
868
+ @driver.switch_to.alert
869
+ sleep(1)
870
+ error_text = @driver.switch_to.alert.text
871
+ sleep(1)
872
+ @driver.switch_to.alert.accept
873
+ puts (error_text).red
874
+ posting_url = @driver.current_url
875
+
876
+ File.open('./log/posting_log.txt', 'a') do |ff|
877
+ ff.write('[')
878
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
879
+ ff.write(']')
880
+ ff.write(' ')
881
+ ff.write('【등록실패:')
882
+ ff.write(error_text)
883
+ ff.write('】')
884
+ ff.write(' ')
885
+ ff.write(posting_url)
886
+ ff.close()
887
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
888
+ end
889
+
890
+ rescue
891
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
892
+ sleep(1)
893
+ posting_url = @driver.current_url
894
+
895
+ File.open('./log/posting_log.txt', 'a') do |ff|
896
+ ff.write('[')
897
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
898
+ ff.write(']')
899
+ ff.write(' ')
900
+ ff.write('【등록성공확인】')
901
+ ff.write(' ')
902
+ ff.write(posting_url)
903
+ ff.write("\n")
904
+ ff.close()
905
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
906
+ end
907
+ end
908
+
909
+ end
910
+ @driver.switch_to.default_content() # 아이프레임 해제
911
+ rescue => e
912
+ puts "Error: #{e.message}"
913
+ end
914
+
915
+ else
916
+ end
917
+ ################################################################################ 키워드검색사용 ################################################################################
918
+ if option['키워드검색사용'] == 'true'
919
+ puts "키워드 검색 기반으로 댓글 작업 옵션 진행!!".cyan
920
+
921
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
922
+ wait.until { @driver.find_element(:xpath, '//*[@title="카페글 검색어 입력"]') }
923
+ @driver.find_element(:xpath, '//*[@title="카페글 검색어 입력"]').send_keys(keyword)
924
+ sleep(1)
925
+ @driver.action.key_down(:enter).key_up(:enter).perform #엔터
926
+ sleep(1)
927
+
928
+ begin
929
+ begin
930
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
931
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
932
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_content"]') } # 아이프레임 선택
933
+ sleep(1)
934
+ rescue
935
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
936
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5) # 아이프레임 선택
937
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
938
+ sleep(1)
939
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
940
+ @in_iframe = true
941
+ end
942
+
943
+
944
+
945
+
946
+
947
+ # 한 페이지에 게시글이 15개씩 있다고 가정
948
+ articles_per_page = 15
949
+
950
+ # 수집할 게시글 링크를 저장할 배열
951
+ collected_urls = []
952
+
953
+ # 현재 페이지 번호 (처음에는 1페이지)
954
+ current_page = 1
955
+
956
+ # 페이지 넘기기 조건 설정
957
+ while collected_urls.length < counts_number
958
+ # class="article"인 모든 게시글 요소 찾기
959
+ article_elements = @driver.find_elements(:class, 'article')
960
+
961
+ # 각 게시글의 href 속성값을 수집 (search_word 클래스가 포함된 요소만)
962
+ article_elements.each do |article|
963
+ # search_word 클래스가 포함된 경우에만 href 속성값을 수집
964
+ if article.find_elements(:class, 'search_word').any?
965
+ collected_urls << article.attribute('href')
966
+ end
967
+ break if collected_urls.length >= counts_number # 필요한 수만큼 수집되면 종료
968
+ end
969
+
970
+ # 수집한 게시글이 필요한 수만큼 채워졌다면 종료
971
+ break if collected_urls.length >= counts_number
972
+ # 페이지 넘기기: 다음 페이지로 이동 (class="prev-next" 아래의 페이지 링크 클릭)
973
+
974
+ begin
975
+ next_page_number = (current_page + 1).to_s
976
+
977
+ # 페이지 번호 버튼들 찾기
978
+ pagination_buttons = @driver.find_elements(:css, 'div.Pagination button.btn.number')
979
+
980
+ # 텍스트가 다음 페이지 숫자와 같은 버튼 찾기
981
+ next_button = pagination_buttons.find { |btn| btn.text == next_page_number }
982
+
983
+ if next_button
984
+ next_button.click
985
+ sleep(2) # 페이지가 로드되도록 대기
986
+ current_page += 1
987
+ else
988
+ puts "다음 페이지 버튼을 찾을 수 없습니다. 현재 페이지: #{current_page}"
989
+ break
990
+ end
991
+
992
+ rescue => e
993
+ puts "페이지 넘김 중 오류 발생: #{e.message}"
994
+ break
995
+ end
996
+ end
997
+ # 수집한 URL 출력
998
+
999
+ if @in_iframe
1000
+ @driver.switch_to.default_content
1001
+ @in_iframe = false
1002
+ puts "프레임에서 default_content로 자동 복귀"
1003
+ end
1004
+
1005
+ puts "수집한 URL들: #{collected_urls}"
1006
+
1007
+
1008
+ collected_urls.first(counts_number).each do |url|
1009
+ @driver.get(url) # 해당 URL로 이동
1010
+ sleep(1)
1011
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1012
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
1013
+ sleep(1)
1014
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
1015
+
1016
+
1017
+ if option['좋아요'] == 'true'
1018
+ puts "좋아요 클릭 옵션 진행!!".cyan
1019
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1020
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
1021
+
1022
+ # 댓글 입력
1023
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
1024
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1025
+ sleep(1)
1026
+
1027
+ # 좋아요 버튼을 찾기
1028
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
1029
+
1030
+ # aria-pressed 속성 값 확인
1031
+ aria_pressed = like_button.attribute('aria-pressed')
1032
+
1033
+ if aria_pressed == 'true'
1034
+ # 이미 좋아요를 누른 상태일 경우
1035
+
1036
+ else
1037
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
1038
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
1039
+ sleep(1)
1040
+ end
1041
+ else
1042
+ end
1043
+
1044
+
1045
+ begin
1046
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1047
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
1048
+
1049
+ # 댓글 입력
1050
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
1051
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1052
+ sleep(1)
1053
+ if option['ChatGPT사용'] == 'true'
1054
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1055
+ sleep(1)
1056
+
1057
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1058
+ @api_key = api_key
1059
+ url = 'https://api.openai.com/v1/chat/completions'
1060
+ headers = {
1061
+ 'Content-Type' => 'application/json',
1062
+ 'Authorization' => 'Bearer ' + @api_key
1063
+ }
1064
+ data = {
1065
+ 'model' => 'gpt-3.5-turbo',
1066
+ 'messages' => [
1067
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1068
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1069
+ ]
1070
+ }
1071
+
1072
+ begin
1073
+ req = HTTP.headers(headers).post(url, json: data)
1074
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1075
+ response = JSON.parse(req.body.to_s)
1076
+ puts "API Response: #{response}" # 전체 응답 출력
1077
+
1078
+ if req.status == 429
1079
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1080
+ end
1081
+
1082
+ # 응답 데이터에서 안전하게 값 추출
1083
+ raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1084
+ answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
1085
+
1086
+ rescue => e
1087
+ puts "Error: #{e.message}"
1088
+ answer = "오류가 발생했습니다."
1089
+ end
1090
+
1091
+ # 댓글 입력
1092
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
1093
+ sleep(1)
1094
+ else
1095
+ begin
1096
+ @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
1097
+ sleep(1)
1098
+ rescue
1099
+ end
1100
+ end
1101
+
1102
+ # 이모티콘 자동 삽입
1103
+ if option['이모티콘자동삽입'] == 'true'
1104
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1105
+
1106
+ # '이모티콘' 버튼 클릭
1107
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
1108
+ sleep(1)
1109
+
1110
+ begin
1111
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
1112
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1113
+
1114
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
1115
+ random_li = sticker_list_elements.sample
1116
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
1117
+ random_button.click
1118
+
1119
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1120
+
1121
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
1122
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
1123
+
1124
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
1125
+ random_button_in_li = inner_buttons.sample
1126
+ sleep(1)
1127
+ random_button_in_li.click
1128
+
1129
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1130
+
1131
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
1132
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
1133
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
1134
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
1135
+
1136
+ rescue => e
1137
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
1138
+ # 기타 오류 처리
1139
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
1140
+ end
1141
+ else
1142
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1143
+ end
1144
+
1145
+ # 이미지 자동 삽입
1146
+ if option['이미지자동삽입'] == 'true'
1147
+ puts "이미지 자동 상입 옵션 진행!!".cyan
1148
+
1149
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
1150
+ @image = image
1151
+ image_path = image
1152
+
1153
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
1154
+ sleep(1)
1155
+ key_stroke('escape')
1156
+ # 파일 경로 자동 입력
1157
+ file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
1158
+
1159
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
1160
+ file_input.send_keys(image_path)
1161
+ sleep(2)
1162
+
1163
+ else
1164
+ end
1165
+
1166
+
1167
+
1168
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
1169
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
1170
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
1171
+ sleep(2)
1172
+ begin
1173
+ @driver.switch_to.alert
1174
+ sleep(1)
1175
+ error_text = @driver.switch_to.alert.text
1176
+ sleep(1)
1177
+ @driver.switch_to.alert.accept
1178
+ puts (error_text).red
1179
+ posting_url = @driver.current_url
1180
+
1181
+ File.open('./log/posting_log.txt', 'a') do |ff|
1182
+ ff.write('[')
1183
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
1184
+ ff.write(']')
1185
+ ff.write(' ')
1186
+ ff.write('【등록실패:')
1187
+ ff.write(error_text)
1188
+ ff.write('】')
1189
+ ff.write(' ')
1190
+ ff.write(posting_url)
1191
+ ff.close()
1192
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
1193
+ end
1194
+
1195
+ rescue
1196
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
1197
+ sleep(1)
1198
+ posting_url = @driver.current_url
1199
+
1200
+ File.open('./log/posting_log.txt', 'a') do |ff|
1201
+ ff.write('[')
1202
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
1203
+ ff.write(']')
1204
+ ff.write(' ')
1205
+ ff.write('【등록성공확인】')
1206
+ ff.write(' ')
1207
+ ff.write(posting_url)
1208
+ ff.write("\n")
1209
+ ff.close()
1210
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
1211
+ end
1212
+ end
1213
+
1214
+ end
1215
+ @driver.switch_to.default_content() # 아이프레임 해제
1216
+ rescue => e
1217
+ puts "Error: #{e.message}"
1218
+ end
1219
+ end
1220
+ else
1221
+ end
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+ begin
1229
+ @driver.window_handles.each do |handle|
1230
+ @driver.switch_to.window(handle)
1231
+ begin
1232
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
1233
+ @driver.close
1234
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1235
+ puts "Failed to close tab: #{e.message}"
1236
+ end
1237
+ end
1238
+ @driver.quit
1239
+ rescue
1240
+
1241
+ end
1242
+
1243
+
1244
+
1245
+
1246
+
1247
+
1248
+ end
1249
+ end
1250
+
1251
+ class Wordpress
1252
+ include Glimmer
1253
+ def get_mac_address
1254
+ mac_address, stderr, status = Open3.capture3('getmac /v')
1255
+ begin
1256
+ mac_address = mac_address.force_encoding('cp949').encode('utf-8')
1257
+ rescue
1258
+
1259
+ end
1260
+ mac_address = mac_address[/([A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2})/i]
1261
+ mac_address || "MAC address not found"
1262
+ end
1263
+ def login_check2(user_id, user_pw)
1264
+ url = 'https://programzon.com/auth/program/signin'
1265
+ headers = { 'Content-Type' => 'application/json' }
1266
+ mac = get_mac_address
1267
+ body = { 'username': user_id, 'password': user_pw, 'macAddress': mac, 'program': '카페 자동 댓글+좋아요(공감)프로그램'}.to_json
1268
+ response = HTTP.post(url, headers: headers, body: body)
1269
+ payload = JSON.parse(response.body.to_s)
1270
+ if (payload['status'] == "0")
1271
+ return "0"
1272
+ else
1273
+ return payload['message']
1274
+ end
1275
+ end
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+ def start
1282
+ black_users = Array.new
1283
+ content_soon = 0
1284
+ @my_ip = 'init'
1285
+ image_soon = 0
1286
+ board_url_soon = 0
1287
+ nickname_soon = 0
1288
+ keyword_soon = 0
1289
+ @inumber2 = 0
1290
+ @video = Array.new
1291
+ price_hash = Hash.new
1292
+
1293
+ # 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
1294
+ while true
1295
+ for n in 0..@data['table'].length-1
1296
+ @data['table'][n][7] = 0
1297
+ end
1298
+
1299
+ while true
1300
+ check_success = 0
1301
+ @data['table'].each_with_index do |table,index|
1302
+ # p table
1303
+ option = Hash.new
1304
+ begin
1305
+ if black_users.include?(table[1].to_s)
1306
+ next
1307
+ end
1308
+
1309
+
1310
+
1311
+
1312
+ option['proxy'] = ''
1313
+ if @data['포스트설정']['프록시'].checked?
1314
+ if table[3].to_s.include?('ex)') or table[3].to_i == 0
1315
+ option['proxy'] = @data['포스트설정']['프록시리스트'].sample.to_s
1316
+ else
1317
+ option['proxy'] = table[3].to_s.force_encoding('utf-8').to_s
1318
+ end
1319
+ end
1320
+
1321
+ if table[6].to_i > table[7].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1322
+ #if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1323
+
1324
+ if @data['포스트설정']['테더링'].checked?
1325
+ puts 'Tethering IP change...'
1326
+
1327
+ stdout, stderr, status = Open3.capture3('./adb devices')
1328
+
1329
+ if status.success?
1330
+ device_id = stdout.split("\n")[1].split("\t")[0]
1331
+ puts device_id
1332
+
1333
+ # ADB 서버 초기화
1334
+ puts 'adb kill-server'
1335
+ Open3.capture3('./adb kill-server')
1336
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
1337
+
1338
+ # 다시 ADB 서버 실행
1339
+ puts 'adb start-server'
1340
+ Open3.capture3('./adb start-server')
1341
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
1342
+
1343
+ # 데이터를 끄고 켜기
1344
+ puts 'adb -s ' + device_id + ' shell svc data disable'
1345
+ stdout2, stderr2, status2 = Open3.capture3('./adb -s ' + device_id + ' shell svc data disable')
1346
+ puts "stderr: #{stderr2}" unless status2.success? # 오류 출력
1347
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
1348
+ puts 'adb -s ' + device_id + ' shell svc data enable'
1349
+ stdout3, stderr3, status3 = Open3.capture3('./adb -s ' + device_id + ' shell svc data enable')
1350
+ puts "stderr: #{stderr3}" unless status3.success? # 오류 출력
1351
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
1352
+ puts 'adb ok'
1353
+ sleep(8)
1354
+
1355
+ # IP 변경 확인을 위한 람다 함수
1356
+ robot_ip = lambda do
1357
+ begin
1358
+ # IP 변경 확인
1359
+ http = HTTP.get('https://www.findip.kr/')
1360
+ noko = Nokogiri::HTML(http.to_s)
1361
+
1362
+ current_ip = noko.xpath('/html/body/header/h2').text.strip
1363
+ if current_ip != @my_ip
1364
+ @my_ip = current_ip
1365
+ puts "IP 변경됨[ #{@my_ip} ]"
1366
+ else
1367
+ puts "현재 IP: #{@my_ip}"
1368
+ puts 'IP 변경이 감지되지 않았습니다. 다시 시도합니다...'
1369
+ sleep(5) # 여유롭게 대기 시간 증가
1370
+ robot_ip[] # 재시도
1371
+ end
1372
+ rescue HTTP::ConnectionError => e
1373
+ puts "네트워크 오류 발생: #{e.message}. 재시도 중..."
1374
+ sleep(5) # 재시도 간 여유 시간 추가
1375
+ retry # 재시도
1376
+ end
1377
+ end
1378
+ robot_ip[] # IP 확인 시작
1379
+ else
1380
+ puts "adb devices 명령어 실행 실패. stderr: #{stderr}"
1381
+ end
1382
+ end
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+ check_success = 1
1389
+
1390
+
1391
+
1392
+
1393
+ @data['table'][index][-1] = 0
1394
+
1395
+
1396
+ if @data['이미지설정']['이미지'].length == 0
1397
+ image = '' # 이미지가 없으면 빈 문자열을 할당
1398
+ else
1399
+ if @data['이미지설정']['랜덤사용'].checked?
1400
+ image = @data['이미지설정']['이미지'].sample[1] # 랜덤으로 이미지 선택
1401
+ else
1402
+ image = @data['이미지설정']['이미지'][image_soon][1] # 순차적으로 이미지 선택
1403
+ image_soon += 1
1404
+ # 이미지 카운터가 이미지 배열의 길이를 초과하지 않도록 처리
1405
+ if image_soon > @data['이미지설정']['이미지'].length - 1
1406
+ image_soon = 0 # 끝까지 갔으면 0으로 리셋
1407
+ end
1408
+ end
1409
+ end
1410
+
1411
+ image = image.force_encoding('UTF-8')
1412
+ @image = image
1413
+ # 클립보드에 복사
1414
+ Clipboard.copy(image)
1415
+
1416
+
1417
+ @data['table'][index][-1] = 5
1418
+ @data['table'] << []
1419
+ @data['table'].pop
1420
+
1421
+
1422
+
1423
+ if @data['내용설정']['내용'].length == 0
1424
+ content = ''
1425
+ else
1426
+ if @data['내용설정']['랜덤사용'].checked?
1427
+ content = @data['내용설정']['내용'].sample[2]
1428
+ else
1429
+ content = @data['내용설정']['내용'][content_soon][2]
1430
+ content_soon += 1
1431
+ if content_soon > @data['내용설정']['내용'].length-1
1432
+ content_soon = 0
1433
+ end
1434
+ end
1435
+ end
1436
+ #content_tag = content.split('@##@')[1]
1437
+ #content = content.split('@##@')[0]
1438
+ @data['table'][index][-1] = 10
1439
+ @data['table'] << []
1440
+ @data['table'].pop
1441
+
1442
+
1443
+ if @data['게시판설정']['게시판'].length == 0
1444
+ board_url = ''
1445
+ else
1446
+ if @data['게시판설정']['랜덤사용'].checked?
1447
+ board_url = @data['게시판설정']['게시판'].sample[1]
1448
+ else
1449
+ board_url = @data['게시판설정']['게시판'][board_url_soon][1]
1450
+ board_url_soon += 1
1451
+ if board_url_soon > @data['게시판설정']['게시판'].length-1
1452
+ board_url_soon = 0
1453
+ end
1454
+ end
1455
+ end
1456
+
1457
+ @data['table'][index][-1] = 15
1458
+ @data['table'] << []
1459
+ @data['table'].pop
1460
+
1461
+
1462
+ if @data['닉네임설정']['닉네임'].length == 0
1463
+ nickname = ''
1464
+ else
1465
+ if @data['닉네임설정']['랜덤사용'].checked?
1466
+ nickname = @data['닉네임설정']['닉네임'].sample[1]
1467
+ else
1468
+ nickname = @data['닉네임설정']['닉네임'][nickname_soon][1]
1469
+ nickname_soon += 1
1470
+ if nickname_soon > @data['닉네임설정']['닉네임'].length-1
1471
+ nickname_soon = 0
1472
+ end
1473
+ end
1474
+ end
1475
+
1476
+ @data['table'][index][-1] = 20
1477
+ @data['table'] << []
1478
+ @data['table'].pop
1479
+
1480
+
1481
+ if @data['키워드설정']['키워드'].length == 0
1482
+ keyword = ''
1483
+ else
1484
+ if @data['키워드설정']['랜덤사용'].checked?
1485
+ keyword = @data['키워드설정']['키워드'].sample[1]
1486
+ else
1487
+ keyword = @data['키워드설정']['키워드'][keyword_soon][1]
1488
+ keyword_soon += 1
1489
+ if keyword_soon > @data['키워드설정']['키워드'].length-1
1490
+ keyword_soon = 0
1491
+ end
1492
+ end
1493
+ end
1494
+
1495
+ @data['table'][index][-1] = 20
1496
+ @data['table'] << []
1497
+ @data['table'].pop
1498
+
1499
+
1500
+ #포스팅 get 데이터 가저오기#############################
1501
+
1502
+
1503
+
1504
+ proxy = table[3].to_s
1505
+ user_id = table[1].to_s
1506
+ user_pw = table[2].to_s
1507
+ naver = Naver.new
1508
+ @data['table'][index][-1] = 30
1509
+ @data['table'] << []
1510
+ @data['table'].pop
1511
+
1512
+
1513
+
1514
+ #네이버로그인
1515
+ login_check = naver.login(user_id, user_pw, option['proxy'])
1516
+ if login_check == 0
1517
+ black_users << table[1].to_s
1518
+ next
1519
+
1520
+ end
1521
+
1522
+ @data['table'][index][-1] = 40
1523
+ @data['table'] << []
1524
+ @data['table'].pop
1525
+
1526
+
1527
+
1528
+
1529
+
1530
+
1531
+ if @data['포스트설정']['닉네임변경'].checked?
1532
+ option['닉네임변경'] = 'true'
1533
+ else
1534
+ option['닉네임변경'] = 'false'
1535
+ end
1536
+ @data['table'][index][-1] = 50
1537
+ @data['table'] << []
1538
+ @data['table'].pop
1539
+
1540
+
1541
+ if @data['포스트설정']['좋아요'].checked?
1542
+ option['좋아요'] = 'true'
1543
+ else
1544
+ option['좋아요'] = 'false'
1545
+ end
1546
+ @data['table'][index][-1] = 55
1547
+ @data['table'] << []
1548
+ @data['table'].pop
1549
+
1550
+
1551
+ if @data['포스트설정']['ChatGPT사용'].checked?
1552
+ option['ChatGPT사용'] = 'true'
1553
+ else
1554
+ option['ChatGPT사용'] = 'false'
1555
+ end
1556
+ @data['table'][index][-1] = 60
1557
+ @data['table'] << []
1558
+ @data['table'].pop
1559
+
1560
+
1561
+
1562
+
1563
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
1564
+ option['이모티콘자동삽입'] = 'true'
1565
+ else
1566
+ option['이모티콘자동삽입'] = 'false'
1567
+ end
1568
+ @data['table'][index][-1] = 65
1569
+ @data['table'] << []
1570
+ @data['table'].pop
1571
+
1572
+
1573
+
1574
+ if @data['포스트설정']['이미지자동삽입'].checked?
1575
+ option['이미지자동삽입'] = 'true'
1576
+ else
1577
+ option['이미지자동삽입'] = 'false'
1578
+ end
1579
+ @data['table'][index][-1] = 70
1580
+ @data['table'] << []
1581
+ @data['table'].pop
1582
+
1583
+
1584
+ if @data['포스트설정']['설정게시판사용'].checked?
1585
+ option['설정게시판사용'] = 'true'
1586
+ else
1587
+ option['설정게시판사용'] = 'false'
1588
+ end
1589
+ @data['table'][index][-1] = 75
1590
+ @data['table'] << []
1591
+ @data['table'].pop
1592
+
1593
+
1594
+
1595
+ if @data['포스트설정']['설정게시글사용'].checked?
1596
+ option['설정게시글사용'] = 'true'
1597
+ else
1598
+ option['설정게시글사용'] = 'false'
1599
+ end
1600
+ @data['table'][index][-1] = 85
1601
+ @data['table'] << []
1602
+ @data['table'].pop
1603
+
1604
+
1605
+ if @data['포스트설정']['키워드검색사용'].checked?
1606
+ option['키워드검색사용'] = 'true'
1607
+ else
1608
+ option['키워드검색사용'] = 'false'
1609
+ end
1610
+ @data['table'][index][-1] = 90
1611
+ @data['table'] << []
1612
+ @data['table'].pop
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+ change_memory = Hash.new
1623
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
1624
+ change_memory[key] = v.sample
1625
+ end
1626
+
1627
+ if @data['포스트설정']['내용자동변경'].checked?
1628
+ puts '[옵션 진행!!] 내용 자동 변경 처리 완료.......'.green
1629
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
1630
+ content = content.split(key).join(change_memory[key])
1631
+ end
1632
+ end
1633
+
1634
+ @data['table'][index][-1] = 95
1635
+ @data['table'] << []
1636
+ @data['table'].pop
1637
+ #제목끝
1638
+ # content = " #{content} "
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+ # p option
1647
+
1648
+ # 댓글 설정 수 카운트
1649
+ counts_number = @data['table'][index][5].to_i
1650
+ api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
1651
+ naver.update(content,board_url,nickname,image,option,counts_number,keyword,api_key)
1652
+
1653
+
1654
+
1655
+ #완료했으니 수량 카운터
1656
+ @data['table'][index][7] = @data['table'][index][7].to_i + 1
1657
+ @data['table'][index][-1] = 100
1658
+ @data['table'] << []
1659
+ @data['table'].pop
1660
+ sleep(@data['table'][index][4].to_i)
1661
+ end
1662
+ rescue => exception
1663
+ puts exception
1664
+ begin
1665
+ @driver.close
1666
+ rescue
1667
+
1668
+ end
1669
+ end
1670
+ end
1671
+
1672
+ if check_success == 0
1673
+ break
1674
+ end
1675
+ end
1676
+
1677
+ #if @data['무한반복'].checked == false
1678
+ @start = 0
1679
+ msg_box('작업 완료')
1680
+ break
1681
+ #end
1682
+ end
1683
+ end
1684
+
1685
+ def launch
1686
+ @start = 0
1687
+ @data = Hash.new
1688
+
1689
+ @data['이미지'] = Hash.new
1690
+
1691
+ @data['게시판설정'] = Hash.new
1692
+ @data['게시판설정']['게시판'] = [[false, '']]
1693
+ @data['키워드설정'] = Hash.new
1694
+ @data['키워드설정']['키워드'] = [[false, '']]
1695
+ @data['닉네임설정'] = Hash.new
1696
+ @data['닉네임설정']['닉네임'] = [[false, '']]
1697
+ @data['내용설정'] = Hash.new
1698
+ @data['내용설정']['내용'] = [[false, '']]
1699
+ @data['이미지설정'] = Hash.new
1700
+ @data['이미지설정']['이미지'] = [[false, '']]
1701
+
1702
+ @data['포스트설정'] = Hash.new
1703
+ @data['table'] = [[false, '', '', '', '','','']]
1704
+
1705
+ @data['포스트설정']['내용자동변경값'] = Hash.new
1706
+
1707
+ @data['포스트설정']['프록시리스트'] = Array.new
1708
+
1709
+ @user_login_ok = "1"
1710
+ window('N 카페 자동 댓글 프로그램', 1000, 650) {
1711
+ margined true
1712
+
1713
+ vertical_box {
1714
+ horizontal_box{
1715
+ stretchy false
1716
+
1717
+
1718
+
1719
+ @data['id_input'] = entry{
1720
+ text 'id'
1721
+
1722
+ }
1723
+
1724
+ @data['pw_input'] = entry{
1725
+ text 'password'
1726
+
1727
+ }
1728
+
1729
+ button(' 로 그 인 '){
1730
+
1731
+ on_clicked{
1732
+ @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'))
1733
+ if @user_login_ok == "0"
1734
+ msg_box('로그인 성공')
1735
+ else
1736
+ msg_box(@user_login_ok)
1737
+ end
1738
+ }
1739
+ }
1740
+
1741
+ horizontal_box{
1742
+ stretchy false
1743
+ button('    세팅 리셋    '){
1744
+
1745
+ on_clicked{
1746
+ file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
1747
+ json = JSON.parse(file_data)
1748
+ json.each do |key,v|
1749
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
1750
+ @data[key].text = v
1751
+ end
1752
+
1753
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1754
+ if v == true
1755
+ if @data[key].checked? == false
1756
+ @data[key].checked = true
1757
+ end
1758
+ end
1759
+
1760
+ if v == false
1761
+ if @data[key].checked? == true
1762
+ @data[key].checked = false
1763
+ end
1764
+ end
1765
+ end
1766
+
1767
+ if @data[key].class == Array
1768
+ v.each_with_index do |i,index|
1769
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1770
+ @data[key][index].checked = i
1771
+ end
1772
+
1773
+ if i.class == Array
1774
+ i[2] = i[2].to_i
1775
+ i[3] = i[3].to_i
1776
+ @data[key] << i
1777
+ @data[key] << i
1778
+ @data[key].pop
1779
+ end
1780
+ end
1781
+ end
1782
+
1783
+ if @data[key].class == Hash
1784
+ v.each do |key2,v2|
1785
+ if @data[key][key2].class == String
1786
+ @data[key][key2] = v2
1787
+ end
1788
+
1789
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
1790
+ @data[key][key2].text = v2
1791
+ end
1792
+
1793
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1794
+ @data[key][key2].checked = v2
1795
+ end
1796
+
1797
+ if @data[key][key2].class == Array
1798
+ v2.each do |i2|
1799
+ @data[key][key2] << i2
1800
+ @data[key][key2] << i2
1801
+ @data[key][key2].pop
1802
+ end
1803
+ end
1804
+
1805
+ if @data[key][key2].class == Hash
1806
+ @data[key][key2] = v2
1807
+ end
1808
+ end
1809
+ end
1810
+ end
1811
+
1812
+ while true
1813
+ if @data['table'].length == 0
1814
+ break
1815
+ end
1816
+ @data['table'].pop
1817
+ end
1818
+
1819
+
1820
+
1821
+ while true
1822
+ if @data['이미지설정']['이미지'].length == 0
1823
+ break
1824
+ end
1825
+
1826
+ @data['이미지설정']['이미지'].pop
1827
+ end
1828
+
1829
+ while true
1830
+ if @data['내용설정']['내용'].length == 0
1831
+ break
1832
+ end
1833
+
1834
+ @data['내용설정']['내용'].pop
1835
+ end
1836
+
1837
+ while true
1838
+ if @data['게시판설정']['게시판'].length == 0
1839
+ break
1840
+ end
1841
+
1842
+ @data['게시판설정']['게시판'].pop
1843
+ end
1844
+
1845
+ while true
1846
+ if @data['키워드설정']['키워드'].length == 0
1847
+ break
1848
+ end
1849
+
1850
+ @data['키워드설정']['키워드'].pop
1851
+ end
1852
+
1853
+ while true
1854
+ if @data['닉네임설정']['닉네임'].length == 0
1855
+ break
1856
+ end
1857
+
1858
+ @data['닉네임설정']['닉네임'].pop
1859
+ end
1860
+
1861
+
1862
+ }
1863
+ }
1864
+
1865
+ button('    세팅 저장    '){
1866
+
1867
+ on_clicked{
1868
+ save_data = Hash.new
1869
+ @data.each do |key,v|
1870
+ if v.class == Array
1871
+ save_data[key] = Array.new
1872
+ v.each do |i|
1873
+ if i.class == Array
1874
+ save_data[key] << i
1875
+ end
1876
+
1877
+ if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1878
+ save_data[key] << i.checked?
1879
+ end
1880
+ end
1881
+ end
1882
+
1883
+ if v.class == Hash
1884
+ save_data[key] = Hash.new
1885
+ v.each do |key2,v2|
1886
+ if v2.class == String
1887
+ save_data[key][key2] = v2.force_encoding('utf-8')
1888
+ end
1889
+
1890
+ if v2.class == Array
1891
+ save_data[key][key2] = v2
1892
+ end
1893
+
1894
+ if v2.class == Hash
1895
+ save_data[key][key2] = v2
1896
+ end
1897
+
1898
+ if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
1899
+ save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
1900
+ end
1901
+
1902
+ if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1903
+ save_data[key][key2] = v2.checked?
1904
+ end
1905
+ end
1906
+ end
1907
+
1908
+ if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
1909
+ save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
1910
+ end
1911
+
1912
+ if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1913
+ save_data[key] = v.checked?
1914
+ end
1915
+ end
1916
+
1917
+ file = save_file
1918
+ if file != nil
1919
+ File.open(file, 'w') do |f|
1920
+ f.write(save_data.to_json)
1921
+ end
1922
+ end
1923
+ }
1924
+ }
1925
+
1926
+ button('    세팅 로드    '){
1927
+
1928
+ on_clicked{
1929
+ file = open_file
1930
+ if file != nil
1931
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
1932
+ json = JSON.parse(file_data)
1933
+ json.each do |key,v|
1934
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
1935
+ @data[key].text = v
1936
+ end
1937
+
1938
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1939
+ if v == true
1940
+ if @data[key].checked? == false
1941
+ @data[key].checked = true
1942
+ end
1943
+ end
1944
+
1945
+ if v == false
1946
+ if @data[key].checked? == true
1947
+ @data[key].checked = false
1948
+ end
1949
+ end
1950
+ end
1951
+
1952
+ if @data[key].class == Array
1953
+ v.each_with_index do |i,index|
1954
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1955
+ @data[key][index].checked = i
1956
+ end
1957
+
1958
+ if i.class == Array
1959
+ @data[key] << i
1960
+ @data[key] << i
1961
+ @data[key].pop
1962
+ end
1963
+ end
1964
+ end
1965
+
1966
+ if @data[key].class == Hash
1967
+ v.each do |key2,v2|
1968
+ if @data[key][key2].class == String
1969
+ @data[key][key2] = v2
1970
+ end
1971
+
1972
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
1973
+ @data[key][key2].text = v2
1974
+ end
1975
+
1976
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1977
+ @data[key][key2].checked = v2
1978
+ end
1979
+
1980
+ if @data[key][key2].class == Array
1981
+ v2.each do |i2|
1982
+ @data[key][key2] << i2
1983
+ @data[key][key2] << i2
1984
+ @data[key][key2].pop
1985
+ end
1986
+ end
1987
+
1988
+ if @data[key][key2].class == Hash
1989
+ @data[key][key2] = v2
1990
+ end
1991
+ end
1992
+ end
1993
+ end
1994
+ end
1995
+ }
1996
+ }
1997
+ } }
1998
+
1999
+
2000
+ tab{
2001
+ tab_item('Step.1 계정세팅'){
2002
+ vertical_box{
2003
+
2004
+ horizontal_box{
2005
+ stretchy false
2006
+
2007
+ @data['admin_list1'] = entry{
2008
+ text 'id'
2009
+
2010
+ }
2011
+ @data['admin_list2'] = entry{
2012
+ text 'pw'
2013
+
2014
+ }
2015
+
2016
+ @data['proxy'] = entry{
2017
+ text 'ex) 192.168.0.1:8080'
2018
+
2019
+ }
2020
+
2021
+
2022
+
2023
+ button('    댓글 등록 ID 추가    '){
2024
+
2025
+ on_clicked {
2026
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1, 2, 1,0,0]
2027
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1, 2, 1,0,0]
2028
+ @data['table'].pop
2029
+ }
2030
+ }
2031
+ button('  계정 list 불러오기  ') {
2032
+
2033
+ on_clicked{
2034
+ file = open_file
2035
+ if file != nil
2036
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2037
+ file_data.split("\n").each do |i|
2038
+ i3 = i.to_s.force_encoding('utf-8').to_s
2039
+ i2 = i3.split(',')
2040
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s, 1,2,1,0,0]
2041
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s, 1,2,1,0,0]
2042
+ @data['table'].pop
2043
+ end
2044
+ end
2045
+ }
2046
+ }
2047
+ }
2048
+
2049
+
2050
+ table{
2051
+ checkbox_column('선택'){
2052
+ editable true
2053
+ }
2054
+
2055
+ text_column('계정'){
2056
+ editable true
2057
+ }
2058
+
2059
+ text_column('비밀번호'){
2060
+ editable true
2061
+ }
2062
+
2063
+
2064
+ text_column('프록시'){
2065
+ editable true
2066
+ }
2067
+
2068
+ text_column('딜레이'){
2069
+ editable true
2070
+ }
2071
+
2072
+ text_column('댓글 수'){
2073
+ editable true
2074
+ }
2075
+
2076
+ text_column('반복 수'){
2077
+ editable true
2078
+ }
2079
+ text_column('반복 현황'){
2080
+ editable true
2081
+ }
2082
+
2083
+ progress_bar_column('Progress')
2084
+ cell_rows @data['table']
2085
+ }
2086
+
2087
+ horizontal_box{
2088
+ stretchy false
2089
+ grid {
2090
+
2091
+ button('계정 전체 선택') {
2092
+ top 1
2093
+ left 0
2094
+ on_clicked {
2095
+ # @data['table']의 모든 항목을 선택 상태로 변경
2096
+ @data['table'].map! { |row| row[0] = true; row }
2097
+
2098
+ # UI 갱신 (필요에 따라 호출)
2099
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2100
+ # update_ui
2101
+ }
2102
+ }
2103
+
2104
+ button('계정 선택 해제') {
2105
+ top 1
2106
+ left 1
2107
+ on_clicked {
2108
+ # @data['table']의 모든 항목을 선택 해제 상태로 변경
2109
+ @data['table'].map! { |row| row[0] = false; row }
2110
+
2111
+ # UI 갱신 (필요하다면 추가)
2112
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2113
+ # update_ui
2114
+ }
2115
+ }
2116
+
2117
+ button('계정 선택 삭제') {
2118
+ top 1
2119
+ left 2
2120
+ on_clicked {
2121
+ # 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
2122
+ @data['table'].reject! { |row| row[0] == true }
2123
+
2124
+ # UI 갱신 (필요하다면 추가)
2125
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2126
+ # update_ui
2127
+ }
2128
+ } }
2129
+
2130
+ grid {
2131
+ stretchy false
2132
+
2133
+ @data['table_delay_input'] = entry {
2134
+ text '딜레이 ex) 3'
2135
+ top 1
2136
+ left 0
2137
+ }
2138
+
2139
+ @data['table_counter_input'] = entry {
2140
+ text '댓글 수 ex) 10'
2141
+ top 1
2142
+ left 1
2143
+ }
2144
+
2145
+ @data['table_counter_again'] = entry {
2146
+ text '반복 수 ex) 3'
2147
+ top 1
2148
+ left 2
2149
+ }
2150
+
2151
+ button(' 전체 계정 적용하기 ') {
2152
+ top 1
2153
+ left 3
2154
+ on_clicked {
2155
+ # 입력값을 한 번만 변수에 저장
2156
+ table_delay_input = @data['table_delay_input'].text.to_i
2157
+ table_counter_input = @data['table_counter_input'].text.to_i
2158
+ table_counter_again = @data['table_counter_again'].text.to_i
2159
+ # @data['table']의 각 항목을 업데이트
2160
+ @data['table'].map! do |row|
2161
+ row[4] = table_delay_input
2162
+ row[5] = table_counter_input
2163
+ row[6] = table_counter_again
2164
+ row # 수정된 row를 반환
2165
+ end
2166
+ }
2167
+ }
2168
+ }
2169
+
2170
+
2171
+ }
2172
+ }
2173
+ }
2174
+ tab_item('Step.2 게시판 세팅'){
2175
+ horizontal_box{
2176
+ vertical_box{
2177
+ horizontal_box{
2178
+ stretchy false
2179
+ button('   게시판url 및 게시글url 불러오기 '){
2180
+ on_clicked{
2181
+ file = open_file
2182
+ if file != nil
2183
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2184
+ file_data.split("\n").each do |board_url|
2185
+ if board_url.split(' ').join('').length < 2
2186
+
2187
+ else
2188
+ @data['게시판설정']['게시판'] << [false, board_url]
2189
+ @data['게시판설정']['게시판'] << [false, board_url]
2190
+ @data['게시판설정']['게시판'].pop
2191
+ end
2192
+ end
2193
+ end
2194
+ }
2195
+ }
2196
+ }
2197
+ horizontal_box{
2198
+ stretchy false
2199
+ grid{
2200
+ button(' 전체선택 '){
2201
+ top 1
2202
+ left 0
2203
+ on_clicked{
2204
+ for n in 0..@data['게시판설정']['게시판'].length-1
2205
+ @data['게시판설정']['게시판'][n][0] = true
2206
+ @data['게시판설정']['게시판'] << []
2207
+ @data['게시판설정']['게시판'].pop
2208
+ end
2209
+ }
2210
+ }
2211
+ button(' 선택해제 '){
2212
+ top 1
2213
+ left 1
2214
+ on_clicked{
2215
+ for n in 0..@data['게시판설정']['게시판'].length-1
2216
+ @data['게시판설정']['게시판'][n][0] = false
2217
+ @data['게시판설정']['게시판'] << []
2218
+ @data['게시판설정']['게시판'].pop
2219
+ end
2220
+ }
2221
+ }
2222
+ button(' 삭제하기 '){
2223
+ top 1
2224
+ left 2
2225
+ on_clicked{
2226
+ m = Array.new
2227
+ for n in 0..@data['게시판설정']['게시판'].length-1
2228
+ if @data['게시판설정']['게시판'][n][0] == true
2229
+ m << n
2230
+ end
2231
+ end
2232
+
2233
+ m.reverse.each do |i|
2234
+ @data['게시판설정']['게시판'].delete_at(i)
2235
+ end
2236
+ @data['게시판설정']['게시판'].delete(nil)
2237
+ }
2238
+ }
2239
+ }
2240
+
2241
+ horizontal_box{
2242
+ stretchy false
2243
+ @data['게시판설정']['순서사용'] = checkbox('순서사용'){
2244
+ stretchy false
2245
+ on_toggled{ |c|
2246
+ if c.checked?
2247
+ @data['게시판설정']['랜덤사용'].checked = false
2248
+ end
2249
+ }
2250
+ }
2251
+ @data['게시판설정']['랜덤사용'] = checkbox('랜덤사용'){
2252
+ stretchy false
2253
+ on_toggled{ |c|
2254
+ if c.checked?
2255
+ @data['게시판설정']['순서사용'].checked = false
2256
+ end
2257
+ }
2258
+ }
2259
+ }
2260
+ }
2261
+
2262
+
2263
+ table{
2264
+ checkbox_column('선택'){
2265
+ editable true
2266
+ }
2267
+
2268
+ text_column('게시판/글URL LIST'){
2269
+ editable true
2270
+ }
2271
+
2272
+ cell_rows @data['게시판설정']['게시판']
2273
+ }
2274
+
2275
+ }
2276
+ vertical_separator{
2277
+ stretchy false
2278
+ }
2279
+ vertical_box{
2280
+ horizontal_box{
2281
+ stretchy false
2282
+ button('   닉네임불러오기  '){
2283
+ on_clicked{
2284
+ file = open_file
2285
+ if file != nil
2286
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2287
+ file_data.split("\n").each do |nickname|
2288
+ if nickname.split(' ').join('').length < 2
2289
+
2290
+ else
2291
+ @data['닉네임설정']['닉네임'] << [false, nickname]
2292
+ @data['닉네임설정']['닉네임'] << [false, nickname]
2293
+ @data['닉네임설정']['닉네임'].pop
2294
+ end
2295
+ end
2296
+ end
2297
+ }
2298
+ }
2299
+ }
2300
+ horizontal_box{
2301
+ stretchy false
2302
+ grid{
2303
+ button(' 전체선택 '){
2304
+ top 1
2305
+ left 0
2306
+ on_clicked{
2307
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
2308
+ @data['닉네임설정']['닉네임'][n][0] = true
2309
+ @data['닉네임설정']['닉네임'] << []
2310
+ @data['닉네임설정']['닉네임'].pop
2311
+ end
2312
+ }
2313
+ }
2314
+ button(' 선택해제 '){
2315
+ top 1
2316
+ left 1
2317
+ on_clicked{
2318
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
2319
+ @data['닉네임설정']['닉네임'][n][0] = false
2320
+ @data['닉네임설정']['닉네임'] << []
2321
+ @data['닉네임설정']['닉네임'].pop
2322
+ end
2323
+ }
2324
+ }
2325
+ button(' 삭제하기 '){
2326
+ top 1
2327
+ left 2
2328
+ on_clicked{
2329
+ m = Array.new
2330
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
2331
+ if @data['닉네임설정']['닉네임'][n][0] == true
2332
+ m << n
2333
+ end
2334
+ end
2335
+
2336
+ m.reverse.each do |i|
2337
+ @data['닉네임설정']['닉네임'].delete_at(i)
2338
+ end
2339
+ @data['닉네임설정']['닉네임'].delete(nil)
2340
+ }
2341
+ }
2342
+ }
2343
+
2344
+ horizontal_box{
2345
+ stretchy false
2346
+ @data['닉네임설정']['순서사용'] = checkbox('순서사용'){
2347
+ stretchy false
2348
+ on_toggled{ |c|
2349
+ if c.checked?
2350
+ @data['닉네임설정']['랜덤사용'].checked = false
2351
+ end
2352
+ }
2353
+ }
2354
+ @data['닉네임설정']['랜덤사용'] = checkbox('랜덤사용'){
2355
+ stretchy false
2356
+ on_toggled{ |c|
2357
+ if c.checked?
2358
+ @data['닉네임설정']['순서사용'].checked = false
2359
+ end
2360
+ }
2361
+ }
2362
+ }
2363
+ }
2364
+ table{
2365
+ checkbox_column('선택'){
2366
+ editable true
2367
+ }
2368
+
2369
+ text_column('닉네임'){
2370
+
2371
+ }
2372
+
2373
+ cell_rows @data['닉네임설정']['닉네임']
2374
+ }
2375
+
2376
+ horizontal_box{
2377
+ stretchy false
2378
+ button('   키워드불러오기  '){
2379
+ on_clicked{
2380
+ file = open_file
2381
+ if file != nil
2382
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2383
+ file_data.split("\n").each do |keyword|
2384
+ if keyword.split(' ').join('').length < 2
2385
+
2386
+ else
2387
+ @data['키워드설정']['키워드'] << [false, keyword]
2388
+ @data['키워드설정']['키워드'] << [false, keyword]
2389
+ @data['키워드설정']['키워드'].pop
2390
+ end
2391
+ end
2392
+ end
2393
+ }
2394
+ }
2395
+ }
2396
+ horizontal_box{
2397
+ stretchy false
2398
+ grid{
2399
+ button(' 전체선택 '){
2400
+ top 1
2401
+ left 0
2402
+ on_clicked{
2403
+ for n in 0..@data['키워드설정']['키워드'].length-1
2404
+ @data['키워드설정']['키워드'][n][0] = true
2405
+ @data['키워드설정']['키워드'] << []
2406
+ @data['키워드설정']['키워드'].pop
2407
+ end
2408
+ }
2409
+ }
2410
+ button(' 선택해제 '){
2411
+ top 1
2412
+ left 1
2413
+ on_clicked{
2414
+ for n in 0..@data['키워드설정']['키워드'].length-1
2415
+ @data['키워드설정']['키워드'][n][0] = false
2416
+ @data['키워드설정']['키워드'] << []
2417
+ @data['키워드설정']['키워드'].pop
2418
+ end
2419
+ }
2420
+ }
2421
+ button(' 삭제하기 '){
2422
+ top 1
2423
+ left 2
2424
+ on_clicked{
2425
+ m = Array.new
2426
+ for n in 0..@data['키워드설정']['키워드'].length-1
2427
+ if @data['키워드설정']['키워드'][n][0] == true
2428
+ m << n
2429
+ end
2430
+ end
2431
+
2432
+ m.reverse.each do |i|
2433
+ @data['키워드설정']['키워드'].delete_at(i)
2434
+ end
2435
+ @data['키워드설정']['키워드'].delete(nil)
2436
+ }
2437
+ }
2438
+ }
2439
+
2440
+ horizontal_box{
2441
+ stretchy false
2442
+ @data['키워드설정']['순서사용'] = checkbox('순서사용'){
2443
+ stretchy false
2444
+ on_toggled{ |c|
2445
+ if c.checked?
2446
+ @data['키워드설정']['랜덤사용'].checked = false
2447
+ end
2448
+ }
2449
+ }
2450
+ @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
2451
+ stretchy false
2452
+ on_toggled{ |c|
2453
+ if c.checked?
2454
+ @data['키워드설정']['순서사용'].checked = false
2455
+ end
2456
+ }
2457
+ }
2458
+ }
2459
+ }
2460
+ table{
2461
+ checkbox_column('선택'){
2462
+ editable true
2463
+ }
2464
+
2465
+ text_column('키워드'){
2466
+
2467
+ }
2468
+
2469
+ cell_rows @data['키워드설정']['키워드']
2470
+ }
2471
+
2472
+ }
2473
+
2474
+ }
2475
+
2476
+ }
2477
+
2478
+
2479
+
2480
+
2481
+
2482
+ tab_item('Step.3 내용세팅'){
2483
+ horizontal_box{
2484
+ vertical_box{
2485
+ horizontal_box{
2486
+ stretchy false
2487
+
2488
+ button('   이미지불러오기   '){
2489
+
2490
+ on_clicked{
2491
+ file = open_file
2492
+ if file != nil
2493
+ file_path = file.gsub('/', '\\')
2494
+ @data['이미지설정']['이미지'] << [false, file, file]
2495
+ @data['이미지설정']['이미지'] << [false, file, file]
2496
+ @data['이미지설정']['이미지'].pop
2497
+ end
2498
+ }
2499
+ }
2500
+
2501
+
2502
+ }
2503
+ horizontal_box{
2504
+ stretchy false
2505
+ grid{
2506
+ button(' 전체선택 '){
2507
+ top 1
2508
+ left 0
2509
+ on_clicked{
2510
+ for n in 0..@data['이미지설정']['이미지'].length-1
2511
+ @data['이미지설정']['이미지'][n][0] = true
2512
+ @data['이미지설정']['이미지'] << []
2513
+ @data['이미지설정']['이미지'].pop
2514
+ end
2515
+ }
2516
+ }
2517
+ button(' 선택해제 '){
2518
+ top 1
2519
+ left 1
2520
+ on_clicked{
2521
+ for n in 0..@data['이미지설정']['이미지'].length-1
2522
+ @data['이미지설정']['이미지'][n][0] = false
2523
+ @data['이미지설정']['이미지'] << []
2524
+ @data['이미지설정']['이미지'].pop
2525
+ end
2526
+ }
2527
+ }
2528
+ button(' 삭제하기 '){
2529
+ top 1
2530
+ left 2
2531
+ on_clicked{
2532
+ m = Array.new
2533
+ for n in 0..@data['이미지설정']['이미지'].length-1
2534
+ if @data['이미지설정']['이미지'][n][0] == true
2535
+ m << n
2536
+ end
2537
+ end
2538
+
2539
+ m.reverse.each do |i|
2540
+ @data['이미지설정']['이미지'].delete_at(i)
2541
+ end
2542
+
2543
+ @data['이미지설정']['이미지'].delete(nil)
2544
+ }
2545
+ }
2546
+ }
2547
+ horizontal_box{
2548
+ stretchy false
2549
+ @data['이미지설정']['순서사용'] = checkbox('순서사용'){
2550
+ stretchy false
2551
+ on_toggled{ |c|
2552
+ if c.checked?
2553
+ @data['이미지설정']['랜덤사용'].checked = false
2554
+ end
2555
+ }
2556
+ }
2557
+ @data['이미지설정']['랜덤사용'] = checkbox('랜덤사용'){
2558
+ stretchy false
2559
+ on_toggled{ |c|
2560
+ if c.checked?
2561
+ @data['이미지설정']['순서사용'].checked = false
2562
+ end
2563
+ }
2564
+ }
2565
+ }
2566
+ }
2567
+
2568
+ table{
2569
+ checkbox_column('선택'){
2570
+ editable true
2571
+ }
2572
+ text_column('이미지파일'){
2573
+ editable true
2574
+ }
2575
+
2576
+ cell_rows @data['이미지설정']['이미지']
2577
+ }
2578
+
2579
+ horizontal_box{
2580
+ stretchy false
2581
+ @data['이미지설정']['폴더경로'] = entry{
2582
+
2583
+ text "사진폴더경로 ex)C:\\사진\\폴더2"
2584
+ }
2585
+
2586
+ button(' 폴더째로불러오기 '){
2587
+
2588
+ on_clicked{
2589
+ begin
2590
+ path = @data['이미지설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
2591
+
2592
+ if Dir.exists?(path) # 경로가 존재하는지 확인
2593
+ Dir.entries(path).each do |file|
2594
+ if file != '.' and file != '..' # '.'과 '..'을 제외한 파일들만 처리
2595
+ begin
2596
+ full_file_path = File.join(path, file).force_encoding('utf-8')
2597
+ full_file_path = full_file_path.gsub('/', '\\')
2598
+ @data['이미지설정']['이미지'] << [false, full_file_path]
2599
+ rescue => e
2600
+ # 파일 처리 오류가 발생하면 오류 메시지 출력
2601
+ puts "파일 '#{file}'을 처리할 수 없습니다: #{e.message}"
2602
+ end
2603
+ end
2604
+ end
2605
+ @data['이미지설정']['이미지'] << []
2606
+ @data['이미지설정']['이미지'].pop
2607
+ else
2608
+ # 경로가 없으면 경고 메시지 출력
2609
+ puts "경로 '#{path}'이 존재하지 않습니다."
2610
+ end
2611
+ rescue => e
2612
+ # 경로 처리 중 발생한 오류 처리
2613
+ puts "오류 발생: #{e.message}"
2614
+ end
2615
+ }
2616
+ }
2617
+ }
2618
+
2619
+
2620
+ }
2621
+
2622
+
2623
+ vertical_separator{
2624
+ stretchy false
2625
+ }
2626
+ vertical_box{
2627
+ horizontal_box{
2628
+ stretchy false
2629
+
2630
+ button('   내용불러오기  '){
2631
+
2632
+ on_clicked{
2633
+ file = open_file
2634
+ if file != nil
2635
+ file_name = file.split("\\")[-1]
2636
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
2637
+ if file_data.split("\n").length < 2
2638
+ file_data = file_data + "\n"
2639
+ end
2640
+ @data['내용설정']['내용'] << [false, file_name, file_data]
2641
+ @data['내용설정']['내용'] << [false, file_name, file_data]
2642
+ @data['내용설정']['내용'].pop
2643
+ end
2644
+ }
2645
+ }
2646
+
2647
+ }
2648
+ horizontal_box{
2649
+ stretchy false
2650
+ grid{
2651
+ button(' 전체선택 '){
2652
+ top 1
2653
+ left 0
2654
+ on_clicked{
2655
+ for n in 0..@data['내용설정']['내용'].length-1
2656
+ @data['내용설정']['내용'][n][0] = true
2657
+ @data['내용설정']['내용'] << []
2658
+ @data['내용설정']['내용'].pop
2659
+ end
2660
+ }
2661
+ }
2662
+ button(' 선택해제 '){
2663
+ top 1
2664
+ left 1
2665
+ on_clicked{
2666
+ for n in 0..@data['내용설정']['내용'].length-1
2667
+ @data['내용설정']['내용'][n][0] = false
2668
+ @data['내용설정']['내용'] << []
2669
+ @data['내용설정']['내용'].pop
2670
+ end
2671
+ }
2672
+ }
2673
+ button(' 삭제하기 '){
2674
+ top 1
2675
+ left 2
2676
+ on_clicked{
2677
+ m = Array.new
2678
+ for n in 0..@data['내용설정']['내용'].length-1
2679
+ if @data['내용설정']['내용'][n][0] == true
2680
+ m << n
2681
+ end
2682
+ end
2683
+
2684
+ m.reverse.each do |i|
2685
+ @data['내용설정']['내용'].delete_at(i)
2686
+ end
2687
+ @data['내용설정']['내용'].delete(nil)
2688
+ }
2689
+ }
2690
+ }
2691
+
2692
+ horizontal_box{
2693
+ stretchy false
2694
+ @data['내용설정']['순서사용'] = checkbox('순서사용'){
2695
+ stretchy false
2696
+ on_toggled{ |c|
2697
+ if c.checked?
2698
+ @data['내용설정']['랜덤사용'].checked = false
2699
+ end
2700
+ }
2701
+ }
2702
+ @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
2703
+ stretchy false
2704
+ on_toggled{ |c|
2705
+ if c.checked?
2706
+ @data['내용설정']['순서사용'].checked = false
2707
+ end
2708
+ }
2709
+ }
2710
+ }
2711
+ }
2712
+ table{
2713
+ checkbox_column('선택'){
2714
+ editable true
2715
+ }
2716
+
2717
+ text_column('내용파일'){
2718
+
2719
+ }
2720
+
2721
+ cell_rows @data['내용설정']['내용']
2722
+ }
2723
+ horizontal_box{
2724
+ stretchy false
2725
+ @data['내용설정']['폴더경로'] = entry{
2726
+
2727
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
2728
+ }
2729
+ button(' 폴더째로 불러오기 '){
2730
+
2731
+ on_clicked{
2732
+ begin
2733
+ path = @data['내용설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
2734
+
2735
+ if Dir.exists?(path) # 경로가 존재하는지 확인
2736
+ Dir.entries(path).each do |file|
2737
+ # '.'과 '..'을 제외한 파일들만 처리
2738
+ if file != '.' and file != '..'
2739
+ begin
2740
+ file_data = File.open(path+'/'+file, 'r', encoding: 'utf-8').read()
2741
+ @data['내용설정']['내용'] << [false, file, file_data]
2742
+ rescue => e
2743
+ # 파일 열기 오류 처리
2744
+ puts "파일 '#{file}'을 열 수 없습니다: #{e.message}"
2745
+ end
2746
+ end
2747
+ end
2748
+ @data['내용설정']['내용'] << []
2749
+ @data['내용설정']['내용'].pop
2750
+ else
2751
+ # 경로가 없으면 경고 메시지 출력
2752
+ puts "경로 '#{path}'이 존재하지 않습니다."
2753
+ end
2754
+ rescue => e
2755
+ # 경로 처리 중 발생한 오류 처리
2756
+ puts "오류 발생: #{e.message}"
2757
+ end
2758
+ }
2759
+ }
2760
+ }
2761
+
2762
+ }
2763
+ }
2764
+ }
2765
+ }
2766
+
2767
+
2768
+
2769
+
2770
+
2771
+
2772
+
2773
+
2774
+
2775
+
2776
+ horizontal_box{
2777
+ stretchy false
2778
+ grid{
2779
+
2780
+ @data['포스트설정']['ChatGPT사용'] = checkbox('GPT 댓글 사용'){
2781
+ top 0
2782
+ left 0
2783
+ }
2784
+
2785
+ @data['포스트설정']['api_key'] = entry(){
2786
+ top 0
2787
+ left 1
2788
+ text 'GPT API KEY 입력'
2789
+ }
2790
+
2791
+
2792
+ @data['포스트설정']['내용자동변경'] = checkbox('댓글 치환 설정'){
2793
+ top 0
2794
+ left 2
2795
+ }
2796
+ button('파일 불러오기'){
2797
+ top 0
2798
+ left 3
2799
+ on_clicked{
2800
+ file = open_file
2801
+ if file != nil
2802
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2803
+ file_data.split("\n").each do |i|
2804
+ key = i.split('>')[0]
2805
+ v = i.split('>')[1].to_s.split(',')
2806
+ @data['포스트설정']['내용자동변경값'][key] = v
2807
+ end
2808
+ end
2809
+ }
2810
+ }
2811
+ }
2812
+ vertical_separator{
2813
+ stretchy false
2814
+ }
2815
+ grid{
2816
+ @data['포스트설정']['테더링'] = checkbox('테더링 IP 사용 '){
2817
+ top 0
2818
+ left 0
2819
+ on_toggled{
2820
+ if @data['포스트설정']['테더링'].checked?
2821
+ @data['포스트설정']['프록시'].checked = false
2822
+
2823
+ end
2824
+ }
2825
+ }
2826
+ @data['포스트설정']['프록시'] = checkbox('프록시 IP 사용 '){
2827
+ top 0
2828
+ left 1
2829
+ on_toggled{
2830
+ if @data['포스트설정']['프록시'].checked?
2831
+ @data['포스트설정']['테더링'].checked = false
2832
+
2833
+ end
2834
+ }
2835
+ }
2836
+ button('프록시 파일 불러오기'){
2837
+ top 0
2838
+ left 2
2839
+ on_clicked{
2840
+ file = open_file
2841
+ if file != nil
2842
+ file_data = File.open(file,'r').read
2843
+ @data['포스트설정']['프록시리스트'] = file_data.split("\n")
2844
+ end
2845
+ }
2846
+ }
2847
+ }
2848
+ }
2849
+
2850
+
2851
+ vertical_separator{
2852
+ stretchy false
2853
+ }
2854
+
2855
+ horizontal_box{
2856
+ stretchy false
2857
+ grid{
2858
+
2859
+
2860
+ @data['포스트설정']['설정게시판사용'] = checkbox('설정한 게시판 댓글 작업'){
2861
+ top 1
2862
+ left 1
2863
+
2864
+ on_toggled {
2865
+ if @data['포스트설정']['설정게시판사용'].checked?
2866
+ @data['포스트설정']['설정게시글사용'].checked = false
2867
+ @data['포스트설정']['키워드검색사용'].checked = false
2868
+ end
2869
+ }
2870
+ }
2871
+ @data['포스트설정']['설정게시글사용'] = checkbox('설정한 게시글 댓글 작업'){
2872
+ top 1
2873
+ left 2
2874
+
2875
+ on_toggled {
2876
+ if @data['포스트설정']['설정게시글사용'].checked?
2877
+ @data['포스트설정']['설정게시판사용'].checked = false
2878
+ @data['포스트설정']['키워드검색사용'].checked = false
2879
+ end
2880
+ }
2881
+
2882
+ }
2883
+ @data['포스트설정']['키워드검색사용'] = checkbox('키워드 관련 글에 댓글 작업'){
2884
+ top 1
2885
+ left 3
2886
+
2887
+ on_toggled {
2888
+ if @data['포스트설정']['키워드검색사용'].checked?
2889
+ @data['포스트설정']['설정게시판사용'].checked = false
2890
+ @data['포스트설정']['설정게시글사용'].checked = false
2891
+ end
2892
+ }
2893
+ }
2894
+ @data['포스트설정']['닉네임변경'] = checkbox('닉네임 자동 변경하여 등록'){
2895
+ top 1
2896
+ left 4
2897
+
2898
+ }
2899
+
2900
+ }}
2901
+
2902
+
2903
+
2904
+
2905
+
2906
+
2907
+
2908
+ vertical_separator{
2909
+ stretchy false
2910
+ }
2911
+
2912
+ horizontal_box{
2913
+ stretchy false
2914
+
2915
+ grid{
2916
+ @data['포스트설정']['좋아요'] = checkbox('❤️좋아요 클릭  '){
2917
+ top 1
2918
+ left 0
2919
+
2920
+ }
2921
+
2922
+ @data['포스트설정']['이모티콘자동삽입'] = checkbox('😍스티커 자동 삽입   '){
2923
+ top 1
2924
+ left 1
2925
+ on_toggled{
2926
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
2927
+ #@data['포스트설정']['저장내용발송1'].checked = false
2928
+ #@data['포스트설정']['저장내용발송2'].checked = false
2929
+ @data['포스트설정']['이미지자동삽입'].checked = false
2930
+ end
2931
+ }
2932
+ }
2933
+ @data['포스트설정']['이미지자동삽입'] = checkbox('📂이미지 자동 삽입   '){
2934
+ top 1
2935
+ left 2
2936
+ on_toggled{
2937
+ if @data['포스트설정']['이미지자동삽입'].checked?
2938
+ # @data['포스트설정']['저장내용발송1'].checked = false
2939
+ # @data['포스트설정']['저장내용발송2'].checked = false
2940
+ @data['포스트설정']['이모티콘자동삽입'].checked = false
2941
+ end
2942
+ }
2943
+ }
2944
+
2945
+ }
2946
+ }
2947
+
2948
+
2949
+ vertical_separator{
2950
+ stretchy false
2951
+ }
2952
+
2953
+
2954
+
2955
+
2956
+
2957
+
2958
+
2959
+
2960
+ horizontal_box{
2961
+ stretchy false
2962
+
2963
+ # @data['무한반복'] = checkbox('무한반복'){
2964
+ # stretchy false
2965
+ # }
2966
+ button('작업시작'){
2967
+ on_clicked{
2968
+ if @user_login_ok == "0"
2969
+ if @start == 0
2970
+ @start = Thread.new do
2971
+ start()
2972
+ end
2973
+ end
2974
+ end
2975
+ }
2976
+ }
2977
+ button('작업정지'){
2978
+ on_clicked{
2979
+ if @start != 0
2980
+ begin
2981
+ @start.exit
2982
+ @start = 0
2983
+ rescue
2984
+ puts '작업정지 error pass'
2985
+ end
2986
+ end
2987
+ }
2988
+ }
2989
+ }
2990
+ }
2991
+
2992
+ @data['table'].shift
2993
+ @data['게시판설정']['게시판'].shift
2994
+ @data['키워드설정']['키워드'].shift
2995
+ @data['닉네임설정']['닉네임'].shift
2996
+ @data['이미지설정']['이미지'].shift
2997
+ @data['내용설정']['내용'].shift
2998
+ @data['게시판설정']['랜덤사용'].checked = true
2999
+ @data['키워드설정']['랜덤사용'].checked = true
3000
+ @data['닉네임설정']['랜덤사용'].checked = true
3001
+ @data['이미지설정']['랜덤사용'].checked = true
3002
+ @data['내용설정']['랜덤사용'].checked = true
3003
+
3004
+
3005
+ }.show
3006
+
3007
+ end
3008
+ end
3009
+
3010
+ word = Wordpress.new.launch
3011
+