import random import json import time import hmac import hashlib import base64 import logging from hashlib import md5 import requests from celery import shared_task logger = logging.getLogger(__name__) from .views.info.baidu_lang_info import ( cuid, mac, p_code, p_lang_type, y_speech_type, pcm_y_lang_type, y_lang_type ) from .views.info.baidu_fanyi_appid import appid, appkey, endpoint def make_md5(s, encoding='utf-8'): return md5(s.encode(encoding)).hexdigest() @shared_task def baidu_translate_task(query, from_lang, to_lang): path = '/api/trans/vip/translate' url = endpoint + path salt = random.randint(32768, 65536) sign = make_md5(appid + query + str(salt) + appkey) headers = {'Content-Type': 'application/x-www-form-urlencoded'} payload = {'appid': appid, 'q': query, 'from': from_lang, 'to': to_lang, 'salt': salt, 'sign': sign} try: r = requests.post(url, params=payload, headers=headers, timeout=15) result = r.json() except requests.exceptions.Timeout: return {'success': False, 'error_code': 'TIMEOUT', 'error_msg': '百度翻译API请求超时,请重试'} except requests.exceptions.RequestException as e: return {'success': False, 'error_code': 'NETWORK_ERROR', 'error_msg': f'网络请求异常: {str(e)}'} except ValueError: return {'success': False, 'error_code': 'PARSE_ERROR', 'error_msg': '百度翻译API响应格式异常'} if 'error_code' in result and result['error_code'] != 0: return {'success': False, 'error_code': result.get('error_code'), 'error_msg': result.get('error_msg', '')} return {'success': True, 'data': result} @shared_task def baidu_recognize_lang_task(query): path = '/api/trans/vip/language' url = endpoint + path salt = random.randint(32768, 65536) sign = make_md5(appid + query + str(salt) + appkey) headers = {'Content-Type': 'application/x-www-form-urlencoded'} payload = {'appid': appid, 'q': query, 'salt': salt, 'sign': sign} try: r = requests.post(url, params=payload, headers=headers, timeout=15) result = r.json() except requests.exceptions.Timeout: return {'success': False, 'error_code': 'TIMEOUT', 'error_msg': '百度翻译API请求超时,请重试'} except requests.exceptions.RequestException as e: return {'success': False, 'error_code': 'NETWORK_ERROR', 'error_msg': f'网络请求异常: {str(e)}'} except ValueError: return {'success': False, 'error_code': 'PARSE_ERROR', 'error_msg': '百度翻译API响应格式异常'} code = result.get('error_code') if code == 0: return {'success': True, 'data': result} else: return {'success': False, 'error_code': code, 'error_msg': result.get('error_msg', '')} @shared_task def baidu_picture_translate_task(file_data_base64, from_lang, to_lang, picture_type): file_data = base64.b64decode(file_data_base64) path = '/api/trans/sdk/picture' url = endpoint + path salt = random.randint(32768, 65536) sign = make_md5(appid + md5(file_data).hexdigest() + str(salt) + cuid + mac + appkey) payload = {'from': from_lang, 'to': to_lang, 'appid': appid, 'salt': salt, 'sign': sign, 'cuid': cuid, 'mac': mac} image = {'image': (f"p_image.{picture_type}", file_data, "multipart/form-data")} try: response = requests.post(url, params=payload, files=image, timeout=20) result = response.json() except requests.exceptions.Timeout: return {'success': False, 'error_code': 'TIMEOUT', 'error_info': '百度图片翻译API请求超时,请重试'} except requests.exceptions.RequestException as e: return {'success': False, 'error_code': 'NETWORK_ERROR', 'error_info': f'网络请求异常: {str(e)}'} except ValueError: return {'success': False, 'error_code': 'PARSE_ERROR', 'error_info': '百度图片翻译API响应格式异常'} if result.get('error_code') == 0: return {'success': True, 'data': result} else: error_info = p_code.get(result.get('error_code'), {}) return {'success': False, 'error_code': result.get('error_code'), 'error_info': error_info} @shared_task def baidu_speech_recognize_task(audio_data_base64, from_lang, to_lang, speech_type): voice = base64.b64decode(audio_data_base64) timestamp = str(int(time.time())) path = "/api/trans/v2/voicetrans" url = endpoint + path msg = appid + timestamp + audio_data_base64 sign = base64.b64encode(hmac.new(appkey.encode("utf-8"), msg.encode("utf-8"), digestmod=hashlib.sha256).digest()) headers = { "Content-Type": "application/json", "X-Appid": appid, "X-Timestamp": timestamp, "X-Sign": sign, "X-EncryptType": "hmac256" } data = { "format": speech_type, "voice": audio_data_base64, "to": to_lang, "from": from_lang, } try: response = requests.post(url, headers=headers, json=data, timeout=20) result = response.json() except requests.exceptions.Timeout: return {'success': False, 'error_code': 'TIMEOUT', 'error_msg': '百度语音翻译API请求超时,请重试'} except requests.exceptions.RequestException as e: return {'success': False, 'error_code': 'NETWORK_ERROR', 'error_msg': f'网络请求异常: {str(e)}'} except ValueError: return {'success': False, 'error_code': 'PARSE_ERROR', 'error_msg': '百度语音翻译API响应格式异常'} return {'success': True, 'data': result} @shared_task def record_translate_usage(translate_type, from_lang, to_lang, text_length, user_id=None, ip_address=None): from .models import TranslateUsage user = None if user_id is not None: from django.contrib.auth import get_user_model User = get_user_model() try: user = User.objects.get(pk=user_id) except User.DoesNotExist: user = None try: TranslateUsage.objects.create( user=user, translate_type=translate_type, from_lang=from_lang, to_lang=to_lang, text_length=text_length, ip_address=ip_address, ) except Exception as e: logger.error(f"记录翻译使用量失败: {e}")