nblog_zon 111.119.999 → 111.120.002

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/nblog_zon.rb +353 -191
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ea92559030bbf7a4e0766496bcc9aeb51f8f214f9152a0f720c5850f05d7916
4
- data.tar.gz: 211fce5304e0fa5536f0aa5d02a5bb93f942ec6dee1cdc4481164367f482acd6
3
+ metadata.gz: 595965e5f3c7b1d69d7c74b60132fdf593929cdae756140076d27e752b293262
4
+ data.tar.gz: 120f11c6c018d9ce3f5c4fe0f6200cc26687343102895b9fea21d9d6b5051c64
5
5
  SHA512:
6
- metadata.gz: 05a8d6cf07bf01ae65db54c2ef436a71955f4d17ca9e1da4e4ae01115563917d7c71f59888ea7697b8d7c065561115a54afa1c6d842e465d0bcb485ec0d81ec7
7
- data.tar.gz: 9c71fc7524a3c137c7dbaf1a6b22f4278c64f61e24e022717b490f436591c8e397aa8ffa10e4f837f0850a1b1309676a88473585304817892b2f4f7397416c98
6
+ metadata.gz: 98e94f6a657edf2483cb147d0685bf1f22e4778e4cd9cd25c78847e71e452dadc41b3ac39d3fffecd34a905808a5bf7bc8a6e74dafd21b2495588d0cf32d20a0
7
+ data.tar.gz: fd9770bbc34d96c45c3cadd0a452ef31317cdad42ba6dc2466ec47783fc79ce1cfcf4de0f6daefb0acd9af9a2020dc1ff14ffcda7caa5e0dfdb3bc5c787ceb40
data/lib/nblog_zon.rb CHANGED
@@ -22,15 +22,15 @@ require 'httpclient'
22
22
  include AutoClickMethods
23
23
  using Rainbow
24
24
  include Glimmer
25
-
26
25
  class Chat
27
- def initialize(api_key, gpt_keyword_prompt)
26
+ def initialize(api_key, gpt_keyword_prompt, model)
28
27
  @api_key = api_key
29
28
  @gpt_keyword_prompt = gpt_keyword_prompt
29
+ @model = model # 모델을 인자로 받도록 수정
30
30
  end
31
31
 
32
32
  def message(keyword)
33
- puts 'Sending request to GPT...(키워드 기반 글 생성 중...)'
33
+ puts 'Sending request to GPT...(키워드 기반 글 생성 중...)'.cyan
34
34
 
35
35
  # "키워드 기반 글 생성 중..." 메시지 출력 스레드
36
36
  thread = Thread.new do
@@ -54,7 +54,7 @@ class Chat
54
54
 
55
55
  # 요청 데이터 설정
56
56
  data = {
57
- 'model' => 'gpt-4',
57
+ 'model' => @model,
58
58
  'messages' => [
59
59
  {
60
60
  "role" => "assistant",
@@ -64,9 +64,10 @@ class Chat
64
64
  'max_tokens' => max_response_tokens # 최대 응답 토큰 설정
65
65
  }
66
66
 
67
-
68
-
69
67
  answer = ''
68
+ retry_count = 0
69
+ max_retries = 5 # 최대 재시도 횟수
70
+
70
71
  begin
71
72
  req = HTTP.headers(headers).post(url, :json => data)
72
73
 
@@ -77,7 +78,6 @@ class Chat
77
78
 
78
79
  # 응답 내용 출력 (디버깅용)
79
80
  response = JSON.parse(req.to_s)
80
-
81
81
 
82
82
  # 응답 데이터에서 안전하게 값 추출
83
83
  if response['choices'] && response['choices'][0] && response['choices'][0]['message']
@@ -88,14 +88,21 @@ class Chat
88
88
  rescue => e
89
89
  # 오류 메시지 출력
90
90
  puts "Error occurred: #{e.message}"
91
- answer = "오류가 발생했습니다."
91
+ if e.message.include?('502') && retry_count < max_retries
92
+ retry_count += 1
93
+ puts "Retrying... Attempt ##{retry_count}"
94
+ sleep(5) # 잠시 대기 후 재시도
95
+ retry
96
+ else
97
+ answer = "오류가 발생했습니다."
98
+ end
92
99
  end
93
100
 
94
101
  # "생성 중..." 메시지 출력 종료
95
102
  thread.kill
96
103
 
97
104
  # 결과 로그 출력
98
- puts "Final API response ==> #{answer}"
105
+ puts "Final API response ==> #{answer}".cyan
99
106
  return answer
100
107
  end
101
108
 
@@ -108,16 +115,16 @@ end
108
115
 
109
116
 
110
117
 
111
-
112
-
113
118
  class Chat_title
114
- def initialize(api_key, gpt_title_prompt)
119
+ def initialize(api_key, gpt_title_prompt, model)
115
120
  @api_key = api_key
116
121
  @gpt_title_prompt = gpt_title_prompt
122
+ @model = model # 모델을 인자로 받도록 수정
117
123
  end
118
124
 
119
125
  def message(title)
120
- puts 'Sending request to GPT...(제목 생성 중...)'
126
+ puts 'Sending request to GPT...(제목 생성 중...)'.cyan
127
+
121
128
  # "키워드 기반 글 생성 중..." 메시지를 별도 스레드로 처리
122
129
  thread = Thread.new do
123
130
  while true
@@ -125,13 +132,15 @@ class Chat_title
125
132
  sleep(3)
126
133
  end
127
134
  end
135
+
128
136
  url = 'https://api.openai.com/v1/chat/completions'
129
137
  headers = {
130
138
  'Content-Type' => 'application/json',
131
139
  'Authorization' => 'Bearer ' + @api_key
132
140
  }
141
+
133
142
  data = {
134
- 'model' => 'gpt-4',
143
+ 'model' => @model,
135
144
  'messages' => [{
136
145
  "role" => "system",
137
146
  "content" => "너는 매우 친절하고 성의 있게 답변하는 AI 어시스턴트야."
@@ -142,11 +151,14 @@ class Chat_title
142
151
  }]
143
152
  }
144
153
 
154
+ answer = ''
155
+ retry_count = 0
156
+ max_retries = 5 # 최대 재시도 횟수
157
+
145
158
  begin
146
159
  req = HTTP.headers(headers).post(url, json: data)
147
160
 
148
161
  response = JSON.parse(req.body.to_s)
149
-
150
162
 
151
163
  if req.status == 429
152
164
  return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
@@ -161,28 +173,37 @@ class Chat_title
161
173
  answer ||= title # 응답이 없을 경우 기본 메시지 설정
162
174
  rescue => e
163
175
  puts "Error: #{e.message}"
164
- answer = "오류가 발생했습니다."
176
+ if e.message.include?('502') && retry_count < max_retries
177
+ retry_count += 1
178
+ puts "Retrying... Attempt ##{retry_count}"
179
+ sleep(5) # 잠시 대기 후 재시도
180
+ retry
181
+ else
182
+ answer = "오류가 발생했습니다."
183
+ end
165
184
  end
166
185
 
167
186
  # "생성 중..." 메시지 출력 종료
168
187
  thread.kill
169
188
 
170
- puts 'API return ==> '
171
- puts answer
189
+ puts 'API return ==> '.cyan
190
+ puts answer.cyan
172
191
  answer
173
192
  end
174
193
  end
175
194
 
176
195
 
177
196
  class Chat_content
178
- def initialize(api_key, gpt_content_prompt)
197
+ def initialize(api_key, gpt_content_prompt, model)
179
198
  @api_key = api_key
180
199
  @gpt_content_prompt = gpt_content_prompt
200
+ @model = model # 모델을 인자로 받도록 수정
181
201
  end
182
202
 
183
203
  def message(content)
184
- puts '주의:GPT 특성상 원고 길이가 공백 포함 4천자를 넘기면 오류가 발생할 수 있습니다.'
185
- puts 'Sending request to GPT...(내용 변형 중...)'
204
+ puts '주의:GPT 특성상 원고 길이가 공백 포함 4천자를 넘기면 오류가 발생할 수 있습니다.'.cyan
205
+ puts 'Sending request to GPT...(내용 변형 중...)'.cyan
206
+
186
207
  # "키워드 기반 글 생성 중..." 메시지를 별도 스레드로 처리
187
208
  thread = Thread.new do
188
209
  while true
@@ -190,14 +211,15 @@ class Chat_content
190
211
  sleep(3)
191
212
  end
192
213
  end
193
-
214
+
194
215
  url = 'https://api.openai.com/v1/chat/completions'
195
216
  headers = {
196
217
  'Content-Type' => 'application/json',
197
218
  'Authorization' => 'Bearer ' + @api_key
198
219
  }
220
+
199
221
  data = {
200
- 'model' => 'gpt-4',
222
+ 'model' => @model,
201
223
  'messages' => [{
202
224
  "role" => "system",
203
225
  "content" => "너는 매우 친절하고 성의 있게 답변하는 AI 어시스턴트야."
@@ -205,16 +227,18 @@ class Chat_content
205
227
  {
206
228
  "role" => "user",
207
229
  "content" => "#{@gpt_content_prompt}\n#{content}"
208
-
209
230
  }]
210
231
  }
211
232
 
233
+ answer = ''
234
+ retry_count = 0
235
+ max_retries = 5 # 최대 재시도 횟수
236
+
212
237
  begin
213
238
  req = HTTP.headers(headers).post(url, json: data)
214
239
 
215
240
  response = JSON.parse(req.body.to_s)
216
-
217
-
241
+
218
242
  if req.status == 429
219
243
  return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
220
244
  end
@@ -224,20 +248,26 @@ class Chat_content
224
248
  answer ||= (content) # 응답이 없을 경우 기본 메시지 설정
225
249
  rescue => e
226
250
  puts "Error: #{e.message}"
227
- answer = "오류가 발생했습니다."
251
+ if e.message.include?('502') && retry_count < max_retries
252
+ retry_count += 1
253
+ puts "Retrying... Attempt ##{retry_count}"
254
+ sleep(5) # 잠시 대기 후 재시도
255
+ retry
256
+ else
257
+ answer = "오류가 발생했습니다."
258
+ end
228
259
  end
229
260
 
230
261
  # "생성 중..." 메시지 출력 종료
231
262
  thread.kill
232
263
 
233
- puts 'API return ==> '
234
- puts answer
264
+ puts 'API return ==> '.cyan
265
+ puts answer.cyan
235
266
  answer
236
267
  end
237
268
  end
238
269
 
239
270
 
240
-
241
271
  #############################################gpt############################################
242
272
 
243
273
  class Naver
@@ -2210,84 +2240,112 @@ class Wordpress
2210
2240
  return @data2
2211
2241
  end
2212
2242
 
2213
- def auto_image(keyword = nil)
2214
- keyword ||= @keyword
2215
- puts "키워드: #{keyword}"
2216
-
2217
- client = HTTPClient.new
2218
- client.default_header = {
2219
- 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2220
- '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2221
- 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2222
- 'Accept-Language' => 'en-US,en;q=0.9',
2223
- 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2224
- 'X-Requested-With' => 'XMLHttpRequest'
2225
- }
2243
+ def crop_image_height_under_width(path, min_crop_ratio = 0.625)
2244
+ img = Magick::Image.read(path).first
2245
+ width = img.columns
2246
+ height = img.rows
2226
2247
 
2227
- retry_count = 0
2228
- max_retries = 10
2229
- results = []
2230
2248
 
2231
- begin
2232
- page = rand(1..15)
2233
- url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2234
- puts "Request URL: #{url}"
2235
- res = client.get(url)
2236
-
2237
- unless res.status == 200
2238
- puts "HTTP Error: #{res.status}"
2239
- raise "HTTP Error"
2240
- end
2241
2249
 
2242
- json = JSON.parse(res.body)
2243
- results = json['results']
2244
- mm = []
2250
+ if height > width
2251
+ min_height = (width * min_crop_ratio).to_i
2252
+ new_height = rand(min_height..width)
2253
+ crop_top = ((height - new_height) / 2.0).round
2245
2254
 
2246
- results.each do |photo|
2247
- full_url = photo.dig('urls', 'full').to_s
2248
- regular_url = photo.dig('urls', 'regular').to_s
2255
+ cropped = img.crop(0, crop_top, width, new_height, true)
2256
+ cropped.write(path)
2249
2257
 
2250
- if full_url.start_with?("https://images.unsplash.com/photo-") &&
2251
- regular_url.include?("1080")
2252
- mm << full_url
2253
- end
2254
- end
2258
+
2259
+ else
2260
+
2261
+ end
2262
+ end
2255
2263
 
2256
- if mm.empty?
2257
- raise "No matching image"
2258
- end
2264
+ def auto_image(keyword = nil)
2265
+ # auto_image 내부에서만 crop 호출
2266
+ keyword ||= @keyword
2267
+ puts "키워드: #{keyword}"
2268
+
2269
+ client = HTTPClient.new
2270
+ client.default_header = {
2271
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2272
+ '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2273
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2274
+ 'Accept-Language' => 'en-US,en;q=0.9',
2275
+ 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2276
+ 'X-Requested-With' => 'XMLHttpRequest'
2277
+ }
2278
+
2279
+ retry_count = 0
2280
+ max_retries = 10
2281
+ results = []
2282
+
2283
+ begin
2284
+ page = rand(1..15)
2285
+ url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2286
+ puts "Request URL: #{url}"
2287
+ res = client.get(url)
2288
+
2289
+ unless res.status == 200
2290
+ puts "HTTP Error: #{res.status}"
2291
+ raise "HTTP Error"
2292
+ end
2259
2293
 
2260
- selected_url = mm.sample
2261
- Down.download(selected_url, destination: "./image/memory.png")
2262
- puts "이미지 다운로드 완료: #{selected_url}"
2294
+ json = JSON.parse(res.body)
2295
+ results = json['results']
2296
+ mm = []
2263
2297
 
2264
- rescue => e
2265
- retry_count += 1
2266
- puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2267
- sleep(3)
2268
- if retry_count < max_retries
2269
- retry
2270
- else
2271
- puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2272
-
2273
- if results && !results.empty?
2274
- random_photo = results.sample
2275
- fallback_url = random_photo.dig('urls', 'full')
2276
- if fallback_url
2277
- Down.download(fallback_url, destination: "./image/memory.png")
2278
- puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2279
- else
2280
- puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2281
- color_image
2282
- end
2298
+ results.each do |photo|
2299
+ full_url = photo.dig('urls', 'full').to_s
2300
+ regular_url = photo.dig('urls', 'regular').to_s
2301
+
2302
+ if full_url.start_with?("https://images.unsplash.com/photo-") &&
2303
+ regular_url.include?("1080")
2304
+ mm << full_url
2305
+ end
2306
+ end
2307
+
2308
+ if mm.empty?
2309
+ raise "No matching image"
2310
+ end
2311
+
2312
+ selected_url = mm.sample
2313
+ destination_path = "./image/memory.png"
2314
+ Down.download(selected_url, destination: destination_path)
2315
+ puts "이미지 다운로드 완료: #{selected_url}"
2316
+
2317
+ # 오직 auto_image에서만 자르기 호출
2318
+ crop_image_height_under_width(destination_path)
2319
+
2320
+ rescue => e
2321
+ retry_count += 1
2322
+ puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2323
+ sleep(3)
2324
+ if retry_count < max_retries
2325
+ retry
2326
+ else
2327
+ puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2328
+
2329
+ if results && !results.empty?
2330
+ random_photo = results.sample
2331
+ fallback_url = random_photo.dig('urls', 'full')
2332
+ if fallback_url
2333
+ Down.download(fallback_url, destination: "./image/memory.png")
2334
+ puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2335
+ crop_image_height_under_width("./image/memory.png")
2283
2336
  else
2284
- puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2285
- color_image
2286
- end
2337
+ puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2338
+ color_image
2287
2339
  end
2340
+ else
2341
+ puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2342
+ color_image
2288
2343
  end
2344
+ end
2345
+ end
2289
2346
  end
2290
2347
 
2348
+
2291
2349
  def color_image
2292
2350
  color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
2293
2351
  image = Magick::Image.new(740, 740) { |k| k.background_color = color.sample }
@@ -2381,56 +2439,103 @@ class Wordpress
2381
2439
 
2382
2440
 
2383
2441
  def image_text(text1, text2)
2442
+ begin
2443
+ color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
2444
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2445
+ font2 = './fonts/' + font_files.sample
2446
+
2447
+ # 랜덤 글자색 선택
2448
+ color2 = color.sample
2449
+
2450
+ # 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
2451
+ def hex_to_rgb(hex)
2452
+ hex = hex.delete('#')
2453
+ [hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
2454
+ end
2455
+
2456
+ # 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
2457
+ def color_distance(c1, c2)
2458
+ Math.sqrt(
2459
+ (c1[0] - c2[0])**2 +
2460
+ (c1[1] - c2[1])**2 +
2461
+ (c1[2] - c2[2])**2
2462
+ )
2463
+ end
2464
+
2465
+ # 대비가 충분히 되는 테두리 색상 선택
2466
+ max_attempts = 10
2467
+ stroke_color = nil
2468
+ base_rgb = hex_to_rgb(color2)
2469
+
2470
+ max_attempts.times do
2471
+ candidate = color.sample
2472
+ candidate_rgb = hex_to_rgb(candidate)
2473
+ dist = color_distance(base_rgb, candidate_rgb)
2474
+
2475
+ # 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
2476
+ if dist > 100
2477
+ stroke_color = candidate
2478
+ break
2479
+ end
2480
+ end
2481
+ stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
2482
+
2483
+ img = Magick::Image.read('./image/memory.png').first
2484
+ draw = Magick::Draw.new
2485
+
2486
+ raw_message = "#{text1}\n#{text2}".strip
2487
+ max_width = img.columns * 0.85
2488
+ max_height = img.rows * 0.6
2489
+
2384
2490
  begin
2385
- color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
2386
- font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2387
- font2 = './fonts/' + font_files.sample
2388
- color2 = color.sample
2389
-
2390
- img = Magick::Image.read('./image/memory.png').first
2391
- draw = Magick::Draw.new
2392
-
2393
- raw_message = "#{text1}\n#{text2}".strip
2394
- max_width = img.columns * 0.85
2395
- max_height = img.rows * 0.6
2396
-
2397
- begin
2398
- size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2399
- rescue
2400
- size = 30
2401
- end
2402
-
2403
- wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2404
-
2405
- if @data['이미지설정']['글자그림자'].checked?
2406
- img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2407
- draw.gravity = Magick::CenterGravity
2408
- draw.pointsize = adjusted_size
2409
- draw.fill = '#000000'
2410
- draw.font = font2
2411
- end
2412
- end
2413
-
2414
- draw2 = Magick::Draw.new
2415
- img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2416
- draw2.gravity = Magick::CenterGravity
2417
- draw2.pointsize = adjusted_size
2418
- draw2.fill = color2
2419
- draw2.font = font2
2420
- if @data['이미지설정']['글자테두리'].checked?
2421
- draw2.stroke_width = 2
2422
- draw2.stroke = '#000000'
2423
- end
2424
- end
2425
-
2426
- img.write('./image/memory.png')
2491
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2427
2492
  rescue
2428
- puts '이미지 폰트 불러오기 오류 재시도...'
2429
- sleep(3)
2430
- retry
2493
+ size = 30
2494
+ end
2495
+
2496
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2497
+
2498
+ if @data['이미지설정']['글자그림자'].checked?
2499
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2500
+ draw.gravity = Magick::CenterGravity
2501
+ draw.pointsize = adjusted_size
2502
+ draw.fill = '#000000'
2503
+ draw.font = font2
2504
+ end
2431
2505
  end
2506
+
2507
+ if @data['이미지설정']['글자테두리'].checked?
2508
+ draw_stroke = Magick::Draw.new
2509
+ img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
2510
+ draw_stroke.gravity = Magick::CenterGravity
2511
+ draw_stroke.pointsize = adjusted_size
2512
+ draw_stroke.fill = 'none'
2513
+ draw_stroke.stroke = stroke_color
2514
+ draw_stroke.stroke_width = rand(5..10)
2515
+ draw_stroke.font = font2
2516
+ end
2517
+ end
2518
+
2519
+ draw2 = Magick::Draw.new
2520
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2521
+ draw2.gravity = Magick::CenterGravity
2522
+ draw2.pointsize = adjusted_size
2523
+ draw2.fill = color2
2524
+ draw2.stroke = 'none'
2525
+ draw2.font = font2
2526
+ end
2527
+
2528
+ img.write('./image/memory.png')
2529
+
2530
+ rescue => e
2531
+ puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
2532
+ sleep(3)
2533
+ retry
2534
+ end
2432
2535
  end
2433
2536
 
2537
+
2538
+
2434
2539
  def border()
2435
2540
  color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
2436
2541
  img = Magick::Image.read('./image/memory.png').first
@@ -2727,6 +2832,19 @@ class Wordpress
2727
2832
  end
2728
2833
  end
2729
2834
 
2835
+ if @data['포스트설정']['gpt35'].checked? || @data['포스트설정']['gpt4turbo'].checked? || @data['포스트설정']['gpt4'].checked?
2836
+ gpt_model = if @data['포스트설정']['gpt35'].checked?
2837
+ 'gpt-3.5-turbo'
2838
+ elsif @data['포스트설정']['gpt4turbo'].checked?
2839
+ 'gpt-4-turbo'
2840
+ elsif @data['포스트설정']['gpt4'].checked?
2841
+ 'gpt-4'
2842
+ end
2843
+ puts "선택 된 GPT model: #{gpt_model}".green
2844
+ else
2845
+
2846
+ end
2847
+
2730
2848
  if @data['포스트설정']['gpt제목'].checked?
2731
2849
  gpt_title_prompt = @data['포스트설정']['gpt제목_프롬프트'].text.to_s.force_encoding('utf-8')
2732
2850
 
@@ -2734,7 +2852,7 @@ class Wordpress
2734
2852
  gpt_title_prompt_sample = gpt_title_prompt.strip.empty? ? "프롬프트: 문장을 비슷한 길이로 ChatGPT의 멘트는 빼고 표현을 더 추가해서 하나만 만들어줘." : gpt_title_prompt
2735
2853
 
2736
2854
  # gpt_title_prompt_sample을 Chat_title 객체에 전달
2737
- chat = Chat_title.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_title_prompt_sample)
2855
+ chat = Chat_title.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_title_prompt_sample, gpt_model)
2738
2856
 
2739
2857
  # 메시지 요청 후 title에 저장
2740
2858
  gpt_text1 = chat.message(title)
@@ -2790,7 +2908,7 @@ class Wordpress
2790
2908
  gpt_content_prompt_sample = gpt_content_prompt.strip.empty? ? "프롬프트:ChatGPT의 멘트는 빼고 위 전체적인 내용의 형식을 똑같이 표현을 더 추가하고 유사어로 변경하여 하나 만들어줘! 전화번호,연락처,가격,홈페이지안내 ,상담안내 관련 문구는 유지해야해" : gpt_content_prompt
2791
2909
 
2792
2910
  # Chat_content 객체 생성 시 api_key와 gpt_content_prompt_sample을 두 개의 인자로 전달
2793
- chat = Chat_content.new(api_key, gpt_content_prompt_sample)
2911
+ chat = Chat_content.new(api_key, gpt_content_prompt_sample, gpt_model)
2794
2912
 
2795
2913
  # 메시지 요청 후 content에 저장
2796
2914
  gpt_text3 = chat.message(content)
@@ -2938,7 +3056,7 @@ class Wordpress
2938
3056
  if @data['포스트설정']['gpt키워드'].checked?
2939
3057
  gpt_keyword_prompt = @data['포스트설정']['gpt키워드_프롬프트'].text.to_s.force_encoding('utf-8')
2940
3058
  gpt_keyword_prompt_sample = gpt_keyword_prompt.strip.empty? ? "프롬프트: 관련된 글을 1500자에서 2500자 사이로 만들어줘" : gpt_keyword_prompt
2941
- chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt)
3059
+ chat = Chat.new(@data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8'), gpt_keyword_prompt, gpt_model)
2942
3060
  gpt_text = chat.message(keyword)
2943
3061
  #content = content.to_s + "\n(자동생성글)\n" + gpt_text.to_s
2944
3062
  content = content.to_s + "(자동생성글)" + gpt_text.to_s
@@ -3871,7 +3989,7 @@ class Wordpress
3871
3989
  @data['포스트설정']['프록시리스트'] = Array.new
3872
3990
  @data['포스트설정']['인용구'] = Array.new
3873
3991
  @user_login_ok = "1"
3874
- window('N_BLOG POSTING', 800, 570) {
3992
+ window('N_BLOG POSTING', 800, 610) {
3875
3993
  margined true
3876
3994
 
3877
3995
  vertical_box {
@@ -4894,7 +5012,11 @@ class Wordpress
4894
5012
  vertical_box{
4895
5013
  horizontal_box{
4896
5014
  stretchy false
4897
- @data['image_type'][0] = checkbox('저장 사진 사용'){
5015
+ grid{
5016
+ stretchy false
5017
+ @data['image_type'][0] = checkbox('저장 사진 사용    '){
5018
+ top 0
5019
+ left 0
4898
5020
  on_toggled{
4899
5021
  if @data['image_type'][0].checked?
4900
5022
  @data['image_type'][1].checked = false
@@ -4902,7 +5024,9 @@ class Wordpress
4902
5024
  end
4903
5025
  }
4904
5026
  }
4905
- @data['image_type'][1] = checkbox('색상 사진 사용'){
5027
+ @data['image_type'][1] = checkbox('색상 사진 사용    '){
5028
+ top 0
5029
+ left 1
4906
5030
  on_toggled{
4907
5031
  if @data['image_type'][1].checked?
4908
5032
  @data['image_type'][0].checked = false
@@ -4911,6 +5035,8 @@ class Wordpress
4911
5035
  }
4912
5036
  }
4913
5037
  @data['image_type'][2] = checkbox('자동 다운로드 사진 사용'){
5038
+ top 0
5039
+ left 2
4914
5040
  on_toggled{
4915
5041
  if @data['image_type'][2].checked?
4916
5042
  @data['image_type'][1].checked = false
@@ -4919,7 +5045,7 @@ class Wordpress
4919
5045
  }
4920
5046
  }
4921
5047
  }
4922
-
5048
+ }
4923
5049
  grid{
4924
5050
  stretchy false
4925
5051
  @data['이미지설정']['글자삽입1'] = checkbox('글자 삽입1'){
@@ -4997,8 +5123,12 @@ class Wordpress
4997
5123
  top 1
4998
5124
  left 6
4999
5125
  }
5000
- @data['이미지설정']['글자순서'] = checkbox('글자 리스트 순서대로 사용'){
5001
- top 2
5126
+ }
5127
+
5128
+ grid{
5129
+ stretchy false
5130
+ @data['이미지설정']['글자순서'] = checkbox('글자 리스트 순서 사용 '){
5131
+ top 1
5002
5132
  left 0
5003
5133
  on_toggled{
5004
5134
  if @data['이미지설정']['글자순서'].checked?
@@ -5007,8 +5137,8 @@ class Wordpress
5007
5137
  }
5008
5138
  }
5009
5139
 
5010
- @data['이미지설정']['글자랜덤'] = checkbox('글자 리스트 랜덤으로 사용'){
5011
- top 2
5140
+ @data['이미지설정']['글자랜덤'] = checkbox('글자 리스트 랜덤 사용'){
5141
+ top 1
5012
5142
  left 1
5013
5143
  on_toggled{
5014
5144
  if @data['이미지설정']['글자랜덤'].checked?
@@ -5016,32 +5146,38 @@ class Wordpress
5016
5146
  end
5017
5147
  }
5018
5148
  }
5149
+ }
5019
5150
 
5020
5151
 
5021
- @data['이미지설정']['필터사용'] = checkbox('필터사용(색상 사진 적용불가)'){
5022
- top 2
5023
- left 2
5152
+ grid{
5153
+ stretchy false
5154
+ @data['이미지설정']['필터사용'] = checkbox('사진 필터 사용 [흑백,흐림,가우시안,,,등 랜덤] (※색상 사진 사용시 적용 불가)'){
5155
+ top 0
5156
+ left 0
5024
5157
  }
5025
- @data['이미지설정']['테두리사용'] = checkbox('테두리 사용'){
5026
- top 3
5158
+ }
5159
+ grid{
5160
+ stretchy false
5161
+ @data['이미지설정']['테두리사용'] = checkbox('사진 테두리 적용하기 '){
5162
+ top 1
5027
5163
  left 0
5028
5164
  }
5029
5165
  @data['이미지설정']['테두리크기1'] = entry{
5030
- top 3
5166
+ top 1
5031
5167
  left 2
5032
5168
  text 'ex) 1'
5033
5169
  }
5034
- label('pt'){
5035
- top 3
5170
+ label('px'){
5171
+ top 1
5036
5172
  left 3
5037
5173
  }
5038
5174
  @data['이미지설정']['테두리크기2'] = entry{
5039
- top 3
5175
+ top 1
5040
5176
  left 4
5041
5177
  text 'ex) 33'
5042
5178
  }
5043
- label('pt'){
5044
- top 3
5179
+ label('px'){
5180
+ top 1
5045
5181
  left 5
5046
5182
  }
5047
5183
 
@@ -5200,7 +5336,7 @@ class Wordpress
5200
5336
  stretchy false
5201
5337
  grid{
5202
5338
  stretchy false
5203
- @data['포스트설정']['제목키워드변경'] = checkbox('제목에 특정 단어를 내용에 사용할 키워드로 변경'){
5339
+ @data['포스트설정']['제목키워드변경'] = checkbox('제목에 특정 단어를 키워드로 변경'){
5204
5340
  top 0
5205
5341
  left 0
5206
5342
 
@@ -5243,13 +5379,10 @@ class Wordpress
5243
5379
  left 3
5244
5380
  text '최대수량'
5245
5381
  }
5246
- label('ㄴ'){
5247
- top 3
5248
- left 2
5249
- }
5250
- @data['포스트설정']['제목앞'] = checkbox('제목에 키워드 삽입 제목 앞'){
5382
+
5383
+ @data['포스트설정']['제목앞'] = checkbox('제목에 키워드 삽입시 제목 앞에 붙이기'){
5251
5384
  top 3
5252
- left 3
5385
+ left 0
5253
5386
  enabled false # 기본적으로 비활성화
5254
5387
  on_toggled{
5255
5388
  if @data['포스트설정']['제목앞'].checked? == true
@@ -5259,13 +5392,10 @@ class Wordpress
5259
5392
  end
5260
5393
  }
5261
5394
  }
5262
- label('ㄴ'){
5263
- top 4
5264
- left 2
5265
- }
5266
- @data['포스트설정']['제목뒤'] = checkbox('제목에 키워드 삽입 제목 뒤'){
5267
- top 4
5268
- left 3
5395
+
5396
+ @data['포스트설정']['제목뒤'] = checkbox('제목에 키워드시 삽입 제목 뒤에 붙이기'){
5397
+ top 3
5398
+ left 1
5269
5399
  enabled false # 기본적으로 비활성화
5270
5400
  on_toggled{
5271
5401
  if @data['포스트설정']['제목뒤'].checked? == true
@@ -5479,34 +5609,65 @@ class Wordpress
5479
5609
  text 'URL'
5480
5610
  }
5481
5611
 
5482
- @data['포스트설정']['ChatGPT사용'] = checkbox('Chat GPT 사용하기'){
5483
- top 15+ aa1
5484
- left 0
5485
- }
5486
-
5487
- @data['포스트설정']['api_key'] = entry(){
5488
- top 15+ aa1
5489
- left 1
5490
- text 'api key 입력 필수!!'
5491
- }
5492
-
5493
5612
  @data['포스트설정']['클립적용'] = checkbox('클립 내용에 넣기'){
5494
- top 16+ aa1
5613
+ top 15+ aa1
5495
5614
  left 0
5496
5615
  }
5497
5616
 
5498
5617
  @data['포스트설정']['클립단어'] = entry(){
5499
- top 16+ aa1
5618
+ top 15+ aa1
5500
5619
  left 1
5501
5620
  text '특정단어'
5502
5621
  }
5503
5622
  @data['포스트설정']['클립넘버'] = entry(){
5504
- top 16+ aa1
5623
+ top 15+ aa1
5505
5624
  left 3
5506
5625
  text '클립넘버 ex)1,2,3'
5507
5626
  }
5508
-
5509
5627
  }
5628
+ grid{
5629
+ stretchy false
5630
+ @data['포스트설정']['ChatGPT사용'] = checkbox('Chat GPT 사용하기             '){
5631
+ top 1
5632
+ left 0
5633
+ }
5634
+
5635
+ @data['포스트설정']['api_key'] = entry(){
5636
+ top 1
5637
+ left 1
5638
+ text 'api key 입력'
5639
+ }
5640
+ @data['포스트설정']['gpt35'] = checkbox('GPT 3.5-turbo'){
5641
+ top 1
5642
+ left 2
5643
+ on_toggled {
5644
+ if @data['포스트설정']['gpt35'].checked?
5645
+ @data['포스트설정']['gpt4'].checked = false
5646
+ @data['포스트설정']['gpt4turbo'].checked = false
5647
+ end
5648
+ }
5649
+ }
5650
+ @data['포스트설정']['gpt4'] = checkbox('GPT 4'){
5651
+ top 1
5652
+ left 3
5653
+ on_toggled {
5654
+ if @data['포스트설정']['gpt4'].checked?
5655
+ @data['포스트설정']['gpt35'].checked = false
5656
+ @data['포스트설정']['gpt4turbo'].checked = false
5657
+ end
5658
+ }
5659
+ }
5660
+ @data['포스트설정']['gpt4turbo'] = checkbox('GPT 4-turbo'){
5661
+ top 1
5662
+ left 4
5663
+ on_toggled {
5664
+ if @data['포스트설정']['gpt4turbo'].checked?
5665
+ @data['포스트설정']['gpt35'].checked = false
5666
+ @data['포스트설정']['gpt4'].checked = false
5667
+ end
5668
+ }
5669
+ }
5670
+ }
5510
5671
  }
5511
5672
 
5512
5673
  vertical_separator{
@@ -6046,6 +6207,7 @@ class Wordpress
6046
6207
  @data['포스트설정']['발행기능'].checked = true
6047
6208
  @data['포스트설정']['인용구랜덤'].checked = true
6048
6209
  @data['이미지설정']['글자순서'].checked = true
6210
+ @data['포스트설정']['gpt35'].checked = true
6049
6211
  }.show
6050
6212
  end
6051
6213
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nblog_zon
3
3
  version: !ruby/object:Gem::Version
4
- version: 111.119.999
4
+ version: 111.120.002
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-19 00:00:00.000000000 Z
10
+ date: 2025-06-26 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: File to Clipboard gem
13
13
  email: rnjstnswp123@naver.com