Skip to content

Commit bfe58ef

Browse files
committed
feature:complete tcyun image upload
1 parent a639cb8 commit bfe58ef

File tree

3 files changed

+150
-26
lines changed

3 files changed

+150
-26
lines changed

lib/api/tcyun_api.dart

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ class TcyunApi {
1111
static const String secretKey = 'secretKey';
1212
static const String secretId = 'secretId';
1313

14-
static Future postObject(String bucket, String area, FormData data) async {
15-
Response res = await NetUtils.getInstance().post('https://$bucket.cos.$area.$BASE_URL', data: data);
14+
static Future postObject(String secretId, String secretKey, String bucket, String area, String ext, FormData formData) async {
15+
Response res = await NetUtils.getInstance().post(
16+
'https://$bucket.cos.$area.$BASE_URL/',
17+
data: formData,
18+
options: Options(
19+
extra: {TcyunApi.secretId: secretId, TcyunApi.secretKey: secretKey},
20+
contentType: 'image/$ext'
21+
)
22+
);
1623
return res.headers;
1724
}
1825

@@ -44,12 +51,17 @@ class TcyunApi {
4451
}
4552

4653
/// post Signature
47-
static String buildSignature(String secretKey, String keyTime, String policy) {
48-
var hmacsha1 = Hmac(sha1, utf8.encode(secretKey));
49-
var signKey = hmacsha1.convert(utf8.encode(keyTime));
54+
static String buildSignature(
55+
String secretKey, String keyTime, String policy) {
56+
/// signkey
57+
var hmacsha1Signkey = Hmac(sha1, utf8.encode(secretKey));
58+
var signKey = hmacsha1Signkey.convert(utf8.encode(keyTime));
59+
// string to sign
5060
var stringToSign = sha1.convert(utf8.encode(policy));
51-
var hmacsha1_2 = Hmac(sha1, signKey.bytes);
52-
return '${hmacsha1_2.convert(stringToSign.bytes)}';
61+
// signature
62+
var hmacsha1Signature = Hmac(sha1, utf8.encode('$signKey'));
63+
var signature = hmacsha1Signature.convert(utf8.encode('$stringToSign'));
64+
return '$signature';
5365
}
5466

5567
/// 生成 KeyTime
Lines changed: 114 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,126 @@
1+
import 'dart:convert';
2+
3+
import 'package:dio/dio.dart';
4+
import 'package:flutter_picgo/api/tcyun_api.dart';
5+
import 'package:flutter_picgo/model/tcyun_config.dart';
16
import 'package:flutter_picgo/model/uploaded.dart';
7+
import 'package:flutter_picgo/resources/pb_type_keys.dart';
8+
import 'package:flutter_picgo/utils/image_upload.dart';
29
import 'dart:io';
310

11+
import 'package:path/path.dart' as path;
412
import 'package:flutter_picgo/utils/strategy/image_upload_strategy.dart';
13+
import 'package:flutter_picgo/utils/strings.dart';
514

615
class TcyunImageUpload implements ImageUploadStrategy {
716
@override
8-
Future<Uploaded> delete(Uploaded uploaded) {
9-
throw UnimplementedError();
17+
Future<Uploaded> delete(Uploaded uploaded) async {
18+
TcyunUploaddedInfo info;
19+
try {
20+
info = TcyunUploaddedInfo.fromJson(json.decode(uploaded.info));
21+
} catch (e) {}
22+
if (info != null) {
23+
await TcyunApi.deleteobject(
24+
info.secretId, info.secretKey, info.bucket, info.area, info.key);
25+
}
26+
return uploaded;
27+
}
28+
29+
@override
30+
Future<Uploaded> upload(File file, String renameImage) async {
31+
String configStr = await ImageUploadUtils.getPBConfig(PBTypeKeys.tcyun);
32+
if (isBlank(configStr)) {
33+
throw TcyunError(error: '读取配置文件错误!请重试');
34+
}
35+
TcyunConfig config = TcyunConfig.fromJson(json.decode(configStr));
36+
String objectPath = isBlank(config.path)
37+
? renameImage
38+
: path.joinAll([config.path, renameImage]);
39+
40+
/// post
41+
String keyTime = TcyunApi.buildKeyTime();
42+
String policy = TcyunApi.buildPolicy(
43+
config.bucket, objectPath, config.secretId, keyTime);
44+
FormData formData = FormData.fromMap({
45+
"key": objectPath,
46+
"file": await MultipartFile.fromFile(file.path, filename: renameImage),
47+
"policy": base64.encode(utf8.encode(policy)),
48+
"q-sign-algorithm": "sha1",
49+
"q-ak": config.secretId,
50+
"q-key-time": keyTime,
51+
"q-sign-time": keyTime,
52+
"q-signature": TcyunApi.buildSignature(config.secretKey, keyTime, policy)
53+
});
54+
print(TcyunApi.buildSignature(config.secretKey, keyTime, policy));
55+
await TcyunApi.postObject(
56+
config.secretId,
57+
config.secretKey,
58+
config.bucket,
59+
config.area,
60+
path.extension(renameImage).replaceFirst('.', ''),
61+
formData);
62+
String imgPath = path.joinAll([
63+
isBlank(config.customUrl)
64+
? 'https://${config.bucket}.cos.${config.area}.myqcloud.com'
65+
: config.customUrl,
66+
objectPath
67+
]);
68+
var uploadedItem = Uploaded(-1, '$imgPath', PBTypeKeys.tcyun,
69+
info: json.encode(TcyunUploaddedInfo(
70+
secretId: config.secretId,
71+
secretKey: config.secretKey,
72+
area: config.area,
73+
key: objectPath,
74+
bucket: config.bucket)));
75+
await ImageUploadUtils.saveUploadedItem(uploadedItem);
76+
return uploadedItem;
1077
}
78+
}
79+
80+
class TcyunError implements Exception {
81+
TcyunError({
82+
this.error,
83+
});
84+
85+
dynamic error;
86+
87+
String get message => (error?.toString() ?? '');
1188

1289
@override
13-
Future<Uploaded> upload(File file, String renameImage) {
14-
throw UnimplementedError();
90+
String toString() {
91+
var msg = 'TcyunError $message';
92+
if (error is Error) {
93+
msg += '\n${error.stackTrace}';
94+
}
95+
return msg;
96+
}
97+
}
98+
99+
class TcyunUploaddedInfo {
100+
String area;
101+
String bucket;
102+
String secretId;
103+
String secretKey;
104+
String key;
105+
106+
TcyunUploaddedInfo(
107+
{this.area, this.bucket, this.secretId, this.secretKey, this.key});
108+
109+
TcyunUploaddedInfo.fromJson(Map<String, dynamic> json) {
110+
area = json['area'];
111+
bucket = json['bucket'];
112+
secretId = json['secretId'];
113+
secretKey = json['secretKey'];
114+
key = json['key'];
115+
}
116+
117+
Map<String, dynamic> toJson() {
118+
final Map<String, dynamic> data = new Map<String, dynamic>();
119+
data['area'] = this.area;
120+
data['bucket'] = this.bucket;
121+
data['secretId'] = this.secretId;
122+
data['secretKey'] = this.secretKey;
123+
data['key'] = this.key;
124+
return data;
15125
}
16126
}

test/api/tcyun_api_test.dart

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,23 @@ main() {
3636
String keyTime = TcyunApi.buildKeyTime();
3737
String policy = TcyunApi.buildPolicy('ap-nanjing', 'logo.png',
3838
'AKIDvb0B9rqfeOr44kt2ar46rO2cwzl6JwUk', keyTime);
39-
TcyunApi.postObject(
40-
'test-1253954259',
41-
'ap-nanjing',
42-
FormData.fromMap({
43-
"key": "logo.png",
44-
"file": await MultipartFile.fromFile(
45-
'C:\\Users\\Administrator\\Desktop\\flutter-picgo\\flutter-picgo\\assets\\images\\logo.png',
46-
filename: 'logo.png'),
47-
"policy": base64.encode(utf8.encode(policy)),
48-
"q-sign-algorithm": "sha1",
49-
"q-ak": "AKIDvb0B9rqfeOr44kt2ar46rO2cwzl6JwUk",
50-
"q-key-time": keyTime,
51-
"q-signature": TcyunApi.buildSignature(
52-
'KOEoR1LL5apX1lFRN4VgZB0nJgmdEbie', keyTime, policy)
53-
}));
39+
print(policy);
40+
// TcyunApi.postObject(
41+
// 'test-1253954259',
42+
// 'ap-nanjing',
43+
// 'png',
44+
// FormData.fromMap({
45+
// "key": "logo.png",
46+
// "file": await MultipartFile.fromFile(
47+
// 'C:\\Users\\Administrator\\Desktop\\flutter-picgo\\flutter-picgo\\assets\\images\\logo.png',
48+
// filename: 'logo.png'),
49+
// "policy": base64.encode(utf8.encode(policy)),
50+
// "q-sign-algorithm": "sha1",
51+
// "q-ak": "AKIDvb0B9rqfeOr44kt2ar46rO2cwzl6JwUk",
52+
// "q-key-time": keyTime,
53+
// "q-signature": TcyunApi.buildSignature(
54+
// 'KOEoR1LL5apX1lFRN4VgZB0nJgmdEbie', keyTime, policy)
55+
// }));
5456
} catch (e) {
5557
print(e);
5658
}

0 commit comments

Comments
 (0)