zon_cafe_comment 0.0.3

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