izuemon commited on
Commit
433638e
·
verified ·
1 Parent(s): f108c05

Update turbowarp-server/qr-converter.py

Browse files
Files changed (1) hide show
  1. turbowarp-server/qr-converter.py +208 -154
turbowarp-server/qr-converter.py CHANGED
@@ -6,7 +6,8 @@ import time
6
  import random
7
  import math
8
 
9
- PROJECT_ID = "1293416663"
 
10
 
11
  # 接続設定
12
  tw = scratchcommunication.TwCloudConnection(
@@ -17,220 +18,273 @@ tw = scratchcommunication.TwCloudConnection(
17
 
18
  # n-chars.txtの読み込み
19
  def load_char_map():
 
20
  char_map = {}
21
- with open("turbowarp-server/n-chars.txt", "r", encoding="utf-8") as f:
22
- lines = f.readlines()
23
- for i, line in enumerate(lines):
24
- char = line.strip()
25
- if char: # 空行をスキップ
26
- char_map[char] = str(i).zfill(2) # 00-99の2桁に
27
- return char_map
28
-
29
- def encode_prompt(prompt, char_map):
 
 
 
 
 
30
  """プロンプトを数字列にエンコード"""
31
  encoded = []
32
  for char in prompt:
33
- if char in char_map:
34
- encoded.append(char_map[char])
35
  else:
36
- # 未知の文字はスペース(または適当な文字)として処理
37
- encoded.append(char_map.get(" ", "00"))
38
  return "".join(encoded)
39
 
40
- def decode_prompt(encoded_str, char_map):
41
  """数字列をプロンプトにデコード"""
42
- # 文字マップの逆引きを作成
43
- reverse_map = {v: k for k, v in char_map.items()}
44
  decoded = []
45
- for i in range(0, len(encoded_str), 2):
46
- code = encoded_str[i:i+2]
47
- if code in reverse_map:
48
- decoded.append(reverse_map[code])
49
  else:
50
  decoded.append("?")
51
  return "".join(decoded)
52
 
53
  def get_var(name):
54
- """クラウド変数の取得(安全版)"""
55
  try:
56
  return tw.get_variable(name=name, name_literal=False)
57
  except Exception:
58
  return None
59
 
60
  def set_var(name, value):
61
- """クラウド変数の設定(安全版)"""
62
  try:
63
  return tw.set_variable(name=name, value=value, name_literal=False)
64
  except Exception:
65
  return None
66
 
67
- def generate_image(prompt):
68
- """画像生成API呼び出し、画像データを取得"""
69
- url = "https://izuemon-pixart-alpha-pixart-sigma-xl-2-1024-ms.hf.space/gen"
70
-
71
- params = {
72
- "prompt": prompt,
73
- "negative_prompt": "nsfw, low quality",
74
- "seed": random.randint(0, 2**32 - 1),
75
- "randomize_seed": "true",
76
- "width": 352,
77
- "height": 352,
78
- "guidance_scale": 0, # CFG=0
79
- "num_inference_steps": 2
80
- }
81
 
 
 
 
 
 
 
 
 
 
 
 
82
  try:
83
- response = requests.get(url, params=params, timeout=30)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  if response.status_code == 200:
85
- return Image.open(BytesIO(response.content))
86
  else:
87
- print(f"画像生成エラー: {response.status_code}")
88
  return None
 
89
  except Exception as e:
90
- print(f"画像生成���外: {e}")
91
  return None
92
 
93
- def resize_image(image, size=(90, 90)):
94
  """画像をリサイズ"""
95
- return image.resize(size, Image.Resampling.LANCZOS)
 
 
 
 
 
 
96
 
97
- def image_to_rgb_string(image):
98
- """画像をRGB文字列に変換(000000-999999形式)"""
99
  pixels = []
100
- width, height = image.size
101
 
102
  for y in range(height):
103
  for x in range(width):
104
- r, g, b = image.getpixel((x, y))
105
- # RGBを6桁の数に変換(例: 255,255,255 -> 255255255
106
- rgb_value = f"{r:03d}{g:03d}{b:03d}"
107
- pixels.append(rgb_value)
108
 
109
  return "".join(pixels)
110
 
111
- def send_packets(data, prefix="10"):
112
  """データをパケットに分割して送信"""
113
- max_chars = 9998 # 10000文字制限ため
 
114
 
115
- # データを分割
116
- packets = []
117
- for i in range(0, len(data), max_chars):
118
- packets.append(data[i:i+max_chars])
119
 
120
- total_packets = len(packets)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
- for packet_index, packet_data in enumerate(packets):
123
- # パケット番号を付加(例: 10_0, 10_1...)
124
- packet_value = f"{prefix}_{packet_index}"
125
-
126
- # データを送信(クラウド変数は文字列として扱う)
127
- set_var(packet_value, packet_data)
128
-
129
- # 次のパケットを送信するまで待機(ack確認)
130
- while True:
131
- ack = get_var("11")
132
- if ack == str(packet_index):
133
- break
134
- time.sleep(0.1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
- # 0.5秒間隔を空ける
137
- time.sleep(0.5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
- # 送信完了を通知
140
- set_var("10_complete", "1")
141
- time.sleep(0.5)
142
-
143
- def process_request():
144
- """メイン処理:リクエストの監視と処理"""
145
- char_map = load_char_map()
146
- last_n1_value = None
147
 
148
- print("サーバー起動完了。リクエストを監視中...")
149
 
150
  while True:
151
  try:
152
- # n1の監視
153
- n1_value = get_var("n1")
154
 
155
- if n1_value is not None and n1_value != last_n1_value:
156
- # 文字列とし扱う
157
- n1_str = str(n1_value)
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
- # 有効な形式かチェック(少なくとも2文字以上)
160
- if len(n1_str) >= 2:
161
- msg_type = n1_str[0] # 0: ID送信, 1: レスポンス返信
162
-
163
- # 受信メッセージ(ID送信)の場合
164
- if msg_type == "0":
165
- print("リクエストを受信しました")
166
-
167
- # ビジー状態に設定
168
- set_var("n0", "1")
169
- time.sleep(0.1)
170
-
171
- try:
172
- # IDを取得(3桁目以降)
173
- encoded_data = n1_str[2:] if len(n1_str) > 2 else ""
174
-
175
- if encoded_data:
176
- # 既読に設定
177
- # 2文字目を1に変更(既読)
178
- new_n1 = "1" + n1_str[1:2] + encoded_data
179
- set_var("n1", new_n1)
180
- time.sleep(0.1)
181
-
182
- # プロンプトをデコード
183
- prompt = decode_prompt(encoded_data, char_map)
184
- print(f"プロンプト: {prompt}")
185
-
186
- # 画像生成
187
- print("画像生成中...")
188
- image = generate_image(prompt)
189
-
190
- if image:
191
- # リサイズ
192
- resized = resize_image(image, (90, 90))
193
-
194
- # RGB文字列に変換
195
- rgb_data = image_to_rgb_string(resized)
196
-
197
- # データの先頭に "10" を付加
198
- full_data = "10" + rgb_data
199
-
200
- # パケット分割送信
201
- print("データ送信中...")
202
- send_packets(full_data)
203
-
204
- print("処理完了")
205
- else:
206
- print("画像生成に失敗しました")
207
- # エラー通知
208
- set_var("10_error", "1")
209
- time.sleep(0.5)
210
- else:
211
- print("データが空です")
212
-
213
- except Exception as e:
214
- print(f"処理中エラー: {e}")
215
- set_var("10_error", "1")
216
- time.sleep(0.5)
217
-
218
- finally:
219
- # ビジー状態を解除
220
- set_var("n0", "0")
221
- time.sleep(0.1)
222
 
223
- last_n1_value = n1_value
 
 
224
 
225
- # 適度な間隔で監視
226
  time.sleep(0.1)
227
 
228
  except KeyboardInterrupt:
229
- print("\nサーバー停止します")
 
230
  break
231
  except Exception as e:
232
- print(f"監視ループエラー: {e}")
233
  time.sleep(1)
234
 
235
  if __name__ == "__main__":
236
- process_request()
 
6
  import random
7
  import math
8
 
9
+ # プロジェクトID
10
+ PROJECT_ID = 1293416663
11
 
12
  # 接続設定
13
  tw = scratchcommunication.TwCloudConnection(
 
18
 
19
  # n-chars.txtの読み込み
20
  def load_char_map():
21
+ """n-chars.txtから文字マッピングを読み込む"""
22
  char_map = {}
23
+ try:
24
+ with open("turbowarp-server/n-chars.txt", "r", encoding="utf-8") as f:
25
+ chars = f.read().strip().split("\n")
26
+ for i, char in enumerate(chars):
27
+ char_map[char] = str(i).zfill(2) # 00, 01, 02...
28
+ char_map[str(i).zfill(2)] = char # 逆引きも保存
29
+ return char_map
30
+ except Exception as e:
31
+ print(f"文字マップ読み込みエラー: {e}")
32
+ return {}
33
+
34
+ CHAR_MAP = load_char_map()
35
+
36
+ def encode_prompt(prompt):
37
  """プロンプトを数字列にエンコード"""
38
  encoded = []
39
  for char in prompt:
40
+ if char in CHAR_MAP:
41
+ encoded.append(CHAR_MAP[char])
42
  else:
43
+ encoded.append("99") # 不明な文字は99
 
44
  return "".join(encoded)
45
 
46
+ def decode_prompt(encoded):
47
  """数字列をプロンプトにデコード"""
 
 
48
  decoded = []
49
+ for i in range(0, len(encoded), 2):
50
+ code = encoded[i:i+2]
51
+ if code in CHAR_MAP:
52
+ decoded.append(CHAR_MAP[code])
53
  else:
54
  decoded.append("?")
55
  return "".join(decoded)
56
 
57
  def get_var(name):
58
+ """クラウド変数の値を取得(安全版)"""
59
  try:
60
  return tw.get_variable(name=name, name_literal=False)
61
  except Exception:
62
  return None
63
 
64
  def set_var(name, value):
65
+ """クラウド変数の値を設定(安全版)"""
66
  try:
67
  return tw.set_variable(name=name, value=value, name_literal=False)
68
  except Exception:
69
  return None
70
 
71
+ def wait_for_var_change(var_name, expected_prefix=None, timeout=30):
72
+ """変数の変更待機"""
73
+ start_time = time.time()
74
+ last_value = get_var(var_name)
 
 
 
 
 
 
 
 
 
 
75
 
76
+ while time.time() - start_time < timeout:
77
+ current_value = get_var(var_name)
78
+ if current_value != last_value:
79
+ if expected_prefix is None or str(current_value).startswith(expected_prefix):
80
+ return current_value
81
+ last_value = current_value
82
+ time.sleep(0.1)
83
+ return None
84
+
85
+ def generate_image(prompt, negative_prompt="nsfw, low quality"):
86
+ """画像生成APIを呼び出し"""
87
  try:
88
+ # ランダムシードを生成
89
+ seed = random.randint(0, 2**32 - 1)
90
+
91
+ params = {
92
+ "prompt": prompt,
93
+ "negative_prompt": negative_prompt,
94
+ "seed": seed,
95
+ "randomize_seed": "false",
96
+ "width": 352,
97
+ "height": 352,
98
+ "guidance_scale": 0.0, # CFG=0
99
+ "num_inference_steps": 2
100
+ }
101
+
102
+ response = requests.get(
103
+ "https://izuemon-pixart-alpha-pixart-sigma-xl-2-1024-ms.hf.space/gen",
104
+ params=params,
105
+ timeout=60
106
+ )
107
+
108
  if response.status_code == 200:
109
+ return response.content
110
  else:
111
+ print(f"画像生成APIエラー: {response.status_code}")
112
  return None
113
+
114
  except Exception as e:
115
+ print(f"画像生成エラー: {e}")
116
  return None
117
 
118
+ def resize_image(image_data, size=(90, 90)):
119
  """画像をリサイズ"""
120
+ try:
121
+ img = Image.open(BytesIO(image_data))
122
+ img = img.resize(size, Image.Resampling.LANCZOS)
123
+ return img
124
+ except Exception as e:
125
+ print(f"リサイズエラー: {e}")
126
+ return None
127
 
128
+ def image_to_rgb_string(img):
129
+ """画像をRGB値の文字列に変換(000000-999999形式)"""
130
  pixels = []
131
+ width, height = img.size
132
 
133
  for y in range(height):
134
  for x in range(width):
135
+ r, g, b = img.getpixel((x, y))[:3]
136
+ # RGBを6桁の数に変換(000000-999999
137
+ rgb_value = r * 10000 + g * 100 + b
138
+ pixels.append(str(rgb_value).zfill(6))
139
 
140
  return "".join(pixels)
141
 
142
+ def send_packets(data, var_name="n1"):
143
  """データをパケットに分割して送信"""
144
+ # パケットサイズ(n1プレフィックス"10"を除く)
145
+ packet_size = 9998 - 2 # "10"分を引く
146
 
147
+ # パケット数
148
+ total_packets = math.ceil(len(data) / packet_size)
 
 
149
 
150
+ for i in range(total_packets):
151
+ start = i * packet_size
152
+ end = min((i + 1) * packet_size, len(data))
153
+ packet_data = data[start:end]
154
+
155
+ # パケット番号を付与(2桁)
156
+ packet_num = str(i + 1).zfill(2)
157
+ packet_value = f"10{packet_num}{packet_data}"
158
+
159
+ # 送信
160
+ set_var(var_name, packet_value)
161
+ print(f"パケット {i+1}/{total_packets} 送信: {len(packet_data)}文字")
162
+
163
+ # 次のパケットの前に既読を待機
164
+ if i < total_packets - 1:
165
+ # "11"に変更されるのを待機
166
+ start_wait = time.time()
167
+ while True:
168
+ current = get_var(var_name)
169
+ if current and str(current).startswith("11"):
170
+ print(f"パケット {i+1} 既読確認")
171
+ break
172
+ if time.time() - start_wait > 30:
173
+ print("既読待機タイムアウト")
174
+ break
175
+ time.sleep(0.1)
176
+
177
+ # 0.5秒間隔
178
+ time.sleep(0.5)
179
 
180
+ return total_packets
181
+
182
+ def process_request(received_value):
183
+ """受信したデータを処理"""
184
+ try:
185
+ # 受信データ: "0[ID][encoded_prompt]"
186
+ # 先頭が'0'か確認
187
+ value_str = str(received_value)
188
+ if not value_str.startswith('0'):
189
+ print(f"無効なデータ形式: {value_str[:10]}...")
190
+ return
191
+
192
+ # ID抽出(2桁)
193
+ if len(value_str) < 3:
194
+ print("IDが不足しています")
195
+ return
196
+
197
+ user_id = value_str[1:3]
198
+ encoded_prompt = value_str[3:]
199
+
200
+ print(f"処理開始 - ID: {user_id}, エンコード長: {len(encoded_prompt)}")
201
+
202
+ # プロンプトをデコード
203
+ prompt = decode_prompt(encoded_prompt)
204
+ print(f"デコードされたプロンプト: {prompt}")
205
+
206
+ # 画像生成
207
+ print("画像生成中...")
208
+ image_data = generate_image(prompt)
209
+ if not image_data:
210
+ print("画像生成失敗")
211
+ return
212
 
213
+ # リサイズ
214
+ print("画像リサイズ中...")
215
+ resized_img = resize_image(image_data)
216
+ if not resized_img:
217
+ print("リサイズ失敗")
218
+ return
219
+
220
+ # RGB文字列に変換
221
+ print("RGB変換中...")
222
+ rgb_string = image_to_rgb_string(resized_img)
223
+ print(f"RGB文字列長: {len(rgb_string)}文字")
224
+
225
+ # パケット送信
226
+ print("パケット送信開始...")
227
+ packet_count = send_packets(rgb_string)
228
+ print(f"送信完了: {packet_count}パケット")
229
+
230
+ return True
231
+
232
+ except Exception as e:
233
+ print(f"処理エラー: {e}")
234
+ import traceback
235
+ traceback.print_exc()
236
+ return False
237
+
238
+ def main():
239
+ """メインループ"""
240
+ print("サーバー起動...")
241
+ print("プロジェクトID:", PROJECT_ID)
242
 
243
+ # 初期化
244
+ set_var("n0", "0")
245
+ set_var("n1", "00")
 
 
 
 
 
246
 
247
+ print("待機中...")
248
 
249
  while True:
250
  try:
251
+ # n1の変更を監視
252
+ n1_value = wait_for_var_change("n1", expected_prefix="0", timeout=5)
253
 
254
+ if n1_value is not None:
255
+ # 使用中フラグを立
256
+ set_var("n0", "1")
257
+ print(f"受信データ検出: {str(n1_value)[:50]}...")
258
+
259
+ # 既読にする(n1を"1x"に変更)
260
+ # 元の値から既読フラグを立てる
261
+ current_n1 = str(n1_value)
262
+ if len(current_n1) >= 2:
263
+ read_value = "1" + current_n1[1:]
264
+ set_var("n1", read_value)
265
+ print(f"既読設定: {read_value}")
266
+
267
+ # リクエスト処理
268
+ success = process_request(n1_value)
269
 
270
+ if success:
271
+ print("処理完了")
272
+ else:
273
+ print("処理失敗")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
 
275
+ # 使用中フラグを解除
276
+ set_var("n0", "0")
277
+ print("待機再開...")
278
 
 
279
  time.sleep(0.1)
280
 
281
  except KeyboardInterrupt:
282
+ print("\nサーバー停止")
283
+ set_var("n0", "0")
284
  break
285
  except Exception as e:
286
+ print(f"メインループエラー: {e}")
287
  time.sleep(1)
288
 
289
  if __name__ == "__main__":
290
+ main()