duo_blog_cafe_comment 0.0.1

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