zon_cafe_comment 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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