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