duo_blog_cafe_comment 0.0.3 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/duo_blog_cafe_comment.rb +204 -122
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4088aab9b2a41ea84152bae09d7a6a5c73760b4fa052b5f85ff9c01a879fc14
|
4
|
+
data.tar.gz: 3f763899612f523ed1167c864e09af1221da22783d8da62eb76edcc82fc7fafa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af4d4b0e56c45502d106ed21c9f7fd80c35f5676eda6d5f2d2fdcdaae98859682723c1d9d9f204edb0a5f815a8213b988ca730107359b402b1710f0fba1bc77f
|
7
|
+
data.tar.gz: 637d2e2b9c891c26449d0fc223da99ca90148000e87992ec3dfd41b92a4343a679675bbab5c6b9f59755d7362890b3085a8c940b1a12e68681cc8cd4e50a8fb2
|
@@ -41,6 +41,8 @@ class Naver
|
|
41
41
|
begin
|
42
42
|
Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
43
43
|
options = Selenium::WebDriver::Chrome::Options.new
|
44
|
+
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
45
|
+
options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
|
44
46
|
options.page_load_strategy = :normal
|
45
47
|
options.timeouts = {page_load: 20_000}
|
46
48
|
options.page_load_strategy = 'none'
|
@@ -48,21 +50,16 @@ class Naver
|
|
48
50
|
options.add_argument('--disable-gpu')
|
49
51
|
options.add_argument('--remote-debugging-port=9222')
|
50
52
|
options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
|
51
|
-
@driver = Selenium::WebDriver.for(:chrome,
|
53
|
+
@driver = Selenium::WebDriver.for(:chrome, options: options)
|
52
54
|
rescue
|
53
|
-
@driver = Selenium::WebDriver.for(:chrome,
|
55
|
+
@driver = Selenium::WebDriver.for(:chrome, options: options)
|
54
56
|
end
|
55
57
|
else
|
56
58
|
begin
|
57
59
|
Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
58
60
|
options = Selenium::WebDriver::Chrome::Options.new
|
59
|
-
#
|
60
|
-
|
61
|
-
# profile['network.proxy.http'] = proxy.split(':')[0]
|
62
|
-
# profile['network.proxy.http_port'] = proxy.split(':')[1].to_i
|
63
|
-
# options = Selenium::WebDriver::Chrome::Options.new
|
64
|
-
# options.profile = profile
|
65
|
-
options = Selenium::WebDriver::Chrome::Options.new
|
61
|
+
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
62
|
+
options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
|
66
63
|
options.add_argument '--proxy-server='+proxy.to_s.force_encoding('utf-8').to_s
|
67
64
|
options.page_load_strategy = :normal
|
68
65
|
options.timeouts = {page_load: 20_000}
|
@@ -71,13 +68,15 @@ class Naver
|
|
71
68
|
options.add_argument('--disable-gpu')
|
72
69
|
options.add_argument('--remote-debugging-port=9222')
|
73
70
|
options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
|
74
|
-
@driver = Selenium::WebDriver.for(:chrome,
|
71
|
+
@driver = Selenium::WebDriver.for(:chrome, options: options)
|
75
72
|
rescue => e
|
76
73
|
puts e
|
77
74
|
puts 'proxy error...'
|
78
75
|
begin
|
79
76
|
Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
80
77
|
options = Selenium::WebDriver::Chrome::Options.new
|
78
|
+
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
79
|
+
options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
|
81
80
|
options.page_load_strategy = :normal
|
82
81
|
options.timeouts = {page_load: 20_000}
|
83
82
|
options.page_load_strategy = 'none'
|
@@ -85,9 +84,9 @@ class Naver
|
|
85
84
|
options.add_argument('--disable-gpu')
|
86
85
|
options.add_argument('--remote-debugging-port=9222')
|
87
86
|
options.add_argument('user-data-dir=C:/naver_cookie/' + user_id)
|
88
|
-
@driver = Selenium::WebDriver.for(:chrome,
|
87
|
+
@driver = Selenium::WebDriver.for(:chrome, options: options)
|
89
88
|
rescue
|
90
|
-
@driver = Selenium::WebDriver.for(:chrome,
|
89
|
+
@driver = Selenium::WebDriver.for(:chrome, options: options)
|
91
90
|
end
|
92
91
|
end
|
93
92
|
end
|
@@ -125,39 +124,58 @@ class Naver
|
|
125
124
|
sleep(1)
|
126
125
|
|
127
126
|
begin
|
128
|
-
wait = Selenium::WebDriver::Wait.new(:timeout =>
|
127
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 7)
|
128
|
+
#요소가 나타날 때까지 3초 동안 기다립니다.
|
129
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__btn_logout___bsTOJ"]') }
|
130
|
+
sleep(1.5)
|
131
|
+
check_cookie_login = 1
|
132
|
+
puts'[Step.02] 계정 세션 확인!! 로그인 skip.......'.yellow
|
133
|
+
sleep(2.5)
|
134
|
+
rescue
|
135
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 7)
|
129
136
|
#요소가 나타날 때까지 3초 동안 기다립니다.
|
130
137
|
wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__link_login___HpHMW"]') }
|
131
138
|
sleep(1.5)
|
132
139
|
@driver.find_element(:xpath, '//*[@class="MyView-module__link_login___HpHMW"]').click
|
133
140
|
check_cookie_login = 0
|
134
141
|
sleep(1)
|
135
|
-
rescue
|
136
|
-
check_cookie_login = 1
|
137
|
-
puts'[Step.02] 계정 세션 확인!! 로그인 skip.......'.yellow
|
138
|
-
sleep(1)
|
139
142
|
end
|
140
143
|
|
141
144
|
if check_cookie_login == 0
|
142
145
|
puts'[Step.02] 계정 세션이 없거나 기간 만료로 인해 로그인 시도.......'.yellow
|
143
146
|
# @driver.find_element(:xpath, '//*[@id="right-content-area"]/div[1]/div[1]/div/a').click
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
147
|
+
sleep(3)
|
148
|
+
begin
|
149
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 7)
|
150
|
+
#요소가 나타날 때까지 3초 동안 기다립니다.
|
151
|
+
wait.until { @driver.find_element(:xpath, '//*[@for="switch"]') }
|
152
|
+
sleep(1.5)
|
153
|
+
@driver.find_element(:xpath, '//*[@id="login_keep_wrap"]/div[1]/label').click
|
154
|
+
sleep(1.5)
|
155
|
+
@driver.find_element(:xpath, '//*[@id="id"]').click
|
156
|
+
Clipboard.copy(user_id)
|
157
|
+
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
158
|
+
sleep(1.5)
|
159
|
+
@driver.find_element(:xpath, '//*[@id="pw"]').click
|
160
|
+
Clipboard.copy(user_pw)
|
161
|
+
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
162
|
+
sleep(1.5)
|
163
|
+
@driver.find_element(:xpath, '//*[@id="log.login"]').click
|
164
|
+
sleep(2.5)
|
165
|
+
rescue => e
|
166
|
+
puts '-[√] 로딩 지연 접속 실패.......'.red
|
167
|
+
@driver.window_handles.each do |handle|
|
168
|
+
@driver.switch_to.window(handle)
|
169
|
+
begin
|
170
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
171
|
+
@driver.close
|
172
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
173
|
+
puts "Failed to close tab: #{e.message}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
return 0
|
177
|
+
@driver.quit
|
178
|
+
end
|
161
179
|
|
162
180
|
else
|
163
181
|
# @driver.switch_to.default_content
|
@@ -169,11 +187,19 @@ class Naver
|
|
169
187
|
wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__btn_logout___bsTOJ"]') }
|
170
188
|
|
171
189
|
rescue => e
|
172
|
-
puts '-[√] 로그인
|
173
|
-
|
174
|
-
|
190
|
+
puts '-[√] 로그인 실패.......'.red
|
191
|
+
@driver.window_handles.each do |handle|
|
192
|
+
@driver.switch_to.window(handle)
|
193
|
+
begin
|
194
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
195
|
+
@driver.close
|
196
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
197
|
+
puts "Failed to close tab: #{e.message}"
|
198
|
+
end
|
199
|
+
end
|
175
200
|
return 0
|
176
|
-
|
201
|
+
@driver.quit
|
202
|
+
end
|
177
203
|
end
|
178
204
|
|
179
205
|
def create_id
|
@@ -197,9 +223,20 @@ class Naver
|
|
197
223
|
# 요소가 나타날 때까지 기다립니다.
|
198
224
|
wait.until { @driver.find_element(:xpath, '//*[@class="tit-info-on"]') }
|
199
225
|
@driver.find_element(:xpath, '//*[@class="tit-info-on"]').click
|
200
|
-
rescue
|
201
|
-
|
202
|
-
|
226
|
+
rescue => e
|
227
|
+
puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
|
228
|
+
@driver.window_handles.each do |handle|
|
229
|
+
@driver.switch_to.window(handle)
|
230
|
+
begin
|
231
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
232
|
+
@driver.close
|
233
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
234
|
+
puts "Failed to close tab: #{e.message}"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
return 0
|
238
|
+
@driver.quit
|
239
|
+
end
|
203
240
|
|
204
241
|
################################################################################ 프로그램에 설정한 이미지랑 글까지 등록
|
205
242
|
if option['닉네임변경'] == 'true'
|
@@ -446,23 +483,22 @@ class Naver
|
|
446
483
|
|
447
484
|
# 이미지 자동 삽입
|
448
485
|
if option['이미지자동삽입'] == 'true'
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
486
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
487
|
+
|
488
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
489
|
+
@image = image
|
490
|
+
image_path = image
|
491
|
+
|
492
|
+
@driver.find_element(:xpath, '//*[@for="attach2"]').click
|
493
|
+
sleep(1)
|
494
|
+
key_stroke('escape')
|
495
|
+
# 파일 경로 자동 입력
|
496
|
+
file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
|
497
|
+
|
498
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
499
|
+
file_input.send_keys(image_path)
|
500
|
+
sleep(2)
|
501
|
+
|
466
502
|
else
|
467
503
|
end
|
468
504
|
|
@@ -665,22 +701,21 @@ class Naver
|
|
665
701
|
# 이미지 자동 삽입
|
666
702
|
if option['이미지자동삽입'] == 'true'
|
667
703
|
puts "이미지 자동 상입 옵션 진행!!".cyan
|
704
|
+
|
668
705
|
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
669
|
-
|
670
|
-
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
671
|
-
wait.until { @driver.find_element(:xpath, '//*[@class="button_file"]') }
|
672
|
-
@driver.find_element(:xpath, '//*[@class="button_file"]').click
|
673
|
-
sleep(1)
|
674
706
|
@image = image
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
707
|
+
image_path = image
|
708
|
+
|
709
|
+
@driver.find_element(:xpath, '//*[@for="attach2"]').click
|
710
|
+
sleep(1)
|
711
|
+
key_stroke('escape')
|
712
|
+
# 파일 경로 자동 입력
|
713
|
+
file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
|
714
|
+
|
715
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
716
|
+
file_input.send_keys(image_path)
|
717
|
+
sleep(2)
|
718
|
+
|
684
719
|
else
|
685
720
|
end
|
686
721
|
|
@@ -942,23 +977,22 @@ class Naver
|
|
942
977
|
|
943
978
|
# 이미지 자동 삽입
|
944
979
|
if option['이미지자동삽입'] == 'true'
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
980
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
981
|
+
|
982
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
983
|
+
@image = image
|
984
|
+
image_path = image
|
985
|
+
|
986
|
+
@driver.find_element(:xpath, '//*[@for="attach2"]').click
|
987
|
+
sleep(1)
|
988
|
+
key_stroke('escape')
|
989
|
+
# 파일 경로 자동 입력
|
990
|
+
file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
|
991
|
+
|
992
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
993
|
+
file_input.send_keys(image_path)
|
994
|
+
sleep(2)
|
995
|
+
|
962
996
|
else
|
963
997
|
end
|
964
998
|
|
@@ -1035,11 +1069,25 @@ class Naver
|
|
1035
1069
|
@driver.get(url)
|
1036
1070
|
|
1037
1071
|
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1072
|
+
begin
|
1073
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
1074
|
+
#요소가 나타날 때까지 10초 동안 기다립니다.
|
1075
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="area_list_search"]') }
|
1076
|
+
sleep(1)
|
1077
|
+
rescue => e
|
1078
|
+
puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
|
1079
|
+
@driver.window_handles.each do |handle|
|
1080
|
+
@driver.switch_to.window(handle)
|
1081
|
+
begin
|
1082
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
1083
|
+
@driver.close
|
1084
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
1085
|
+
puts "Failed to close tab: #{e.message}"
|
1086
|
+
end
|
1087
|
+
end
|
1088
|
+
return 0
|
1089
|
+
@driver.quit
|
1090
|
+
end
|
1043
1091
|
|
1044
1092
|
# 현재 페이지에서 7개의 post-url을 찾기
|
1045
1093
|
posts = @driver.find_elements(:xpath, '//div[@class="list_search_post"]//div[@class="desc"]//a[@class="desc_inner"]')
|
@@ -1069,10 +1117,25 @@ class Naver
|
|
1069
1117
|
# 페이지 열기
|
1070
1118
|
url = "https://section.blog.naver.com/Search/Post.naver?pageNo=#{page_no}&rangeType=ALL&orderBy=recentdate&keyword=#{keyword}"
|
1071
1119
|
@driver.get(url)
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1120
|
+
begin
|
1121
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
1122
|
+
#요소가 나타날 때까지 10초 동안 기다립니다.
|
1123
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="area_list_search"]') }
|
1124
|
+
sleep(1)
|
1125
|
+
rescue => e
|
1126
|
+
puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
|
1127
|
+
@driver.window_handles.each do |handle|
|
1128
|
+
@driver.switch_to.window(handle)
|
1129
|
+
begin
|
1130
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
1131
|
+
@driver.close
|
1132
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
1133
|
+
puts "Failed to close tab: #{e.message}"
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
return 0
|
1137
|
+
@driver.quit
|
1138
|
+
end
|
1076
1139
|
|
1077
1140
|
# 현재 페이지에서 7개의 post-url을 찾기
|
1078
1141
|
posts = @driver.find_elements(:xpath, '//div[@class="list_search_post"]//div[@class="desc"]//a[@class="desc_inner"]')
|
@@ -1129,11 +1192,25 @@ class Naver
|
|
1129
1192
|
# URL 생성
|
1130
1193
|
url = "https://section.blog.naver.com/ThemePost.naver?directoryNo=#{page_no1}&activeDirectorySeq=#{page_no2}¤tPage=#{page_no}"
|
1131
1194
|
@driver.get(url)
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1195
|
+
begin
|
1196
|
+
# 요소가 나타날 때까지 10초 동안 기다립니다.
|
1197
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
1198
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="list_post_article"]') }
|
1199
|
+
sleep(1)
|
1200
|
+
rescue => e
|
1201
|
+
puts '-[√] 인터넷 로딩 지연 접속실패!!.......'.red
|
1202
|
+
@driver.window_handles.each do |handle|
|
1203
|
+
@driver.switch_to.window(handle)
|
1204
|
+
begin
|
1205
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
1206
|
+
@driver.close
|
1207
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
1208
|
+
puts "Failed to close tab: #{e.message}"
|
1209
|
+
end
|
1210
|
+
end
|
1211
|
+
return 0
|
1212
|
+
@driver.quit
|
1213
|
+
end
|
1137
1214
|
|
1138
1215
|
# 현재 페이지에서 7개의 post-url을 찾기
|
1139
1216
|
posts = @driver.find_elements(:xpath, '//div[@class="item multi_pic"]//div[@class="desc"]//a[@class="desc_inner"]')
|
@@ -1714,22 +1791,17 @@ class Naver
|
|
1714
1791
|
|
1715
1792
|
|
1716
1793
|
elsif option['이미지자동삽입'] == 'true'
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
@driver.find_element(:xpath, '//*[@data-log="RPO.photo"]').click
|
1722
|
-
sleep(1)
|
1723
|
-
@image = image
|
1794
|
+
begin
|
1795
|
+
sleep(1)
|
1796
|
+
@image = image
|
1797
|
+
image_path = image
|
1724
1798
|
#클립보드에 복사
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
sleep(3)
|
1732
|
-
else
|
1799
|
+
file_input = @driver.find_element(:xpath, '//*[@class="u-cbox-browse-file-input"]')
|
1800
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
1801
|
+
file_input.send_keys(image_path)
|
1802
|
+
sleep(1)
|
1803
|
+
rescue
|
1804
|
+
end
|
1733
1805
|
end
|
1734
1806
|
sleep(1)
|
1735
1807
|
element = @driver.find_element(:xpath, '//*[@data-uiselector="writeButton"]')
|
@@ -1794,10 +1866,20 @@ class Naver
|
|
1794
1866
|
else
|
1795
1867
|
end
|
1796
1868
|
|
1797
|
-
begin
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1869
|
+
begin
|
1870
|
+
@driver.window_handles.each do |handle|
|
1871
|
+
@driver.switch_to.window(handle)
|
1872
|
+
begin
|
1873
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
1874
|
+
@driver.close
|
1875
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
1876
|
+
puts "Failed to close tab: #{e.message}"
|
1877
|
+
end
|
1878
|
+
end
|
1879
|
+
@driver.quit
|
1880
|
+
rescue
|
1881
|
+
|
1882
|
+
end
|
1801
1883
|
|
1802
1884
|
|
1803
1885
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duo_blog_cafe_comment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-02-
|
11
|
+
date: 2025-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: File to Clipboard gem
|
14
14
|
email: mymin26@naver.com
|