zhaoyadi 1 жил өмнө
commit
276c076528

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+.dart_tool/

+ 30 - 0
analysis_options.yaml

@@ -0,0 +1,30 @@
+# This file configures the static analysis results for your project (errors,
+# warnings, and lints).
+#
+# This enables the 'recommended' set of lints from `package:lints`.
+# This set helps identify many issues that may lead to problems when running
+# or consuming Dart code, and enforces writing Dart using a single, idiomatic
+# style and format.
+#
+# If you want a smaller set of lints you can change this to specify
+# 'package:lints/core.yaml'. These are just the most critical lints
+# (the recommended set includes the core lints).
+# The core lints are also what is used by pub.dev for scoring packages.
+
+include: package:lints/recommended.yaml
+
+# Uncomment the following section to specify additional rules.
+
+# linter:
+#   rules:
+#     - camel_case_types
+
+# analyzer:
+#   exclude:
+#     - path/to/excluded/files/**
+
+# For more information about the core and recommended set of lints, see
+# https://dart.dev/go/core-lints
+
+# For additional information about configuring this file, see
+# https://dart.dev/guides/language/analysis-options

+ 47 - 0
bin/upload.dart

@@ -0,0 +1,47 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+
+import 'package:process_run/shell.dart';
+import 'package:upload/upload.dart' as upload;
+
+/// fvm dart compile exe -o upload.exe bin\upload.dart
+Future<void> main(List<String> arguments) async {
+  if (!arguments.contains("--nobuild")) {
+    final stdinController = StreamController<List<int>>.broadcast();
+    final stdoutController = StreamController<List<int>>.broadcast();
+    final stderrController = StreamController<List<int>>.broadcast();
+
+    stdoutController.stream.listen((event) {
+      // print(utf8.decode(event));
+    });
+
+    int errCount = 0;
+    stderrController.stream.listen((event) {
+      // print(utf8.decode(event));
+      errCount++;
+      stdout.write("\r打包过程出现警告:$errCount");
+    });
+
+    var shell = Shell(
+      stdout: stdoutController.sink,
+      stdin: stdinController.stream,
+      stderr: stderrController.sink,
+    );
+
+    try {
+      stdout.write("\n准备并开始打包APK文件\n");
+      await shell.run("flutter clean");
+      await shell.run("flutter pub get");
+      await shell.run("flutter build apk");
+      stdout.write("\nAPK文件打包成功🎈🎈\n");
+      stdout.write("\n准备上传APK至蒲公英");
+    } catch (e) {
+      stdout.write("\n打包过程中发生了错误");
+      exit(1);
+    }
+  }
+
+  upload.getToken();
+}

+ 31 - 0
lib/file_formdata.dart

@@ -0,0 +1,31 @@
+import 'dart:async';
+
+import 'package:dio/dio.dart';
+
+typedef OnProgress = void Function(int currentBytes, int totalBytes);
+
+class FileFormData extends FormData {
+  FileFormData(this.onProgress) : super();
+
+  final OnProgress onProgress;
+
+  @override
+  Stream<List<int>> finalize() {
+    final byteStream = super.finalize();
+
+    final total = length;
+    int bytes = 0;
+
+    final t = StreamTransformer.fromHandlers(
+      handleData: (List<int> data, EventSink<List<int>> sink) {
+        bytes += data.length;
+        onProgress(bytes, total);
+        if (total >= bytes) {
+          sink.add(data);
+        }
+      },
+    );
+    final stream = byteStream.transform(t);
+    return stream;
+  }
+}

+ 35 - 0
lib/file_request.dart

@@ -0,0 +1,35 @@
+import 'dart:async';
+
+import 'package:http/http.dart' as http;
+
+typedef OnProgress = void Function(int bytes, int totalBytes);
+
+class FileRequest extends http.MultipartRequest {
+  FileRequest(
+    super.method,
+    super.url,
+    this.onProgress,
+  );
+
+  final OnProgress onProgress;
+
+  @override
+  http.ByteStream finalize() {
+    final byteStream = super.finalize();
+
+    final total = contentLength;
+    int bytes = 0;
+
+    final t = StreamTransformer.fromHandlers(
+      handleData: (List<int> data, EventSink<List<int>> sink) {
+        bytes += data.length;
+        onProgress(bytes, total);
+        if (total >= bytes) {
+          sink.add(data);
+        }
+      },
+    );
+    final stream = byteStream.transform(t);
+    return http.ByteStream(stream);
+  }
+}

+ 114 - 0
lib/upload.dart

@@ -0,0 +1,114 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'package:dio/dio.dart';
+import 'package:path/path.dart' as path;
+import 'package:http/http.dart' as http;
+import 'package:upload/file_formdata.dart';
+
+import 'file_request.dart';
+
+const String _API_KEY_DEV = "";
+const String _FILE_PATH = "\\build\\app\\outputs\\apk\\release\\app-release.apk";
+
+void _log(String message) {
+  stdout.write(message);
+}
+
+Future<void> getToken() async {
+  _log("\n获取上传token和endpoint中");
+  final url = Uri.https("www.pgyer.com", "apiv2/app/getCOSToken");
+  var result = await http.post(url, body: {
+    "_api_key": "804cf948c5fcf01bc70bb8d086721a58",
+    "buildType": "android",
+  });
+
+  if (result.statusCode == 200) {
+    _log("\n获取token和endpoint成功\n");
+    var json = jsonDecode(result.body)["data"];
+    final String uploadUrl = json["endpoint"];
+    final String key = json["key"];
+
+    final Map<String, dynamic> params = json["params"];
+    final String signature = params["signature"];
+    final String xCosSecurityToken = params["x-cos-security-token"];
+
+    await upload2(uploadUrl, key, signature, xCosSecurityToken);
+  } else {
+    _log("\n获取token和endpoint失败\n");
+  }
+}
+
+Future<void> upload(
+  String url,
+  String key,
+  String sign,
+  String token,
+) async {
+  final endPoint = Uri.tryParse(url);
+  final file = File(Directory.current.path + _FILE_PATH);
+
+  if (endPoint != null) {
+    var formData = FileRequest("POST", endPoint, (current, total) {
+      _log("\r已上传 ${(current / total * 100).toStringAsFixed(2)}%");
+    });
+
+    formData.fields["key"] = key;
+    formData.fields["signature"] = sign;
+    formData.fields["x-cos-security-token"] = token;
+
+    formData.files.add(await http.MultipartFile.fromPath(
+      path.basename(file.path),
+      file.path,
+    ));
+
+    _log("\n开始上传APK到蒲公英:${DateTime.now().toString()}\n\n");
+    var response = await formData.send();
+
+    if (response.statusCode == 204) {
+      _log("\n上传APK到蒲公英完成:${DateTime.now().toString()}");
+    } else {
+      _log("\n上传APK到蒲公英失败:${DateTime.now().toString()}");
+    }
+  }
+}
+
+Future<void> upload2(
+  String url,
+  String key,
+  String sign,
+  String token,
+) async {
+  final file = File(Directory.current.path + _FILE_PATH);
+
+  var dio = Dio();
+
+  dio.options.connectTimeout = 5000;
+  dio.options.receiveTimeout = 5000;
+
+  var form = FileFormData((current, total) {
+    stdout.write("\r已上传 ${(current / total * 100).toStringAsFixed(2)}%");
+  });
+
+  form.fields.add(MapEntry("key", key));
+  form.fields.add(MapEntry("signature", sign));
+  form.fields.add(MapEntry("x-cos-security-token", token));
+
+  form.files.add(MapEntry("file", await MultipartFile.fromFile(file.path, filename: path.basename(file.path))));
+
+  _log("\n准备开始上传到蒲公英:${DateTime.now().toString()}\n");
+  var response = await dio.post(
+    url,
+    data: form,
+    options: Options(
+      method: "POST",
+      responseType: ResponseType.json,
+    ),
+  );
+
+  if (response.statusCode == 204) {
+    _log("\n上传APK到蒲公英完成:${DateTime.now().toString()}");
+  } else {
+    _log("\n上传APK到蒲公英失败:${DateTime.now().toString()}");
+  }
+}

+ 413 - 0
pubspec.lock

@@ -0,0 +1,413 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+  _fe_analyzer_shared:
+    dependency: transitive
+    description:
+      name: _fe_analyzer_shared
+      sha256: "0c80aeab9bc807ab10022cd3b2f4cf2ecdf231949dc1ddd9442406a003f19201"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "52.0.0"
+  analyzer:
+    dependency: transitive
+    description:
+      name: analyzer
+      sha256: cd8ee83568a77f3ae6b913a36093a1c9b1264e7cb7f834d9ddd2311dade9c1f4
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "5.4.0"
+  args:
+    dependency: transitive
+    description:
+      name: args
+      sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.4.0"
+  async:
+    dependency: transitive
+    description:
+      name: async
+      sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.10.0"
+  boolean_selector:
+    dependency: transitive
+    description:
+      name: boolean_selector
+      sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.1"
+  charcode:
+    dependency: transitive
+    description:
+      name: charcode
+      sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.3.1"
+  collection:
+    dependency: transitive
+    description:
+      name: collection
+      sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.17.1"
+  convert:
+    dependency: transitive
+    description:
+      name: convert
+      sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.1.1"
+  coverage:
+    dependency: transitive
+    description:
+      name: coverage
+      sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.6.3"
+  crypto:
+    dependency: transitive
+    description:
+      name: crypto
+      sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.0.2"
+  dio:
+    dependency: "direct main"
+    description:
+      name: dio
+      sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "4.0.6"
+  file:
+    dependency: transitive
+    description:
+      name: file
+      sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "6.1.4"
+  frontend_server_client:
+    dependency: transitive
+    description:
+      name: frontend_server_client
+      sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.2.0"
+  glob:
+    dependency: transitive
+    description:
+      name: glob
+      sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.1"
+  http:
+    dependency: "direct main"
+    description:
+      name: http
+      sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.13.5"
+  http_multi_server:
+    dependency: transitive
+    description:
+      name: http_multi_server
+      sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.2.1"
+  http_parser:
+    dependency: transitive
+    description:
+      name: http_parser
+      sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "4.0.2"
+  io:
+    dependency: transitive
+    description:
+      name: io
+      sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.4"
+  js:
+    dependency: transitive
+    description:
+      name: js
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.6.7"
+  lints:
+    dependency: "direct dev"
+    description:
+      name: lints
+      sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.0.1"
+  logging:
+    dependency: transitive
+    description:
+      name: logging
+      sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.1.1"
+  matcher:
+    dependency: transitive
+    description:
+      name: matcher
+      sha256: c94db23593b89766cda57aab9ac311e3616cf87c6fa4e9749df032f66f30dcb8
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.12.14"
+  meta:
+    dependency: transitive
+    description:
+      name: meta
+      sha256: "12307e7f0605ce3da64cf0db90e5fcab0869f3ca03f76be6bb2991ce0a55e82b"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.9.0"
+  mime:
+    dependency: transitive
+    description:
+      name: mime
+      sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.4"
+  node_preamble:
+    dependency: transitive
+    description:
+      name: node_preamble
+      sha256: "8ebdbaa3b96d5285d068f80772390d27c21e1fa10fb2df6627b1b9415043608d"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.0.1"
+  package_config:
+    dependency: transitive
+    description:
+      name: package_config
+      sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.0"
+  path:
+    dependency: "direct main"
+    description:
+      name: path
+      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.8.3"
+  pool:
+    dependency: transitive
+    description:
+      name: pool
+      sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.5.1"
+  process_run:
+    dependency: "direct main"
+    description:
+      name: process_run
+      sha256: "1142d7f4f0c3f36393a1319406efcf481def2b6d862b2bf600c8ae8fa74d5bd8"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.12.5+2"
+  pub_semver:
+    dependency: transitive
+    description:
+      name: pub_semver
+      sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.3"
+  shelf:
+    dependency: transitive
+    description:
+      name: shelf
+      sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.4.0"
+  shelf_packages_handler:
+    dependency: transitive
+    description:
+      name: shelf_packages_handler
+      sha256: aef74dc9195746a384843102142ab65b6a4735bb3beea791e63527b88cc83306
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.0.1"
+  shelf_static:
+    dependency: transitive
+    description:
+      name: shelf_static
+      sha256: e792b76b96a36d4a41b819da593aff4bdd413576b3ba6150df5d8d9996d2e74c
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.1.1"
+  shelf_web_socket:
+    dependency: transitive
+    description:
+      name: shelf_web_socket
+      sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.3"
+  source_map_stack_trace:
+    dependency: transitive
+    description:
+      name: source_map_stack_trace
+      sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.1"
+  source_maps:
+    dependency: transitive
+    description:
+      name: source_maps
+      sha256: "490098075234dcedb83c5d949b4c93dad5e6b7702748de000be2b57b8e6b2427"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.10.11"
+  source_span:
+    dependency: transitive
+    description:
+      name: source_span
+      sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.9.1"
+  stack_trace:
+    dependency: transitive
+    description:
+      name: stack_trace
+      sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.11.0"
+  stream_channel:
+    dependency: transitive
+    description:
+      name: stream_channel
+      sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.1"
+  string_scanner:
+    dependency: transitive
+    description:
+      name: string_scanner
+      sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.2.0"
+  synchronized:
+    dependency: transitive
+    description:
+      name: synchronized
+      sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.0.1"
+  term_glyph:
+    dependency: transitive
+    description:
+      name: term_glyph
+      sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.2.1"
+  test:
+    dependency: "direct dev"
+    description:
+      name: test
+      sha256: "5301f54eb6fe945daa99bc8df6ece3f88b5ceaa6f996f250efdaaf63e22886be"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.23.1"
+  test_api:
+    dependency: transitive
+    description:
+      name: test_api
+      sha256: "6182294da5abf431177fccc1ee02401f6df30f766bc6130a0852c6b6d7ee6b2d"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.4.18"
+  test_core:
+    dependency: transitive
+    description:
+      name: test_core
+      sha256: d2e9240594b409565524802b84b7b39341da36dd6fd8e1660b53ad928ec3e9af
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.4.24"
+  typed_data:
+    dependency: transitive
+    description:
+      name: typed_data
+      sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.3.1"
+  vm_service:
+    dependency: transitive
+    description:
+      name: vm_service
+      sha256: a4040e9852e56bf8a3c5a2e08a56f6facd76e75500cf2a922ce5d52394c4998a
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "11.0.1"
+  watcher:
+    dependency: transitive
+    description:
+      name: watcher
+      sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.2"
+  web_socket_channel:
+    dependency: transitive
+    description:
+      name: web_socket_channel
+      sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.3.0"
+  webkit_inspection_protocol:
+    dependency: transitive
+    description:
+      name: webkit_inspection_protocol
+      sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.2.0"
+  yaml:
+    dependency: transitive
+    description:
+      name: yaml
+      sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.1.1"
+sdks:
+  dart: ">=2.19.0 <3.0.0"

+ 17 - 0
pubspec.yaml

@@ -0,0 +1,17 @@
+name: upload
+description: A sample command-line application.
+version: 1.0.0
+# homepage: https://www.example.com
+
+environment:
+  sdk: '>=2.18.0 <3.0.0'
+
+dependencies:
+  path: ^1.8.0
+  http: ^0.13.5
+  dio: ^4.0.6
+  process_run: ^0.12.3+2
+
+dev_dependencies:
+  lints: ^2.0.0
+  test: ^1.16.0