Skip to content

Commit

Permalink
feat: Added actions for Introduction, TTS, and STT.
Browse files Browse the repository at this point in the history
  • Loading branch information
mathrunet committed Jul 26, 2023
1 parent a9fa1f1 commit 4c16e62
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 6 deletions.
41 changes: 41 additions & 0 deletions packages/katana_cli/lib/action/app/introduction.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Project imports:
import 'package:katana_cli/katana_cli.dart';

/// Add a module to use the introduction.
///
/// 導入部分を利用するためのモジュールを追加します。
class AppIntroductionCliAction extends CliCommand with CliActionMixin {
/// Add a module to use the introduction.
///
/// 導入部分を利用するためのモジュールを追加します。
const AppIntroductionCliAction();

@override
String get description =>
"Add a module to use the introduction. 導入部分を利用するためのモジュールを追加します。";

@override
bool checkEnabled(ExecContext context) {
final value = context.yaml.getAsMap("app").getAsMap("introduction");
final enabled = value.get("enable", false);
if (!enabled) {
return false;
}
return true;
}

@override
Future<void> exec(ExecContext context) async {
final bin = context.yaml.getAsMap("bin");
final flutter = bin.get("flutter", "flutter");
await command(
"Import packages.",
[
flutter,
"pub",
"add",
"masamune_introduction",
],
);
}
}
191 changes: 191 additions & 0 deletions packages/katana_cli/lib/action/app/speech_to_text.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// Project imports:
import 'dart:io';

import 'package:katana_cli/katana_cli.dart';
import 'package:xml/xml.dart';

/// Add a module for using Speech-to-Text.
///
/// Speech-to-Textを利用するためのモジュールを追加します。
class AppSpeechToTextCliAction extends CliCommand with CliActionMixin {
/// Add a module for using Speech-to-Text.
///
/// Speech-to-Textを利用するためのモジュールを追加します。
const AppSpeechToTextCliAction();

@override
String get description =>
"Add a module for using Speech-to-Text. Speech-to-Textを利用するためのモジュールを追加します。";

@override
bool checkEnabled(ExecContext context) {
final value = context.yaml.getAsMap("app").getAsMap("speech_to_text");
final enabled = value.get("enable", false);
if (!enabled) {
return false;
}
return true;
}

@override
Future<void> exec(ExecContext context) async {
final bin = context.yaml.getAsMap("bin");
final flutter = bin.get("flutter", "flutter");
final stt = context.yaml.getAsMap("app").getAsMap("speech_to_text");
final permission = stt.getAsMap("permission");
if (permission.isEmpty) {
error(
"The item [app]->[speech_to_text]->[permission] is missing. Please include the language code and the message when authorization is granted here.",
);
return;
}
await command(
"Import packages.",
[
flutter,
"pub",
"add",
"masamune_speech_to_text",
],
);
label("Addition of permission messages.");
await XCodePermissionType.microphoneUsage.setMessageToXCode(
permission
.map((key, value) => MapEntry(key, value.toString()))
.where((key, value) => value.isNotEmpty),
);
await XCodePermissionType.speechRecognitionUsage.setMessageToXCode(
permission
.map((key, value) => MapEntry(key, value.toString()))
.where((key, value) => value.isNotEmpty),
);
label("Edit AndroidManifest.xml.");
final file = File("android/app/src/main/AndroidManifest.xml");
if (!file.existsSync()) {
throw Exception(
"AndroidManifest does not exist in `android/app/src/main/AndroidManifest.xml`. Do `katana create` to complete the initial setup of the project.",
);
}
final document = XmlDocument.parse(await file.readAsString());
final manifest = document.findAllElements("manifest");
if (manifest.isEmpty) {
throw Exception(
"The structure of AndroidManifest.xml is broken. Do `katana create` to complete the initial setup of the project.",
);
}
if (!manifest.first.children.any((p0) =>
p0 is XmlElement &&
p0.name.toString() == "uses-permission" &&
p0.attributes.any((p1) =>
p1.name.toString() == "android:name" &&
p1.value == "android.permission.RECORD_AUDIO"))) {
manifest.first.children.add(
XmlElement(
XmlName("uses-permission"),
[
XmlAttribute(
XmlName("android:name"),
"android.permission.RECORD_AUDIO",
),
],
[],
),
);
}
if (!manifest.first.children.any((p0) =>
p0 is XmlElement &&
p0.name.toString() == "uses-permission" &&
p0.attributes.any((p1) =>
p1.name.toString() == "android:name" &&
p1.value == "android.permission.BLUETOOTH"))) {
manifest.first.children.add(
XmlElement(
XmlName("uses-permission"),
[
XmlAttribute(
XmlName("android:name"),
"android.permission.BLUETOOTH",
),
],
[],
),
);
}
if (!manifest.first.children.any((p0) =>
p0 is XmlElement &&
p0.name.toString() == "uses-permission" &&
p0.attributes.any((p1) =>
p1.name.toString() == "android:name" &&
p1.value == "android.permission.BLUETOOTH_ADMIN"))) {
manifest.first.children.add(
XmlElement(
XmlName("uses-permission"),
[
XmlAttribute(
XmlName("android:name"),
"android.permission.BLUETOOTH_ADMIN",
),
],
[],
),
);
}
if (!manifest.first.children.any((p0) =>
p0 is XmlElement &&
p0.name.toString() == "uses-permission" &&
p0.attributes.any((p1) =>
p1.name.toString() == "android:name" &&
p1.value == "android.permission.BLUETOOTH_CONNECT"))) {
manifest.first.children.add(
XmlElement(
XmlName("uses-permission"),
[
XmlAttribute(
XmlName("android:name"),
"android.permission.BLUETOOTH_CONNECT",
),
],
[],
),
);
}
final queries = manifest.first.children.firstWhereOrNull(
(p0) => p0 is XmlElement && p0.name.toString() == "queries") ??
() {
final q = XmlElement(XmlName("queries"), [], []);
manifest.first.children.insertFirst(q);
return q;
}();
if (!queries.children.any((p0) =>
p0 is XmlElement &&
p0.name.toString() == "intent" &&
p0.children.any((p1) =>
p1 is XmlElement &&
p1.name.toString() == "action" &&
p1.attributes.any((p2) =>
p2.name.toString() == "android:name" &&
p2.value == "android.speech.RecognitionService")))) {
queries.children.add(
XmlElement(
XmlName("intent"),
[],
[
XmlElement(
XmlName("action"),
[
XmlAttribute(
XmlName("android:name"),
"android.speech.RecognitionService",
),
],
[],
),
],
),
);
}
await file.writeAsString(
document.toXmlString(pretty: true, indent: " ", newLine: "\n"),
);
}
}
124 changes: 124 additions & 0 deletions packages/katana_cli/lib/action/app/text_to_speech.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Project imports:
import 'dart:io';

import 'package:katana_cli/katana_cli.dart';
import 'package:xml/xml.dart';

/// Add a module to use Text-to-Speech.
///
/// Text-to-Speechを利用するためのモジュールを追加します。
class AppTextToSpeechCliAction extends CliCommand with CliActionMixin {
/// Add a module to use Text-to-Speech.
///
/// Text-to-Speechを利用するためのモジュールを追加します。
const AppTextToSpeechCliAction();

@override
String get description =>
"Add a module to use Text-to-Speech. Text-to-Speechを利用するためのモジュールを追加します。";

@override
bool checkEnabled(ExecContext context) {
final value = context.yaml.getAsMap("app").getAsMap("text_to_speech");
final enabled = value.get("enable", false);
if (!enabled) {
return false;
}
return true;
}

@override
Future<void> exec(ExecContext context) async {
final bin = context.yaml.getAsMap("bin");
final flutter = bin.get("flutter", "flutter");
await command(
"Import packages.",
[
flutter,
"pub",
"add",
"masamune_text_to_speech",
],
);
label("Edit config.properties");
final configPropertiesFile = File("android/config.properties");
if (!configPropertiesFile.existsSync()) {
await configPropertiesFile.writeAsString("");
}
final configProperties = await configPropertiesFile.readAsLines();
if (!configProperties
.any((element) => element.startsWith("flutter.minSdkVersion"))) {
await configPropertiesFile.writeAsString([
...configProperties,
"flutter.minSdkVersion=23",
].join("\n"));
}
label("Edit build.gradle");
final gradle = AppGradle();
await gradle.load();
if (!gradle.loadProperties.any((e) => e.name == "configProperties")) {
gradle.loadProperties.add(
GradleLoadProperties(
path: "config.properties",
name: "configProperties",
file: "configPropertiesFile",
),
);
}
gradle.android?.defaultConfig.minSdkVersion =
"configProperties[\"flutter.minSdkVersion\"]";
await gradle.save();
label("Edit AndroidManifest.xml.");
final file = File("android/app/src/main/AndroidManifest.xml");
if (!file.existsSync()) {
throw Exception(
"AndroidManifest does not exist in `android/app/src/main/AndroidManifest.xml`. Do `katana create` to complete the initial setup of the project.",
);
}
final document = XmlDocument.parse(await file.readAsString());
final manifest = document.findAllElements("manifest");
if (manifest.isEmpty) {
throw Exception(
"The structure of AndroidManifest.xml is broken. Do `katana create` to complete the initial setup of the project.",
);
}
final queries = manifest.first.children.firstWhereOrNull(
(p0) => p0 is XmlElement && p0.name.toString() == "queries") ??
() {
final q = XmlElement(XmlName("queries"), [], []);
manifest.first.children.insertFirst(q);
return q;
}();
if (!queries.children.any((p0) =>
p0 is XmlElement &&
p0.name.toString() == "intent" &&
p0.children.any((p1) =>
p1 is XmlElement &&
p1.name.toString() == "action" &&
p1.attributes.any((p2) =>
p2.name.toString() == "android:name" &&
p2.value == "android.intent.action.TTS_SERVICE")))) {
queries.children.add(
XmlElement(
XmlName("intent"),
[],
[
XmlElement(
XmlName("action"),
[
XmlAttribute(
XmlName("android:name"),
"android.intent.action.TTS_SERVICE",
),
],
[],
),
],
),
);
}
await file.writeAsString(
document.toXmlString(pretty: true, indent: " ", newLine: "\n"),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ class FirebaseAuthenticationCliAction extends CliCommand with CliActionMixin {
.any((element) => element.startsWith("flutter.minSdkVersion"))) {
await configPropertiesFile.writeAsString([
...configProperties,
"flutter.minSdkVersion=21",
"flutter.minSdkVersion=23",
].join("\n"));
}
label("Edit build.gradle");
Expand Down
2 changes: 1 addition & 1 deletion packages/katana_cli/lib/action/firebase/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ class FirebaseInitCliAction extends CliCommand with CliActionMixin {
.any((element) => element.startsWith("flutter.minSdkVersion"))) {
await configPropertiesFile.writeAsString([
...configProperties,
"flutter.minSdkVersion=21",
"flutter.minSdkVersion=23",
].join("\n"));
}
label("Edit build.gradle");
Expand Down

0 comments on commit 4c16e62

Please sign in to comment.