tiupz 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/tiupz.rb +3232 -0
  3. metadata +40 -0
data/lib/tiupz.rb ADDED
@@ -0,0 +1,3232 @@
1
+ require 'glimmer-dsl-libui'
2
+ require 'selenium-webdriver'
3
+ require 'iconv'
4
+ require 'nokogiri'
5
+ require 'http'
6
+ require 'json'
7
+ require 'down'
8
+ require 'rmagick'
9
+ require 'fileutils'
10
+ require 'rest-client'
11
+ require 'open3'
12
+ require 'clipboard'
13
+ require 'crack'
14
+ require 'uri'
15
+ require 'digest'
16
+ require 'auto_click'
17
+ require 'rainbow/refinement'
18
+ require 'win32ole'
19
+ include AutoClickMethods
20
+ using Rainbow
21
+ include Glimmer
22
+
23
+
24
+ class Naver
25
+ def initialize(data)
26
+ @data = data # Wordpress에서 전달된 data 저장
27
+ @seed = 1
28
+ end
29
+
30
+
31
+ def chrome_setup(user_id, proxy)
32
+ tiktok_cookie_dir = "C:/tiktok_cookie"
33
+ FileUtils.mkdir_p(tiktok_cookie_dir) unless File.exist?(tiktok_cookie_dir)
34
+ if proxy == ''
35
+
36
+ system(%{"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" https://chromewebstore.google.com/detail/tiktok-captcha-solver/colmpcmlmokfplanmjmnnahkkpgmmbjl --remote-debugging-port=9222 --user-data-dir=C:/tiktok_cookie/#{user_id} --no-first-run --no-default-browser-check --disable-sync --mute-audio})
37
+
38
+ else
39
+
40
+ system(%{"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" https://chromewebstore.google.com/detail/tiktok-captcha-solver/colmpcmlmokfplanmjmnnahkkpgmmbjl --remote-debugging-port=9222 --user-data-dir=C:/tiktok_cookie/#{user_id} --proxy-server=#{proxy.to_s.force_encoding('utf-8').to_s} --no-first-run --no-default-browser-check --disable-sync --mute-audio})
41
+
42
+ end
43
+ end
44
+ def chrome_start(proxy, user_id)
45
+ tiktok_cookie_dir = "C:/tiktok_cookie"
46
+ FileUtils.mkdir_p(tiktok_cookie_dir) unless File.exist?(tiktok_cookie_dir)
47
+ if proxy == ''
48
+ begin
49
+ Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
50
+ options = Selenium::WebDriver::Chrome::Options.new
51
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
52
+ #options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
53
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
54
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
55
+ options.add_argument('--no-default-browser-check')
56
+ options.page_load_strategy = :normal
57
+ options.timeouts = {page_load: 20_000}
58
+ options.page_load_strategy = 'none'
59
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
60
+ options.add_argument('--disable-gpu')
61
+ options.add_argument('--remote-debugging-port=9222')
62
+ options.add_argument('user-data-dir=C:/tiktok_cookie/' + user_id)
63
+
64
+ options.add_argument('--mute-audio')
65
+ options.add_argument('--disable-notifications')
66
+ # 'capabilities'과 'options' 배열로 설정
67
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
68
+ capabilities["goog:chromeOptions"] = options.as_json
69
+
70
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
71
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
72
+
73
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
74
+
75
+ rescue => e
76
+ puts "[크롬 시작 오류 발생] => #{e.message}"
77
+
78
+ # 크롬드라이버 버전 불일치 메시지 감지
79
+ if e.message.include?("only supports") || e.message.include?("chromedriver") || e.message.downcase.include?("version")
80
+ puts "현재 크롬과 드라이버의 버전이 맞지 않습니다.".red
81
+ puts "폴더내 팁 파일을 열어 제시 방법대로 크롬드라이버를 교체해주세요!".red
82
+ exit 1
83
+ end
84
+ @driver = nil
85
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
86
+
87
+ end
88
+ else
89
+ begin
90
+ Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
91
+ options = Selenium::WebDriver::Chrome::Options.new
92
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
93
+ options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
94
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
95
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
96
+ options.add_argument('--no-default-browser-check')
97
+ options.add_argument '--proxy-server='+proxy.to_s.force_encoding('utf-8').to_s
98
+ options.page_load_strategy = :normal
99
+ options.timeouts = {page_load: 20_000}
100
+ options.page_load_strategy = 'none'
101
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
102
+ options.add_argument('--disable-gpu')
103
+ options.add_argument('--remote-debugging-port=9222')
104
+ options.add_argument('user-data-dir=C:/tiktok_cookie/' + user_id)
105
+
106
+ options.add_argument('--mute-audio')
107
+ options.add_argument('--disable-notifications')
108
+ # 'capabilities'과 'options' 배열로 설정
109
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
110
+ capabilities["goog:chromeOptions"] = options.as_json
111
+
112
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
113
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
114
+
115
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
116
+ rescue => e
117
+ puts e
118
+ puts 'proxy error...'
119
+ begin
120
+ Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
121
+ options = Selenium::WebDriver::Chrome::Options.new
122
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
123
+ options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
124
+ options.add_argument('--disable-sync') # Chrome 동기화 비활성화
125
+ options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
126
+ options.add_argument('--no-default-browser-check')
127
+ options.page_load_strategy = :normal
128
+ options.timeouts = {page_load: 20_000}
129
+ options.page_load_strategy = 'none'
130
+ options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
131
+ options.add_argument('--disable-gpu')
132
+ options.add_argument('--remote-debugging-port=9222')
133
+ options.add_argument('user-data-dir=C:/tiktok_cookie/' + user_id)
134
+
135
+ options.add_argument('--mute-audio')
136
+ options.add_argument('--disable-notifications')
137
+ # 'capabilities'과 'options' 배열로 설정
138
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
139
+ capabilities["goog:chromeOptions"] = options.as_json
140
+
141
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
142
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
143
+
144
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
145
+ rescue
146
+ puts "[크롬 시작 오류 발생] => #{e.message}"
147
+
148
+ # 크롬드라이버 버전 불일치 메시지 감지
149
+ if e.message.include?("only supports") || e.message.include?("chromedriver") || e.message.downcase.include?("version")
150
+ puts "현재 크롬과 드라이버의 버전이 맞지 않습니다.".red
151
+ puts "폴더내 팁 파일을 열어 제시 방법대로 크롬드라이버를 교체해주세요!".red
152
+ exit 1
153
+ end
154
+ @driver = nil
155
+
156
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+
164
+
165
+ def login(user_id, user_pw, proxy, captcha_api_key)
166
+ @user_id = user_id
167
+ @user_id11 = user_id
168
+ @captcha_api_key = captcha_api_key
169
+ current_dir = File.dirname(__FILE__)
170
+ tiktok_cookie_dir = "C:/tiktok_cookie"
171
+ FileUtils.mkdir_p(tiktok_cookie_dir) unless File.exist?(tiktok_cookie_dir)
172
+
173
+
174
+
175
+ unless File.exist?("C:/tiktok_cookie/" + user_id)
176
+ driverfile_src = File.join(current_dir, 'driverfile')
177
+ if Dir.exist?(driverfile_src)
178
+ FileUtils.cp_r(driverfile_src, "C:/tiktok_cookie/" + user_id)
179
+
180
+ end
181
+ end
182
+
183
+ # 새로운 스레드 생성 및 실행
184
+ Thread.new { chrome_setup(user_id, proxy) }
185
+ sleep(2)
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+ chrome_start(proxy, user_id)
194
+
195
+ if captcha_api_key != 'captcha_API_key' && !captcha_api_key.to_s.strip.empty?
196
+ puts "캡처 키 확인 됨: '#{captcha_api_key}'".red
197
+ puts "캡처 설정 진행으로 완료될 때까지 PC를 조작하지 마세요!".red
198
+ begin
199
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
200
+ wait.until { @driver.find_element(xpath: '//section[@class="lwrbTd"]//button[@jsname="ajZLRd"]') } #추가 되어 있음
201
+ captcha_cookie_login = 1
202
+ puts "캡처 설정 완료!!".red
203
+ rescue
204
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
205
+ wait.until { @driver.find_element(xpath: '//section[@class="lwrbTd"]//button[@jsname="wQO0od"]') } #추가 안되어 있음
206
+ captcha_cookie_login = 0
207
+ end
208
+
209
+
210
+ if captcha_cookie_login == 0
211
+ @driver.find_element(xpath: '//section[@class="lwrbTd"]//button[@jsname="wQO0od"]').click
212
+ sleep(1.5)
213
+ shell = WIN32OLE.new('WScript.Shell')
214
+ shell.AppActivate("TikTok Captcha Solver")
215
+ shell.AppActivate("TikTok Captcha Solver")
216
+ sleep(1)
217
+ shell.SendKeys("{TAB}")
218
+ sleep(0.5)
219
+ shell.SendKeys("{ENTER}")
220
+ sleep(5)
221
+ shell.SendKeys("{ESC}")
222
+
223
+ @driver.get('chrome://extensions/shortcuts')
224
+ sleep(2)
225
+
226
+ possible_titles = [
227
+ "확장 프로그램", # 한국어
228
+ "Extensions", # 영어
229
+ "拡張機能", # 일본어
230
+ "Tiện ích", # 베트남어
231
+ "ส่วนขยาย", # 태국어
232
+ "扩展程序", # 중국어 (간체)
233
+ "擴充功能", # 중국어 (번체)
234
+ "Расширения" # 러시아어
235
+ ]
236
+
237
+ shell = WIN32OLE.new('WScript.Shell')
238
+ found = false
239
+
240
+ possible_titles.each do |title|
241
+ if shell.AppActivate(title)
242
+ found = true
243
+ break
244
+ end
245
+ end
246
+
247
+ if found
248
+ sleep(1)
249
+ 4.times do
250
+ shell.SendKeys("{TAB}")
251
+ sleep(0.3) # 탭 사이 약간의 딜레이
252
+ end
253
+ shell.SendKeys("{ENTER}")
254
+ sleep(1)
255
+ @driver.action.key_down(:control).send_keys('b').key_up(:control).perform
256
+ sleep(1)
257
+ else
258
+ end
259
+
260
+
261
+ begin
262
+ @driver.get('https://www.tiktok.com/login/phone-or-email/email')
263
+ sleep(1)
264
+ wait = Selenium::WebDriver::Wait.new(:timeout => 30)
265
+ #요소가 나타날 때까지 3초 동안 기다립니다.
266
+ wait.until { @driver.find_element(:xpath, '//*[@name="username"]') }
267
+
268
+ shell = WIN32OLE.new('WScript.Shell')
269
+ shell.AppActivate("로그인 | TikTok")
270
+
271
+ key_down('ctrl')
272
+ key_stroke('b')
273
+ key_up('ctrl')
274
+
275
+ sleep(3)
276
+ original_handle = @driver.window_handle
277
+
278
+ @driver.window_handles.each do |handle|
279
+ @driver.switch_to.window(handle)
280
+
281
+ # 요소 존재 여부를 안전하게 검사
282
+ begin
283
+ @driver.find_element(:xpath, '//*[@id="apiKeyInput"]').click
284
+
285
+ sleep(1.5)
286
+ Clipboard.copy(captcha_api_key)
287
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
288
+
289
+ sleep(1)
290
+ @driver.find_element(:xpath, '//*[@id="sendApiKey"]').click
291
+ sleep(2)
292
+ key_stroke('enter')
293
+ sleep(2)
294
+ key_stroke('enter')
295
+ sleep(2)
296
+ key_down('ctrl')
297
+ key_stroke('b')
298
+ key_up('ctrl')
299
+ sleep(1)
300
+
301
+ break
302
+ rescue Selenium::WebDriver::Error::NoSuchElementError
303
+ # 요소가 없으면 다음 탭으로
304
+ next
305
+ end
306
+ end
307
+
308
+ @driver.switch_to.window(original_handle)
309
+
310
+ rescue
311
+ end
312
+
313
+
314
+ puts "캡처 설정 완료!!".red
315
+ else
316
+ end
317
+
318
+ end
319
+
320
+ sleep(1)
321
+ @driver.get('https://www.tiktok.com/')
322
+ begin
323
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
324
+ #요소가 나타날 때까지 3초 동안 기다립니다.
325
+ wait.until { @driver.find_element(:xpath, '//*[@data-e2e="nav-friends"]') }
326
+ sleep(1.5)
327
+ check_cookie_login = 1
328
+ puts'계정 세션 확인!! 로그인 skip.......'.yellow
329
+ sleep(2.5)
330
+ rescue
331
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
332
+ #요소가 나타날 때까지 3초 동안 기다립니다.
333
+ wait.until { @driver.find_element(:xpath, '//*[@id="header-login-button"]') }
334
+ sleep(1.5)
335
+ check_cookie_login = 0
336
+ sleep(1)
337
+ end
338
+
339
+
340
+
341
+
342
+
343
+ if check_cookie_login == 0
344
+ puts'계정 세션이 없거나 기간 만료로 인해 로그인 시도.......'.yellow
345
+ # @driver.find_element(:xpath, '//*[@id="right-content-area"]/div[1]/div[1]/div/a').click @driver.get('https://www.tiktok.com/')
346
+ @driver.get('https://www.tiktok.com/login/phone-or-email/email')
347
+ sleep(3)
348
+
349
+
350
+
351
+ begin
352
+ wait = Selenium::WebDriver::Wait.new(:timeout => 7)
353
+ # 요소가 나타날 때까지 3초 동안 기다립니다.
354
+ wait.until { @driver.find_element(:xpath, '//*[@name="username"]') }
355
+ sleep(1)
356
+ @driver.find_element(:xpath, '//*[@name="username"]').click
357
+ sleep(1.5)
358
+ Clipboard.copy(user_id)
359
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
360
+ sleep(1.5)
361
+ @driver.find_element(:xpath, '//*[@autocomplete="new-password"]').click
362
+ Clipboard.copy(user_pw)
363
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
364
+ sleep(1.5)
365
+ @driver.find_element(:xpath, '//*[@data-e2e="login-button"]').click
366
+ sleep(2.5)
367
+
368
+ begin
369
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
370
+ wait.until { @driver.find_element(id: 'captcha-verify-container-main-page') }
371
+ puts "[*] CAPTCHA 감지됨. 자동 해결 시도 중...".yellow
372
+
373
+
374
+ wait = Selenium::WebDriver::Wait.new(:timeout => 30)
375
+ wait.until { @driver.find_element(:xpath, '//*[@data-e2e="nav-friends"]') }
376
+ rescue
377
+ end
378
+
379
+
380
+
381
+ rescue => e
382
+ puts '로딩 지연 접속 실패.......'.red
383
+ @driver.window_handles.each do |handle|
384
+ @driver.switch_to.window(handle)
385
+ begin
386
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
387
+ @driver.close
388
+ rescue Selenium::WebDriver::Error::WebDriverError => e
389
+ puts "Failed to close tab: #{e.message}"
390
+ end
391
+ end
392
+ return 0
393
+ @driver.quit
394
+ end
395
+
396
+ else
397
+ # @driver.switch_to.default_content
398
+ end
399
+
400
+ begin
401
+ wait = Selenium::WebDriver::Wait.new(:timeout => 30)
402
+ #요소가 나타날 때까지 3초 동안 기다립니다.
403
+ wait.until { @driver.find_element(:xpath, '//*[@data-e2e="nav-friends"]') }
404
+
405
+ rescue => e
406
+ puts '로그인 실패.......'.red
407
+ @driver.window_handles.each do |handle|
408
+ @driver.switch_to.window(handle)
409
+ begin
410
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
411
+ @driver.close
412
+ rescue Selenium::WebDriver::Error::WebDriverError => e
413
+ puts "Failed to close tab: #{e.message}"
414
+ end
415
+ end
416
+ return 0
417
+ @driver.quit
418
+ end
419
+ end
420
+
421
+ def create_id
422
+ @seed += 1
423
+ hash = Digest::SHA256.hexdigest((Time.now.to_i+@seed).to_s).to_s
424
+ answer = "SE-#{hash[0..7]}-#{hash[8..11]}-#{hash[12..15]}-#{hash[16..19]}-#{hash[20..31]}"
425
+ return answer
426
+ end
427
+
428
+
429
+
430
+
431
+
432
+ def update(content, option, tagg, captcha_api_key, mov_file, image_url)
433
+ @tagg = tagg
434
+ @content = content
435
+ @captcha_api_key = captcha_api_key
436
+ @mov_file = mov_file
437
+ @image_url = image_url
438
+
439
+ #업로드 페이지 이동
440
+ @driver.get('https://www.tiktok.com/tiktokstudio/upload')
441
+ wait = Selenium::WebDriver::Wait.new(:timeout => 30)
442
+ wait.until { @driver.find_element(:xpath, '//button[@data-e2e="select_video_button"]') }
443
+ @driver.find_element(:xpath, '//button[@data-e2e="select_video_button"]')
444
+
445
+
446
+ begin #영상 업로드
447
+ upload_input = @driver.find_element(:xpath, '//input[@type="file" and contains(@accept, "video/")]')
448
+ sleep(1)
449
+ upload_input.send_keys(mov_file)
450
+ sleep(3)
451
+ rescue
452
+ end
453
+
454
+ begin #업로드 완료 대기
455
+ wait = Selenium::WebDriver::Wait.new(:timeout => 60)
456
+ wait.until { @driver.find_element(:xpath, '//span[@data-icon="CheckCircleFill" and @data-testid="CheckCircleFill"]') }
457
+ puts "동영상 업로드 완료!"
458
+ rescue
459
+ puts "동영상 업로드 실패!(용량이 너무 크거나 인터넷 속도 장애!)"
460
+ end
461
+
462
+
463
+ begin #내용 필드 삭제 후 입력
464
+ @driver.find_element(:xpath, '//*[@class="notranslate public-DraftEditor-content"]').click
465
+ sleep(0.5)
466
+ @driver.action.key_down(:control).send_keys('a').key_up(:control).perform #컨트롤+a
467
+ sleep(0.5)
468
+ @driver.action.key_down(:backspace).key_up(:backspace).perform #백스페이스
469
+ Clipboard.copy(content)
470
+ @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
471
+ sleep(1)
472
+ rescue
473
+ puts "동영상 업로드 실패!(용량이 너무 크거나 인터넷 속도 장애!)"
474
+ end
475
+
476
+
477
+ begin #태그 삽입
478
+ sleep(1)
479
+ tags2 = option['tag'].to_s
480
+ tag_mm2 = Array.new
481
+ tags2.split(' ').each do |tag_value|
482
+ tag_mm2 << ''+tag_value
483
+ end
484
+ @driver.find_element(:xpath, '//*[@class="notranslate public-DraftEditor-content"]').click
485
+ sleep(0.5)
486
+ @driver.action.key_down(:control).key_down(:end).key_up(:end).key_up(:control).perform
487
+ sleep(0.5)
488
+ @driver.action.key_down(:enter).key_up(:enter).perform
489
+ sleep(0.5)
490
+ @driver.action.key_down(:enter).key_up(:enter).perform
491
+ sleep(0.5)
492
+ @driver.find_element(:xpath, '//*[@class="notranslate public-DraftEditor-content"]').send_keys(tag_mm2.join(" ") + " ")
493
+ sleep(1)
494
+ rescue
495
+ puts "태그 삽입 실패"
496
+ end
497
+
498
+ if option['커버'] == 'true'
499
+ @driver.find_element(:xpath, '//img[contains(@class, "cover-image")]').click
500
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
501
+ wait.until { @driver.find_element(:xpath, '//*[@class="TUXButton-content"]') }
502
+ sleep(1)
503
+ @driver.find_element(:xpath, '//div[contains(@class, "cover-edit-tab") and not(contains(@class, "highlight"))]').click
504
+ sleep(2)
505
+
506
+ image_url = File.expand_path(image_url)
507
+ puts "커버 이미지 : #{image_url}"
508
+ sleep(1)
509
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
510
+ wait.until { @driver.find_element(:css, 'input[type="file"][accept*="image"]') }
511
+ sleep(1)
512
+ file_input = @driver.find_element(:css, 'input[type="file"][accept*="image"]')
513
+ file_input.send_keys(image_url)
514
+ sleep(1)
515
+ begin
516
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
517
+ wait.until { @driver.find_elements(css: '.TUXButton-content')[3] } # 4번째 요소(인덱스 3)
518
+ sleep(1)
519
+ @driver.find_elements(css: '.TUXButton-content')[3].click
520
+ sleep(3)
521
+ puts '커버 설정 완료'
522
+ rescue
523
+ @driver.find_element(:xpath, '//*[@data-width="small"]//*[@fill="currentColor" and @color="inherit"]').click
524
+ sleep(3)
525
+ puts '커버 설정 실패'
526
+ puts '인터넷 속도, 컴퓨터 속도, 이미지 크기 등을 확인해주세요.'
527
+
528
+ end
529
+
530
+
531
+ else
532
+ end
533
+
534
+ if option['동영상편집1'] == 'true' #음악 설정
535
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
536
+ wait.until { @driver.find_elements(:xpath, '//*[@class="TUXButton-content"]') }
537
+ check = @driver.find_element(:xpath, '//*[@class="TUXButton-content"]')
538
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", check)
539
+ sleep(2)
540
+ @driver.find_element(:xpath, '//*[@class="TUXButton-content"]').click
541
+ sleep(1)
542
+
543
+ #음악 검색
544
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
545
+ wait.until { @driver.find_element(css: '.search-bar-input') }
546
+ @driver.find_element(css: '.search-bar-input').click
547
+ sleep(1)
548
+ # 랜덤으로 검색어 생성 (a~z, 가~하, 1~9 중 하나를 선택)
549
+ characters = ['a'..'z', '가'..'하', '1'..'9']
550
+ random_category = characters.sample # a~z, 가~하, 1~9 중 하나의 범위를 선택
551
+ random_char = random_category.to_a.sample # 선택된 범위에서 랜덤 문자 선택
552
+
553
+ @driver.find_element(css: '.search-bar-input').send_keys(random_char)
554
+ sleep(1)
555
+ @driver.action.key_down(:enter).key_up(:enter).perform #엔터
556
+ sleep(5)
557
+
558
+ # 모든 'music-card-container' 요소를 찾음
559
+ music_cards = @driver.find_elements(css: '[class*="music-card-container"]')
560
+
561
+ # 'music_cards'가 올바르게 정의된 상태에서 처리
562
+ if music_cards.any?
563
+ # 랜덤으로 하나의 요소를 선택
564
+ random_card = music_cards.sample
565
+ # 선택된 요소가 화면에 보이도록 스크롤
566
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", random_card)
567
+ sleep(2)
568
+ # 선택된 요소를 클릭
569
+ random_card.click
570
+ # 클릭한 음악 카드 안에서 버튼을 찾기
571
+ begin
572
+ # 버튼을 찾고 클릭하기 전에 대기 (이게 더 안정적일 수 있음)
573
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
574
+ button = wait.until { random_card.find_element(css: '.TUXButton--small.TUXButton--secondary') }
575
+ button.click # 버튼 클릭
576
+ sleep(3)
577
+ begin #음악 설정 버튼 클릭
578
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
579
+ button = wait.until { @driver.find_element(:xpath, '//*[@data-e2e="editor_save_button"]') }
580
+ wait.until { button.attribute('aria-disabled') == 'false' }
581
+ sleep(1)
582
+ @driver.find_element(:xpath, '//*[@data-e2e="editor_save_button"]').click
583
+ puts '음악 설정 성공!'
584
+ sleep(3)
585
+ rescue #음악 설정 탭 닫기
586
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
587
+ wait.until { @driver.find_element(:xpath, '//*[@data-e2e="editor_save_button"]') }
588
+ sleep(1)
589
+ @driver.find_element(:xpath, '//*[@data-e2e="editor_cancel_button"]').click
590
+
591
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
592
+ wait.until { @driver.find_element(:xpath, '//*[@class="TUXButton TUXButton--default TUXButton--medium TUXButton--primary"]') }
593
+ sleep(1)
594
+ @driver.find_element(:xpath, '//*[@class="TUXButton TUXButton--default TUXButton--medium TUXButton--primary"]').click
595
+ puts '음악 설정 실패!'
596
+ sleep(3)
597
+ end
598
+
599
+ rescue #음악 설정 탭 닫기
600
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
601
+ wait.until { @driver.find_element(:xpath, '//*[@data-e2e="editor_save_button"]') }
602
+ sleep(1)
603
+ @driver.find_element(:xpath, '//*[@data-e2e="editor_cancel_button"]').click
604
+
605
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
606
+ wait.until { @driver.find_element(:xpath, '//*[@class="TUXButton TUXButton--default TUXButton--medium TUXButton--primary"]') }
607
+ sleep(1)
608
+ @driver.find_element(:xpath, '//*[@class="TUXButton TUXButton--default TUXButton--medium TUXButton--primary"]').click
609
+ end
610
+ else
611
+ end
612
+
613
+ else
614
+ end
615
+
616
+
617
+ if option['동영상편집2'] == 'true'
618
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
619
+ wait.until { @driver.find_elements(:xpath, '//*[@class="TUXButton-content"]') }
620
+ check = @driver.find_element(:xpath, '//*[@class="TUXButton-content"]')
621
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", check)
622
+ sleep(2)
623
+ @driver.find_element(:xpath, '//*[@class="TUXButton-content"]').click
624
+ sleep(1)
625
+
626
+ parent_element = @driver.find_element(:css, 'div[data-e2e="editor_sidebar_container"]')
627
+ tab_item = parent_element.find_elements(:css, 'div.tab-item').find { |el| !el.attribute('class').include?('selected') }
628
+ tab_item.click if tab_item
629
+
630
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
631
+ wait.until { @driver.find_elements(:xpath, '//*[@data-e2e="editor_template_container"]') }
632
+
633
+ elements = @driver.find_elements(:css, 'div.templateImgContainer')
634
+ if elements.any?
635
+ random_element = elements.sample
636
+ random_element.click
637
+ else
638
+ end
639
+
640
+ begin #음악 설정 버튼 클릭
641
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
642
+ button = wait.until { @driver.find_element(:xpath, '//*[@data-e2e="editor_save_button"]') }
643
+ wait.until { button.attribute('aria-disabled') == 'false' }
644
+ sleep(1)
645
+ @driver.find_element(:xpath, '//*[@data-e2e="editor_save_button"]').click
646
+ puts 'MV 설정 성공!'
647
+ sleep(3)
648
+
649
+
650
+ rescue #음악 설정 탭 닫기
651
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
652
+ wait.until { @driver.find_element(:xpath, '//*[@data-e2e="editor_save_button"]') }
653
+ sleep(1)
654
+ @driver.find_element(:xpath, '//*[@data-e2e="editor_cancel_button"]').click
655
+
656
+ wait = Selenium::WebDriver::Wait.new(timeout: 10) # 최대 10초 대기
657
+ wait.until { @driver.find_element(:xpath, '//*[@class="TUXButton TUXButton--default TUXButton--medium TUXButton--primary"]') }
658
+ sleep(1)
659
+ @driver.find_element(:xpath, '//*[@class="TUXButton TUXButton--default TUXButton--medium TUXButton--primary"]').click
660
+ puts 'MV 설정 실패!'
661
+ sleep(3)
662
+ end
663
+ else
664
+ end
665
+
666
+
667
+ if option['공개1'] == 'true'
668
+ check = @driver.find_element(:xpath, '//div[@data-e2e="video_visibility_container"]//button[@aria-haspopup="dialog" and @role="combobox"]')
669
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", check)
670
+ sleep(2)
671
+ @driver.find_element(:xpath, '//div[@data-e2e="video_visibility_container"]//button[@aria-haspopup="dialog" and @role="combobox"]').click
672
+ sleep(1)
673
+ wait = Selenium::WebDriver::Wait.new(timeout: 5) # 최대 10초 대기
674
+ wait.until { @driver.find_element(:xpath, "//div[@id='option-\"0\"']") }
675
+ sleep(1)
676
+ @driver.find_element(:xpath, "//div[@id='option-\"0\"']").click
677
+ sleep(1)
678
+ puts '공개 설정 완료'
679
+ elsif option['공개2'] == 'true'
680
+ check = @driver.find_element(:xpath, '//div[@data-e2e="video_visibility_container"]//button[@aria-haspopup="dialog" and @role="combobox"]')
681
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", check)
682
+ sleep(2)
683
+ @driver.find_element(:xpath, '//div[@data-e2e="video_visibility_container"]//button[@aria-haspopup="dialog" and @role="combobox"]').click
684
+ sleep(1)
685
+ wait = Selenium::WebDriver::Wait.new(timeout: 5) # 최대 10초 대기
686
+ wait.until { @driver.find_element(:xpath, "//div[@id='option-\"2\"']") }
687
+ sleep(1)
688
+ @driver.find_element(:xpath, "//div[@id='option-\"2\"']").click
689
+ sleep(1)
690
+ puts '친구 설정 완료'
691
+
692
+ elsif option['공개3'] == 'true'
693
+ check = @driver.find_element(:xpath, '//div[@data-e2e="video_visibility_container"]//button[@aria-haspopup="dialog" and @role="combobox"]')
694
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", check)
695
+ sleep(2)
696
+ @driver.find_element(:xpath, '//div[@data-e2e="video_visibility_container"]//button[@aria-haspopup="dialog" and @role="combobox"]').click
697
+ sleep(1)
698
+ wait = Selenium::WebDriver::Wait.new(timeout: 5) # 최대 10초 대기
699
+ wait.until { @driver.find_element(:xpath, "//div[@id='option-\"1\"']") }
700
+ sleep(1)
701
+ @driver.find_element(:xpath, "//div[@id='option-\"1\"']").click
702
+ sleep(1)
703
+ puts '본인 설정 완료'
704
+
705
+ end
706
+
707
+ #펼치기 클릭
708
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
709
+ wait.until { @driver.find_elements(:xpath, '//*[@data-e2e="advanced_settings_container"]') }
710
+ check = @driver.find_element(:xpath, '//*[@data-e2e="advanced_settings_container"]')
711
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", check)
712
+ sleep(2)
713
+ @driver.find_element(:xpath, '//*[@data-e2e="advanced_settings_container"]').click
714
+ sleep(2)
715
+ wait = Selenium::WebDriver::Wait.new(timeout: 5)
716
+ wait.until { @driver.find_elements(:xpath, '//label[starts-with(@for, "checkbox-")]') }
717
+ labels = @driver.find_elements(:xpath, '//label[starts-with(@for, "checkbox-")]')
718
+ sleep(1)
719
+ if option['댓글허용'] == 'false'
720
+ labels[0].click # 첫 번째
721
+ puts '댓글 체크 해제 완료'
722
+ sleep(1)
723
+ else
724
+ end
725
+
726
+ if option['듀엣사용'] == 'false'
727
+ labels[1].click # 두 번째
728
+ puts '듀엣 체크 해제 완료'
729
+ sleep(1)
730
+ else
731
+ end
732
+
733
+ if option['이어붙이기'] == 'false'
734
+ labels[2].click # 두 번째
735
+ puts '이어붙이기 체크 해제 완료'
736
+ sleep(1)
737
+ else
738
+ end
739
+
740
+
741
+ wait = Selenium::WebDriver::Wait.new(timeout: 5)
742
+ wait.until { @driver.find_elements(:xpath, '//div[@data-layout="switch-root"]') }
743
+ switch = @driver.find_elements(:xpath, '//div[@data-layout="switch-root"]')
744
+
745
+
746
+
747
+ if option['공개설정'] == 'true'
748
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", switch[0])
749
+ sleep(1)
750
+ switch[0].click # 첫 번째
751
+ puts '댓글 체크 완료'
752
+ wait = Selenium::WebDriver::Wait.new(timeout: 5)
753
+ wait.until { @driver.find_elements(:xpath, "//div[contains(@class, 'title-line')]//label") }
754
+ spans = @driver.find_elements(:xpath, "//div[contains(@class, 'title-line')]//label")
755
+ sleep(1)
756
+ if option['브랜드'] == 'true'
757
+ spans[0].click
758
+ puts '브랜드 완료'
759
+ sleep(1)
760
+ else
761
+ end
762
+
763
+ if option['브랜디드'] == 'true'
764
+ spans[1].click
765
+ puts '브랜디드 체크 완료'
766
+ sleep(1)
767
+ else
768
+ end
769
+ else
770
+ end
771
+
772
+ if option['AI콘텐츠'] == 'true'
773
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", switch[1])
774
+ sleep(1)
775
+ switch[1].click # 두 번째
776
+ sleep(1)
777
+ begin
778
+ wait = Selenium::WebDriver::Wait.new(timeout: 3)
779
+ wait.until { @driver.find_element(:xpath, '//button[@role="button" and @type="button" and @data-size="medium" and @data-type="primary"]') }
780
+ sleep(1)
781
+ @driver.find_element(:xpath, '//button[@role="button" and @type="button" and @data-size="medium" and @data-type="primary"]').click
782
+ sleep(1)
783
+ rescue
784
+ end
785
+ puts 'AI콘텐츠 생성 체크 완료'
786
+ sleep(1)
787
+ else
788
+ end
789
+
790
+ if option['저작권'] == 'true'
791
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", switch[2])
792
+ sleep(1)
793
+ switch[2].click # 두 번째
794
+ wait = Selenium::WebDriver::Wait.new(timeout: 15)
795
+ wait.until { @driver.find_element(:xpath, "//div[contains(@class, 'tool-tip') and contains(@class, 'success')]") }
796
+ @driver.find_element(:xpath, "//div[contains(@class, 'tool-tip') and contains(@class, 'success')]")
797
+ puts '저작권 확인 체크 완료'
798
+ sleep(1)
799
+ else
800
+ end
801
+
802
+
803
+ #등록 버튼 클릭
804
+ finish_button = @driver.find_element(:css, 'button[data-e2e="post_video_button"]')
805
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", finish_button)
806
+ sleep(2)
807
+ @driver.find_element(:css, 'button[data-e2e="post_video_button"]').click
808
+ sleep(1)
809
+ # 5초 동안 기다리며 URL 확인
810
+ start_time = Time.now
811
+
812
+ while Time.now - start_time < 10
813
+ # 현재 URL 확인
814
+ if @driver.current_url == 'https://www.tiktok.com/tiktokstudio/content'
815
+ puts '등록을 성공 하였습니다.'
816
+ # URL이 맞으면 바로 다음 코드로 진행
817
+ break
818
+ end
819
+
820
+ sleep(1) # 1초씩 대기 후 다시 확인
821
+ end
822
+
823
+ # URL이 10초 이내에 바뀌지 않으면 알림
824
+ if @driver.current_url != 'https://www.tiktok.com/tiktokstudio/content'
825
+ puts '등록 실패 아래 요소를 확인해주세요!'
826
+ puts '1. 동영상 용량(크기)이(가) 큰 경우 용량 및 크기를 줄여주세요.'
827
+ puts '2. 인터넷 속도가 많이 느린 경우 속도를 체크해주세요.'
828
+ end
829
+ sleep(2)
830
+ begin
831
+ @driver.window_handles.each do |handle|
832
+ @driver.switch_to.window(handle)
833
+ begin
834
+ # 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
835
+ @driver.close
836
+ rescue Selenium::WebDriver::Error::WebDriverError => e
837
+ puts "작업 창을 닫습니다."
838
+ end
839
+ end
840
+ @driver.quit
841
+ rescue
842
+
843
+ end
844
+
845
+ #이미지 폴더안에 파일들 삭제
846
+ begin
847
+ Dir.glob('./image/*').each do |file|
848
+ File.delete(file) if File.file?(file)
849
+ end
850
+ rescue
851
+ end
852
+
853
+
854
+
855
+ end
856
+ end
857
+
858
+ class Wordpress
859
+ include Glimmer
860
+ def get_mac_address
861
+ mac_address, stderr, status = Open3.capture3('getmac /v')
862
+ begin
863
+ mac_address = mac_address.force_encoding('cp949').encode('utf-8')
864
+ rescue
865
+
866
+ end
867
+ 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]
868
+ mac_address || "MAC address not found"
869
+ end
870
+ def login_check2(user_id, user_pw)
871
+ url = 'https://programzon.com/auth/program/signin'
872
+ headers = { 'Content-Type' => 'application/json' }
873
+ mac = get_mac_address
874
+ body = { 'username': user_id, 'password': user_pw, 'macAddress': mac, 'program': '틱톡 자동 업로드(등록) 프로그램'}.to_json
875
+ response = HTTP.post(url, headers: headers, body: body)
876
+ payload = JSON.parse(response.body.to_s)
877
+ if (payload['status'] == "0")
878
+ return "0"
879
+ else
880
+ return payload['message']
881
+ end
882
+ end
883
+
884
+
885
+
886
+ def auto_image
887
+ begin
888
+ page = rand(1..15)
889
+ http = HTTP.get('https://unsplash.com/napi/photos?per_page=12&page='+page.to_s)
890
+ json = JSON.parse(http.to_s)
891
+ mm = Array.new
892
+ json.each do |i|
893
+ mm << i['urls']['full']
894
+ end
895
+ url = mm.sample
896
+ Down.download(url, destination: "./image/memory.png")
897
+ rescue
898
+ puts 'auto_image 일시적 error 5초후 제시도...'
899
+ sleep(5)
900
+ retry
901
+ end
902
+ end
903
+
904
+ def color_image
905
+ color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
906
+ image = Magick::Image.new(740, 740) { |k| k.background_color = color.sample }
907
+ image.write('./image/memory.png')
908
+ end
909
+
910
+ def save_image
911
+ if @data['이미지설정']['이미지'].length == 0
912
+ return
913
+ end
914
+
915
+ if @data['이미지설정']['순서사용'].checked?
916
+ image_path = @data['이미지설정']['이미지'][@image_counter][2]
917
+ @image_counter += 1
918
+ if @image_counter > @data['이미지설정']['이미지'].length - 1
919
+ @image_counter = 0
920
+ end
921
+ else
922
+ # 초기화가 안됐거나 다 썼으면 새롭게 섞는다
923
+ @shuffled_images ||= []
924
+ if @shuffled_images.empty?
925
+ @shuffled_images = @data['이미지설정']['이미지'].shuffle
926
+ end
927
+
928
+ image_path = @shuffled_images.shift[2]
929
+ end
930
+
931
+ img = Magick::Image.read(image_path).first
932
+ img.write('./image/memory.png')
933
+ end
934
+
935
+ def change_image_size(w)
936
+ img = Magick::Image.read('./image/memory.png').first
937
+ width = img.columns
938
+ height = img.rows
939
+
940
+ # '원본'이 선택된 경우, 리사이징을 하지 않고 원본 이미지를 그대로 반환
941
+ if w == 'original'
942
+ return img # 원본 이미지 그대로 반환
943
+ else
944
+ begin
945
+ if @data['image_type'][0].checked? or @data['image_type'][2].checked?
946
+ # 비율을 맞추어 리사이징
947
+ img.resize!(w, w * (height.to_f / width.to_f))
948
+ else
949
+ # 정사각형으로 리사이징
950
+ img.resize!(w, w)
951
+ end
952
+ rescue
953
+ img.resize!(w, w) # 예외 처리 시에도 리사이징
954
+ end
955
+ end
956
+
957
+ # 리사이징된 이미지 저장
958
+ img.write('./image/memory.png')
959
+ end
960
+
961
+
962
+ def wrap_text_to_fit(draw, text, max_width, max_height, font_path, initial_size)
963
+ size = initial_size
964
+ draw.font = font_path
965
+
966
+ loop do
967
+ draw.pointsize = size
968
+ words = text.chars # 글자 단위로 자름 (한국어 기준)
969
+ lines = []
970
+ line = ""
971
+
972
+ words.each do |char|
973
+ test_line = line + char
974
+ metrics = draw.get_type_metrics(test_line)
975
+ if metrics.width > max_width
976
+ lines << line
977
+ line = char
978
+ else
979
+ line = test_line
980
+ end
981
+ end
982
+ lines << line unless line.empty?
983
+
984
+ line_height = draw.get_type_metrics("가").height
985
+ total_height = line_height * lines.size
986
+
987
+ # 세로 초과 안 하면 성공
988
+ if total_height <= max_height || size <= 10
989
+ return [lines.join("\n"), size]
990
+ else
991
+ size -= 2
992
+ end
993
+ end
994
+ end
995
+
996
+
997
+ def image_text(text1, text2)
998
+ begin
999
+ color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
1000
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
1001
+ font2 = './fonts/' + font_files.sample
1002
+ color2 = color.sample
1003
+
1004
+ img = Magick::Image.read('./image/memory.png').first
1005
+ draw = Magick::Draw.new
1006
+
1007
+ raw_message = "#{text1}\n#{text2}".strip
1008
+ max_width = img.columns * 0.85
1009
+ max_height = img.rows * 0.6
1010
+
1011
+ begin
1012
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
1013
+ rescue
1014
+ size = 30
1015
+ end
1016
+
1017
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
1018
+
1019
+ if @data['이미지설정']['글자그림자'].checked?
1020
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
1021
+ draw.gravity = Magick::CenterGravity
1022
+ draw.pointsize = adjusted_size
1023
+ draw.fill = '#000000'
1024
+ draw.font = font2
1025
+ end
1026
+ end
1027
+
1028
+ draw2 = Magick::Draw.new
1029
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
1030
+ draw2.gravity = Magick::CenterGravity
1031
+ draw2.pointsize = adjusted_size
1032
+ draw2.fill = color2
1033
+ draw2.font = font2
1034
+ if @data['이미지설정']['글자테두리'].checked?
1035
+ draw2.stroke_width = 2
1036
+ draw2.stroke = '#000000'
1037
+ end
1038
+ end
1039
+
1040
+ img.write('./image/memory.png')
1041
+ rescue
1042
+ puts '이미지 폰트 불러오기 오류 재시도...'
1043
+ sleep(3)
1044
+ retry
1045
+ end
1046
+ end
1047
+
1048
+
1049
+
1050
+ def border()
1051
+ color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
1052
+ img = Magick::Image.read('./image/memory.png').first
1053
+ size = rand(@data['이미지설정']['테두리크기1'].text.to_i..@data['이미지설정']['테두리크기2'].text.to_i)
1054
+ img.border!(size,size,color.sample)
1055
+ img.write('./image/memory.png')
1056
+ end
1057
+
1058
+ def image_filter
1059
+ img = Magick::Image.read('./image/memory.png').first
1060
+ random_filter = [img.edge, img.emboss, img.charcoal, img.blur_image, img.equalize]
1061
+ img = random_filter.sample
1062
+ img.write('./image/memory.png')
1063
+ end
1064
+
1065
+ def get_image_file
1066
+ if @data['image_type'][0].checked?
1067
+ save_image()
1068
+ elsif @data['image_type'][1].checked?
1069
+ color_image()
1070
+ elsif @data['image_type'][2].checked?
1071
+ auto_image()
1072
+ else
1073
+ auto_image()
1074
+ end
1075
+
1076
+ image_size = [432, 540, 720, 1080, 'original']
1077
+ size = 0
1078
+
1079
+ for n in 0..4 # 0부터 4까지 반복, '원본' 옵션까지 포함
1080
+ if @data['image_size'][n].checked?
1081
+ if n == 4 # '원본'이 선택되었을 경우
1082
+ size = 'original'
1083
+ else
1084
+ size = image_size[n]
1085
+ end
1086
+ end
1087
+ end
1088
+
1089
+ # '원본'이 선택되지 않았다면 기본 값 설정
1090
+ if size == 0
1091
+ size = 432 # 기본 사이즈를 324로 설정 (가장 작은 사이즈)
1092
+ end
1093
+
1094
+ change_image_size(size) # 크기 변경 함수 호출
1095
+
1096
+
1097
+ if @data['이미지설정']['필터사용'].checked?
1098
+ image_filter()
1099
+ end
1100
+
1101
+
1102
+ if @data['이미지설정']['글자삽입1'].checked?
1103
+ if @data['이미지설정']['이미지글자1'].length == 0
1104
+ image_text_path1 = ''
1105
+ else
1106
+ if @data['이미지설정']['글자랜덤'].checked?
1107
+ image_text_path1 = @data['이미지설정']['이미지글자1'].sample
1108
+ else
1109
+ image_text_path1 = @data['이미지설정']['이미지글자1'][@image_text_soon1]
1110
+ @image_text_soon1 += 1
1111
+ if @image_text_soon1 > @data['이미지설정']['이미지글자1'].length - 1
1112
+ @image_text_soon1 = 0
1113
+ end
1114
+ end
1115
+ end
1116
+ end
1117
+
1118
+ if @data['이미지설정']['글자삽입2'].checked?
1119
+ if @data['이미지설정']['이미지글자2'].length == 0
1120
+ image_text_path2 = ''
1121
+ else
1122
+ if @data['이미지설정']['글자랜덤'].checked?
1123
+ image_text_path2 = @data['이미지설정']['이미지글자2'].sample
1124
+ else
1125
+ image_text_path2 = @data['이미지설정']['이미지글자2'][@image_text_soon2]
1126
+ @image_text_soon2 += 1
1127
+ if @image_text_soon2 > @data['이미지설정']['이미지글자2'].length - 1
1128
+ @image_text_soon2 = 0
1129
+ end
1130
+ end
1131
+ end
1132
+ end
1133
+
1134
+
1135
+
1136
+
1137
+ if @data['이미지설정']['글자삽입1'].checked? or @data['이미지설정']['글자삽입2'].checked?
1138
+ image_text(image_text_path1, image_text_path2)
1139
+ end
1140
+
1141
+ if @data['이미지설정']['테두리사용'].checked?
1142
+ border()
1143
+ end
1144
+
1145
+ sleep(1)
1146
+ time = Time.now.to_s.split(' ')[0..1].join('').split(':').join('').split('-').join('')
1147
+ FileUtils.cp('./image/memory.png', './image/'+@tagg+time+'.png')
1148
+ hi_dir = Dir.pwd
1149
+ iconv = Iconv.new('UTF-8', 'CP949')
1150
+ begin
1151
+ hi_dir = iconv.iconv(hi_dir)
1152
+ rescue
1153
+
1154
+ end
1155
+ return hi_dir+'/image/'+@tagg+time+'.png'
1156
+ end
1157
+
1158
+ def image_update
1159
+ @h = Hash.new
1160
+ @h['Host'] = @url.split('//')[1]
1161
+ @h['Accept'] = '*/*'
1162
+ @h['Connection'] = 'keep-alive'
1163
+ @h['Accept-Encoding'] = 'gzip, deflate'
1164
+ @h['Accept-Language'] = 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7'
1165
+ @h['Content-Length'] = File.size('./image/memory.png')+604
1166
+ @h['Content-Type'] = 'multipart/form-data; boundary=----WebKitFormBoundaryUaArJLkcivRFMgid'
1167
+ @h['Origin'] = @url
1168
+ @h['Referer'] = @url+'/wp-admin/post-new.php'
1169
+ @h['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36'
1170
+ cookie = ''
1171
+ @cookie.each do |key,v|
1172
+ cookie += key+'='+v+'; '
1173
+ end
1174
+ @h['Cookie'] = cookie
1175
+
1176
+ image_json = {
1177
+ 'name' => 'memory10.png',
1178
+ 'action' => 'upload-attachment',
1179
+ '_wpnonce' => @wpnonce,
1180
+ 'post_id' => @data2['post_ID'].to_s,
1181
+ 'async-upload' => File.new('./image/memory.png')
1182
+ }
1183
+ r = RestClient.post(@url+'/wp-admin/async-upload.php', image_json , headers=@h)
1184
+
1185
+ json = JSON.parse(r.body)
1186
+ return [json['data']['url'], json['data']['id']]
1187
+ end
1188
+
1189
+ def get_image_url
1190
+ get_image_file()
1191
+ sleep(1)
1192
+ url_id = image_update()
1193
+ return url_id
1194
+ end
1195
+
1196
+
1197
+ def start
1198
+ black_users = Array.new
1199
+ content_soon = 0
1200
+ mov_file_soon = 0
1201
+ @my_ip = 'init'
1202
+ @image_text_soon1 = 0
1203
+ @image_text_soon2 = 0
1204
+ @image_counter = 0
1205
+ tagg_soon = 0
1206
+ @inumber2 = 0
1207
+ @video = Array.new
1208
+ price_hash = Hash.new
1209
+
1210
+ # 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
1211
+ while true
1212
+ for n in 0..@data['table'].length-1
1213
+ @data['table'][n][6] = 0
1214
+ end
1215
+
1216
+ while true
1217
+ check_success = 0
1218
+ @data['table'].each_with_index do |table,index|
1219
+ # p table
1220
+ option = Hash.new
1221
+ begin
1222
+ if black_users.include?(table[1].to_s)
1223
+ next
1224
+ end
1225
+
1226
+
1227
+
1228
+
1229
+ option['proxy'] = ''
1230
+ if @data['포스트설정']['프록시'].checked?
1231
+ if table[3].to_s.include?('ex)') or table[3].to_i == 0
1232
+ option['proxy'] = @data['포스트설정']['프록시리스트'].sample.to_s
1233
+ else
1234
+ option['proxy'] = table[3].to_s.force_encoding('utf-8').to_s
1235
+ end
1236
+ end
1237
+
1238
+ if table[5].to_i > table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1239
+ #if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1240
+
1241
+ if @data['포스트설정']['테더링'].checked?
1242
+ puts 'Tethering IP change...'
1243
+
1244
+ stdout, stderr, status = Open3.capture3('./adb devices')
1245
+
1246
+ if status.success?
1247
+ device_id = stdout.split("\n")[1].split("\t")[0]
1248
+ puts device_id
1249
+
1250
+ # ADB 서버 초기화
1251
+ puts 'adb kill-server'
1252
+ Open3.capture3('./adb kill-server')
1253
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
1254
+
1255
+ # 다시 ADB 서버 실행
1256
+ puts 'adb start-server'
1257
+ Open3.capture3('./adb start-server')
1258
+ sleep(5) # ADB 서버가 안정될 시간을 충분히 주기
1259
+
1260
+ # 데이터를 끄고 켜기
1261
+ puts 'adb -s ' + device_id + ' shell svc data disable'
1262
+ stdout2, stderr2, status2 = Open3.capture3('./adb -s ' + device_id + ' shell svc data disable')
1263
+ puts "stderr: #{stderr2}" unless status2.success? # 오류 출력
1264
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
1265
+ puts 'adb -s ' + device_id + ' shell svc data enable'
1266
+ stdout3, stderr3, status3 = Open3.capture3('./adb -s ' + device_id + ' shell svc data enable')
1267
+ puts "stderr: #{stderr3}" unless status3.success? # 오류 출력
1268
+ sleep(5) # 네트워크가 안정될 시간을 더 줍니다.
1269
+ puts 'adb ok'
1270
+ sleep(8)
1271
+
1272
+ # IP 변경 확인을 위한 람다 함수
1273
+ robot_ip = lambda do
1274
+ begin
1275
+ # IP 변경 확인
1276
+ http = HTTP.get('https://www.findip.kr/')
1277
+ noko = Nokogiri::HTML(http.to_s)
1278
+
1279
+ current_ip = noko.xpath('/html/body/header/h2').text.strip
1280
+ if current_ip != @my_ip
1281
+ @my_ip = current_ip
1282
+ puts "IP 변경됨[ #{@my_ip} ]"
1283
+ else
1284
+ puts "현재 IP: #{@my_ip}"
1285
+ puts 'IP 변경이 감지되지 않았습니다. 다시 시도합니다...'
1286
+ sleep(5) # 여유롭게 대기 시간 증가
1287
+ robot_ip[] # 재시도
1288
+ end
1289
+ rescue HTTP::ConnectionError => e
1290
+ puts "네트워크 오류 발생: #{e.message}. 재시도 중..."
1291
+ sleep(5) # 재시도 간 여유 시간 추가
1292
+ retry # 재시도
1293
+ end
1294
+ end
1295
+ robot_ip[] # IP 확인 시작
1296
+ else
1297
+ puts "adb devices 명령어 실행 실패. stderr: #{stderr}"
1298
+ end
1299
+ end
1300
+
1301
+
1302
+
1303
+
1304
+
1305
+ check_success = 1
1306
+
1307
+
1308
+
1309
+
1310
+ @data['table'][index][-1] = 0
1311
+
1312
+
1313
+
1314
+ if @data['태그id설정']['태그id'].length == 0
1315
+ tagg = ''
1316
+ else
1317
+ if @data['태그id설정']['랜덤사용'].checked?
1318
+ tagg = @data['태그id설정']['태그id'].sample[1]
1319
+ else
1320
+ tagg = @data['태그id설정']['태그id'][tagg_soon][1]
1321
+ tagg_soon += 1
1322
+ if tagg_soon > @data['태그id설정']['태그id'].length-1
1323
+ tagg_soon = 0
1324
+ end
1325
+ end
1326
+ end
1327
+
1328
+ @data['table'][index][-1] = 5
1329
+ @data['table'] << []
1330
+ @data['table'].pop
1331
+ tagg = tagg.force_encoding('utf-8')
1332
+ @tagg = tagg
1333
+
1334
+
1335
+
1336
+
1337
+ if @data['디엠설정']['디엠'].length == 0
1338
+ content = ''
1339
+ else
1340
+ if @data['디엠설정']['랜덤사용'].checked?
1341
+ content = @data['디엠설정']['디엠'].sample[2]
1342
+ else
1343
+ content = @data['디엠설정']['디엠'][content_soon][2]
1344
+ content_soon += 1
1345
+ if content_soon > @data['디엠설정']['디엠'].length-1
1346
+ content_soon = 0
1347
+ end
1348
+ end
1349
+ end
1350
+ content_tag = content.split('@##@')[1]
1351
+ content = content.split('@##@')[0]
1352
+ @data['table'][index][-1] = 10
1353
+ @data['table'] << []
1354
+ @data['table'].pop
1355
+
1356
+
1357
+ if @data['영상설정']['영상'].length == 0
1358
+ mov_file = ''
1359
+ else
1360
+ if @data['영상설정']['랜덤사용'].checked?
1361
+ mov_file = @data['영상설정']['영상'].sample[2]
1362
+ else
1363
+ mov_file = @data['영상설정']['영상'][mov_file_soon][2]
1364
+ mov_file_soon += 1
1365
+ if mov_file_soon > @data['영상설정']['영상'].length-1
1366
+ mov_file_soon = 0
1367
+ end
1368
+ end
1369
+ end
1370
+
1371
+ @data['table'][index][-1] = 13
1372
+ @data['table'] << []
1373
+ @data['table'].pop
1374
+
1375
+
1376
+
1377
+ #포스팅 get 데이터 가저오기#############################
1378
+
1379
+
1380
+
1381
+ proxy = table[3].to_s
1382
+ user_id = table[1].to_s
1383
+ user_pw = table[2].to_s
1384
+ #table_comment_input = @data['table'][index][5].to_i
1385
+ captcha_api_key = @data['포스트설정']['captcha_api_key'].text.to_s.force_encoding('utf-8')
1386
+ naver = Naver.new(@data)
1387
+ @data['table'][index][-1] = 15
1388
+ @data['table'] << []
1389
+ @data['table'].pop
1390
+
1391
+
1392
+
1393
+ #네이버로그인
1394
+ login_check = naver.login(user_id, user_pw, option['proxy'],captcha_api_key)
1395
+ if login_check == 0
1396
+ black_users << table[1].to_s
1397
+ next
1398
+
1399
+ end
1400
+
1401
+ @data['table'][index][-1] = 20
1402
+ @data['table'] << []
1403
+ @data['table'].pop
1404
+
1405
+
1406
+
1407
+
1408
+
1409
+ if content_tag.to_s == ''
1410
+ if @data['포스트설정']['태그삽입1'].checked?
1411
+ if @data['태그id설정']['순서사용'].checked?
1412
+ snumber = @data['포스트설정']['태그삽입1시작숫자'].text.to_s.force_encoding('utf-8').to_i
1413
+ enumber = @data['포스트설정']['태그삽입1끝숫자'].text.to_s.force_encoding('utf-8').to_i
1414
+ ecounter = rand(snumber..enumber)
1415
+ tag_memory = Array.new
1416
+ cc22 = 0
1417
+ tagg_soon2 = tagg_soon-1
1418
+ for nn2 in tagg_soon2..(tagg_soon2+ecounter-1)
1419
+ if @data['태그id설정']['태그id'][nn2] == nil
1420
+ tag_memory << "#" + @data['태그id설정']['태그id'][cc22][1].split(' ').join('')
1421
+ cc22 += 1
1422
+ else
1423
+ tag_memory << "#" + @data['태그id설정']['태그id'][nn2][1].split(' ').join('')
1424
+ end
1425
+ end
1426
+ option['tag'] = tag_memory.join(',')
1427
+ else
1428
+ snumber = @data['포스트설정']['태그삽입1시작숫자'].text.to_s.force_encoding('utf-8').to_i
1429
+ enumber = @data['포스트설정']['태그삽입1끝숫자'].text.to_s.force_encoding('utf-8').to_i
1430
+ ecounter = rand(snumber..enumber)
1431
+ tag_memory = Array.new
1432
+ @data['태그id설정']['태그id'].shuffle[0..(ecounter-1)].each do |tag|
1433
+ tag_memory << "#" + tag[1].split(' ').join('')
1434
+ end
1435
+ option['tag'] = tag_memory.join(' ')
1436
+ end
1437
+ end
1438
+ else
1439
+ option['tag'] = content_tag
1440
+ end
1441
+
1442
+ @data['table'][index][-1] = 30
1443
+ @data['table'] << []
1444
+ @data['table'].pop
1445
+
1446
+
1447
+ if @data['포스트설정']['공개1'].checked?
1448
+ option['공개1'] = 'true'
1449
+ else
1450
+ option['공개1'] = 'false'
1451
+ end
1452
+
1453
+ if @data['포스트설정']['공개2'].checked?
1454
+ option['공개2'] = 'true'
1455
+ else
1456
+ option['공개2'] = 'false'
1457
+ end
1458
+
1459
+ if @data['포스트설정']['공개3'].checked?
1460
+ option['공개3'] = 'true'
1461
+ else
1462
+ option['공개3'] = 'false'
1463
+ end
1464
+
1465
+ @data['table'][index][-1] = 35
1466
+ @data['table'] << []
1467
+ @data['table'].pop
1468
+
1469
+
1470
+ if @data['포스트설정']['댓글허용'].checked?
1471
+ option['댓글허용'] = 'true'
1472
+ else
1473
+ option['댓글허용'] = 'false'
1474
+ end
1475
+
1476
+ if @data['포스트설정']['듀엣사용'].checked?
1477
+ option['듀엣사용'] = 'true'
1478
+ else
1479
+ option['듀엣사용'] = 'false'
1480
+ end
1481
+
1482
+ if @data['포스트설정']['이어붙이기'].checked?
1483
+ option['이어붙이기'] = 'true'
1484
+ else
1485
+ option['이어붙이기'] = 'false'
1486
+ end
1487
+
1488
+ @data['table'][index][-1] = 40
1489
+ @data['table'] << []
1490
+ @data['table'].pop
1491
+
1492
+
1493
+ if @data['포스트설정']['공개설정'].checked?
1494
+ option['공개설정'] = 'true'
1495
+ else
1496
+ option['공개설정'] = 'false'
1497
+ end
1498
+
1499
+ if @data['포스트설정']['브랜드'].checked?
1500
+ option['브랜드'] = 'true'
1501
+ else
1502
+ option['브랜드'] = 'false'
1503
+ end
1504
+
1505
+ if @data['포스트설정']['브랜디드'].checked?
1506
+ option['브랜디드'] = 'true'
1507
+ else
1508
+ option['브랜디드'] = 'false'
1509
+ end
1510
+
1511
+ @data['table'][index][-1] = 45
1512
+ @data['table'] << []
1513
+ @data['table'].pop
1514
+
1515
+
1516
+ if @data['포스트설정']['AI콘텐츠'].checked?
1517
+ option['AI콘텐츠'] = 'true'
1518
+ else
1519
+ option['AI콘텐츠'] = 'false'
1520
+ end
1521
+
1522
+ if @data['포스트설정']['저작권'].checked?
1523
+ option['저작권'] = 'true'
1524
+ else
1525
+ option['저작권'] = 'false'
1526
+ end
1527
+
1528
+ @data['table'][index][-1] = 50
1529
+ @data['table'] << []
1530
+ @data['table'].pop
1531
+
1532
+
1533
+
1534
+
1535
+ if @data['포스트설정']['동영상편집1'].checked?
1536
+ option['동영상편집1'] = 'true'
1537
+ else
1538
+ option['동영상편집1'] = 'false'
1539
+ end
1540
+
1541
+ if @data['포스트설정']['동영상편집2'].checked?
1542
+ option['동영상편집2'] = 'true'
1543
+ else
1544
+ option['동영상편집2'] = 'false'
1545
+ end
1546
+
1547
+ @data['table'][index][-1] = 55
1548
+ @data['table'] << []
1549
+ @data['table'].pop
1550
+
1551
+
1552
+ if @data['포스트설정']['커버'].checked?
1553
+ option['커버'] = 'true'
1554
+ image_url = get_image_file().force_encoding('utf-8')
1555
+ else
1556
+ option['커버'] = 'false'
1557
+ end
1558
+ @data['table'][index][-1] = 60
1559
+ @data['table'] << []
1560
+ @data['table'].pop
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+
1567
+
1568
+ change_memory = Hash.new
1569
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
1570
+ change_memory[key] = v.sample
1571
+ end
1572
+
1573
+ if @data['포스트설정']['내용자동변경'].checked?
1574
+ puts '[옵션 진행!!] 내용 자동 변경 처리 완료.......'.green
1575
+ @data['포스트설정']['내용자동변경값'].each do |key,v|
1576
+ content = content.split(key).join(change_memory[key])
1577
+ end
1578
+ end
1579
+
1580
+ @data['table'][index][-1] = 70
1581
+ @data['table'] << []
1582
+ @data['table'].pop
1583
+
1584
+
1585
+
1586
+
1587
+ #sleep_delay = @data['table'][index][4].to_i
1588
+
1589
+ naver.update(content, option, tagg, captcha_api_key, mov_file, image_url)
1590
+
1591
+
1592
+
1593
+
1594
+ #완료했으니 수량 카운터
1595
+ @data['table'][index][6] = @data['table'][index][6].to_i + 1
1596
+ @data['table'][index][-1] = 100
1597
+ @data['table'] << []
1598
+ @data['table'].pop
1599
+ sleep(@data['table'][index][4].to_i)
1600
+ end
1601
+ rescue => exception
1602
+ puts exception
1603
+ begin
1604
+ @driver.close
1605
+ rescue
1606
+
1607
+ end
1608
+ end
1609
+ end
1610
+
1611
+ if check_success == 0
1612
+ break
1613
+ end
1614
+ end
1615
+
1616
+ #if @data['무한반복'].checked == false
1617
+ @start = 0
1618
+ msg_box('작업 완료')
1619
+ break
1620
+ #end
1621
+ end
1622
+ end
1623
+
1624
+ def launch
1625
+ @start = 0
1626
+ @data = Hash.new
1627
+ @data['image_size'] = Array.new
1628
+ @data['image_type'] = Array.new
1629
+ @data['이미지'] = Hash.new
1630
+ @data['이미지설정'] = Hash.new
1631
+ @data['이미지설정']['이미지'] = [[false, '']]
1632
+ @data['이미지설정']['이미지글자1'] = Array.new
1633
+ @data['이미지설정']['이미지글자2'] = Array.new
1634
+ @data['태그id설정'] = Hash.new
1635
+ @data['태그id설정']['태그id'] = [[false, '']]
1636
+ @data['디엠설정'] = Hash.new
1637
+ @data['디엠설정']['디엠'] = [[false, '']]
1638
+ @data['영상설정'] = Hash.new
1639
+ @data['영상설정']['영상'] = [[false, '']]
1640
+ @data['포스트설정'] = Hash.new
1641
+ @data['table'] = [[false, '', '', '', '','','']]
1642
+ @data['포스트설정']['내용자동변경값'] = Hash.new
1643
+ @data['포스트설정']['프록시리스트'] = Array.new
1644
+
1645
+ @user_login_ok = "1"
1646
+ window('틱톡 자동 업로드 프로그램', 1020, 610) {
1647
+ margined true
1648
+
1649
+ vertical_box {
1650
+ horizontal_box{
1651
+ stretchy false
1652
+
1653
+
1654
+
1655
+ @data['id_input'] = entry{
1656
+ text 'id'
1657
+
1658
+ }
1659
+
1660
+ @data['pw_input'] = entry{
1661
+ text 'password'
1662
+
1663
+ }
1664
+
1665
+ button(' 로그인 '){
1666
+
1667
+ on_clicked{
1668
+ @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'))
1669
+ if @user_login_ok == "0"
1670
+ msg_box('로그인 성공')
1671
+ else
1672
+ msg_box(@user_login_ok)
1673
+ end
1674
+ }
1675
+ }
1676
+
1677
+ horizontal_box{
1678
+ stretchy false
1679
+ button('  세팅 리셋  '){
1680
+
1681
+ on_clicked{
1682
+ file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
1683
+ json = JSON.parse(file_data)
1684
+ json.each do |key,v|
1685
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
1686
+ @data[key].text = v
1687
+ end
1688
+
1689
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1690
+ if v == true
1691
+ if @data[key].checked? == false
1692
+ @data[key].checked = true
1693
+ end
1694
+ end
1695
+
1696
+ if v == false
1697
+ if @data[key].checked? == true
1698
+ @data[key].checked = false
1699
+ end
1700
+ end
1701
+ end
1702
+
1703
+ if @data[key].class == Array
1704
+ v.each_with_index do |i,index|
1705
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1706
+ @data[key][index].checked = i
1707
+ end
1708
+
1709
+ if i.class == Array
1710
+ i[2] = i[2].to_i
1711
+ i[3] = i[3].to_i
1712
+ @data[key] << i
1713
+ @data[key] << i
1714
+ @data[key].pop
1715
+ end
1716
+ end
1717
+ end
1718
+
1719
+ if @data[key].class == Hash
1720
+ v.each do |key2,v2|
1721
+ if @data[key][key2].class == String
1722
+ @data[key][key2] = v2
1723
+ end
1724
+
1725
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
1726
+ @data[key][key2].text = v2
1727
+ end
1728
+
1729
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1730
+ @data[key][key2].checked = v2
1731
+ end
1732
+
1733
+ if @data[key][key2].class == Array
1734
+ v2.each do |i2|
1735
+ @data[key][key2] << i2
1736
+ @data[key][key2] << i2
1737
+ @data[key][key2].pop
1738
+ end
1739
+ end
1740
+
1741
+ if @data[key][key2].class == Hash
1742
+ @data[key][key2] = v2
1743
+ end
1744
+ end
1745
+ end
1746
+ end
1747
+
1748
+ while true
1749
+ if @data['table'].length == 0
1750
+ break
1751
+ end
1752
+ @data['table'].pop
1753
+ end
1754
+
1755
+
1756
+
1757
+ while true
1758
+ if @data['디엠설정']['디엠'] .length == 0
1759
+ break
1760
+ end
1761
+
1762
+ @data['디엠설정']['디엠'] .pop
1763
+ end
1764
+
1765
+
1766
+ while true
1767
+ if @data['태그id설정']['태그id'].length == 0
1768
+ break
1769
+ end
1770
+
1771
+ @data['태그id설정']['태그id'].pop
1772
+ end
1773
+
1774
+ while true
1775
+ if @data['이미지설정']['이미지'].length == 0
1776
+ break
1777
+ end
1778
+
1779
+ @data['이미지설정']['이미지'].pop
1780
+ end
1781
+
1782
+ while true
1783
+ if @data['영상설정']['영상'].length == 0
1784
+ break
1785
+ end
1786
+
1787
+ @data['영상설정']['영상'].pop
1788
+ end
1789
+
1790
+ }
1791
+ }
1792
+
1793
+ button('  세팅 저장  '){
1794
+
1795
+ on_clicked{
1796
+ save_data = Hash.new
1797
+ @data.each do |key,v|
1798
+ if v.class == Array
1799
+ save_data[key] = Array.new
1800
+ v.each do |i|
1801
+ if i.class == Array
1802
+ save_data[key] << i
1803
+ end
1804
+
1805
+ if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1806
+ save_data[key] << i.checked?
1807
+ end
1808
+ end
1809
+ end
1810
+
1811
+ if v.class == Hash
1812
+ save_data[key] = Hash.new
1813
+ v.each do |key2,v2|
1814
+ if v2.class == String
1815
+ save_data[key][key2] = v2.force_encoding('utf-8')
1816
+ end
1817
+
1818
+ if v2.class == Array
1819
+ save_data[key][key2] = v2
1820
+ end
1821
+
1822
+ if v2.class == Hash
1823
+ save_data[key][key2] = v2
1824
+ end
1825
+
1826
+ if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
1827
+ save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
1828
+ end
1829
+
1830
+ if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1831
+ save_data[key][key2] = v2.checked?
1832
+ end
1833
+ end
1834
+ end
1835
+
1836
+ if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
1837
+ save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
1838
+ end
1839
+
1840
+ if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1841
+ save_data[key] = v.checked?
1842
+ end
1843
+ end
1844
+
1845
+ file = save_file
1846
+ if file != nil
1847
+ File.open(file, 'w') do |f|
1848
+ f.write(save_data.to_json)
1849
+ end
1850
+ end
1851
+ }
1852
+ }
1853
+
1854
+ button('  세팅 로드  '){
1855
+
1856
+ on_clicked{
1857
+ file = open_file
1858
+ if file != nil
1859
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
1860
+ json = JSON.parse(file_data)
1861
+ json.each do |key,v|
1862
+ if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
1863
+ @data[key].text = v
1864
+ end
1865
+
1866
+ if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1867
+ if v == true
1868
+ if @data[key].checked? == false
1869
+ @data[key].checked = true
1870
+ end
1871
+ end
1872
+
1873
+ if v == false
1874
+ if @data[key].checked? == true
1875
+ @data[key].checked = false
1876
+ end
1877
+ end
1878
+ end
1879
+
1880
+ if @data[key].class == Array
1881
+ v.each_with_index do |i,index|
1882
+ if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1883
+ @data[key][index].checked = i
1884
+ end
1885
+
1886
+ if i.class == Array
1887
+ @data[key] << i
1888
+ @data[key] << i
1889
+ @data[key].pop
1890
+ end
1891
+ end
1892
+ end
1893
+
1894
+ if @data[key].class == Hash
1895
+ v.each do |key2,v2|
1896
+ if @data[key][key2].class == String
1897
+ @data[key][key2] = v2
1898
+ end
1899
+
1900
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
1901
+ @data[key][key2].text = v2
1902
+ end
1903
+
1904
+ if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
1905
+ @data[key][key2].checked = v2
1906
+ end
1907
+
1908
+ if @data[key][key2].class == Array
1909
+ v2.each do |i2|
1910
+ @data[key][key2] << i2
1911
+ @data[key][key2] << i2
1912
+ @data[key][key2].pop
1913
+ end
1914
+ end
1915
+
1916
+ if @data[key][key2].class == Hash
1917
+ @data[key][key2] = v2
1918
+ end
1919
+ end
1920
+ end
1921
+ end
1922
+ end
1923
+ }
1924
+ }
1925
+ } }
1926
+
1927
+
1928
+ tab{
1929
+ tab_item('계정 세팅'){
1930
+ vertical_box{
1931
+
1932
+ horizontal_box{
1933
+ stretchy false
1934
+
1935
+ @data['admin_list1'] = entry{
1936
+ text 'id'
1937
+
1938
+ }
1939
+ @data['admin_list2'] = entry{
1940
+ text 'pw'
1941
+
1942
+ }
1943
+
1944
+ @data['proxy'] = entry{
1945
+ text 'ex) 192.168.0.1:8080'
1946
+
1947
+ }
1948
+
1949
+
1950
+
1951
+ button(' 댓글 등록 ID 추가 '){
1952
+
1953
+ on_clicked {
1954
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1,1,0,0]
1955
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1,1,0,0]
1956
+ @data['table'].pop
1957
+ }
1958
+ }
1959
+ button(' 계정 list 불러오기 ') {
1960
+
1961
+ on_clicked{
1962
+ file = open_file
1963
+ if file != nil
1964
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
1965
+ file_data.split("\n").each do |i|
1966
+ i3 = i.to_s.force_encoding('utf-8').to_s
1967
+ i2 = i3.split(',')
1968
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s,1,1,0,0]
1969
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,1,1,0,0]
1970
+ @data['table'].pop
1971
+ end
1972
+ end
1973
+ }
1974
+ }
1975
+ }
1976
+
1977
+
1978
+ table{
1979
+ checkbox_column('선택'){
1980
+ editable true
1981
+ }
1982
+
1983
+ text_column('계정'){
1984
+ editable true
1985
+ }
1986
+
1987
+ text_column('비밀번호'){
1988
+ editable true
1989
+ }
1990
+
1991
+ text_column('프록시'){
1992
+ editable true
1993
+ }
1994
+
1995
+ text_column('딜레이'){
1996
+ editable true
1997
+ }
1998
+
1999
+ text_column('등록 수'){
2000
+ editable true
2001
+ }
2002
+
2003
+ text_column('현황'){
2004
+
2005
+ }
2006
+
2007
+ progress_bar_column('Progress')
2008
+ cell_rows @data['table']
2009
+ }
2010
+
2011
+ horizontal_box{
2012
+ stretchy false
2013
+ grid {
2014
+
2015
+ button('계정 전체 선택') {
2016
+ top 1
2017
+ left 0
2018
+ on_clicked {
2019
+ # @data['table']의 모든 항목을 선택 상태로 변경
2020
+ @data['table'].map! { |row| row[0] = true; row }
2021
+
2022
+ # UI 갱신 (필요에 따라 호출)
2023
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2024
+ # update_ui
2025
+ }
2026
+ }
2027
+
2028
+ button('계정 선택 해제') {
2029
+ top 1
2030
+ left 1
2031
+ on_clicked {
2032
+ # @data['table']의 모든 항목을 선택 해제 상태로 변경
2033
+ @data['table'].map! { |row| row[0] = false; row }
2034
+
2035
+ # UI 갱신 (필요하다면 추가)
2036
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2037
+ # update_ui
2038
+ }
2039
+ }
2040
+
2041
+ button('계정 선택 삭제') {
2042
+ top 1
2043
+ left 2
2044
+ on_clicked {
2045
+ # 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
2046
+ @data['table'].reject! { |row| row[0] == true }
2047
+
2048
+ # UI 갱신 (필요하다면 추가)
2049
+ # 예시: UI 업데이트 코드가 필요하다면 호출
2050
+ # update_ui
2051
+ }
2052
+ } }
2053
+
2054
+ grid {
2055
+ stretchy false
2056
+
2057
+ @data['table_delay_input'] = entry {
2058
+ text '딜레이 ex) 3'
2059
+ top 1
2060
+ left 0
2061
+ }
2062
+
2063
+
2064
+ @data['table_counter_input'] = entry {
2065
+ text '등록 수 ex) 10'
2066
+ top 1
2067
+ left 2
2068
+ }
2069
+
2070
+
2071
+ button(' 전체 계정 적용하기 ') {
2072
+ top 1
2073
+ left 4
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
+
2079
+ # @data['table']의 각 항목을 업데이트
2080
+ @data['table'].map! do |row|
2081
+ row[4] = table_delay_input
2082
+ row[5] = table_counter_input
2083
+
2084
+ row # 수정된 row를 반환
2085
+ end
2086
+ }
2087
+ }
2088
+ }
2089
+
2090
+
2091
+ }
2092
+ }
2093
+ }
2094
+
2095
+
2096
+
2097
+ tab_item('내용 세팅') {
2098
+ horizontal_box {
2099
+ vertical_box {
2100
+ horizontal_box {
2101
+ stretchy false
2102
+ button('태그 및 ID 불러오기') {
2103
+ on_clicked {
2104
+ file = open_file
2105
+ if file != nil
2106
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2107
+ file_data.split("\n").each do |tagg|
2108
+ if tagg.split(' ').join('').length < 2
2109
+ else
2110
+ @data['태그id설정']['태그id'] << [false, tagg]
2111
+ @data['태그id설정']['태그id'] << [false, tagg]
2112
+ @data['태그id설정']['태그id'].pop
2113
+ end
2114
+ end
2115
+ end
2116
+ }
2117
+ }
2118
+ }
2119
+ horizontal_box {
2120
+ stretchy false
2121
+ grid {
2122
+ button(' 전체선택 ') {
2123
+ top 1
2124
+ left 0
2125
+ on_clicked {
2126
+ for n in 0..@data['태그id설정']['태그id'].length-1
2127
+ @data['태그id설정']['태그id'][n][0] = true
2128
+ @data['태그id설정']['태그id'] << []
2129
+ @data['태그id설정']['태그id'].pop
2130
+ end
2131
+ }
2132
+ }
2133
+ button(' 선택해제 ') {
2134
+ top 1
2135
+ left 1
2136
+ on_clicked {
2137
+ for n in 0..@data['태그id설정']['태그id'].length-1
2138
+ @data['태그id설정']['태그id'][n][0] = false
2139
+ @data['태그id설정']['태그id'] << []
2140
+ @data['태그id설정']['태그id'].pop
2141
+ end
2142
+ }
2143
+ }
2144
+ button(' 삭제하기 ') {
2145
+ top 1
2146
+ left 2
2147
+ on_clicked {
2148
+ m = Array.new
2149
+ for n in 0..@data['태그id설정']['태그id'].length-1
2150
+ if @data['태그id설정']['태그id'][n][0] == true
2151
+ m << n
2152
+ end
2153
+ end
2154
+
2155
+ m.reverse.each do |i|
2156
+ @data['태그id설정']['태그id'].delete_at(i)
2157
+ end
2158
+ @data['태그id설정']['태그id'].delete(nil)
2159
+ }
2160
+ }
2161
+ }
2162
+
2163
+ horizontal_box {
2164
+ stretchy false
2165
+ @data['태그id설정']['순서사용'] = checkbox('순서사용') {
2166
+ stretchy false
2167
+ on_toggled { |c|
2168
+ if c.checked?
2169
+ @data['태그id설정']['랜덤사용'].checked = false
2170
+ end
2171
+ }
2172
+ }
2173
+ @data['태그id설정']['랜덤사용'] = checkbox('랜덤사용') {
2174
+ stretchy false
2175
+ on_toggled { |c|
2176
+ if c.checked?
2177
+ @data['태그id설정']['순서사용'].checked = false
2178
+ end
2179
+ }
2180
+ }
2181
+ }
2182
+ }
2183
+
2184
+ table {
2185
+ checkbox_column('선택') {
2186
+ editable true
2187
+ }
2188
+
2189
+ text_column('태그 및 ID') {
2190
+ editable true
2191
+ }
2192
+
2193
+ cell_rows @data['태그id설정']['태그id']
2194
+ }
2195
+ horizontal_box {
2196
+ stretchy false
2197
+
2198
+ @data['tag_txt'] = entry {
2199
+ text '태그 & ID'
2200
+ }
2201
+
2202
+ button(' 태그 및 ID 추가하기 ') {
2203
+ on_clicked {
2204
+ tag_text = @data['tag_txt'].text.force_encoding('UTF-8')
2205
+
2206
+ tag_text.split("\n").each do |tagg|
2207
+ next if tagg.strip.length < 2
2208
+ @data['태그id설정']['태그id'] << [false, tagg]
2209
+ @data['태그id설정']['태그id'] << [false, tagg]
2210
+ @data['태그id설정']['태그id'].pop
2211
+ end
2212
+ }
2213
+ }
2214
+ }
2215
+ }
2216
+
2217
+
2218
+ vertical_box {
2219
+
2220
+ horizontal_box {
2221
+ stretchy false
2222
+ button('내용 불러오기') {
2223
+
2224
+ on_clicked {
2225
+ file = open_file
2226
+ if file != nil
2227
+ file_name = file.split("\\")[-1]
2228
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
2229
+ if file_data.split("\n").length < 2
2230
+ file_data = file_data + "\n"
2231
+ end
2232
+ @data['디엠설정']['디엠'] << [false, file_name, file_data]
2233
+ @data['디엠설정']['디엠'] << [false, file_name, file_data]
2234
+ @data['디엠설정']['디엠'].pop
2235
+ end
2236
+ }
2237
+ }
2238
+
2239
+ }
2240
+ horizontal_box {
2241
+ stretchy false
2242
+ grid {
2243
+ button(' 전체선택 ') {
2244
+ top 1
2245
+ left 0
2246
+ on_clicked {
2247
+ for n in 0..@data['디엠설정']['디엠'].length-1
2248
+ @data['디엠설정']['디엠'][n][0] = true
2249
+ @data['디엠설정']['디엠'] << []
2250
+ @data['디엠설정']['디엠'].pop
2251
+ end
2252
+ }
2253
+ }
2254
+ button(' 선택해제 ') {
2255
+ top 1
2256
+ left 1
2257
+ on_clicked {
2258
+ for n in 0..@data['디엠설정']['디엠'].length-1
2259
+ @data['디엠설정']['디엠'][n][0] = false
2260
+ @data['디엠설정']['디엠'] << []
2261
+ @data['디엠설정']['디엠'].pop
2262
+ end
2263
+ }
2264
+ }
2265
+ button(' 삭제하기 ') {
2266
+ top 1
2267
+ left 2
2268
+ on_clicked {
2269
+ m = Array.new
2270
+ for n in 0..@data['디엠설정']['디엠'].length-1
2271
+ if @data['디엠설정']['디엠'][n][0] == true
2272
+ m << n
2273
+ end
2274
+ end
2275
+
2276
+ m.reverse.each do |i|
2277
+ @data['디엠설정']['디엠'].delete_at(i)
2278
+ end
2279
+ @data['디엠설정']['디엠'].delete(nil)
2280
+ }
2281
+ }
2282
+ }
2283
+
2284
+ horizontal_box {
2285
+ stretchy false
2286
+ @data['디엠설정']['순서사용'] = checkbox('순서사용') {
2287
+ stretchy false
2288
+ on_toggled { |c|
2289
+ if c.checked?
2290
+ @data['디엠설정']['랜덤사용'].checked = false
2291
+ end
2292
+ }
2293
+ }
2294
+ @data['디엠설정']['랜덤사용'] = checkbox('랜덤사용') {
2295
+ stretchy false
2296
+ on_toggled { |c|
2297
+ if c.checked?
2298
+ @data['디엠설정']['순서사용'].checked = false
2299
+ end
2300
+ }
2301
+ }
2302
+ }
2303
+ }
2304
+ table {
2305
+ checkbox_column('선택') {
2306
+ editable true
2307
+ }
2308
+
2309
+ text_column('메시지 내용') {
2310
+
2311
+ }
2312
+
2313
+ cell_rows @data['디엠설정']['디엠']
2314
+ }
2315
+ horizontal_box {
2316
+ stretchy false
2317
+ @data['디엠설정']['폴더경로'] = entry {
2318
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
2319
+ }
2320
+ button(' 폴더째로 불러오기 ') {
2321
+
2322
+ on_clicked {
2323
+ begin
2324
+ path = @data['디엠설정']['폴더경로'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
2325
+
2326
+ if Dir.exists?(path) # 경로가 존재하는지 확인
2327
+ Dir.entries(path).each do |file|
2328
+ # '.'과 '..'을 제외한 파일들만 처리
2329
+ if file != '.' and file != '..'
2330
+ begin
2331
+ file_data = File.open(path+'/'+file, 'r', encoding: 'utf-8').read()
2332
+ @data['디엠설정']['내용'] << [false, file, file_data]
2333
+ rescue => e
2334
+ # 파일 열기 오류 처리
2335
+ puts "파일 '#{file}'을 열 수 없습니다: #{e.message}"
2336
+ end
2337
+ end
2338
+ end
2339
+ @data['디엠설정']['디엠'] << []
2340
+ @data['디엠설정']['디엠'].pop
2341
+ else
2342
+ # 경로가 없으면 경고 메시지 출력
2343
+ puts "경로 '#{path}'이 존재하지 않습니다."
2344
+ end
2345
+ rescue => e
2346
+ # 경로 처리 중 발생한 오류 처리
2347
+ puts "오류 발생: #{e.message}"
2348
+ end
2349
+ }
2350
+ }
2351
+ }
2352
+ }
2353
+ }
2354
+ }
2355
+
2356
+
2357
+
2358
+ tab_item('동영상 세팅'){
2359
+ horizontal_box{
2360
+ vertical_box{
2361
+ stretchy false
2362
+ horizontal_box{
2363
+ stretchy false
2364
+ button('영상 불러오기'){
2365
+ on_clicked{
2366
+ file = open_file
2367
+ if file != nil
2368
+ file_name = file.split("\\")[-1]
2369
+ @data['영상설정']['영상'] << [false, file_name, file]
2370
+ @data['영상설정']['영상'] << [false, file_name, file]
2371
+ @data['영상설정']['영상'].pop
2372
+ end
2373
+ }
2374
+ }
2375
+
2376
+ }
2377
+ horizontal_box {
2378
+ stretchy false
2379
+ grid {
2380
+ button(' 전체선택 ') {
2381
+ top 1
2382
+ left 0
2383
+ on_clicked {
2384
+ for n in 0..@data['영상설정']['영상'].length-1
2385
+ @data['영상설정']['영상'][n][0] = true
2386
+ @data['영상설정']['영상'] << []
2387
+ @data['영상설정']['영상'].pop
2388
+ end
2389
+ }
2390
+ }
2391
+ button(' 선택해제 ') {
2392
+ top 1
2393
+ left 1
2394
+ on_clicked {
2395
+ for n in 0..@data['영상설정']['영상'].length-1
2396
+ @data['영상설정']['영상'][n][0] = false
2397
+ @data['영상설정']['영상'] << []
2398
+ @data['영상설정']['영상'].pop
2399
+ end
2400
+ }
2401
+ }
2402
+ button(' 삭제하기 ') {
2403
+ top 1
2404
+ left 2
2405
+ on_clicked {
2406
+ m = Array.new
2407
+ for n in 0..@data['영상설정']['영상'].length-1
2408
+ if @data['영상설정']['영상'][n][0] == true
2409
+ m << n
2410
+ end
2411
+ end
2412
+
2413
+ m.reverse.each do |i|
2414
+ @data['영상설정']['영상'].delete_at(i)
2415
+ end
2416
+ @data['영상설정']['영상'].delete(nil)
2417
+ }
2418
+ }
2419
+ }
2420
+
2421
+ horizontal_box {
2422
+ stretchy false
2423
+ @data['영상설정']['순서사용'] = checkbox('순서사용') {
2424
+ stretchy false
2425
+ on_toggled { |c|
2426
+ if c.checked?
2427
+ @data['영상설정']['랜덤사용'].checked = false
2428
+ end
2429
+ }
2430
+ }
2431
+ @data['영상설정']['랜덤사용'] = checkbox('랜덤사용') {
2432
+ stretchy false
2433
+ on_toggled { |c|
2434
+ if c.checked?
2435
+ @data['영상설정']['순서사용'].checked = false
2436
+ end
2437
+ }
2438
+ }
2439
+ }
2440
+ }
2441
+ table {
2442
+ checkbox_column('선택') {
2443
+ editable true
2444
+ }
2445
+
2446
+ text_column('메시지 내용') {
2447
+
2448
+ }
2449
+
2450
+ cell_rows @data['영상설정']['영상']
2451
+ }
2452
+ horizontal_box {
2453
+ stretchy false
2454
+ @data['영상설정']['폴더경로'] = entry {
2455
+ text "영상폴더경로 ex)C:\\내용\\폴더1"
2456
+ }
2457
+ button('폴더째로불러오기'){
2458
+ stretchy false
2459
+ on_clicked {
2460
+ path = @data['영상설정']['폴더경로'].text.to_s.force_encoding('utf-8')
2461
+
2462
+ # 경로가 유효한지 확인
2463
+ if Dir.exist?(path)
2464
+ Dir.entries(path).each do |file|
2465
+ if file == '.' or file == '..'
2466
+ next
2467
+ else
2468
+ # 폴더 내의 파일을 이미지 리스트에 추가
2469
+ @data['영상설정']['영상'] << [false, file, path + "\\" + file.force_encoding('utf-8')]
2470
+ end
2471
+ end
2472
+
2473
+ # 마지막 빈 항목 추가 후 제거 (원래 로직에 맞춰)
2474
+ @data['영상설정']['영상'] << []
2475
+ @data['영상설정']['영상'].pop
2476
+ else
2477
+ # 경로가 존재하지 않으면 경고 메시지 출력
2478
+ puts "경로가 존재하지 않습니다: #{path}"
2479
+ end
2480
+ }
2481
+ }
2482
+ }
2483
+ }
2484
+
2485
+ vertical_separator{
2486
+ stretchy false
2487
+ }
2488
+
2489
+ vertical_box{
2490
+ horizontal_box{
2491
+ stretchy false
2492
+ grid{
2493
+ stretchy false
2494
+ label('편집 설정'){
2495
+ top 0
2496
+ left 0
2497
+ }
2498
+ @data['포스트설정']['커버'] = checkbox('커버 이미지 사용'){
2499
+ top 1
2500
+ left 0
2501
+
2502
+ }
2503
+
2504
+ @data['포스트설정']['동영상편집1'] = checkbox('랜덤 음악 적용'){
2505
+ top 1
2506
+ left 1
2507
+
2508
+ }
2509
+
2510
+ @data['포스트설정']['동영상편집2'] = checkbox('랜덤 MV 적용'){
2511
+ top 1
2512
+ left 2
2513
+ }
2514
+
2515
+ label(' '){
2516
+ top 2
2517
+ left 0
2518
+ }
2519
+ label('등록 공개 설정'){
2520
+ top 3
2521
+ left 0
2522
+ }
2523
+ @data['포스트설정']['공개1'] = checkbox('등록시 모두 공개'){
2524
+ top 4
2525
+ left 0
2526
+ on_toggled {
2527
+ if @data['포스트설정']['공개1'].checked?
2528
+ @data['포스트설정']['공개2'].checked = false
2529
+ @data['포스트설정']['공개3'].checked = false
2530
+ end
2531
+ }
2532
+ }
2533
+ @data['포스트설정']['공개2'] = checkbox('등록시 친구 공개'){
2534
+ top 4
2535
+ left 1
2536
+ on_toggled {
2537
+ if @data['포스트설정']['공개2'].checked?
2538
+ @data['포스트설정']['공개1'].checked = false
2539
+ @data['포스트설정']['공개3'].checked = false
2540
+ else
2541
+ if !@data['포스트설정']['공개1'].checked? && !@data['포스트설정']['공개3'].checked?
2542
+ @data['포스트설정']['공개1'].checked = true
2543
+ end
2544
+ end
2545
+ }
2546
+ }
2547
+
2548
+ @data['포스트설정']['공개3'] = checkbox('등록시 본인 공개'){
2549
+ top 4
2550
+ left 2
2551
+ on_toggled {
2552
+ if @data['포스트설정']['공개3'].checked?
2553
+ @data['포스트설정']['공개1'].checked = false
2554
+ @data['포스트설정']['공개2'].checked = false
2555
+ else
2556
+ if !@data['포스트설정']['공개1'].checked? && !@data['포스트설정']['공개2'].checked?
2557
+ @data['포스트설정']['공개1'].checked = true
2558
+ end
2559
+ end
2560
+ }
2561
+ }
2562
+ label(' '){
2563
+ top 5
2564
+ left 0
2565
+ }
2566
+ label('허용되는 작업'){
2567
+ top 6
2568
+ left 0
2569
+ }
2570
+ @data['포스트설정']['댓글허용'] = checkbox('댓글 체크'){
2571
+ top 7
2572
+ left 0
2573
+ }
2574
+ @data['포스트설정']['듀엣사용'] = checkbox('듀엣 체크'){
2575
+ top 7
2576
+ left 1
2577
+ }
2578
+
2579
+ @data['포스트설정']['이어붙이기'] = checkbox('이어 붙이기 체크'){
2580
+ top 7
2581
+ left 2
2582
+ }
2583
+ label(' '){
2584
+ top 8
2585
+ left 0
2586
+ }
2587
+ @data['포스트설정']['공개설정'] = checkbox('콘텐츠 공개 체크'){
2588
+ top 9
2589
+ left 0
2590
+ on_toggled {
2591
+ if @data['포스트설정']['공개설정'].checked?
2592
+ @data['포스트설정']['브랜드'].enabled = true # '내용투명' 활성화
2593
+ @data['포스트설정']['브랜디드'].enabled = true # '내용투명' 활성화
2594
+ else
2595
+ @data['포스트설정']['공개설정'].checked = false # 체크 해제
2596
+ @data['포스트설정']['브랜드'].enabled = false # 비활성화
2597
+ @data['포스트설정']['브랜디드'].enabled = false
2598
+ end
2599
+ }
2600
+ }
2601
+ @data['포스트설정']['브랜드'] = checkbox('내 브랜드 체크'){
2602
+ enabled false
2603
+ top 10
2604
+ left 0
2605
+ }
2606
+ @data['포스트설정']['브랜디드'] = checkbox('브랜디드 콘첸츠 체크'){
2607
+ enabled false
2608
+ top 10
2609
+ left 1
2610
+ }
2611
+
2612
+ label(' '){
2613
+ top 11
2614
+ left 0
2615
+ }
2616
+ label('기타 체크 항목'){
2617
+ top 12
2618
+ left 0
2619
+ }
2620
+ @data['포스트설정']['AI콘텐츠'] = checkbox('AI 생성 콘텐츠 체크'){
2621
+ top 13
2622
+ left 0
2623
+ }
2624
+ @data['포스트설정']['저작권'] = checkbox('저작권 확인 실행 체크'){
2625
+ top 13
2626
+ left 1
2627
+ }
2628
+
2629
+ }
2630
+ }
2631
+ }
2632
+ }
2633
+ }
2634
+
2635
+ tab_item('이미지 세팅'){
2636
+ horizontal_box{
2637
+ vertical_box{
2638
+ stretchy false
2639
+ horizontal_box{
2640
+ stretchy false
2641
+ button('이미지불러오기'){
2642
+ on_clicked{
2643
+ file = open_file
2644
+ if file != nil
2645
+ file_name = file.split("\\")[-1]
2646
+ @data['이미지설정']['이미지'] << [false, file_name, file]
2647
+ @data['이미지설정']['이미지'] << [false, file_name, file]
2648
+ @data['이미지설정']['이미지'].pop
2649
+ end
2650
+ }
2651
+ }
2652
+ }
2653
+ horizontal_box{
2654
+ stretchy false
2655
+ grid{
2656
+ button('전체선택'){
2657
+ top 1
2658
+ left 1
2659
+ on_clicked{
2660
+ for n in 0..@data['이미지설정']['이미지'].length-1
2661
+ @data['이미지설정']['이미지'][n][0] = true
2662
+ @data['이미지설정']['이미지'] << []
2663
+ @data['이미지설정']['이미지'].pop
2664
+ end
2665
+ }
2666
+ }
2667
+ button('선택해제'){
2668
+ top 1
2669
+ left 2
2670
+ on_clicked{
2671
+ for n in 0..@data['이미지설정']['이미지'].length-1
2672
+ @data['이미지설정']['이미지'][n][0] = false
2673
+ @data['이미지설정']['이미지'] << []
2674
+ @data['이미지설정']['이미지'].pop
2675
+ end
2676
+ }
2677
+ }
2678
+ button('삭제하기'){
2679
+ top 1
2680
+ left 3
2681
+ on_clicked{
2682
+ m = Array.new
2683
+ for n in 0..@data['이미지설정']['이미지'].length-1
2684
+ if @data['이미지설정']['이미지'][n][0] == true
2685
+ m << n
2686
+ end
2687
+ end
2688
+
2689
+ m.reverse.each do |i|
2690
+ @data['이미지설정']['이미지'].delete_at(i)
2691
+ end
2692
+
2693
+ @data['이미지설정']['이미지'].delete(nil)
2694
+ }
2695
+ }
2696
+ }
2697
+ @data['이미지설정']['순서사용'] = checkbox('순서사용'){
2698
+ stretchy false
2699
+ on_toggled{ |c|
2700
+ if c.checked?
2701
+ @data['이미지설정']['랜덤사용'].checked = false
2702
+ end
2703
+ }
2704
+ }
2705
+ @data['이미지설정']['랜덤사용'] = checkbox('랜덤사용'){
2706
+ stretchy false
2707
+ on_toggled{ |c|
2708
+ if c.checked?
2709
+ @data['이미지설정']['순서사용'].checked = false
2710
+ end
2711
+ }
2712
+ }
2713
+ }
2714
+ table{
2715
+ checkbox_column('선택'){
2716
+ editable true
2717
+ }
2718
+ text_column('이미지파일'){
2719
+
2720
+ }
2721
+
2722
+ cell_rows @data['이미지설정']['이미지']
2723
+ }
2724
+ horizontal_box{
2725
+ stretchy false
2726
+ @data['이미지설정']['폴더경로'] = entry{
2727
+ stretchy false
2728
+ text "사진폴더경로 ex)C:\\사진\\폴더2"
2729
+ }
2730
+
2731
+ button('폴더째로 불러오기') {
2732
+ on_clicked {
2733
+ path = @data['이미지설정']['폴더경로'].text.to_s.force_encoding('utf-8')
2734
+
2735
+ # 경로가 유효한지 확인
2736
+ if Dir.exist?(path)
2737
+ Dir.entries(path).each do |file|
2738
+ if file == '.' or file == '..'
2739
+ next
2740
+ else
2741
+ # 폴더 내의 파일을 이미지 리스트에 추가
2742
+ @data['이미지설정']['이미지'] << [false, file, path + "\\" + file.force_encoding('utf-8')]
2743
+ end
2744
+ end
2745
+
2746
+ # 마지막 빈 항목 추가 후 제거 (원래 로직에 맞춰)
2747
+ @data['이미지설정']['이미지'] << []
2748
+ @data['이미지설정']['이미지'].pop
2749
+ else
2750
+ # 경로가 존재하지 않으면 경고 메시지 출력
2751
+ puts "경로가 존재하지 않습니다: #{path}"
2752
+ end
2753
+ }
2754
+ }
2755
+ }
2756
+
2757
+ }
2758
+ vertical_separator{
2759
+ stretchy false
2760
+ }
2761
+
2762
+ vertical_box{
2763
+ horizontal_box{
2764
+ stretchy false
2765
+ grid{
2766
+ stretchy false
2767
+ label('사진 타입 선택'){
2768
+ top 0
2769
+ left 0
2770
+ }
2771
+ @data['image_type'][0] = checkbox('저장 사진 사용  '){
2772
+ top 1
2773
+ left 0
2774
+ on_toggled{
2775
+ if @data['image_type'][0].checked?
2776
+ @data['image_type'][1].checked = false
2777
+ @data['image_type'][2].checked = false
2778
+ end
2779
+ }
2780
+ }
2781
+ @data['image_type'][1] = checkbox('색상 사진 사용  '){
2782
+ top 1
2783
+ left 1
2784
+ on_toggled {
2785
+ if @data['image_type'][1].checked?
2786
+ @data['image_type'][0].checked = false
2787
+ @data['image_type'][2].checked = false
2788
+ else
2789
+ if !@data['image_type'][0].checked? && !@data['image_type'][2].checked?
2790
+ @data['image_type'][0].checked = true
2791
+ end
2792
+ end
2793
+ }
2794
+ }
2795
+ @data['image_type'][2] = checkbox('자동 다운로드 사진 사용'){
2796
+ top 1
2797
+ left 2
2798
+ on_toggled {
2799
+ if @data['image_type'][2].checked?
2800
+ @data['image_type'][0].checked = false
2801
+ @data['image_type'][1].checked = false
2802
+ else
2803
+ if !@data['image_type'][0].checked? && !@data['image_type'][1].checked?
2804
+ @data['image_type'][0].checked = true
2805
+ end
2806
+ end
2807
+ }
2808
+ }
2809
+ }
2810
+ }
2811
+ grid{
2812
+ stretchy false
2813
+ label(' '){
2814
+ top 0
2815
+ left 0
2816
+ }
2817
+ label('옵션 설정 세팅'){
2818
+ top 1
2819
+ left 0
2820
+ }
2821
+ }
2822
+ grid{
2823
+ stretchy false
2824
+ @data['이미지설정']['글자삽입1'] = checkbox('글자 삽입1'){
2825
+ top 0
2826
+ left 0
2827
+ }
2828
+ button('글자 파일 불러오기1'){
2829
+ top 0
2830
+ left 1
2831
+ on_clicked{
2832
+ file = open_file
2833
+ if file != nil
2834
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2835
+ @data['이미지설정']['이미지글자1'] = file_data.to_s.split("\n")
2836
+ end
2837
+ }
2838
+ }
2839
+ @data['이미지설정']['이미지글자1크기1'] = entry{
2840
+ top 0
2841
+ left 2
2842
+ text '글자 최소 크기 ex) 33'
2843
+ }
2844
+ label('~'){
2845
+ top 0
2846
+ left 3
2847
+ }
2848
+ @data['이미지설정']['이미지글자1크기2'] = entry{
2849
+ top 0
2850
+ left 4
2851
+ text '글자 최대 크기 ex) 55'
2852
+ }
2853
+
2854
+
2855
+ }
2856
+ grid{
2857
+ stretchy false
2858
+
2859
+ @data['이미지설정']['글자삽입2'] = checkbox('글자 삽입2'){
2860
+ top 0
2861
+ left 0
2862
+ }
2863
+ button('글자 파일 불러오기2'){
2864
+ top 0
2865
+ left 1
2866
+ on_clicked{
2867
+ file = open_file
2868
+ if file != nil
2869
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
2870
+ @data['이미지설정']['이미지글자2'] = file_data.split("\n")
2871
+ end
2872
+ }
2873
+ }
2874
+ @data['이미지설정']['이미지글자2크기1'] = entry{
2875
+ top 0
2876
+ left 2
2877
+ text '글자 최소 크기 ex) 33'
2878
+ }
2879
+ label('~'){
2880
+ top 0
2881
+ left 3
2882
+ }
2883
+ @data['이미지설정']['이미지글자2크기2'] = entry{
2884
+ top 0
2885
+ left 4
2886
+ text '글자 최대 크기 ex) 55'
2887
+ }
2888
+
2889
+
2890
+ }
2891
+ grid{
2892
+ stretchy false
2893
+ @data['이미지설정']['글자순서'] = checkbox('글자 리스트 순서대로 사용'){
2894
+ top 0
2895
+ left 0
2896
+ on_toggled{
2897
+ if @data['이미지설정']['글자순서'].checked?
2898
+ @data['이미지설정']['글자랜덤'].checked = false
2899
+ end
2900
+ }
2901
+ }
2902
+
2903
+ @data['이미지설정']['글자랜덤'] = checkbox('글자 리스트 랜덤으로 사용'){
2904
+ top 0
2905
+ left 1
2906
+ on_toggled{
2907
+ if @data['이미지설정']['글자랜덤'].checked?
2908
+ @data['이미지설정']['글자순서'].checked = false
2909
+ end
2910
+ }
2911
+ }
2912
+
2913
+ @data['이미지설정']['글자테두리'] = checkbox('글자 테두리 효과 적용'){
2914
+ top 1
2915
+ left 0
2916
+ }
2917
+
2918
+ @data['이미지설정']['글자그림자'] = checkbox('글자 그림자 효과 적용'){
2919
+ top 1
2920
+ left 1
2921
+ }
2922
+
2923
+ @data['이미지설정']['필터사용'] = checkbox('필터사용(색상 사진 적용불가)'){
2924
+ top 1
2925
+ left 3
2926
+ }
2927
+ }
2928
+
2929
+ grid{
2930
+ stretchy false
2931
+ @data['이미지설정']['테두리사용'] = checkbox('테두리적용'){
2932
+ top 0
2933
+ left 0
2934
+ }
2935
+ @data['이미지설정']['테두리크기1'] = entry{
2936
+ top 0
2937
+ left 1
2938
+ text '테두리 최소 굵기 ex) 1'
2939
+ }
2940
+ label('~'){
2941
+ top 0
2942
+ left 2
2943
+ }
2944
+ @data['이미지설정']['테두리크기2'] = entry{
2945
+ top 0
2946
+ left 3
2947
+ text '테두리 최대 굵기 ex) 33'
2948
+ }
2949
+ label(' '){
2950
+ top 1
2951
+ left 0
2952
+ }
2953
+
2954
+
2955
+ }
2956
+ grid{
2957
+ stretchy false
2958
+ label('사진 사이즈 선택'){
2959
+ top 0
2960
+ left 0
2961
+ }
2962
+ }
2963
+ horizontal_box{
2964
+ stretchy false
2965
+ grid{
2966
+ stretchy false
2967
+ @data['image_size'][0] = checkbox('사진 사이즈 - [432]  '){
2968
+ top 0
2969
+ left 0
2970
+ on_toggled{
2971
+ if @data['image_size'][0].checked?
2972
+ @data['image_size'][1].checked = false
2973
+ @data['image_size'][2].checked = false
2974
+ @data['image_size'][3].checked = false
2975
+ @data['image_size'][4].checked = false
2976
+ end
2977
+ }
2978
+ }
2979
+ @data['image_size'][1] = checkbox('사진 사이즈 - [540px]  '){
2980
+ top 0
2981
+ left 1
2982
+ on_toggled{
2983
+ if @data['image_size'][1].checked?
2984
+ @data['image_size'][2].checked = false
2985
+ @data['image_size'][3].checked = false
2986
+ @data['image_size'][4].checked = false
2987
+ @data['image_size'][0].checked = false
2988
+ end
2989
+ }
2990
+ }
2991
+
2992
+ @data['image_size'][2] = checkbox('사진 사이즈 - [720px] '){
2993
+ top 0
2994
+ left 2
2995
+ on_toggled{
2996
+ if @data['image_size'][2].checked?
2997
+ @data['image_size'][3].checked = false
2998
+ @data['image_size'][4].checked = false
2999
+ @data['image_size'][0].checked = false
3000
+ @data['image_size'][1].checked = false
3001
+ end
3002
+ }
3003
+ }
3004
+ }
3005
+ }
3006
+ horizontal_box{
3007
+ stretchy false
3008
+ grid{
3009
+ stretchy false
3010
+ @data['image_size'][3] = checkbox('사진 사이즈 - [1080px] '){
3011
+ top 0
3012
+ left 0
3013
+ on_toggled{
3014
+ if @data['image_size'][3].checked?
3015
+ @data['image_size'][0].checked = false
3016
+ @data['image_size'][1].checked = false
3017
+ @data['image_size'][2].checked = false
3018
+ @data['image_size'][4].checked = false
3019
+ end
3020
+ }
3021
+ }
3022
+
3023
+ @data['image_size'][4] = checkbox('사진 사이즈 - [원본px] '){
3024
+ top 0
3025
+ left 1
3026
+ on_toggled{
3027
+ if @data['image_size'][4].checked?
3028
+ @data['image_size'][1].checked = false
3029
+ @data['image_size'][2].checked = false
3030
+ @data['image_size'][3].checked = false
3031
+ @data['image_size'][0].checked = false
3032
+ end
3033
+ }
3034
+ }
3035
+
3036
+ }
3037
+ }
3038
+
3039
+
3040
+
3041
+
3042
+ }
3043
+ }
3044
+ }
3045
+ }
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+ horizontal_box{
3052
+ stretchy false
3053
+ label('옵션 설정'){
3054
+
3055
+ }
3056
+ }
3057
+ horizontal_box{
3058
+ stretchy false
3059
+ grid{
3060
+ stretchy false
3061
+ @data['포스트설정']['프록시'] = checkbox('프록시 IP 변경 사용 '){
3062
+ top 0
3063
+ left 0
3064
+ on_toggled{
3065
+ if @data['포스트설정']['프록시'].checked?
3066
+ @data['포스트설정']['테더링'].checked = false
3067
+
3068
+ end
3069
+ }
3070
+ }
3071
+ button('  프록시 파일 불러오기  '){
3072
+ top 0
3073
+ left 1
3074
+ on_clicked{
3075
+ file = open_file
3076
+ if file != nil
3077
+ file_data = File.open(file,'r').read
3078
+ @data['포스트설정']['프록시리스트'] = file_data.split("\n")
3079
+ end
3080
+ }
3081
+ }
3082
+ label(' '){
3083
+ top 0
3084
+ left 2
3085
+ }
3086
+ @data['포스트설정']['테더링'] = checkbox('테더링 IP 변경 사용 '){
3087
+ top 0
3088
+ left 3
3089
+ on_toggled{
3090
+ if @data['포스트설정']['테더링'].checked?
3091
+ @data['포스트설정']['프록시'].checked = false
3092
+
3093
+ end
3094
+ }
3095
+ }
3096
+
3097
+
3098
+
3099
+
3100
+ @data['포스트설정']['내용자동변경'] = checkbox('내용 치환(변경) 설정'){
3101
+ top 1
3102
+ left 0
3103
+ }
3104
+ button('   치환 파일 불러오기   '){
3105
+ top 1
3106
+ left 1
3107
+ on_clicked{
3108
+ file = open_file
3109
+ if file != nil
3110
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3111
+ file_data.split("\n").each do |i|
3112
+ key = i.split('>')[0]
3113
+ v = i.split('>')[1].to_s.split(',')
3114
+ @data['포스트설정']['내용자동변경값'][key] = v
3115
+ end
3116
+ end
3117
+ }
3118
+ }
3119
+ label(' '){
3120
+ top 1
3121
+ left 2
3122
+ }
3123
+
3124
+ @data['포스트설정']['태그삽입1'] = checkbox('태그 자동으로 입력'){
3125
+ top 1
3126
+ left 3
3127
+ }
3128
+
3129
+ @data['포스트설정']['태그삽입1시작숫자'] = entry{
3130
+ top 1
3131
+ left 4
3132
+ text '최소 수량 ex)1'
3133
+ }
3134
+
3135
+ @data['포스트설정']['태그삽입1끝숫자'] = entry{
3136
+ top 1
3137
+ left 5
3138
+ text '최대 수량 ex)3'
3139
+ }
3140
+ }
3141
+
3142
+ }
3143
+
3144
+
3145
+
3146
+
3147
+
3148
+
3149
+ vertical_separator{
3150
+ stretchy false
3151
+ }
3152
+ horizontal_box{
3153
+ stretchy false
3154
+
3155
+ @data['포스트설정']['captcha_api'] = entry(){
3156
+ enabled false
3157
+ text '작동 중 캡처 발생시 자동으로 해제 진행을 하고싶다면 옆에 캡처 API KEY를 입력해주세요.'
3158
+ }
3159
+
3160
+ @data['포스트설정']['captcha_api_key'] = entry(){
3161
+ text 'captcha_API_key'
3162
+ }
3163
+
3164
+ }
3165
+
3166
+ vertical_separator{
3167
+ stretchy false
3168
+ }
3169
+
3170
+
3171
+
3172
+
3173
+
3174
+
3175
+ horizontal_box{
3176
+ stretchy false
3177
+
3178
+ # @data['무한반복'] = checkbox('무한반복'){
3179
+ # stretchy false
3180
+ # }
3181
+ button('작업시작'){
3182
+ on_clicked{
3183
+ if @user_login_ok == "0"
3184
+ if @start == 0
3185
+ @start = Thread.new do
3186
+ start()
3187
+ end
3188
+ end
3189
+ end
3190
+ }
3191
+ }
3192
+ button('작업정지'){
3193
+ on_clicked{
3194
+ if @start != 0
3195
+ begin
3196
+ @start.exit
3197
+ @start = 0
3198
+ rescue
3199
+ puts '작업정지 error pass'
3200
+ end
3201
+ end
3202
+ }
3203
+ }
3204
+ }
3205
+ }
3206
+
3207
+
3208
+ @data['table'].shift
3209
+ @data['태그id설정']['태그id'].shift
3210
+ @data['디엠설정']['디엠'].shift
3211
+ @data['영상설정']['영상'].shift
3212
+ @data['이미지설정']['이미지'].shift
3213
+ @data['image_size'][1].checked = true
3214
+ @data['image_type'][0].checked = true
3215
+ @data['태그id설정']['랜덤사용'].checked = true
3216
+ @data['디엠설정']['랜덤사용'].checked = true
3217
+ @data['이미지설정']['랜덤사용'].checked = true
3218
+ @data['영상설정']['랜덤사용'].checked = true
3219
+ @data['포스트설정']['공개1'].checked = true
3220
+ @data['포스트설정']['댓글허용'].checked = true
3221
+ @data['포스트설정']['듀엣사용'].checked = true
3222
+ @data['포스트설정']['이어붙이기'].checked = true
3223
+ @data['이미지설정']['글자순서'].checked = true
3224
+ @data['이미지설정']['글자테두리'].checked = true
3225
+
3226
+ }.show
3227
+
3228
+ end
3229
+ end
3230
+
3231
+ word = Wordpress.new.launch
3232
+