-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Added actions for Introduction, TTS, and STT.
- Loading branch information
Showing
8 changed files
with
389 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.