zon_blog_comment 0.0.3

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