Skip to content

Commit 534c41a

Browse files
committed
Merge branch 'dev'
2 parents bb20eb7 + 639ac45 commit 534c41a

File tree

19 files changed

+462
-138
lines changed

19 files changed

+462
-138
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,6 @@ app.*.map.json
4343

4444
# Exceptions to above rules.
4545
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
46+
47+
# ios build
48+
ios/Flutter/.last_build_id

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ Flutter-PicGo: 一个用于快速上传图片并获取图片URL链接的**手机
3030
# 特色功能
3131

3232
- 长按相册列表项可**同步删除远端的文件**,也可配置仅删除本地列表
33-
- 支持管理(查看或删除)远端图床(内测中)[v1.9+]
34-
- 支持扫描二维码将*PicGo(v2.3.0-beta.2以上版本)*配置文件转换成*Flutter-PicGo*的配置,使用请移步[链接](https://github.com/Molunerfinn/PicGo/releases/tag/v2.3.0-beta.2)
33+
- 支持管理(查看或删除)远端图床(内测中,目前支持管理Github、Gitee、SM.MS、兰空、七牛[v1.9+]
34+
- 支持扫描二维码将[PicGo(v2.3.0-beta.2以上版本支持将配置导出成二维码)](https://github.com/Molunerfinn/PicGo/releases/tag/v2.3.0-beta.2)配置文件转换成**Flutter-PicGo**的配置
3535
- 适配深色模式,可跟随系统或手动设置
3636
- 支持将*Flutter-PicGo*的配置导出至剪切板
3737

3838
> 注:牛图与兰空不支持远端删除,腾讯云COS仅支持v5版配置
3939
4040
# 应用截图
4141

42-
![](https://github.static.si-yee.com/image_picker_82452E23-BE11-4712-BFBA-8E93038DB410-3851-00000340B21CCF62.png)
42+
![上传页面](https://github.static.si-yee.com/image_picker_82452E23-BE11-4712-BFBA-8E93038DB410-3851-00000340B21CCF62.png)
43+
44+
![管理页面Gif](https://github.static.si-yee.com/picgo/repo_use.gif)
4345

4446
# 下载安装
4547

@@ -62,7 +64,8 @@ Flutter-PicGo: 一个用于快速上传图片并获取图片URL链接的**手机
6264
6365
# 相关
6466

65-
- [PicGo](https://github.com/Molunerfinn/PicGo)
67+
- [PicGo](https://github.com/Molunerfinn/PicGo) : PicGo 的桌面版
68+
- [vs-picgo](https://github.com/PicGo/vs-picgo):PicGo 的 VS Code 版。
6669

6770
# 致谢
6871

ios/Podfile

100755100644
Lines changed: 15 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,78 +10,32 @@ project 'Runner', {
1010
'Release' => :release,
1111
}
1212

13-
def parse_KV_file(file, separator='=')
14-
file_abs_path = File.expand_path(file)
15-
if !File.exists? file_abs_path
16-
return [];
13+
def flutter_root
14+
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15+
unless File.exist?(generated_xcode_build_settings_path)
16+
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
1717
end
18-
generated_key_values = {}
19-
skip_line_start_symbols = ["#", "/"]
20-
File.foreach(file_abs_path) do |line|
21-
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22-
plugin = line.split(pattern=separator)
23-
if plugin.length == 2
24-
podname = plugin[0].strip()
25-
path = plugin[1].strip()
26-
podpath = File.expand_path("#{path}", file_abs_path)
27-
generated_key_values[podname] = podpath
28-
else
29-
puts "Invalid plugin specification: #{line}"
30-
end
18+
19+
File.foreach(generated_xcode_build_settings_path) do |line|
20+
matches = line.match(/FLUTTER_ROOT\=(.*)/)
21+
return matches[1].strip if matches
3122
end
32-
generated_key_values
23+
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
3324
end
3425

26+
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27+
28+
flutter_ios_podfile_setup
29+
3530
target 'Runner' do
3631
use_frameworks!
3732
use_modular_headers!
3833

39-
# Flutter Pod
40-
41-
copied_flutter_dir = File.join(__dir__, 'Flutter')
42-
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
43-
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
44-
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
45-
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
46-
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
47-
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
48-
49-
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
50-
unless File.exist?(generated_xcode_build_settings_path)
51-
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
52-
end
53-
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
54-
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
55-
56-
unless File.exist?(copied_framework_path)
57-
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
58-
end
59-
unless File.exist?(copied_podspec_path)
60-
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
61-
end
62-
end
63-
64-
# Keep pod path relative so it can be checked into Podfile.lock.
65-
pod 'Flutter', :path => 'Flutter'
66-
67-
# Plugin Pods
68-
69-
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
70-
# referring to absolute paths on developers' machines.
71-
system('rm -rf .symlinks')
72-
system('mkdir -p .symlinks/plugins')
73-
plugin_pods = parse_KV_file('../.flutter-plugins')
74-
plugin_pods.each do |name, path|
75-
symlink = File.join('.symlinks', 'plugins', name)
76-
File.symlink(path, symlink)
77-
pod name, :path => File.join(symlink, 'ios')
78-
end
34+
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
7935
end
8036

8137
post_install do |installer|
8238
installer.pods_project.targets.each do |target|
83-
target.build_configurations.each do |config|
84-
config.build_settings['ENABLE_BITCODE'] = 'NO'
85-
end
39+
flutter_additional_ios_build_settings(target)
8640
end
8741
end

ios/Podfile.lock

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ PODS:
66
- Flutter (1.0.0)
77
- flutter_local_notifications (0.0.1):
88
- Flutter
9-
- flutter_plugin_android_lifecycle (0.0.1):
10-
- Flutter
119
- FMDB (2.7.5):
1210
- FMDB/standard (= 2.7.5)
1311
- FMDB/standard (2.7.5)
@@ -18,47 +16,28 @@ PODS:
1816
- Flutter
1917
- path_provider (0.0.1):
2018
- Flutter
21-
- path_provider_linux (0.0.1):
22-
- Flutter
23-
- path_provider_macos (0.0.1):
24-
- Flutter
25-
- permission_handler (5.0.1):
19+
- "permission_handler (5.0.1+1)":
2620
- Flutter
2721
- shared_preferences (0.0.1):
2822
- Flutter
29-
- shared_preferences_macos (0.0.1):
30-
- Flutter
31-
- shared_preferences_web (0.0.1):
32-
- Flutter
3323
- sqflite (0.0.1):
3424
- Flutter
3525
- FMDB (~> 2.7.2)
3626
- SwiftProtobuf (1.9.0)
3727
- url_launcher (0.0.1):
3828
- Flutter
39-
- url_launcher_macos (0.0.1):
40-
- Flutter
41-
- url_launcher_web (0.0.1):
42-
- Flutter
4329

4430
DEPENDENCIES:
4531
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
4632
- Flutter (from `Flutter`)
4733
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
48-
- flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`)
4934
- image_picker (from `.symlinks/plugins/image_picker/ios`)
5035
- package_info (from `.symlinks/plugins/package_info/ios`)
5136
- path_provider (from `.symlinks/plugins/path_provider/ios`)
52-
- path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
53-
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
5437
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
5538
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
56-
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
57-
- shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)
5839
- sqflite (from `.symlinks/plugins/sqflite/ios`)
5940
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
60-
- url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`)
61-
- url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
6241

6342
SPEC REPOS:
6443
trunk:
@@ -73,57 +52,36 @@ EXTERNAL SOURCES:
7352
:path: Flutter
7453
flutter_local_notifications:
7554
:path: ".symlinks/plugins/flutter_local_notifications/ios"
76-
flutter_plugin_android_lifecycle:
77-
:path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios"
7855
image_picker:
7956
:path: ".symlinks/plugins/image_picker/ios"
8057
package_info:
8158
:path: ".symlinks/plugins/package_info/ios"
8259
path_provider:
8360
:path: ".symlinks/plugins/path_provider/ios"
84-
path_provider_linux:
85-
:path: ".symlinks/plugins/path_provider_linux/ios"
86-
path_provider_macos:
87-
:path: ".symlinks/plugins/path_provider_macos/ios"
8861
permission_handler:
8962
:path: ".symlinks/plugins/permission_handler/ios"
9063
shared_preferences:
9164
:path: ".symlinks/plugins/shared_preferences/ios"
92-
shared_preferences_macos:
93-
:path: ".symlinks/plugins/shared_preferences_macos/ios"
94-
shared_preferences_web:
95-
:path: ".symlinks/plugins/shared_preferences_web/ios"
9665
sqflite:
9766
:path: ".symlinks/plugins/sqflite/ios"
9867
url_launcher:
9968
:path: ".symlinks/plugins/url_launcher/ios"
100-
url_launcher_macos:
101-
:path: ".symlinks/plugins/url_launcher_macos/ios"
102-
url_launcher_web:
103-
:path: ".symlinks/plugins/url_launcher_web/ios"
10469

10570
SPEC CHECKSUMS:
10671
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
10772
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
10873
flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186
109-
flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35
11074
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
111-
image_picker: 66aa71bc96850a90590a35d4c4a2907b0d823109
75+
image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09
11276
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
11377
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
11478
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
115-
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
116-
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
117-
permission_handler: 7022f8972d2d85ce95c1040db945f28bdbfa45d1
79+
permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6
11880
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
119-
shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087
120-
shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9
12181
sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0
12282
SwiftProtobuf: ecbec1be9036d15655f6b3443a1c4ea693c97932
12383
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
124-
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
125-
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
12684

127-
PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a
85+
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
12886

12987
COCOAPODS: 1.9.1

ios/Runner.xcodeproj/project.pbxproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,6 @@
308308
/* Begin XCBuildConfiguration section */
309309
249021D3217E4FDB00AE95B9 /* Profile */ = {
310310
isa = XCBuildConfiguration;
311-
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
312311
buildSettings = {
313312
ALWAYS_SEARCH_USER_PATHS = NO;
314313
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
@@ -392,7 +391,6 @@
392391
};
393392
97C147031CF9000F007C117D /* Debug */ = {
394393
isa = XCBuildConfiguration;
395-
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
396394
buildSettings = {
397395
ALWAYS_SEARCH_USER_PATHS = NO;
398396
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
@@ -449,7 +447,6 @@
449447
};
450448
97C147041CF9000F007C117D /* Release */ = {
451449
isa = XCBuildConfiguration;
452-
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
453450
buildSettings = {
454451
ALWAYS_SEARCH_USER_PATHS = NO;
455452
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;

lib/api/qiniu_api.dart

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ import 'package:flutter_picgo/utils/net.dart';
55
import 'package:flutter_picgo/utils/strings.dart';
66

77
class QiniuApi {
8+
/// 管理Base_url,accesstoken和uptoken不共用baseurl
9+
static const String BASE_URL = "https://rs.qbox.me";
10+
static const String BASE_URL2 = "https://rsf.qbox.me";
11+
12+
static const String accessKey = 'accessKey';
13+
static const String secretKey = 'secretKey';
14+
815
/// 上传
916
static Future upload(
1017
String area, FormData data, Map<String, dynamic> headers) async {
@@ -14,18 +21,33 @@ class QiniuApi {
1421
}
1522

1623
/// 删除
17-
static Future delete(url, String accessToken) async {
24+
static Future delete(String url, String ak, String sk) async {
1825
Response res = await NetUtils.getInstance().post(url,
19-
data: '',
2026
options: Options(
21-
headers: {
22-
"Authorization": 'Qiniu $accessToken',
27+
extra: {
28+
QiniuApi.accessKey: ak,
29+
QiniuApi.secretKey: sk,
2330
},
2431
contentType: 'application/x-www-form-urlencoded',
2532
));
2633
return res.data;
2734
}
2835

36+
// 资源列举
37+
static Future list(Map<String, dynamic> query, String ak, String sk) async {
38+
Response res =
39+
await NetUtils.getInstance().get('${QiniuApi.BASE_URL2}/list',
40+
queryParameters: query,
41+
options: Options(
42+
extra: {
43+
QiniuApi.accessKey: ak,
44+
QiniuApi.secretKey: sk,
45+
},
46+
contentType: 'application/x-www-form-urlencoded',
47+
));
48+
return res.data;
49+
}
50+
2951
/// 上传凭证算法
3052
/// https://developer.qiniu.com/kodo/manual/1208/upload-token
3153
/// https://pub.flutter-io.cn/packages/crypto
@@ -60,8 +82,8 @@ class QiniuApi {
6082
signStr += '\nContent-Type: $contentType';
6183
}
6284
signStr += '\n\n';
63-
if (contentType != 'application/octet-stream') {
64-
signStr += body ?? '';
85+
if (contentType != 'application/octet-stream' && body != null) {
86+
signStr += body;
6587
}
6688
// 使用SecertKey对上一步生成的原始字符串计算HMAC-SHA1签名:
6789
var hmacsha1 = Hmac(sha1, utf8.encode(secretKey));
@@ -70,6 +92,18 @@ class QiniuApi {
7092
return '$accessKey:$encodedSign';
7193
}
7294

95+
/// 管理凭证历史文档
96+
/// https://developer.qiniu.com/kodo/manual/6671/historical-document-management-certificate
97+
static String generateAuthTokenByQBox(String path, String query, String body,
98+
String accessKey, String secretKey) {
99+
String signStr = '$path?$query\n${body ?? ''}';
100+
// 使用SecertKey对上一步生成的原始字符串计算HMAC-SHA1签名:
101+
var hmacsha1 = Hmac(sha1, utf8.encode(secretKey));
102+
var sign = hmacsha1.convert(utf8.encode(signStr));
103+
var encodedSign = urlSafeBase64Encode(sign.bytes);
104+
return '$accessKey:$encodedSign';
105+
}
106+
73107
/// 生成putPolicy
74108
/// https://developer.qiniu.com/kodo/manual/1206/put-policy
75109
static String generatePutPolicy(String bucket, String key) {
@@ -106,3 +140,37 @@ class QiniuApi {
106140
}
107141
}
108142
}
143+
144+
/// 七牛管理验签拦截器
145+
class QiniuInterceptor extends InterceptorsWrapper {
146+
@override
147+
Future onRequest(RequestOptions options) async {
148+
if (options.path.contains(QiniuApi.BASE_URL)) {
149+
String ak = '${options.extra[QiniuApi.accessKey]}';
150+
String sk = '${options.extra[QiniuApi.secretKey]}';
151+
options.data = options.data ?? '';
152+
var accessToken = QiniuApi.generateAuthToken(
153+
options.method,
154+
options.uri.path,
155+
options.uri.query,
156+
options.uri.host,
157+
options.contentType,
158+
options.data,
159+
ak,
160+
sk);
161+
options.headers.addAll({
162+
'Authorization': 'Qiniu $accessToken',
163+
});
164+
} else if (options.path.contains(QiniuApi.BASE_URL2)) {
165+
String ak = '${options.extra[QiniuApi.accessKey]}';
166+
String sk = '${options.extra[QiniuApi.secretKey]}';
167+
options.data = options.data ?? '';
168+
var accessToken = QiniuApi.generateAuthTokenByQBox(
169+
options.uri.path, options.uri.query, options.data, ak, sk);
170+
options.headers.addAll({
171+
'Authorization': 'QBox $accessToken',
172+
});
173+
}
174+
return options;
175+
}
176+
}

0 commit comments

Comments
 (0)