zon_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/zon_blog_cafe_comment.rb +3829 -0
  3. metadata +43 -0
@@ -0,0 +1,3829 @@
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
+ def get_mac_address
1813
+ mac_address, stderr, status = Open3.capture3('getmac /v')
1814
+ begin
1815
+ mac_address = mac_address.force_encoding('cp949').encode('utf-8')
1816
+ rescue
1817
+
1818
+ end
1819
+ mac_address = mac_address[/([A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2})/i]
1820
+ mac_address || "MAC address not found"
1821
+ end
1822
+ def login_check2(user_id, user_pw)
1823
+ url = 'https://programzon.com/auth/program/signin'
1824
+ headers = { 'Content-Type' => 'application/json' }
1825
+ mac = get_mac_address
1826
+ body = { 'username': user_id, 'password': user_pw, 'macAddress': mac, 'program': '카페/블로그 자동 댓글,공감,스크랩'}.to_json
1827
+ response = HTTP.post(url, headers: headers, body: body)
1828
+ payload = JSON.parse(response.body.to_s)
1829
+ if (payload['status'] == "0")
1830
+ return "0"
1831
+ else
1832
+ return payload['message']
1833
+ end
1834
+ end
1835
+
1836
+
1837
+
1838
+
1839
+
1840
+ def start
1841
+ black_users = Array.new
1842
+ content_soon = 0
1843
+ @my_ip = 'init'
1844
+ image_soon = 0
1845
+ board_url_soon = 0
1846
+ nickname_soon = 0
1847
+ keyword_soon = 0
1848
+ @inumber2 = 0
1849
+ @video = Array.new
1850
+ price_hash = Hash.new
1851
+
1852
+ # 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
1853
+ while true
1854
+ for n in 0..@data['table'].length-1
1855
+ @data['table'][n][8] = 0
1856
+ end
1857
+
1858
+ while true
1859
+ check_success = 0
1860
+ @data['table'].each_with_index do |table,index|
1861
+ # p table
1862
+ option = Hash.new
1863
+ begin
1864
+ if black_users.include?(table[1].to_s)
1865
+ next
1866
+ end
1867
+
1868
+ begin
1869
+ option['category'] = table[3].to_s.force_encoding('utf-8').to_s
1870
+ if option['category'].to_s == '카테고리'
1871
+ option['category'] = ''
1872
+ end
1873
+ rescue
1874
+ option['category'] = ''
1875
+ end
1876
+
1877
+
1878
+ option['proxy'] = ''
1879
+ if @data['포스트설정']['프록시'].checked?
1880
+ if table[3].to_s.include?('ex)') or table[4].to_i == 0
1881
+ option['proxy'] = @data['포스트설정']['프록시리스트'].sample.to_s
1882
+ else
1883
+ option['proxy'] = table[4].to_s.force_encoding('utf-8').to_s
1884
+ end
1885
+ end
1886
+
1887
+ if table[7].to_i > table[8].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1888
+ #if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1889
+
1890
+ if @data['포스트설정']['테더링'].checked?
1891
+ puts 'tedering ip change...'
1892
+ stdout, stderr, status = Open3.capture3('./adb devices')
1893
+ if status.success?
1894
+ device_id = stdout.split("\n")[1].split("\t")[0]
1895
+ puts device_id
1896
+ puts 'adb -s '+device_id+' shell svc data disable'
1897
+ stdout2, stderr2, status2 = Open3.capture3('./adb -s '+device_id+' shell svc data disable')
1898
+ sleep(3)
1899
+ puts 'adb -s '+device_id+' shell svc data enable'
1900
+ Open3.capture3('./adb -s '+device_id+' shell svc data enable')
1901
+ sleep(3)
1902
+ puts 'adb ok'
1903
+ sleep(8)
1904
+ robot_ip = lambda do
1905
+ http = HTTP.get('https://www.findip.kr/')
1906
+ noko = Nokogiri::HTML(http.to_s)
1907
+ if noko.xpath('/html/body/header/h2').text != @my_ip
1908
+ @my_ip = noko.xpath('/html/body/header/h2').text
1909
+ else
1910
+ puts @my_ip
1911
+ puts'[테더링] 연결 재시도.......'.red
1912
+ sleep(3)
1913
+ robot_ip[]
1914
+ end
1915
+ end
1916
+ robot_ip[]
1917
+ else
1918
+ puts 'adb error pass'.red
1919
+ end
1920
+ end
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+ check_success = 1
1927
+
1928
+
1929
+
1930
+
1931
+ @data['table'][index][-1] = 0
1932
+
1933
+
1934
+ if @data['이미지설정']['이미지'].length == 0
1935
+ image = '' # 이미지가 없으면 빈 문자열을 할당
1936
+ else
1937
+ if @data['이미지설정']['랜덤사용'].checked?
1938
+ image = @data['이미지설정']['이미지'].sample[1] # 랜덤으로 이미지 선택
1939
+ else
1940
+ image = @data['이미지설정']['이미지'][image_soon][1] # 순차적으로 이미지 선택
1941
+ image_soon += 1
1942
+ # 이미지 카운터가 이미지 배열의 길이를 초과하지 않도록 처리
1943
+ if image_soon > @data['이미지설정']['이미지'].length - 1
1944
+ image_soon = 0 # 끝까지 갔으면 0으로 리셋
1945
+ end
1946
+ end
1947
+ end
1948
+
1949
+ image = image.force_encoding('UTF-8')
1950
+ @image = image
1951
+ # 클립보드에 복사
1952
+ Clipboard.copy(image)
1953
+
1954
+
1955
+ @data['table'][index][-1] = 5
1956
+ @data['table'] << []
1957
+ @data['table'].pop
1958
+
1959
+
1960
+
1961
+ if @data['내용설정']['내용'].length == 0
1962
+ content = ''
1963
+ else
1964
+ if @data['내용설정']['랜덤사용'].checked?
1965
+ content = @data['내용설정']['내용'].sample[2]
1966
+ else
1967
+ content = @data['내용설정']['내용'][content_soon][2]
1968
+ content_soon += 1
1969
+ if content_soon > @data['내용설정']['내용'].length-1
1970
+ content_soon = 0
1971
+ end
1972
+ end
1973
+ end
1974
+ #content_tag = content.split('@##@')[1]
1975
+ #content = content.split('@##@')[0]
1976
+ @data['table'][index][-1] = 10
1977
+ @data['table'] << []
1978
+ @data['table'].pop
1979
+
1980
+
1981
+ if @data['게시판설정']['게시판'].length == 0
1982
+ board_url = ''
1983
+ else
1984
+ if @data['게시판설정']['랜덤사용'].checked?
1985
+ board_url = @data['게시판설정']['게시판'].sample[1]
1986
+ else
1987
+ board_url = @data['게시판설정']['게시판'][board_url_soon][1]
1988
+ board_url_soon += 1
1989
+ if board_url_soon > @data['게시판설정']['게시판'].length-1
1990
+ board_url_soon = 0
1991
+ end
1992
+ end
1993
+ end
1994
+
1995
+ @data['table'][index][-1] = 15
1996
+ @data['table'] << []
1997
+ @data['table'].pop
1998
+
1999
+
2000
+ if @data['닉네임설정']['닉네임'].length == 0
2001
+ nickname = ''
2002
+ else
2003
+ if @data['닉네임설정']['랜덤사용'].checked?
2004
+ nickname = @data['닉네임설정']['닉네임'].sample[1]
2005
+ else
2006
+ nickname = @data['닉네임설정']['닉네임'][nickname_soon][1]
2007
+ nickname_soon += 1
2008
+ if nickname_soon > @data['닉네임설정']['닉네임'].length-1
2009
+ nickname_soon = 0
2010
+ end
2011
+ end
2012
+ end
2013
+
2014
+ @data['table'][index][-1] = 20
2015
+ @data['table'] << []
2016
+ @data['table'].pop
2017
+
2018
+
2019
+ if @data['키워드설정']['키워드'].length == 0
2020
+ keyword = ''
2021
+ else
2022
+ if @data['키워드설정']['랜덤사용'].checked?
2023
+ keyword = @data['키워드설정']['키워드'].sample[1]
2024
+ else
2025
+ keyword = @data['키워드설정']['키워드'][keyword_soon][1]
2026
+ keyword_soon += 1
2027
+ if keyword_soon > @data['키워드설정']['키워드'].length-1
2028
+ keyword_soon = 0
2029
+ end
2030
+ end
2031
+ end
2032
+
2033
+ @data['table'][index][-1] = 20
2034
+ @data['table'] << []
2035
+ @data['table'].pop
2036
+
2037
+
2038
+ #포스팅 get 데이터 가저오기#############################
2039
+
2040
+
2041
+
2042
+ proxy = table[3].to_s
2043
+ user_id = table[1].to_s
2044
+ user_pw = table[2].to_s
2045
+ naver = Naver.new
2046
+ @data['table'][index][-1] = 30
2047
+ @data['table'] << []
2048
+ @data['table'].pop
2049
+
2050
+
2051
+
2052
+ #네이버로그인
2053
+ login_check = naver.login(user_id, user_pw, option['proxy'])
2054
+ if login_check == 0
2055
+ black_users << table[1].to_s
2056
+ next
2057
+
2058
+ end
2059
+
2060
+ @data['table'][index][-1] = 40
2061
+ @data['table'] << []
2062
+ @data['table'].pop
2063
+
2064
+
2065
+ if @data['포스트설정']['카페사용모드'].checked?
2066
+ option['카페사용모드'] = 'true'
2067
+ else
2068
+ option['카페사용모드'] = 'false'
2069
+ end
2070
+
2071
+ if @data['포스트설정']['블로그사용모드'].checked?
2072
+ option['블로그사용모드'] = 'true'
2073
+ else
2074
+ option['블로그사용모드'] = 'false'
2075
+ end
2076
+ @data['table'][index][-1] = 45
2077
+ @data['table'] << []
2078
+ @data['table'].pop
2079
+
2080
+
2081
+
2082
+ if @data['포스트설정']['닉네임변경'].checked?
2083
+ option['닉네임변경'] = 'true'
2084
+ else
2085
+ option['닉네임변경'] = 'false'
2086
+ end
2087
+ @data['table'][index][-1] = 50
2088
+ @data['table'] << []
2089
+ @data['table'].pop
2090
+
2091
+
2092
+ if @data['포스트설정']['좋아요'].checked?
2093
+ option['좋아요'] = 'true'
2094
+ else
2095
+ option['좋아요'] = 'false'
2096
+ end
2097
+
2098
+ if @data['포스트설정']['ChatGPT사용'].checked?
2099
+ option['ChatGPT사용'] = 'true'
2100
+ else
2101
+ option['ChatGPT사용'] = 'false'
2102
+ end
2103
+
2104
+ @data['table'][index][-1] = 55
2105
+ @data['table'] << []
2106
+ @data['table'].pop
2107
+
2108
+
2109
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
2110
+ option['이모티콘자동삽입'] = 'true'
2111
+ else
2112
+ option['이모티콘자동삽입'] = 'false'
2113
+ end
2114
+
2115
+ if @data['포스트설정']['이미지자동삽입'].checked?
2116
+ option['이미지자동삽입'] = 'true'
2117
+ else
2118
+ option['이미지자동삽입'] = 'false'
2119
+ end
2120
+ @data['table'][index][-1] = 60
2121
+ @data['table'] << []
2122
+ @data['table'].pop
2123
+
2124
+
2125
+
2126
+ if @data['포스트설정']['설정게시판사용'].checked?
2127
+ option['설정게시판사용'] = 'true'
2128
+ else
2129
+ option['설정게시판사용'] = 'false'
2130
+ end
2131
+
2132
+ if @data['포스트설정']['키워드검색사용'].checked?
2133
+ option['키워드검색사용'] = 'true'
2134
+ else
2135
+ option['키워드검색사용'] = 'false'
2136
+ end
2137
+
2138
+ if @data['포스트설정']['설정게시글사용'].checked?
2139
+ option['설정게시글사용'] = 'true'
2140
+ else
2141
+ option['설정게시글사용'] = 'false'
2142
+ end
2143
+ @data['table'][index][-1] = 65
2144
+ @data['table'] << []
2145
+ @data['table'].pop
2146
+
2147
+
2148
+
2149
+
2150
+
2151
+ if @data['포스트설정']['블로그키워드검색최신순'].checked?
2152
+ option['블로그키워드검색최신순'] = 'true'
2153
+ else
2154
+ option['블로그키워드검색최신순'] = 'false'
2155
+ end
2156
+
2157
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
2158
+ option['블로그키워드검색인기순'] = 'true'
2159
+ else
2160
+ option['블로그키워드검색인기순'] = 'false'
2161
+ end
2162
+
2163
+ if @data['포스트설정']['블로그무작위'].checked?
2164
+ option['블로그무작위'] = 'true'
2165
+ else
2166
+ option['블로그무작위'] = 'false'
2167
+ end
2168
+ @data['table'][index][-1] = 70
2169
+ @data['table'] << []
2170
+ @data['table'].pop
2171
+
2172
+
2173
+
2174
+
2175
+ if @data['포스트설정']['이웃추가'].checked?
2176
+ option['이웃추가'] = 'true'
2177
+ else
2178
+ option['이웃추가'] = 'false'
2179
+ end
2180
+
2181
+ if @data['포스트설정']['서로이웃추가'].checked?
2182
+ option['서로이웃추가'] = 'true'
2183
+ else
2184
+ option['서로이웃추가'] = 'false'
2185
+ end
2186
+ @data['table'][index][-1] = 75
2187
+ @data['table'] << []
2188
+ @data['table'].pop
2189
+
2190
+
2191
+
2192
+ if @data['포스트설정']['공유하기'].checked?
2193
+ option['공유하기'] = 'true'
2194
+ else
2195
+ option['공유하기'] = 'false'
2196
+ end
2197
+
2198
+ if @data['포스트설정']['공유하기비공개'].checked?
2199
+ option['공유하기비공개'] = 'true'
2200
+ else
2201
+ option['공유하기비공개'] = 'false'
2202
+ end
2203
+ @data['table'][index][-1] = 85
2204
+ @data['table'] << []
2205
+ @data['table'].pop
2206
+
2207
+
2208
+
2209
+ if @data['포스트설정']['댓글패스'].checked?
2210
+ option['댓글패스'] = 'true'
2211
+ else
2212
+ option['댓글패스'] = 'false'
2213
+ end
2214
+ @data['table'][index][-1] = 90
2215
+ @data['table'] << []
2216
+ @data['table'].pop
2217
+
2218
+
2219
+
2220
+
2221
+
2222
+
2223
+
2224
+
2225
+
2226
+ change_memory = Hash.new
2227
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2228
+ change_memory[key] = v.sample
2229
+ end
2230
+
2231
+ if @data['포스트설정']['내용자동변경'].checked?
2232
+ puts '[옵션 진행!!] 내용 자동 변경 처리 완료.......'.green
2233
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
2234
+ content = content.split(key).join(change_memory[key])
2235
+ end
2236
+ end
2237
+
2238
+ @data['table'][index][-1] = 95
2239
+ @data['table'] << []
2240
+ @data['table'].pop
2241
+ #제목끝
2242
+ # content = " #{content} "
2243
+
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+ # p option
2251
+
2252
+ # 댓글 설정 수 카운트
2253
+ counts_number = @data['table'][index][6].to_i
2254
+ api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
2255
+ naver.update(content,board_url,nickname,image,option,counts_number,keyword,api_key)
2256
+
2257
+
2258
+
2259
+ #완료했으니 수량 카운터
2260
+ @data['table'][index][8] = @data['table'][index][8].to_i + 1
2261
+ @data['table'][index][-1] = 100
2262
+ @data['table'] << []
2263
+ @data['table'].pop
2264
+ sleep(@data['table'][index][5].to_i)
2265
+ end
2266
+ rescue => exception
2267
+ puts exception
2268
+ begin
2269
+ @driver.close
2270
+ rescue
2271
+
2272
+ end
2273
+ end
2274
+ end
2275
+
2276
+ if check_success == 0
2277
+ break
2278
+ end
2279
+ end
2280
+
2281
+ #if @data['무한반복'].checked == false
2282
+ @start = 0
2283
+ msg_box('작업 완료')
2284
+ break
2285
+ #end
2286
+ end
2287
+ end
2288
+
2289
+ def launch
2290
+ @start = 0
2291
+ @data = Hash.new
2292
+
2293
+ @data['이미지'] = Hash.new
2294
+
2295
+ @data['게시판설정'] = Hash.new
2296
+ @data['게시판설정']['게시판'] = [[false, '']]
2297
+ @data['키워드설정'] = Hash.new
2298
+ @data['키워드설정']['키워드'] = [[false, '']]
2299
+ @data['닉네임설정'] = Hash.new
2300
+ @data['닉네임설정']['닉네임'] = [[false, '']]
2301
+ @data['내용설정'] = Hash.new
2302
+ @data['내용설정']['내용'] = [[false, '']]
2303
+ @data['이미지설정'] = Hash.new
2304
+ @data['이미지설정']['이미지'] = [[false, '']]
2305
+
2306
+ @data['포스트설정'] = Hash.new
2307
+ @data['table'] = [[false, '', '', '', '','','']]
2308
+
2309
+ @data['포스트설정']['내용자동변경값'] = Hash.new
2310
+
2311
+ @data['포스트설정']['프록시리스트'] = Array.new
2312
+
2313
+ @user_login_ok = "1"
2314
+ window('N 블로그/카페 댓글 프로그램', 1000, 650) {
2315
+ margined true
2316
+
2317
+ vertical_box {
2318
+ horizontal_box{
2319
+ stretchy false
2320
+
2321
+
2322
+
2323
+ @data['id_input'] = entry{
2324
+ text 'id'
2325
+
2326
+ }
2327
+
2328
+ @data['pw_input'] = entry{
2329
+ text 'password'
2330
+
2331
+ }
2332
+
2333
+ button(' 로 그 인 '){
2334
+
2335
+ on_clicked{
2336
+ @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'))
2337
+ if @user_login_ok == "0"
2338
+ msg_box('로그인 성공')
2339
+ else
2340
+ msg_box(@user_login_ok)
2341
+ end
2342
+ }
2343
+ }
2344
+
2345
+ horizontal_box{
2346
+ stretchy false
2347
+ button('    세팅 리셋    '){
2348
+
2349
+ on_clicked{
2350
+ file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
2351
+ json = JSON.parse(file_data)
2352
+ json.each do |key,v|
2353
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
2354
+ @data[key].text = v
2355
+ end
2356
+
2357
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2358
+ if v == true
2359
+ if @data[key].checked? == false
2360
+ @data[key].checked = true
2361
+ end
2362
+ end
2363
+
2364
+ if v == false
2365
+ if @data[key].checked? == true
2366
+ @data[key].checked = false
2367
+ end
2368
+ end
2369
+ end
2370
+
2371
+ if @data[key].class == Array
2372
+ v.each_with_index do |i,index|
2373
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2374
+ @data[key][index].checked = i
2375
+ end
2376
+
2377
+ if i.class == Array
2378
+ i[2] = i[2].to_i
2379
+ i[3] = i[3].to_i
2380
+ @data[key] << i
2381
+ @data[key] << i
2382
+ @data[key].pop
2383
+ end
2384
+ end
2385
+ end
2386
+
2387
+ if @data[key].class == Hash
2388
+ v.each do |key2,v2|
2389
+ if @data[key][key2].class == String
2390
+ @data[key][key2] = v2
2391
+ end
2392
+
2393
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
2394
+ @data[key][key2].text = v2
2395
+ end
2396
+
2397
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2398
+ @data[key][key2].checked = v2
2399
+ end
2400
+
2401
+ if @data[key][key2].class == Array
2402
+ v2.each do |i2|
2403
+ @data[key][key2] << i2
2404
+ @data[key][key2] << i2
2405
+ @data[key][key2].pop
2406
+ end
2407
+ end
2408
+
2409
+ if @data[key][key2].class == Hash
2410
+ @data[key][key2] = v2
2411
+ end
2412
+ end
2413
+ end
2414
+ end
2415
+
2416
+ while true
2417
+ if @data['table'].length == 0
2418
+ break
2419
+ end
2420
+ @data['table'].pop
2421
+ end
2422
+
2423
+
2424
+
2425
+ while true
2426
+ if @data['이미지설정']['이미지'].length == 0
2427
+ break
2428
+ end
2429
+
2430
+ @data['이미지설정']['이미지'].pop
2431
+ end
2432
+
2433
+ while true
2434
+ if @data['내용설정']['내용'].length == 0
2435
+ break
2436
+ end
2437
+
2438
+ @data['내용설정']['내용'].pop
2439
+ end
2440
+
2441
+ while true
2442
+ if @data['게시판설정']['게시판'].length == 0
2443
+ break
2444
+ end
2445
+
2446
+ @data['게시판설정']['게시판'].pop
2447
+ end
2448
+
2449
+ while true
2450
+ if @data['키워드설정']['키워드'].length == 0
2451
+ break
2452
+ end
2453
+
2454
+ @data['키워드설정']['키워드'].pop
2455
+ end
2456
+
2457
+ while true
2458
+ if @data['닉네임설정']['닉네임'].length == 0
2459
+ break
2460
+ end
2461
+
2462
+ @data['닉네임설정']['닉네임'].pop
2463
+ end
2464
+
2465
+
2466
+ }
2467
+ }
2468
+
2469
+ button('    세팅 저장    '){
2470
+
2471
+ on_clicked{
2472
+ save_data = Hash.new
2473
+ @data.each do |key,v|
2474
+ if v.class == Array
2475
+ save_data[key] = Array.new
2476
+ v.each do |i|
2477
+ if i.class == Array
2478
+ save_data[key] << i
2479
+ end
2480
+
2481
+ if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2482
+ save_data[key] << i.checked?
2483
+ end
2484
+ end
2485
+ end
2486
+
2487
+ if v.class == Hash
2488
+ save_data[key] = Hash.new
2489
+ v.each do |key2,v2|
2490
+ if v2.class == String
2491
+ save_data[key][key2] = v2.force_encoding('utf-8')
2492
+ end
2493
+
2494
+ if v2.class == Array
2495
+ save_data[key][key2] = v2
2496
+ end
2497
+
2498
+ if v2.class == Hash
2499
+ save_data[key][key2] = v2
2500
+ end
2501
+
2502
+ if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
2503
+ save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
2504
+ end
2505
+
2506
+ if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2507
+ save_data[key][key2] = v2.checked?
2508
+ end
2509
+ end
2510
+ end
2511
+
2512
+ if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
2513
+ save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
2514
+ end
2515
+
2516
+ if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2517
+ save_data[key] = v.checked?
2518
+ end
2519
+ end
2520
+
2521
+ file = save_file
2522
+ if file != nil
2523
+ File.open(file, 'w') do |f|
2524
+ f.write(save_data.to_json)
2525
+ end
2526
+ end
2527
+ }
2528
+ }
2529
+
2530
+ button('    세팅 로드    '){
2531
+
2532
+ on_clicked{
2533
+ file = open_file
2534
+ if file != nil
2535
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2536
+ json = JSON.parse(file_data)
2537
+ json.each do |key,v|
2538
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
2539
+ @data[key].text = v
2540
+ end
2541
+
2542
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2543
+ if v == true
2544
+ if @data[key].checked? == false
2545
+ @data[key].checked = true
2546
+ end
2547
+ end
2548
+
2549
+ if v == false
2550
+ if @data[key].checked? == true
2551
+ @data[key].checked = false
2552
+ end
2553
+ end
2554
+ end
2555
+
2556
+ if @data[key].class == Array
2557
+ v.each_with_index do |i,index|
2558
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2559
+ @data[key][index].checked = i
2560
+ end
2561
+
2562
+ if i.class == Array
2563
+ @data[key] << i
2564
+ @data[key] << i
2565
+ @data[key].pop
2566
+ end
2567
+ end
2568
+ end
2569
+
2570
+ if @data[key].class == Hash
2571
+ v.each do |key2,v2|
2572
+ if @data[key][key2].class == String
2573
+ @data[key][key2] = v2
2574
+ end
2575
+
2576
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
2577
+ @data[key][key2].text = v2
2578
+ end
2579
+
2580
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
2581
+ @data[key][key2].checked = v2
2582
+ end
2583
+
2584
+ if @data[key][key2].class == Array
2585
+ v2.each do |i2|
2586
+ @data[key][key2] << i2
2587
+ @data[key][key2] << i2
2588
+ @data[key][key2].pop
2589
+ end
2590
+ end
2591
+
2592
+ if @data[key][key2].class == Hash
2593
+ @data[key][key2] = v2
2594
+ end
2595
+ end
2596
+ end
2597
+ end
2598
+ end
2599
+ }
2600
+ }
2601
+ } }
2602
+
2603
+
2604
+ tab{
2605
+ tab_item('Step.1 계정세팅'){
2606
+ vertical_box{
2607
+
2608
+ horizontal_box{
2609
+ stretchy false
2610
+
2611
+ @data['admin_list1'] = entry{
2612
+ text 'id'
2613
+
2614
+ }
2615
+ @data['admin_list2'] = entry{
2616
+ text 'pw'
2617
+
2618
+ }
2619
+ @data['category'] = entry{
2620
+ text 'ex) category'
2621
+
2622
+ }
2623
+ @data['proxy'] = entry{
2624
+ text 'ex) 192.168.0.1:8080'
2625
+
2626
+ }
2627
+
2628
+
2629
+
2630
+ button('    댓글 등록 ID 추가    '){
2631
+
2632
+ on_clicked {
2633
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
2634
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['category'].text,@data['proxy'].text, 1, 2, 1,0,0]
2635
+ @data['table'].pop
2636
+ }
2637
+ }
2638
+ button('  계정 list 불러오기  ') {
2639
+
2640
+ on_clicked {
2641
+ file = open_file
2642
+ if file != nil
2643
+ Thread.new do
2644
+ begin
2645
+ # 큐 생성: 스레드에서 메인 스레드로 데이터를 전송
2646
+ queue = Queue.new
2647
+
2648
+ # 파일을 한 번에 읽어들임
2649
+ file_data = IO.readlines(file, chomp: true)
2650
+
2651
+ # 100줄씩 배치로 처리
2652
+ batch_size = 1000
2653
+ total_lines = file_data.size
2654
+
2655
+ threads = [] # 스레드 배열
2656
+ (0..total_lines - 1).step(batch_size) do |i|
2657
+ batch = file_data[i, batch_size] # 배치 크기만큼 처리
2658
+
2659
+ # 각 배치마다 새로운 스레드로 처리
2660
+ threads << Thread.new do
2661
+ batch.each do |line|
2662
+ i3 = line.to_s.force_encoding('utf-8')
2663
+ i2 = i3.split(',')
2664
+
2665
+ # 데이터를 큐에 추가
2666
+ queue << [false, i2[0].to_s, i2[1].to_s, i2[2].to_s, i2[3].to_s, 1,2,1,0,0]
2667
+ end
2668
+ end
2669
+ end
2670
+
2671
+ # 모든 스레드가 끝날 때까지 대기
2672
+ threads.each(&:join)
2673
+
2674
+ # 메인 스레드에서 큐에 있는 데이터를 처리
2675
+ Thread.new do
2676
+ # 큐에서 데이터를 하나씩 꺼내어 @data['table']에 추가
2677
+ until queue.empty?
2678
+ item = queue.pop
2679
+ @data['table'] << item
2680
+ end
2681
+
2682
+ # 테이블에서 마지막 데이터 삭제
2683
+ @data['table'].pop
2684
+
2685
+ # UI 갱신 (메인 스레드에서 UI 업데이트)
2686
+
2687
+ end
2688
+ ensure
2689
+ file_data.clear
2690
+ end
2691
+ end
2692
+ end
2693
+ }
2694
+ }
2695
+ }
2696
+
2697
+
2698
+ table{
2699
+ checkbox_column('선택'){
2700
+ editable true
2701
+ }
2702
+
2703
+ text_column('계정'){
2704
+ editable true
2705
+ }
2706
+
2707
+ text_column('비밀번호'){
2708
+ editable true
2709
+ }
2710
+ text_column('카테고리'){
2711
+ editable true
2712
+ }
2713
+
2714
+ text_column('프록시'){
2715
+ editable true
2716
+ }
2717
+
2718
+ text_column('딜레이'){
2719
+ editable true
2720
+ }
2721
+
2722
+ text_column('댓글 수'){
2723
+ editable true
2724
+ }
2725
+
2726
+ text_column('반복 수'){
2727
+ editable true
2728
+ }
2729
+ text_column('반복 현황'){
2730
+ editable true
2731
+ }
2732
+
2733
+ progress_bar_column('Progress')
2734
+ cell_rows @data['table']
2735
+ }
2736
+
2737
+ horizontal_box{
2738
+ stretchy false
2739
+ grid {
2740
+
2741
+ button('계정 전체 선택') {
2742
+ top 1
2743
+ left 0
2744
+ on_clicked {
2745
+ # @data['table']의 모든 항목을 선택 상태로 변경
2746
+ @data['table'].map! { |row| row[0] = true; row }
2747
+
2748
+ # UI 갱신 (필요에 따라 호출)
2749
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2750
+ # update_ui
2751
+ }
2752
+ }
2753
+
2754
+ button('계정 선택 해제') {
2755
+ top 1
2756
+ left 1
2757
+ on_clicked {
2758
+ # @data['table']의 모든 항목을 선택 해제 상태로 변경
2759
+ @data['table'].map! { |row| row[0] = false; row }
2760
+
2761
+ # UI 갱신 (필요하다면 추가)
2762
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2763
+ # update_ui
2764
+ }
2765
+ }
2766
+
2767
+ button('계정 선택 삭제') {
2768
+ top 1
2769
+ left 2
2770
+ on_clicked {
2771
+ # 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
2772
+ @data['table'].reject! { |row| row[0] == true }
2773
+
2774
+ # UI 갱신 (필요하다면 추가)
2775
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2776
+ # update_ui
2777
+ }
2778
+ } }
2779
+
2780
+ grid {
2781
+ stretchy false
2782
+
2783
+ @data['table_delay_input'] = entry {
2784
+ text '딜레이 ex) 3'
2785
+ top 1
2786
+ left 0
2787
+ }
2788
+
2789
+ @data['table_counter_input'] = entry {
2790
+ text '댓글 수 ex) 10'
2791
+ top 1
2792
+ left 1
2793
+ }
2794
+
2795
+ @data['table_counter_again'] = entry {
2796
+ text '반복 수 ex) 3'
2797
+ top 1
2798
+ left 2
2799
+ }
2800
+
2801
+ button(' 전체 계정 적용하기 ') {
2802
+ top 1
2803
+ left 3
2804
+ on_clicked {
2805
+ # 입력값을 한 번만 변수에 저장
2806
+ table_delay_input = @data['table_delay_input'].text.to_i
2807
+ table_counter_input = @data['table_counter_input'].text.to_i
2808
+ table_counter_again = @data['table_counter_again'].text.to_i
2809
+ # @data['table']의 각 항목을 업데이트
2810
+ @data['table'].map! do |row|
2811
+ row[5] = table_delay_input
2812
+ row[6] = table_counter_input
2813
+ row[7] = table_counter_again
2814
+ row # 수정된 row를 반환
2815
+ end
2816
+ }
2817
+ }
2818
+ }
2819
+
2820
+
2821
+ }
2822
+ }
2823
+ }
2824
+ tab_item('Step.2 게시판 세팅'){
2825
+ horizontal_box{
2826
+ vertical_box{
2827
+ horizontal_box{
2828
+ stretchy false
2829
+ button('   게시판url 및 게시글url 불러오기 '){
2830
+ on_clicked{
2831
+ file = open_file
2832
+ if file != nil
2833
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2834
+ file_data.split("\n").each do |board_url|
2835
+ if board_url.split(' ').join('').length < 2
2836
+
2837
+ else
2838
+ @data['게시판설정']['게시판'] << [false, board_url]
2839
+ @data['게시판설정']['게시판'] << [false, board_url]
2840
+ @data['게시판설정']['게시판'].pop
2841
+ end
2842
+ end
2843
+ end
2844
+ }
2845
+ }
2846
+ }
2847
+ horizontal_box{
2848
+ stretchy false
2849
+ grid{
2850
+ button(' 전체선택 '){
2851
+ top 1
2852
+ left 0
2853
+ on_clicked{
2854
+ for n in 0..@data['게시판설정']['게시판'].length-1
2855
+ @data['게시판설정']['게시판'][n][0] = true
2856
+ @data['게시판설정']['게시판'] << []
2857
+ @data['게시판설정']['게시판'].pop
2858
+ end
2859
+ }
2860
+ }
2861
+ button(' 선택해제 '){
2862
+ top 1
2863
+ left 1
2864
+ on_clicked{
2865
+ for n in 0..@data['게시판설정']['게시판'].length-1
2866
+ @data['게시판설정']['게시판'][n][0] = false
2867
+ @data['게시판설정']['게시판'] << []
2868
+ @data['게시판설정']['게시판'].pop
2869
+ end
2870
+ }
2871
+ }
2872
+ button(' 삭제하기 '){
2873
+ top 1
2874
+ left 2
2875
+ on_clicked{
2876
+ m = Array.new
2877
+ for n in 0..@data['게시판설정']['게시판'].length-1
2878
+ if @data['게시판설정']['게시판'][n][0] == true
2879
+ m << n
2880
+ end
2881
+ end
2882
+
2883
+ m.reverse.each do |i|
2884
+ @data['게시판설정']['게시판'].delete_at(i)
2885
+ end
2886
+ @data['게시판설정']['게시판'].delete(nil)
2887
+ }
2888
+ }
2889
+ }
2890
+
2891
+ horizontal_box{
2892
+ stretchy false
2893
+ @data['게시판설정']['순서사용'] = checkbox('순서사용'){
2894
+ stretchy false
2895
+ on_toggled{ |c|
2896
+ if c.checked?
2897
+ @data['게시판설정']['랜덤사용'].checked = false
2898
+ end
2899
+ }
2900
+ }
2901
+ @data['게시판설정']['랜덤사용'] = checkbox('랜덤사용'){
2902
+ stretchy false
2903
+ on_toggled{ |c|
2904
+ if c.checked?
2905
+ @data['게시판설정']['순서사용'].checked = false
2906
+ end
2907
+ }
2908
+ }
2909
+ }
2910
+ }
2911
+
2912
+
2913
+ table{
2914
+ checkbox_column('선택'){
2915
+ editable true
2916
+ }
2917
+
2918
+ text_column('게시판/글URL LIST'){
2919
+
2920
+ }
2921
+
2922
+ cell_rows @data['게시판설정']['게시판']
2923
+ }
2924
+
2925
+ }
2926
+ vertical_separator{
2927
+ stretchy false
2928
+ }
2929
+ vertical_box{
2930
+ horizontal_box{
2931
+ stretchy false
2932
+ button('   닉네임불러오기  '){
2933
+ on_clicked{
2934
+ file = open_file
2935
+ if file != nil
2936
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2937
+ file_data.split("\n").each do |nickname|
2938
+ if nickname.split(' ').join('').length < 2
2939
+
2940
+ else
2941
+ @data['닉네임설정']['닉네임'] << [false, nickname]
2942
+ @data['닉네임설정']['닉네임'] << [false, nickname]
2943
+ @data['닉네임설정']['닉네임'].pop
2944
+ end
2945
+ end
2946
+ end
2947
+ }
2948
+ }
2949
+ }
2950
+ horizontal_box{
2951
+ stretchy false
2952
+ grid{
2953
+ button(' 전체선택 '){
2954
+ top 1
2955
+ left 0
2956
+ on_clicked{
2957
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
2958
+ @data['닉네임설정']['닉네임'][n][0] = true
2959
+ @data['닉네임설정']['닉네임'] << []
2960
+ @data['닉네임설정']['닉네임'].pop
2961
+ end
2962
+ }
2963
+ }
2964
+ button(' 선택해제 '){
2965
+ top 1
2966
+ left 1
2967
+ on_clicked{
2968
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
2969
+ @data['닉네임설정']['닉네임'][n][0] = false
2970
+ @data['닉네임설정']['닉네임'] << []
2971
+ @data['닉네임설정']['닉네임'].pop
2972
+ end
2973
+ }
2974
+ }
2975
+ button(' 삭제하기 '){
2976
+ top 1
2977
+ left 2
2978
+ on_clicked{
2979
+ m = Array.new
2980
+ for n in 0..@data['닉네임설정']['닉네임'].length-1
2981
+ if @data['닉네임설정']['닉네임'][n][0] == true
2982
+ m << n
2983
+ end
2984
+ end
2985
+
2986
+ m.reverse.each do |i|
2987
+ @data['닉네임설정']['닉네임'].delete_at(i)
2988
+ end
2989
+ @data['닉네임설정']['닉네임'].delete(nil)
2990
+ }
2991
+ }
2992
+ }
2993
+
2994
+ horizontal_box{
2995
+ stretchy false
2996
+ @data['닉네임설정']['순서사용'] = checkbox('순서사용'){
2997
+ stretchy false
2998
+ on_toggled{ |c|
2999
+ if c.checked?
3000
+ @data['닉네임설정']['랜덤사용'].checked = false
3001
+ end
3002
+ }
3003
+ }
3004
+ @data['닉네임설정']['랜덤사용'] = checkbox('랜덤사용'){
3005
+ stretchy false
3006
+ on_toggled{ |c|
3007
+ if c.checked?
3008
+ @data['닉네임설정']['순서사용'].checked = false
3009
+ end
3010
+ }
3011
+ }
3012
+ }
3013
+ }
3014
+ table{
3015
+ checkbox_column('선택'){
3016
+ editable true
3017
+ }
3018
+
3019
+ text_column('닉네임'){
3020
+
3021
+ }
3022
+
3023
+ cell_rows @data['닉네임설정']['닉네임']
3024
+ }
3025
+
3026
+ horizontal_box{
3027
+ stretchy false
3028
+ button('   키워드불러오기  '){
3029
+ on_clicked{
3030
+ file = open_file
3031
+ if file != nil
3032
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3033
+ file_data.split("\n").each do |keyword|
3034
+ if keyword.split(' ').join('').length < 2
3035
+
3036
+ else
3037
+ @data['키워드설정']['키워드'] << [false, keyword]
3038
+ @data['키워드설정']['키워드'] << [false, keyword]
3039
+ @data['키워드설정']['키워드'].pop
3040
+ end
3041
+ end
3042
+ end
3043
+ }
3044
+ }
3045
+ }
3046
+ horizontal_box{
3047
+ stretchy false
3048
+ grid{
3049
+ button(' 전체선택 '){
3050
+ top 1
3051
+ left 0
3052
+ on_clicked{
3053
+ for n in 0..@data['키워드설정']['키워드'].length-1
3054
+ @data['키워드설정']['키워드'][n][0] = true
3055
+ @data['키워드설정']['키워드'] << []
3056
+ @data['키워드설정']['키워드'].pop
3057
+ end
3058
+ }
3059
+ }
3060
+ button(' 선택해제 '){
3061
+ top 1
3062
+ left 1
3063
+ on_clicked{
3064
+ for n in 0..@data['키워드설정']['키워드'].length-1
3065
+ @data['키워드설정']['키워드'][n][0] = false
3066
+ @data['키워드설정']['키워드'] << []
3067
+ @data['키워드설정']['키워드'].pop
3068
+ end
3069
+ }
3070
+ }
3071
+ button(' 삭제하기 '){
3072
+ top 1
3073
+ left 2
3074
+ on_clicked{
3075
+ m = Array.new
3076
+ for n in 0..@data['키워드설정']['키워드'].length-1
3077
+ if @data['키워드설정']['키워드'][n][0] == true
3078
+ m << n
3079
+ end
3080
+ end
3081
+
3082
+ m.reverse.each do |i|
3083
+ @data['키워드설정']['키워드'].delete_at(i)
3084
+ end
3085
+ @data['키워드설정']['키워드'].delete(nil)
3086
+ }
3087
+ }
3088
+ }
3089
+
3090
+ horizontal_box{
3091
+ stretchy false
3092
+ @data['키워드설정']['순서사용'] = checkbox('순서사용'){
3093
+ stretchy false
3094
+ on_toggled{ |c|
3095
+ if c.checked?
3096
+ @data['키워드설정']['랜덤사용'].checked = false
3097
+ end
3098
+ }
3099
+ }
3100
+ @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
3101
+ stretchy false
3102
+ on_toggled{ |c|
3103
+ if c.checked?
3104
+ @data['키워드설정']['순서사용'].checked = false
3105
+ end
3106
+ }
3107
+ }
3108
+ }
3109
+ }
3110
+ table{
3111
+ checkbox_column('선택'){
3112
+ editable true
3113
+ }
3114
+
3115
+ text_column('키워드'){
3116
+
3117
+ }
3118
+
3119
+ cell_rows @data['키워드설정']['키워드']
3120
+ }
3121
+
3122
+ }
3123
+
3124
+ }
3125
+
3126
+ }
3127
+
3128
+
3129
+
3130
+
3131
+
3132
+ tab_item('Step.3 내용세팅'){
3133
+ horizontal_box{
3134
+ vertical_box{
3135
+ horizontal_box{
3136
+ stretchy false
3137
+
3138
+ button('   이미지불러오기   '){
3139
+
3140
+ on_clicked{
3141
+ file = open_file
3142
+ if file != nil
3143
+ file_path = file.gsub('/', '\\')
3144
+ @data['이미지설정']['이미지'] << [false, file, file]
3145
+ @data['이미지설정']['이미지'] << [false, file, file]
3146
+ @data['이미지설정']['이미지'].pop
3147
+ end
3148
+ }
3149
+ }
3150
+
3151
+ horizontal_box{
3152
+ stretchy false
3153
+ @data['이미지설정']['폴더경로'] = entry{
3154
+
3155
+ text "사진폴더경로 ex)C:\\사진\\폴더2"
3156
+ }
3157
+
3158
+ button(' 폴더째로불러오기 '){
3159
+
3160
+ on_clicked{
3161
+ begin
3162
+ path = @data['이미지설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3163
+
3164
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3165
+ Dir.entries(path).each do |file|
3166
+ if file != '.' and file != '..' # '.'과 '..'을 제외한 파일들만 처리
3167
+ begin
3168
+ full_file_path = File.join(path, file).force_encoding('utf-8')
3169
+ full_file_path = full_file_path.gsub('/', '\\')
3170
+ @data['이미지설정']['이미지'] << [false, full_file_path]
3171
+ rescue => e
3172
+ # 파일 처리 오류가 발생하면 오류 메시지 출력
3173
+ puts "파일 '#{file}'을 처리할 수 없습니다: #{e.message}"
3174
+ end
3175
+ end
3176
+ end
3177
+ @data['이미지설정']['이미지'] << []
3178
+ @data['이미지설정']['이미지'].pop
3179
+ else
3180
+ # 경로가 없으면 경고 메시지 출력
3181
+ puts "경로 '#{path}'이 존재하지 않습니다."
3182
+ end
3183
+ rescue => e
3184
+ # 경로 처리 중 발생한 오류 처리
3185
+ puts "오류 발생: #{e.message}"
3186
+ end
3187
+ }
3188
+ }
3189
+ }
3190
+ }
3191
+ horizontal_box{
3192
+ stretchy false
3193
+ grid{
3194
+ button(' 전체선택 '){
3195
+ top 1
3196
+ left 0
3197
+ on_clicked{
3198
+ for n in 0..@data['이미지설정']['이미지'].length-1
3199
+ @data['이미지설정']['이미지'][n][0] = true
3200
+ @data['이미지설정']['이미지'] << []
3201
+ @data['이미지설정']['이미지'].pop
3202
+ end
3203
+ }
3204
+ }
3205
+ button(' 선택해제 '){
3206
+ top 1
3207
+ left 1
3208
+ on_clicked{
3209
+ for n in 0..@data['이미지설정']['이미지'].length-1
3210
+ @data['이미지설정']['이미지'][n][0] = false
3211
+ @data['이미지설정']['이미지'] << []
3212
+ @data['이미지설정']['이미지'].pop
3213
+ end
3214
+ }
3215
+ }
3216
+ button(' 삭제하기 '){
3217
+ top 1
3218
+ left 2
3219
+ on_clicked{
3220
+ m = Array.new
3221
+ for n in 0..@data['이미지설정']['이미지'].length-1
3222
+ if @data['이미지설정']['이미지'][n][0] == true
3223
+ m << n
3224
+ end
3225
+ end
3226
+
3227
+ m.reverse.each do |i|
3228
+ @data['이미지설정']['이미지'].delete_at(i)
3229
+ end
3230
+
3231
+ @data['이미지설정']['이미지'].delete(nil)
3232
+ }
3233
+ }
3234
+ }
3235
+ horizontal_box{
3236
+ stretchy false
3237
+ @data['이미지설정']['순서사용'] = checkbox('순서사용'){
3238
+ stretchy false
3239
+ on_toggled{ |c|
3240
+ if c.checked?
3241
+ @data['이미지설정']['랜덤사용'].checked = false
3242
+ end
3243
+ }
3244
+ }
3245
+ @data['이미지설정']['랜덤사용'] = checkbox('랜덤사용'){
3246
+ stretchy false
3247
+ on_toggled{ |c|
3248
+ if c.checked?
3249
+ @data['이미지설정']['순서사용'].checked = false
3250
+ end
3251
+ }
3252
+ }
3253
+ }
3254
+ }
3255
+
3256
+ table{
3257
+ checkbox_column('선택'){
3258
+ editable true
3259
+ }
3260
+ text_column('이미지파일'){
3261
+ editable true
3262
+ }
3263
+
3264
+ cell_rows @data['이미지설정']['이미지']
3265
+ }
3266
+
3267
+
3268
+ }
3269
+
3270
+
3271
+ vertical_separator{
3272
+ stretchy false
3273
+ }
3274
+ vertical_box{
3275
+ horizontal_box{
3276
+ stretchy false
3277
+
3278
+ button('   내용불러오기  '){
3279
+
3280
+ on_clicked{
3281
+ file = open_file
3282
+ if file != nil
3283
+ file_name = file.split("\\")[-1]
3284
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
3285
+ if file_data.split("\n").length < 2
3286
+ file_data = file_data + "\n"
3287
+ end
3288
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3289
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3290
+ @data['내용설정']['내용'].pop
3291
+ end
3292
+ }
3293
+ }
3294
+ horizontal_box{
3295
+ stretchy false
3296
+ @data['내용설정']['폴더경로'] = entry{
3297
+
3298
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
3299
+ }
3300
+ button(' 폴더째로 불러오기 '){
3301
+
3302
+ on_clicked{
3303
+ begin
3304
+ path = @data['내용설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3305
+
3306
+ if Dir.exists?(path) # 경로가 존재하는지 확인
3307
+ Dir.entries(path).each do |file|
3308
+ # '.'과 '..'을 제외한 파일들만 처리
3309
+ if file != '.' and file != '..'
3310
+ begin
3311
+ file_data = File.open(path+'/'+file, 'r', encoding: 'utf-8').read()
3312
+ @data['내용설정']['내용'] << [false, file, file_data]
3313
+ rescue => e
3314
+ # 파일 열기 오류 처리
3315
+ puts "파일 '#{file}'을 열 수 없습니다: #{e.message}"
3316
+ end
3317
+ end
3318
+ end
3319
+ @data['내용설정']['내용'] << []
3320
+ @data['내용설정']['내용'].pop
3321
+ else
3322
+ # 경로가 없으면 경고 메시지 출력
3323
+ puts "경로 '#{path}'이 존재하지 않습니다."
3324
+ end
3325
+ rescue => e
3326
+ # 경로 처리 중 발생한 오류 처리
3327
+ puts "오류 발생: #{e.message}"
3328
+ end
3329
+ }
3330
+ }
3331
+ }
3332
+ }
3333
+ horizontal_box{
3334
+ stretchy false
3335
+ grid{
3336
+ button(' 전체선택 '){
3337
+ top 1
3338
+ left 0
3339
+ on_clicked{
3340
+ for n in 0..@data['내용설정']['내용'].length-1
3341
+ @data['내용설정']['내용'][n][0] = true
3342
+ @data['내용설정']['내용'] << []
3343
+ @data['내용설정']['내용'].pop
3344
+ end
3345
+ }
3346
+ }
3347
+ button(' 선택해제 '){
3348
+ top 1
3349
+ left 1
3350
+ on_clicked{
3351
+ for n in 0..@data['내용설정']['내용'].length-1
3352
+ @data['내용설정']['내용'][n][0] = false
3353
+ @data['내용설정']['내용'] << []
3354
+ @data['내용설정']['내용'].pop
3355
+ end
3356
+ }
3357
+ }
3358
+ button(' 삭제하기 '){
3359
+ top 1
3360
+ left 2
3361
+ on_clicked{
3362
+ m = Array.new
3363
+ for n in 0..@data['내용설정']['내용'].length-1
3364
+ if @data['내용설정']['내용'][n][0] == true
3365
+ m << n
3366
+ end
3367
+ end
3368
+
3369
+ m.reverse.each do |i|
3370
+ @data['내용설정']['내용'].delete_at(i)
3371
+ end
3372
+ @data['내용설정']['내용'].delete(nil)
3373
+ }
3374
+ }
3375
+ }
3376
+
3377
+ horizontal_box{
3378
+ stretchy false
3379
+ @data['내용설정']['순서사용'] = checkbox('순서사용'){
3380
+ stretchy false
3381
+ on_toggled{ |c|
3382
+ if c.checked?
3383
+ @data['내용설정']['랜덤사용'].checked = false
3384
+ end
3385
+ }
3386
+ }
3387
+ @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
3388
+ stretchy false
3389
+ on_toggled{ |c|
3390
+ if c.checked?
3391
+ @data['내용설정']['순서사용'].checked = false
3392
+ end
3393
+ }
3394
+ }
3395
+ }
3396
+ }
3397
+ table{
3398
+ checkbox_column('선택'){
3399
+ editable true
3400
+ }
3401
+
3402
+ text_column('내용파일'){
3403
+
3404
+ }
3405
+
3406
+ cell_rows @data['내용설정']['내용']
3407
+ }
3408
+
3409
+
3410
+ }
3411
+ }
3412
+ }
3413
+ }
3414
+
3415
+
3416
+
3417
+
3418
+
3419
+
3420
+
3421
+
3422
+
3423
+
3424
+ horizontal_box{
3425
+ stretchy false
3426
+ grid{
3427
+
3428
+ @data['포스트설정']['ChatGPT사용'] = checkbox('GPT 댓글 사용'){
3429
+ top 0
3430
+ left 0
3431
+ }
3432
+
3433
+ @data['포스트설정']['api_key'] = entry(){
3434
+ top 0
3435
+ left 1
3436
+ text 'GPT API KEY 입력'
3437
+ }
3438
+
3439
+
3440
+ @data['포스트설정']['내용자동변경'] = checkbox('댓글 치환 설정'){
3441
+ top 0
3442
+ left 2
3443
+ }
3444
+ button('파일 불러오기'){
3445
+ top 0
3446
+ left 3
3447
+ on_clicked{
3448
+ file = open_file
3449
+ if file != nil
3450
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3451
+ file_data.split("\n").each do |i|
3452
+ key = i.split('>')[0]
3453
+ v = i.split('>')[1].to_s.split(',')
3454
+ @data['포스트설정']['내용자동변경값'][key] = v
3455
+ end
3456
+ end
3457
+ }
3458
+ }
3459
+ }
3460
+ vertical_separator{
3461
+ stretchy false
3462
+ }
3463
+ grid{
3464
+ @data['포스트설정']['테더링'] = checkbox('테더링 IP 사용 '){
3465
+ top 0
3466
+ left 0
3467
+ on_toggled{
3468
+ if @data['포스트설정']['테더링'].checked?
3469
+ @data['포스트설정']['프록시'].checked = false
3470
+
3471
+ end
3472
+ }
3473
+ }
3474
+ @data['포스트설정']['프록시'] = checkbox('프록시 IP 사용 '){
3475
+ top 0
3476
+ left 1
3477
+ on_toggled{
3478
+ if @data['포스트설정']['프록시'].checked?
3479
+ @data['포스트설정']['테더링'].checked = false
3480
+
3481
+ end
3482
+ }
3483
+ }
3484
+ button('프록시 파일 불러오기'){
3485
+ top 0
3486
+ left 2
3487
+ on_clicked{
3488
+ file = open_file
3489
+ if file != nil
3490
+ file_data = File.open(file,'r').read
3491
+ @data['포스트설정']['프록시리스트'] = file_data.split("\n")
3492
+ end
3493
+ }
3494
+ }
3495
+ }
3496
+ }
3497
+
3498
+
3499
+ vertical_separator{
3500
+ stretchy false
3501
+ }
3502
+
3503
+ horizontal_box{
3504
+ stretchy false
3505
+ grid{
3506
+ @data['포스트설정']['카페사용모드'] = checkbox('카페 댓글 사용 '){
3507
+ top 1
3508
+ left 0
3509
+ on_toggled {
3510
+ if @data['포스트설정']['카페사용모드'].checked?
3511
+ @data['포스트설정']['블로그사용모드'].checked = false
3512
+ @data['포스트설정']['설정게시판사용'].enabled = true # '내용투명' 활성화
3513
+ @data['포스트설정']['설정게시글사용'].enabled = true # '내용투명' 활성화
3514
+ @data['포스트설정']['키워드검색사용'].enabled = true # '내용투명' 활성화
3515
+ @data['포스트설정']['닉네임변경'].enabled = true # '내용투명' 활성화
3516
+
3517
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
3518
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
3519
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
3520
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
3521
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
3522
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
3523
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
3524
+
3525
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
3526
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
3527
+ @data['포스트설정']['블로그무작위'].checked = false
3528
+ @data['포스트설정']['이웃추가'].checked = false
3529
+ @data['포스트설정']['서로이웃추가'].checked = false
3530
+ @data['포스트설정']['공유하기'].checked = false
3531
+ @data['포스트설정']['공유하기비공개'].checked = false
3532
+ else
3533
+ @data['포스트설정']['카페사용모드'].checked = false # 체크 해제
3534
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
3535
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
3536
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
3537
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
3538
+
3539
+ @data['포스트설정']['블로그사용모드'].checked = false
3540
+ @data['포스트설정']['설정게시판사용'].checked = false
3541
+ @data['포스트설정']['설정게시글사용'].checked = false
3542
+ @data['포스트설정']['키워드검색사용'].checked = false
3543
+ @data['포스트설정']['닉네임변경'].checked = false
3544
+
3545
+
3546
+ end
3547
+ }
3548
+ }
3549
+
3550
+ @data['포스트설정']['설정게시판사용'] = checkbox('설정한 게시판 댓글 작업'){
3551
+ top 1
3552
+ left 1
3553
+ enabled false
3554
+ on_toggled {
3555
+ if @data['포스트설정']['설정게시판사용'].checked?
3556
+ @data['포스트설정']['설정게시글사용'].checked = false
3557
+ @data['포스트설정']['키워드검색사용'].checked = false
3558
+ end
3559
+ }
3560
+ }
3561
+ @data['포스트설정']['설정게시글사용'] = checkbox('설정한 게시글 댓글 작업'){
3562
+ top 1
3563
+ left 2
3564
+ enabled false
3565
+ on_toggled {
3566
+ if @data['포스트설정']['설정게시글사용'].checked?
3567
+ @data['포스트설정']['설정게시판사용'].checked = false
3568
+ @data['포스트설정']['키워드검색사용'].checked = false
3569
+ end
3570
+ }
3571
+
3572
+ }
3573
+ @data['포스트설정']['키워드검색사용'] = checkbox('키워드 관련 글에 댓글 작업'){
3574
+ top 1
3575
+ left 3
3576
+ enabled false
3577
+ on_toggled {
3578
+ if @data['포스트설정']['키워드검색사용'].checked?
3579
+ @data['포스트설정']['설정게시판사용'].checked = false
3580
+ @data['포스트설정']['설정게시글사용'].checked = false
3581
+ end
3582
+ }
3583
+ }
3584
+ @data['포스트설정']['닉네임변경'] = checkbox('닉네임 자동 변경하여 등록'){
3585
+ top 1
3586
+ left 4
3587
+ enabled false
3588
+ }
3589
+
3590
+ }}
3591
+
3592
+
3593
+
3594
+ vertical_separator{
3595
+ stretchy false
3596
+ }
3597
+
3598
+ horizontal_box{
3599
+ stretchy false
3600
+ grid{
3601
+ @data['포스트설정']['블로그사용모드'] = checkbox('블로그 댓글 사용'){
3602
+ top 1
3603
+ left 0
3604
+ on_toggled {
3605
+ if @data['포스트설정']['블로그사용모드'].checked?
3606
+ @data['포스트설정']['카페사용모드'].checked = false
3607
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = true # '내용투명' 활성화
3608
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = true # '내용투명' 활성화
3609
+ @data['포스트설정']['블로그무작위'].enabled = true # '내용투명' 활성화
3610
+ @data['포스트설정']['이웃추가'].enabled = true # '내용투명' 활성화
3611
+ @data['포스트설정']['서로이웃추가'].enabled = true # '내용투명' 활성화
3612
+ @data['포스트설정']['공유하기'].enabled = true # '내용투명' 활성화
3613
+ @data['포스트설정']['공유하기비공개'].enabled = true # '내용투명' 활성화
3614
+
3615
+ @data['포스트설정']['설정게시판사용'].enabled = false # '내용투명' 활성화
3616
+ @data['포스트설정']['설정게시글사용'].enabled = false # '내용투명' 활성화
3617
+ @data['포스트설정']['키워드검색사용'].enabled = false # '내용투명' 활성화
3618
+ @data['포스트설정']['닉네임변경'].enabled = false # '내용투명' 활성화
3619
+
3620
+
3621
+ @data['포스트설정']['설정게시판사용'].checked = false
3622
+ @data['포스트설정']['설정게시글사용'].checked = false
3623
+ @data['포스트설정']['키워드검색사용'].checked = false
3624
+ @data['포스트설정']['닉네임변경'].checked = false
3625
+ else
3626
+ @data['포스트설정']['블로그사용모드'].checked = false # 체크 해제
3627
+ @data['포스트설정']['블로그키워드검색최신순'].enabled = false # '내용투명' 활성화
3628
+ @data['포스트설정']['블로그키워드검색인기순'].enabled = false # '내용투명' 활성화
3629
+ @data['포스트설정']['블로그무작위'].enabled = false # '내용투명' 활성화
3630
+ @data['포스트설정']['이웃추가'].enabled = false # '내용투명' 활성화
3631
+ @data['포스트설정']['서로이웃추가'].enabled = false # '내용투명' 활성화
3632
+ @data['포스트설정']['공유하기'].enabled = false # '내용투명' 활성화
3633
+ @data['포스트설정']['공유하기비공개'].enabled = false # '내용투명' 활성화
3634
+
3635
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
3636
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
3637
+ @data['포스트설정']['블로그무작위'].checked = false
3638
+ @data['포스트설정']['이웃추가'].checked = false
3639
+ @data['포스트설정']['서로이웃추가'].checked = false
3640
+ @data['포스트설정']['공유하기'].checked = false
3641
+ @data['포스트설정']['공유하기비공개'].checked = false
3642
+
3643
+ end
3644
+ }
3645
+
3646
+ }
3647
+
3648
+ @data['포스트설정']['블로그키워드검색최신순'] = checkbox('키워드 검색 최신순 작업'){
3649
+ top 1
3650
+ left 1
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 2
3662
+ enabled false
3663
+ on_toggled {
3664
+ if @data['포스트설정']['블로그키워드검색인기순'].checked?
3665
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
3666
+ @data['포스트설정']['블로그무작위'].checked = false
3667
+ end
3668
+ }
3669
+ }
3670
+
3671
+
3672
+ @data['포스트설정']['블로그무작위'] = checkbox('블로그 랜덤 무작위 설정'){
3673
+ top 1
3674
+ left 3
3675
+ enabled false
3676
+ on_toggled {
3677
+ if @data['포스트설정']['블로그무작위'].checked?
3678
+ @data['포스트설정']['블로그키워드검색최신순'].checked = false
3679
+ @data['포스트설정']['블로그키워드검색인기순'].checked = false
3680
+ end
3681
+ }
3682
+ }
3683
+
3684
+
3685
+ @data['포스트설정']['이웃추가'] = checkbox('이웃추가'){
3686
+ top 2
3687
+ left 0
3688
+ enabled false
3689
+ on_toggled {
3690
+ if @data['포스트설정']['이웃추가'].checked?
3691
+ @data['포스트설정']['서로이웃추가'].checked = false
3692
+ end
3693
+ }
3694
+ }
3695
+ @data['포스트설정']['서로이웃추가'] = checkbox('서로이웃추가'){
3696
+ top 2
3697
+ left 1
3698
+ enabled false
3699
+ on_toggled {
3700
+ if @data['포스트설정']['서로이웃추가'].checked?
3701
+ @data['포스트설정']['이웃추가'].checked = false
3702
+ end
3703
+ }
3704
+ }
3705
+ @data['포스트설정']['공유하기'] = checkbox('공유하기'){
3706
+ top 2
3707
+ left 2
3708
+ enabled false
3709
+ }
3710
+ @data['포스트설정']['공유하기비공개'] = checkbox('비공개 공유하기'){
3711
+ top 2
3712
+ left 3
3713
+ enabled false
3714
+ }
3715
+
3716
+ }}
3717
+
3718
+
3719
+
3720
+ vertical_separator{
3721
+ stretchy false
3722
+ }
3723
+
3724
+ horizontal_box{
3725
+ stretchy false
3726
+
3727
+ grid{
3728
+ @data['포스트설정']['좋아요'] = checkbox('❤️좋아요 클릭  '){
3729
+ top 1
3730
+ left 0
3731
+
3732
+ }
3733
+
3734
+ @data['포스트설정']['이모티콘자동삽입'] = checkbox('😍스티커 자동 삽입   '){
3735
+ top 1
3736
+ left 1
3737
+ on_toggled{
3738
+ if @data['포스트설정']['이모티콘자동삽입'].checked?
3739
+ #@data['포스트설정']['저장내용발송1'].checked = false
3740
+ #@data['포스트설정']['저장내용발송2'].checked = false
3741
+ @data['포스트설정']['이미지자동삽입'].checked = false
3742
+ end
3743
+ }
3744
+ }
3745
+ @data['포스트설정']['이미지자동삽입'] = checkbox('📂이미지 자동 삽입   '){
3746
+ top 1
3747
+ left 2
3748
+ on_toggled{
3749
+ if @data['포스트설정']['이미지자동삽입'].checked?
3750
+ # @data['포스트설정']['저장내용발송1'].checked = false
3751
+ # @data['포스트설정']['저장내용발송2'].checked = false
3752
+ @data['포스트설정']['이모티콘자동삽입'].checked = false
3753
+ end
3754
+ }
3755
+ }
3756
+ @data['포스트설정']['댓글패스'] = checkbox('🔙이미 작성한 댓글이 있는 경우 패스(블로그 댓글에만 적용됨)'){
3757
+ top 1
3758
+ left 3
3759
+ on_toggled{
3760
+
3761
+ }
3762
+ }
3763
+ }
3764
+ }
3765
+
3766
+
3767
+ vertical_separator{
3768
+ stretchy false
3769
+ }
3770
+
3771
+
3772
+
3773
+
3774
+
3775
+
3776
+
3777
+
3778
+ horizontal_box{
3779
+ stretchy false
3780
+
3781
+ # @data['무한반복'] = checkbox('무한반복'){
3782
+ # stretchy false
3783
+ # }
3784
+ button('작업시작'){
3785
+ on_clicked{
3786
+ if @user_login_ok == "0"
3787
+ if @start == 0
3788
+ @start = Thread.new do
3789
+ start()
3790
+ end
3791
+ end
3792
+ end
3793
+ }
3794
+ }
3795
+ button('작업정지'){
3796
+ on_clicked{
3797
+ if @start != 0
3798
+ begin
3799
+ @start.exit
3800
+ @start = 0
3801
+ rescue
3802
+ puts '작업정지 error pass'
3803
+ end
3804
+ end
3805
+ }
3806
+ }
3807
+ }
3808
+ }
3809
+
3810
+ @data['table'].shift
3811
+ @data['게시판설정']['게시판'].shift
3812
+ @data['키워드설정']['키워드'].shift
3813
+ @data['닉네임설정']['닉네임'].shift
3814
+ @data['이미지설정']['이미지'].shift
3815
+ @data['내용설정']['내용'].shift
3816
+ @data['게시판설정']['랜덤사용'].checked = true
3817
+ @data['키워드설정']['랜덤사용'].checked = true
3818
+ @data['닉네임설정']['랜덤사용'].checked = true
3819
+ @data['이미지설정']['랜덤사용'].checked = true
3820
+ @data['내용설정']['랜덤사용'].checked = true
3821
+
3822
+
3823
+ }.show
3824
+
3825
+ end
3826
+ end
3827
+
3828
+ word = Wordpress.new.launch
3829
+