tblog_zon 0.0.15 → 0.0.33

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 +4 -4
  2. data/lib/tblog_zon.rb +491 -378
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 227824dd9194402552a4d6d29a70034447dbf8cf36bb803f062e230d64b81568
4
- data.tar.gz: d29e3cd4b1163b7705f997b657512df6ddf056e863168224dc9db6c40081a9a3
3
+ metadata.gz: af125531c5abb4f735518a15a00613310da34ed91d5e429e83a1816e8be60a0a
4
+ data.tar.gz: 4b7b8a41441690612b25dde68ae846b892c8cf098cf9bca7f87262f928d753bc
5
5
  SHA512:
6
- metadata.gz: 65f3111ffdad096f9d5b50c51f664a3319892751656fee9b017b7bfa513b643c30aaaddefc3cae5f2fdde9ae783ab5132e7bab347a3308f9f4f1c05a8c5d55af
7
- data.tar.gz: 3ab2e1a0c8118c571789627089dc100465ddd66b1eb27f27d2830ad8a134ff78603c71fb85434390d0728d588e0a793f91a9df58ea54a99c1711e8f075dee3c8
6
+ metadata.gz: 19cd6335c20c748982f7db099b6293dc0775b06999ec9b7204cea1d2e8662329be4949b0eae84de8bf7c4c56885ec636ae925f7495a9263fc93169e1eec0eec5
7
+ data.tar.gz: cb06cab1a20556a661fb530862e4bea5a261f1f31d3afff76bd0c272c80006fe4325004f0a90fa9067e0e081189774a6ca512d6dff2408d91f6fd3f2ba12fcb0
data/lib/tblog_zon.rb CHANGED
@@ -25,93 +25,107 @@ include Glimmer
25
25
 
26
26
 
27
27
  class Chat
28
- def initialize(api_key)
28
+ def initialize(api_key, gpt_keyword_prompt)
29
29
  @api_key = api_key
30
+ @gpt_keyword_prompt = gpt_keyword_prompt
30
31
  end
31
32
 
32
- def message2(keyword)
33
- url = 'https://api.openai.com/v1/chat/completions'
34
- h = {
35
- 'Content-Type' => 'application/json',
36
- 'Authorization' => 'Bearer ' + @api_key
37
- }
38
- d = {
39
- #'model' => 'gpt-3.5-turbo',
40
- 'model' => 'gpt-4',
41
- 'messages' => [{
42
- "role" => "assistant",
43
- "content" => keyword.to_s+" 소개하는 글을 1500자에서 2500자 사이로 만들어줘"
44
- }]
45
- }
46
- answer = ''
47
- begin
48
- req = HTTP.headers(h).post(url, :json => d)
49
- print(req.to_s)
50
- answer = JSON.parse(req.to_s)['choices'][0]['message']['content']
51
- rescue => e
52
- begin
53
- answer = JSON.parse(req.to_s)['choices'][0]['message']['message']
54
- rescue
33
+ def message(keyword)
34
+ puts 'Sending request to GPT...(키워드 기반 글 생성 중...)'
55
35
 
36
+ # "키워드 기반 글 생성 중..." 메시지 출력 스레드
37
+ thread = Thread.new do
38
+ while true
39
+ print "▶"
40
+ sleep 3
56
41
  end
57
42
  end
58
43
 
59
-
60
- print('api return ==> ')
61
- puts(answer)
62
-
63
- return answer
64
- end
65
-
66
- def message(keyword)
67
- puts 'chat gpt ...'
68
44
  url = 'https://api.openai.com/v1/chat/completions'
69
- h = {
45
+ headers = {
70
46
  'Content-Type' => 'application/json',
71
47
  'Authorization' => 'Bearer ' + @api_key
72
48
  }
73
- d = {
74
- #'model' => 'gpt-3.5-turbo',
49
+
50
+ # 사용자로부터 받은 입력과 GPT 프롬프트의 토큰 수 계산
51
+ message_tokens = calculate_tokens(keyword) + calculate_tokens(@gpt_keyword_prompt)
52
+
53
+ # 8,192 토큰을 초과하지 않도록 최대 토큰 수를 설정
54
+ max_response_tokens = [8192 - message_tokens, 4000].min # 8,192 - 입력된 토큰 수, 4,000 이하로 설정
55
+
56
+ # 요청 데이터 설정
57
+ data = {
75
58
  'model' => 'gpt-4',
76
- 'messages' => [{
77
- "role" => "assistant",
78
- "content" => keyword.to_s+" 관련된 글을 1500자에서 2500자 사이로 만들어줘"
79
- }]
59
+ 'messages' => [
60
+ {
61
+ "role" => "assistant",
62
+ "content" => "#{keyword}\n#{@gpt_keyword_prompt}"
63
+ }
64
+ ],
65
+ 'max_tokens' => max_response_tokens # 최대 응답 토큰 설정
80
66
  }
67
+
68
+
69
+
81
70
  answer = ''
82
71
  begin
83
- req = HTTP.headers(h).post(url, :json => d)
84
- print(req.to_s)
85
- answer = JSON.parse(req.to_s)['choices'][0]['message']['content']
86
- rescue => e
87
- begin
88
- answer = JSON.parse(req.to_s)['choices'][0]['message']['message']
89
- rescue
72
+ req = HTTP.headers(headers).post(url, :json => data)
90
73
 
74
+ # 상태 코드 확인
75
+ if req.status != 200
76
+ raise "HTTP Error: #{req.status}, Response Body: #{req.body.to_s}"
91
77
  end
92
- end
93
- con = 0
94
- while con > 5
95
- answer = answer + message2(keyword)
96
- if answer.length > 2000
97
- break
78
+
79
+ # 응답 내용 출력 (디버깅용)
80
+ response = JSON.parse(req.to_s)
81
+
82
+
83
+ # 응답 데이터에서 안전하게 값 추출
84
+ if response['choices'] && response['choices'][0] && response['choices'][0]['message']
85
+ answer = response['choices'][0]['message']['content']
86
+ else
87
+ raise "Invalid API response format"
98
88
  end
99
- con += 1
89
+ rescue => e
90
+ # 오류 메시지 출력
91
+ puts "Error occurred: #{e.message}"
92
+ answer = "오류가 발생했습니다."
100
93
  end
101
94
 
102
- print('api return ==> ')
103
- puts(answer)
95
+ # "생성 중..." 메시지 출력 종료
96
+ thread.kill
104
97
 
98
+ # 결과 로그 출력
99
+ puts "Final API response ==> #{answer}"
105
100
  return answer
106
101
  end
102
+
103
+ def calculate_tokens(text)
104
+ # 간단한 방식으로 텍스트의 토큰 수 계산 (정확도는 다를 수 있음)
105
+ # OpenAI API는 1토큰이 대략 4글자 정도임
106
+ text.split(/\s+/).length # 간단한 단어 수로 계산
107
+ end
107
108
  end
108
109
 
110
+
111
+
112
+
113
+
109
114
  class Chat_title
110
- def initialize(api_key)
115
+ def initialize(api_key, gpt_title_prompt)
111
116
  @api_key = api_key
117
+ @gpt_title_prompt = gpt_title_prompt
112
118
  end
113
119
 
114
120
  def message(title)
121
+ puts 'Sending request to GPT...(제목 생성 중...)'
122
+ # "키워드 기반 글 생성 중..." 메시지를 별도 스레드로 처리
123
+ thread = Thread.new do
124
+ while true
125
+ print "▶"
126
+ sleep(3)
127
+ end
128
+ end
115
129
  url = 'https://api.openai.com/v1/chat/completions'
116
130
  headers = {
117
131
  'Content-Type' => 'application/json',
@@ -125,15 +139,15 @@ class Chat_title
125
139
  },
126
140
  {
127
141
  "role" => "user",
128
- "content" => "#{title}\n위 문장을 비슷한 길이로 ChatGPT의 멘트는 빼고 표현을 더 추가해서 하나만 만들어줘."
142
+ "content" => "#{@gpt_title_prompt}\n#{title}"
129
143
  }]
130
144
  }
131
145
 
132
146
  begin
133
147
  req = HTTP.headers(headers).post(url, json: data)
134
- puts "HTTP Status: #{req.status}" # 상태 코드 확인
148
+
135
149
  response = JSON.parse(req.body.to_s)
136
- puts "API Response: #{response}" # 전체 응답 출력
150
+
137
151
 
138
152
  if req.status == 429
139
153
  return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
@@ -141,11 +155,18 @@ class Chat_title
141
155
 
142
156
  # 응답 데이터에서 안전하게 값 추출
143
157
  answer = response.dig('choices', 0, 'message', 'content')
144
- answer ||= (title) # 응답이 없을 경우 기본 메시지 설정
158
+
159
+ # 따옴표 제거
160
+ answer = answer.gsub('"', '') if answer
161
+
162
+ answer ||= title # 응답이 없을 경우 기본 메시지 설정
145
163
  rescue => e
146
164
  puts "Error: #{e.message}"
147
165
  answer = "오류가 발생했습니다."
148
166
  end
167
+
168
+ # "생성 중..." 메시지 출력 종료
169
+ thread.kill
149
170
 
150
171
  puts 'API return ==> '
151
172
  puts answer
@@ -153,12 +174,23 @@ class Chat_title
153
174
  end
154
175
  end
155
176
 
177
+
156
178
  class Chat_content
157
- def initialize(api_key)
179
+ def initialize(api_key, gpt_content_prompt)
158
180
  @api_key = api_key
181
+ @gpt_content_prompt = gpt_content_prompt
159
182
  end
160
183
 
161
184
  def message(content)
185
+ puts '주의:GPT 특성상 원고 길이가 공백 포함 4천자를 넘기면 오류가 발생할 수 있습니다.'
186
+ puts 'Sending request to GPT...(내용 변형 중...)'
187
+ # "키워드 기반 글 생성 중..." 메시지를 별도 스레드로 처리
188
+ thread = Thread.new do
189
+ while true
190
+ print "▶"
191
+ sleep(3)
192
+ end
193
+ end
162
194
 
163
195
  url = 'https://api.openai.com/v1/chat/completions'
164
196
  headers = {
@@ -173,15 +205,16 @@ class Chat_content
173
205
  },
174
206
  {
175
207
  "role" => "user",
176
- "content" => "#{content}\nChatGPT의 멘트는 빼고 위 전체적인 내용의 형식을 똑같이 표현을 더 추가하고 유사어로 변경하여 하나 만들어줘! 전화번호,연락처,가격,홈페이지안내 ,상담안내 관련 문구는 유지해야해"
208
+ "content" => "#{@gpt_content_prompt}\n#{content}"
209
+
177
210
  }]
178
211
  }
179
212
 
180
213
  begin
181
214
  req = HTTP.headers(headers).post(url, json: data)
182
- puts "HTTP Status: #{req.status}" # 상태 코드 확인
215
+
183
216
  response = JSON.parse(req.body.to_s)
184
- puts "API Response: #{response}" # 전체 응답 출력
217
+
185
218
 
186
219
  if req.status == 429
187
220
  return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
@@ -195,6 +228,9 @@ class Chat_content
195
228
  answer = "오류가 발생했습니다."
196
229
  end
197
230
 
231
+ # "생성 중..." 메시지 출력 종료
232
+ thread.kill
233
+
198
234
  puts 'API return ==> '
199
235
  puts answer
200
236
  answer
@@ -202,6 +238,7 @@ class Chat_content
202
238
  end
203
239
 
204
240
 
241
+
205
242
  #############################################gpt############################################
206
243
 
207
244
  class Naver
@@ -214,7 +251,8 @@ class Naver
214
251
  # 공통 옵션 설정
215
252
  Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
216
253
  options = Selenium::WebDriver::Chrome::Options.new
217
-
254
+ options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
255
+ options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
218
256
  options.add_extension('./crx/app.crx') # 확장 프로그램을 첫 번째 탭에 추가
219
257
  options.add_argument('--disable-blink-features=AutomationControlled')
220
258
  options.add_argument('--disable-popup-blocking')
@@ -249,11 +287,14 @@ class Naver
249
287
 
250
288
  # 브라우저 실행
251
289
  begin
252
- # 드라이버 실행
253
- @driver = Selenium::WebDriver.for(:chrome, options: options)
254
-
255
- # 첫 번째 탭에서 확장 프로그램을 로드
256
- #@driver.get("chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html")
290
+ # 'capabilities'과 'options' 배열로 설정
291
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
292
+ capabilities["goog:chromeOptions"] = options.as_json
293
+
294
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
295
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
296
+
297
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
257
298
 
258
299
  sleep(1)
259
300
  # 두 번째 탭에서 로그인 페이지 열기
@@ -264,8 +305,15 @@ class Naver
264
305
 
265
306
  puts "Error: #{e.message}"
266
307
  puts 'Using default Chrome driver without proxy'
267
- @driver = Selenium::WebDriver.for(:chrome, options: options)
268
-
308
+ # 'capabilities'과 'options' 배열로 설정
309
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
310
+ capabilities["goog:chromeOptions"] = options.as_json
311
+
312
+ # Selenium 4에서는 'capabilities'만 사용하는 방식
313
+ @driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
314
+
315
+ @driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
316
+
269
317
  # 첫 번째 탭에서 확장 프로그램을 로드
270
318
  #@driver.get("chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html")
271
319
  sleep(1)
@@ -1880,7 +1928,15 @@ class Wordpress
1880
1928
  end
1881
1929
 
1882
1930
  if @data['포스트설정']['gpt제목'].checked?
1883
- chat = Chat_title.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'))
1931
+ gpt_title_prompt = @data['포스트설정']['gpt제목_프롬프트'].text.to_s.force_encoding('utf-8')
1932
+
1933
+ # 공백을 포함한 빈 문자열을 체크하기 위해 strip을 사용
1934
+ gpt_title_prompt_sample = gpt_title_prompt.strip.empty? ? "프롬프트: 문장을 비슷한 길이로 ChatGPT의 멘트는 빼고 표현을 더 추가해서 하나만 만들어줘." : gpt_title_prompt
1935
+
1936
+ # gpt_title_prompt_sample을 Chat_title 객체에 전달
1937
+ chat = Chat_title.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_title_prompt_sample)
1938
+
1939
+ # 메시지 요청 후 title에 저장
1884
1940
  gpt_text1 = chat.message(title)
1885
1941
  title = gpt_text1.to_s
1886
1942
  end
@@ -1925,18 +1981,16 @@ class Wordpress
1925
1981
  end
1926
1982
 
1927
1983
  if @data['포스트설정']['gpt내용'].checked?
1984
+ gpt_content_prompt = @data['포스트설정']['gpt내용_프롬프트'].text.to_s.force_encoding('utf-8')
1928
1985
  api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
1929
- #key_change = @data['포스트설정']['특정단어키워드로변경값'].text.to_s.force_encoding('utf-8')
1930
- #imotcon_change = @data['포스트설정']['스티커로변경단어'].text.to_s.force_encoding('utf-8')
1931
- #template_change = @data['포스트설정']['내템플릿변경단어'].text.to_s.force_encoding('utf-8')
1932
- #ttdanar_change = @data['포스트설정']['단어링크적용단어'].text.to_s.force_encoding('utf-8')
1933
- #sajine_change = @data['포스트설정']['단어사진으로변경단어'].text.to_s.force_encoding('utf-8')
1934
- #mov_change = @data['포스트설정']['영상으로변경단어'].text.to_s.force_encoding('utf-8')
1935
- #map_change = @data['포스트설정']['지도로변경단어'].text.to_s.force_encoding('utf-8')
1936
- #inyong9_change = @data['포스트설정']['인용구변경단어'].text.to_s.force_encoding('utf-8')
1937
-
1938
1986
 
1939
- chat = Chat_content.new(api_key)
1987
+ # 공백을 포함한 빈 문자열을 체크하기 위해 strip을 사용
1988
+ gpt_content_prompt_sample = gpt_content_prompt.strip.empty? ? "프롬프트:ChatGPT의 멘트는 빼고 위 전체적인 내용의 형식을 똑같이 표현을 더 추가하고 유사어로 변경하여 하나 만들어줘! 전화번호,연락처,가격,홈페이지안내 ,상담안내 관련 문구는 유지해야해" : gpt_content_prompt
1989
+
1990
+ # Chat_content 객체 생성 시 api_key와 gpt_content_prompt_sample을 두 개의 인자로 전달
1991
+ chat = Chat_content.new(api_key, gpt_content_prompt_sample)
1992
+
1993
+ # 메시지 요청 후 content에 저장
1940
1994
  gpt_text3 = chat.message(content)
1941
1995
  content = gpt_text3.to_s
1942
1996
  end
@@ -2142,13 +2196,17 @@ class Wordpress
2142
2196
  @data['table'] << []
2143
2197
  @data['table'].pop
2144
2198
  if @data['포스트설정']['gpt키워드'].checked?
2145
- chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'))
2199
+ gpt_keyword_prompt = @data['포스트설정']['gpt키워드_프롬프트'].text.to_s.force_encoding('utf-8')
2200
+ gpt_keyword_prompt_sample = gpt_keyword_prompt.strip.empty? ? "프롬프트: 관련된 글을 1500자에서 2500자 사이로 만들어줘" : gpt_keyword_prompt
2201
+ chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt)
2146
2202
  gpt_text = chat.message(keyword)
2147
- content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
2203
+ #content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
2204
+ content = content.to_s + "(자동생성글)" + gpt_text.to_s
2148
2205
  elsif @data['포스트설정']['내용을자동생성'].checked?
2149
2206
  content = auto_text
2150
2207
  elsif @data['포스트설정']['내용과자동생성'].checked?
2151
- content = content + "\n(자동생성글)\n" + auto_text
2208
+ #content = content + "\n(자동생성글)\n" + auto_text
2209
+ content = content + "(자동생성글)" + auto_text
2152
2210
  end
2153
2211
 
2154
2212
  if @data['포스트설정']['내용키워드삽입'].checked?
@@ -2183,7 +2241,8 @@ class Wordpress
2183
2241
  end
2184
2242
 
2185
2243
  if @data['포스트설정']['내용을자동생성'].checked?
2186
- content2 = content.split("\n")
2244
+ #content2 = content.split("\n")
2245
+ content2 = content.split
2187
2246
  end
2188
2247
 
2189
2248
  if @data['포스트설정']['내용과자동생성'].checked? or @data['포스트설정']['gpt키워드'].checked?
@@ -3154,162 +3213,170 @@ class Wordpress
3154
3213
  }
3155
3214
  }
3156
3215
  tab_item('내용설정'){
3216
+ horizontal_box{
3217
+ vertical_box{
3157
3218
  horizontal_box{
3158
- vertical_box{
3159
- horizontal_box{
3160
- stretchy false
3161
- button('키워드불러오기'){
3162
- on_clicked{
3163
- file = open_file
3164
- if file != nil
3165
- file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3166
- file_data.split("\n").each do |keyword|
3167
- if keyword.split(' ').join('').length < 2
3168
-
3169
- else
3170
- @data['키워드설정']['키워드'] << [false, keyword]
3171
- @data['키워드설정']['키워드'] << [false, keyword]
3172
- @data['키워드설정']['키워드'].pop
3173
- end
3174
- end
3175
- end
3176
-
3177
- }
3178
- }
3219
+ stretchy false
3220
+ button('키워드불러오기'){
3221
+ on_clicked{
3222
+ file = open_file
3223
+ if file != nil
3224
+ file_data = File.open(file, 'r', :encoding => 'utf-8').read()
3225
+ file_data.split("\n").each do |keyword|
3226
+ if keyword.split(' ').join('').length < 2
3179
3227
 
3180
- }
3181
- horizontal_box{
3182
- stretchy false
3183
- grid{
3184
- button('전체선택'){
3185
- top 1
3186
- left 1
3187
- on_clicked{
3188
- for n in 0..@data['키워드설정']['키워드'].length-1
3189
- @data['키워드설정']['키워드'][n][0] = true
3190
- @data['키워드설정']['키워드'] << []
3191
- @data['키워드설정']['키워드'].pop
3192
- end
3193
- }
3194
- }
3195
- button('선택해제'){
3196
- top 1
3197
- left 2
3198
- on_clicked{
3199
- for n in 0..@data['키워드설정']['키워드'].length-1
3200
- @data['키워드설정']['키워드'][n][0] = false
3201
- @data['키워드설정']['키워드'] << []
3228
+ else
3229
+ @data['키워드설정']['키워드'] << [false, keyword]
3230
+ @data['키워드설정']['키워드'] << [false, keyword]
3202
3231
  @data['키워드설정']['키워드'].pop
3203
3232
  end
3204
- }
3205
- }
3206
- button('삭제하기'){
3207
- top 1
3208
- left 3
3209
- on_clicked{
3210
- m = Array.new
3211
- for n in 0..@data['키워드설정']['키워드'].length-1
3212
- if @data['키워드설정']['키워드'][n][0] == true
3213
- m << n
3214
- end
3215
- end
3216
-
3217
- m.reverse.each do |i|
3218
- @data['키워드설정']['키워드'].delete_at(i)
3219
- end
3220
- @data['키워드설정']['키워드'].delete(nil)
3221
- }
3222
- }
3233
+ end
3234
+ end
3235
+
3223
3236
  }
3224
-
3225
- @data['키워드설정']['순서사용'] = checkbox('순서사용'){
3226
- stretchy false
3227
- on_toggled{ |c|
3228
- if c.checked?
3229
- @data['키워드설정']['랜덤사용'].checked = false
3230
- end
3231
- }
3232
- }
3233
- @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
3234
- stretchy false
3235
- on_toggled{ |c|
3236
- if c.checked?
3237
- @data['키워드설정']['순서사용'].checked = false
3238
- end
3239
- }
3240
- }
3237
+ }
3238
+
3239
+ }
3240
+ horizontal_box{
3241
+ stretchy false
3242
+ grid{
3243
+ button('전체선택'){
3244
+ top 1
3245
+ left 1
3246
+ on_clicked{
3247
+ for n in 0..@data['키워드설정']['키워드'].length-1
3248
+ @data['키워드설정']['키워드'][n][0] = true
3249
+ @data['키워드설정']['키워드'] << []
3250
+ @data['키워드설정']['키워드'].pop
3251
+ end
3241
3252
  }
3242
- vertical_separator{
3243
- stretchy false
3253
+ }
3254
+ button('선택해제'){
3255
+ top 1
3256
+ left 2
3257
+ on_clicked{
3258
+ for n in 0..@data['키워드설정']['키워드'].length-1
3259
+ @data['키워드설정']['키워드'][n][0] = false
3260
+ @data['키워드설정']['키워드'] << []
3261
+ @data['키워드설정']['키워드'].pop
3262
+ end
3244
3263
  }
3245
- horizontal_box{
3246
- stretchy false
3247
- grid{
3248
- @data['포스트설정']['gpt키워드'] = checkbox('GPT 키워드 기반 글 생성'){
3249
- top 1
3250
- left 0
3251
- #enabled false # 기본적으로 비활성화
3252
- on_toggled {
3253
- if @data['포스트설정']['gpt키워드'].checked?
3254
- @data['포스트설정']['gpt상단'].enabled = true # '내용투명' 활성화
3255
- @data['포스트설정']['gpt하단'].enabled = true # '내용투명' 활성화
3256
- else
3257
- @data['포스트설정']['gpt상단'].checked = false # 체크 해제
3258
- @data['포스트설정']['gpt상단'].enabled = false # 비활성화
3259
- @data['포스트설정']['gpt하단'].checked = false # 체크 해제
3260
- @data['포스트설정']['gpt하단'].enabled = false # 비활성화
3261
- end
3262
- }
3263
-
3264
- }
3265
-
3266
- @data['포스트설정']['gpt상단'] = checkbox('원고 위에 넣기'){
3267
- top 1
3268
- left 1
3269
- enabled false # 기본적으로 비활성화
3270
- on_toggled{
3271
- if @data['포스트설정']['gpt상단'].checked?
3272
- @data['포스트설정']['gpt하단'].checked = false
3273
- end
3274
- }
3275
- }
3276
-
3277
- @data['포스트설정']['gpt하단'] = checkbox('원고 아래 넣기'){
3278
- top 1
3279
- left 2
3280
- enabled false # 기본적으로 비활성화
3281
- on_toggled{
3282
- if @data['포스트설정']['gpt하단'].checked?
3283
- @data['포스트설정']['gpt상단'].checked = false
3264
+ }
3265
+ button('삭제하기'){
3266
+ top 1
3267
+ left 3
3268
+ on_clicked{
3269
+ m = Array.new
3270
+ for n in 0..@data['키워드설정']['키워드'].length-1
3271
+ if @data['키워드설정']['키워드'][n][0] == true
3272
+ m << n
3284
3273
  end
3285
- }
3286
- }
3287
- } }
3288
- horizontal_box{
3289
- stretchy false
3290
- grid{
3291
- label('※ GPT 기능 사용시 포스트설정1에서 GPT사용에 체크 필수'){
3292
- } } }
3293
-
3294
- table{
3295
- checkbox_column('선택'){
3296
- editable true
3297
- }
3298
- text_column('키워드'){
3299
-
3300
- }
3274
+ end
3301
3275
 
3302
- cell_rows @data['키워드설정']['키워드']
3276
+ m.reverse.each do |i|
3277
+ @data['키워드설정']['키워드'].delete_at(i)
3278
+ end
3279
+ @data['키워드설정']['키워드'].delete(nil)
3303
3280
  }
3304
-
3305
3281
  }
3306
- vertical_separator{
3282
+ }
3283
+
3284
+ @data['키워드설정']['순서사용'] = checkbox('순서사용'){
3307
3285
  stretchy false
3286
+ on_toggled{ |c|
3287
+ if c.checked?
3288
+ @data['키워드설정']['랜덤사용'].checked = false
3289
+ end
3290
+ }
3308
3291
  }
3309
- vertical_box{
3310
- horizontal_box{
3311
- stretchy false
3312
- button('제목불러오기'){
3292
+ @data['키워드설정']['랜덤사용'] = checkbox('랜덤사용'){
3293
+ stretchy false
3294
+ on_toggled{ |c|
3295
+ if c.checked?
3296
+ @data['키워드설정']['순서사용'].checked = false
3297
+ end
3298
+ }
3299
+ }
3300
+ }
3301
+ vertical_separator{
3302
+ stretchy false
3303
+ }
3304
+ horizontal_box{
3305
+ stretchy false
3306
+ grid{
3307
+ @data['포스트설정']['gpt키워드'] = checkbox('GPT 키워드 기반 글 생성'){
3308
+ top 1
3309
+ left 0
3310
+ #enabled false # 기본적으로 비활성화
3311
+ on_toggled {
3312
+ if @data['포스트설정']['gpt키워드'].checked?
3313
+ @data['포스트설정']['gpt상단'].enabled = true # '내용투명' 활성화
3314
+ @data['포스트설정']['gpt하단'].enabled = true # '내용투명' 활성화
3315
+ else
3316
+ @data['포스트설정']['gpt상단'].checked = false # 체크 해제
3317
+ @data['포스트설정']['gpt상단'].enabled = false # 비활성화
3318
+ @data['포스트설정']['gpt하단'].checked = false # 체크 해제
3319
+ @data['포스트설정']['gpt하단'].enabled = false # 비활성화
3320
+ end
3321
+ }
3322
+
3323
+ }
3324
+
3325
+ @data['포스트설정']['gpt상단'] = checkbox('원고 위에 넣기'){
3326
+ top 1
3327
+ left 1
3328
+ enabled false # 기본적으로 비활성화
3329
+ on_toggled{
3330
+ if @data['포스트설정']['gpt상단'].checked?
3331
+ @data['포스트설정']['gpt하단'].checked = false
3332
+ end
3333
+ }
3334
+ }
3335
+
3336
+ @data['포스트설정']['gpt하단'] = checkbox('원고 아래 넣기'){
3337
+ top 1
3338
+ left 2
3339
+ enabled false # 기본적으로 비활성화
3340
+ on_toggled{
3341
+ if @data['포스트설정']['gpt하단'].checked?
3342
+ @data['포스트설정']['gpt상단'].checked = false
3343
+ end
3344
+ }
3345
+ }
3346
+ } }
3347
+ horizontal_box{
3348
+ stretchy false
3349
+ @data['포스트설정']['gpt키워드_프롬프트'] = entry(){
3350
+ text '프롬프트:관련 글을 1500자에서 2500자 사이로 만들어줘'
3351
+ }}
3352
+ horizontal_box{
3353
+ stretchy false
3354
+ grid{
3355
+ label('※ GPT 기능 사용시 포스트설정1에서 GPT사용에 체크 필수'){
3356
+ } } }
3357
+
3358
+
3359
+ table{
3360
+ checkbox_column('선택'){
3361
+ editable true
3362
+ }
3363
+ text_column('키워드'){
3364
+
3365
+ }
3366
+
3367
+ cell_rows @data['키워드설정']['키워드']
3368
+ }
3369
+
3370
+
3371
+
3372
+ }
3373
+ vertical_separator{
3374
+ stretchy false
3375
+ }
3376
+ vertical_box{
3377
+ horizontal_box{
3378
+ stretchy false
3379
+ button('제목불러오기'){
3313
3380
  on_clicked{
3314
3381
  file = open_file
3315
3382
  if file != nil
@@ -3398,158 +3465,187 @@ class Wordpress
3398
3465
 
3399
3466
 
3400
3467
  }}}
3468
+ horizontal_box{
3469
+ stretchy false
3470
+ @data['포스트설정']['gpt제목_프롬프트'] = entry(){
3471
+ text '프롬프트:비슷한 길이로 제목으로 사용할수있게 하나만 만들어줘'
3472
+ }}
3401
3473
  horizontal_box{
3402
3474
  stretchy false
3403
3475
  grid{
3404
3476
  label('※ GPT 기능 사용시 포스트설정1에서 GPT사용에 체크 필수'){
3405
3477
  } } }
3406
- table{
3407
- checkbox_column('선택'){
3408
- editable true
3409
- }
3410
- text_column('제목'){
3478
+
3411
3479
 
3412
- }
3480
+ table{
3481
+ checkbox_column('선택'){
3482
+ editable true
3483
+ }
3484
+ text_column('제목'){
3413
3485
 
3414
- cell_rows @data['제목설정']['제목']
3415
- }
3486
+ }
3487
+
3488
+ cell_rows @data['제목설정']['제목']
3489
+ }
3490
+
3416
3491
 
3492
+ }
3493
+ vertical_separator{
3494
+ stretchy false
3495
+ }
3496
+ vertical_box{
3497
+ horizontal_box{
3498
+ stretchy false
3499
+ button('내용불러오기'){
3500
+ on_clicked{
3501
+ file = open_file
3502
+ if file != nil
3503
+ file_name = file.split("\\")[-1]
3504
+ file_data = File.open(file,'r', :encoding => 'utf-8').read()
3505
+ if file_data.split("\n").length < 2
3506
+ file_data = file_data + "\n"
3507
+ end
3508
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3509
+ @data['내용설정']['내용'] << [false, file_name, file_data]
3510
+ @data['내용설정']['내용'].pop
3511
+ end
3512
+ }
3417
3513
  }
3418
- vertical_separator{
3419
- stretchy false
3514
+
3515
+ }
3516
+ horizontal_box{
3517
+ stretchy false
3518
+ grid{
3519
+ button('전체선택'){
3520
+ top 1
3521
+ left 1
3522
+ on_clicked{
3523
+ for n in 0..@data['내용설정']['내용'].length-1
3524
+ @data['내용설정']['내용'][n][0] = true
3525
+ @data['내용설정']['내용'] << []
3526
+ @data['내용설정']['내용'].pop
3527
+ end
3528
+ }
3420
3529
  }
3421
- vertical_box{
3422
- horizontal_box{
3423
- stretchy false
3424
- button('내용불러오기'){
3425
- on_clicked{
3426
- file = open_file
3427
- if file != nil
3428
- file_name = file.split("\\")[-1]
3429
- file_data = File.open(file,'r', :encoding => 'utf-8').read()
3430
- if file_data.split("\n").length < 2
3431
- file_data = file_data + "\n"
3432
- end
3433
- @data['내용설정']['내용'] << [false, file_name, file_data]
3434
- @data['내용설정']['내용'] << [false, file_name, file_data]
3435
- @data['내용설정']['내용'].pop
3436
- end
3437
- }
3438
- }
3439
-
3530
+ button('선택해제'){
3531
+ top 1
3532
+ left 2
3533
+ on_clicked{
3534
+ for n in 0..@data['내용설정']['내용'].length-1
3535
+ @data['내용설정']['내용'][n][0] = false
3536
+ @data['내용설정']['내용'] << []
3537
+ @data['내용설정']['내용'].pop
3538
+ end
3440
3539
  }
3441
- horizontal_box{
3442
- stretchy false
3443
- grid{
3444
- button('전체선택'){
3445
- top 1
3446
- left 1
3447
- on_clicked{
3448
- for n in 0..@data['내용설정']['내용'].length-1
3449
- @data['내용설정']['내용'][n][0] = true
3450
- @data['내용설정']['내용'] << []
3451
- @data['내용설정']['내용'].pop
3452
- end
3453
- }
3454
- }
3455
- button('선택해제'){
3456
- top 1
3457
- left 2
3458
- on_clicked{
3459
- for n in 0..@data['내용설정']['내용'].length-1
3460
- @data['내용설정']['내용'][n][0] = false
3461
- @data['내용설정']['내용'] << []
3462
- @data['내용설정']['내용'].pop
3463
- end
3464
- }
3465
- }
3466
- button('삭제하기'){
3467
- top 1
3468
- left 3
3469
- on_clicked{
3470
- m = Array.new
3471
- for n in 0..@data['내용설정']['내용'].length-1
3472
- if @data['내용설정']['내용'][n][0] == true
3473
- m << n
3474
- end
3475
- end
3476
-
3477
- m.reverse.each do |i|
3478
- @data['내용설정']['내용'].delete_at(i)
3479
- end
3480
- @data['내용설정']['내용'].delete(nil)
3481
- }
3482
- }
3540
+ }
3541
+ button('삭제하기'){
3542
+ top 1
3543
+ left 3
3544
+ on_clicked{
3545
+ m = Array.new
3546
+ for n in 0..@data['내용설정']['내용'].length-1
3547
+ if @data['내용설정']['내용'][n][0] == true
3548
+ m << n
3549
+ end
3550
+ end
3551
+
3552
+ m.reverse.each do |i|
3553
+ @data['내용설정']['내용'].delete_at(i)
3554
+ end
3555
+ @data['내용설정']['내용'].delete(nil)
3483
3556
  }
3484
- @data['내용설정']['순서사용'] = checkbox('순서사용'){
3485
- stretchy false
3486
- on_toggled{ |c|
3487
- if c.checked?
3488
- @data['내용설정']['랜덤사용'].checked = false
3489
- end
3490
- }
3491
- }
3492
- @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
3493
- stretchy false
3494
- on_toggled{ |c|
3495
- if c.checked?
3496
- @data['내용설정']['순서사용'].checked = false
3497
- end
3498
- }
3499
- }
3557
+ }
3558
+ }
3559
+ @data['내용설정']['순서사용'] = checkbox('순서사용'){
3560
+ stretchy false
3561
+ on_toggled{ |c|
3562
+ if c.checked?
3563
+ @data['내용설정']['랜덤사용'].checked = false
3564
+ end
3500
3565
  }
3501
- vertical_separator{
3502
- stretchy false
3566
+ }
3567
+ @data['내용설정']['랜덤사용'] = checkbox('랜덤사용'){
3568
+ stretchy false
3569
+ on_toggled{ |c|
3570
+ if c.checked?
3571
+ @data['내용설정']['순서사용'].checked = false
3572
+ end
3503
3573
  }
3504
- horizontal_box{
3505
- stretchy false
3506
- grid{
3507
- @data['포스트설정']['gpt내용'] = checkbox('내용파일을 이용해 GPT로 글 변형'){
3508
-
3509
-
3510
- }}}
3511
- horizontal_box{
3512
- stretchy false
3513
- grid{
3514
- label('※ GPT 기능 사용시 포스트설정1에서 GPT사용에 체크 필수'){
3515
- } } }
3516
- table{
3517
- checkbox_column('선택'){
3518
- editable true
3519
- }
3520
- text_column('내용파일'){
3574
+ }
3575
+ }
3576
+ vertical_separator{
3577
+ stretchy false
3578
+ }
3579
+ horizontal_box{
3580
+ stretchy false
3581
+ grid{
3582
+ @data['포스트설정']['gpt내용'] = checkbox('내용파일을 이용해 GPT로 글 변형'){
3583
+
3584
+
3585
+ }}}
3586
+ horizontal_box{
3587
+ stretchy false
3588
+ @data['포스트설정']['gpt내용_프롬프트'] = entry(){
3589
+ text '프롬프트:동의어,유사어를 이용해 변경해줘'
3590
+ }}
3591
+ horizontal_box{
3592
+ stretchy false
3593
+ grid{
3594
+ label('※ GPT 기능 사용시 포스트설정1에서 GPT사용에 체크 필수'){
3595
+ } } }
3596
+
3597
+ table{
3598
+ checkbox_column('선택'){
3599
+ editable true
3600
+ }
3601
+ text_column('내용파일'){
3521
3602
 
3522
- }
3603
+ }
3523
3604
 
3524
- cell_rows @data['내용설정']['내용']
3525
- }
3605
+ cell_rows @data['내용설정']['내용']
3606
+ }
3526
3607
 
3527
- horizontal_box{
3528
- stretchy false
3529
- @data['이미지설정']['폴더경로2'] = entry{
3530
- stretchy false
3531
- text "내용폴더경로 ex)C:\\내용\\폴더1"
3532
- }
3533
- button('폴더째로불러오기'){
3534
- stretchy false
3535
- on_clicked{
3536
- path = @data['이미지설정']['폴더경로2'].text.to_s.force_encoding('utf-8').force_encoding('utf-8')
3537
- Dir.entries(@data['이미지설정']['폴더경로2'].text.to_s.force_encoding('utf-8')).each do |file|
3538
- if file == '.' or file == '..'
3608
+ horizontal_box{
3609
+ stretchy false
3610
+ @data['이미지설정']['폴더경로2'] = entry{
3611
+ stretchy false
3612
+ text "내용폴더경로 ex)C:\\내용\\폴더1"
3613
+ }
3539
3614
 
3540
- else
3541
- file_data = File.open(path+'/'+file,'r', :encoding => 'utf-8').read()
3615
+ button('폴더째로 불러오기') {
3616
+ on_clicked {
3617
+ path = @data['이미지설정']['폴더경로2'].text.to_s.force_encoding('utf-8')
3618
+
3619
+ # 경로가 유효한지 확인
3620
+ if Dir.exist?(path)
3621
+ Dir.entries(path).each do |file|
3622
+ if file == '.' or file == '..'
3623
+ next
3624
+ else
3625
+ begin
3626
+ # 파일을 열고 내용을 읽어서 추가
3627
+ file_data = File.open(path + '/' + file, 'r', encoding: 'utf-8').read
3542
3628
  @data['내용설정']['내용'] << [false, file, file_data]
3629
+ rescue => e
3630
+ # 파일을 열 수 없는 경우, 오류 메시지 출력
3631
+ puts "파일을 열 수 없습니다: #{file}, 오류: #{e.message}"
3543
3632
  end
3544
3633
  end
3545
- @data['내용설정']['내용'] << []
3546
- @data['내용설정']['내용'].pop
3547
- }
3548
- }
3634
+ end
3635
+
3636
+ # 내용 배열에서 마지막 빈 항목 제거
3637
+ @data['내용설정']['내용'] << []
3638
+ @data['내용설정']['내용'].pop
3639
+ else
3640
+ # 경로가 유효하지 않을 경우, 오류 메시지 출력
3641
+ puts "경로가 존재하지 않습니다: #{path}"
3642
+ end
3549
3643
  }
3550
3644
  }
3551
3645
  }
3552
3646
  }
3647
+ }
3648
+ }
3553
3649
  tab_item('이미지설정'){
3554
3650
  horizontal_box{
3555
3651
  vertical_box{
@@ -4011,36 +4107,53 @@ class Wordpress
4011
4107
  left 1
4012
4108
  text 'URL'
4013
4109
  }
4014
- @data['포스트설정']['내용을자동생성'] = checkbox('키워드기반 생성으로만 등록(GPT사용시 자체 생성)'){
4110
+ @data['포스트설정']['내용을자동생성'] = checkbox('키워드기반 글만 등록(GPT사용시 체크 해제)'){
4015
4111
  top 9
4016
4112
  left 0
4017
- on_toggled {
4018
- if @data['포스트설정']['내용을자동생성'].checked?
4019
- @data['포스트설정']['내용과자동생성'].checked = false
4020
- @data['포스트설정']['내용투명'].checked = false
4021
- @data['포스트설정']['내용투명'].enabled = false # 비활성화
4022
-
4023
- end
4113
+ on_toggled{
4114
+ if @data['포스트설정']['내용을자동생성'].checked?
4115
+ @data['포스트설정']['내용과자동생성'].checked = false
4116
+ @data['포스트설정']['내용투명'].checked = false
4117
+ @data['포스트설정']['내용투명'].enabled = false # 비활성화
4118
+
4119
+ end
4024
4120
  }
4025
4121
  }
4026
-
4027
-
4122
+ label('※GPT사용시 내용설정 탭에서 설정'){
4123
+ top 9
4124
+ left 1
4125
+ }
4126
+
4127
+ label('※GPT 미 사용시 세팅 권장'){
4128
+ top 9
4129
+ left 3
4130
+ }
4131
+
4132
+
4028
4133
  aa1 = 2
4029
- @data['포스트설정']['내용과자동생성'] = checkbox('내용파일+키워드기반 생성 등록(GPT사용시 자체 생성)') {
4134
+ @data['포스트설정']['내용과자동생성'] = checkbox('원고+키워드기반 등록(GPT사용시 체크 해제)') {
4030
4135
  top 10 + aa1
4031
4136
  left 0
4032
4137
  on_toggled {
4033
- if @data['포스트설정']['내용과자동생성'].checked?
4034
- @data['포스트설정']['내용을자동생성'].checked = false
4035
- @data['포스트설정']['내용투명'].enabled = true # '내용투명' 활성화
4036
-
4037
- else
4038
- @data['포스트설정']['내용투명'].checked = false # 체크 해제
4039
- @data['포스트설정']['내용투명'].enabled = false # 비활성화
4040
-
4041
- end
4138
+ if @data['포스트설정']['내용과자동생성'].checked?
4139
+ @data['포스트설정']['내용을자동생성'].checked = false
4140
+ @data['포스트설정']['내용투명'].enabled = true # '내용투명' 활성화
4141
+
4142
+ else
4143
+ @data['포스트설정']['내용투명'].checked = false # 체크 해제
4144
+ @data['포스트설정']['내용투명'].enabled = false # 비활성화
4145
+
4146
+ end
4042
4147
  }
4043
4148
  }
4149
+ label('※GPT사용시 내용설정 탭에서 설정'){
4150
+ top 10 + aa1
4151
+ left 1
4152
+ }
4153
+ label('※GPT 미 사용시 세팅 권장'){
4154
+ top 10 + aa1
4155
+ left 3
4156
+ }
4044
4157
 
4045
4158
  @data['포스트설정']['내용투명'] = checkbox('키워드 기반 자동 생성글 안보이게 처리') {
4046
4159
  top 11 + aa1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tblog_zon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-20 00:00:00.000000000 Z
11
+ date: 2025-02-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: File to Clipboard gem
14
14
  email: mymin26@naver.com