Skip to content

Instantly share code, notes, and snippets.

@demirdev
Created October 17, 2023 15:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demirdev/d62a4b75a217cf463ba8d4190f2294e6 to your computer and use it in GitHub Desktop.
Save demirdev/d62a4b75a217cf463ba8d4190f2294e6 to your computer and use it in GitHub Desktop.
quran_translations.dart
library quran_translations;
import 'dart:convert';
import 'dart:io';
import 'package:quran_translations/data/translations_from_github.dart';
import 'package:quran_translations/db/quran_translations_db.dart';
import 'package:quran_translations/model/translation.dart';
import 'package:quran_translations/model/translator.dart';
import 'data/surah_names.dart';
import 'data/translations_from_tanzil_net.dart';
import 'model/translation_source.dart';
import 'package:http/http.dart' as http;
class QuranTranslations {
static final instance = QuranTranslations._();
QuranTranslations._();
Future<void> init() async {
await QuranTranslationsDB.instance.openDatabase();
}
final _client = HttpClient();
List<TranslationSource> _translations = [];
Future<List<TranslationSource>> getTranslationsListsFromInternet() async {
if (_translations.isNotEmpty) {
return _translations;
}
final _fromTanzilNet = jsonDecode(translationJSONSource);
final _fromGithub = jsonDecode(translationFromGithubJSONSource);
final List<dynamic> translationsMap = [..._fromTanzilNet, ..._fromGithub];
_translations =
translationsMap.map((e) => TranslationSource.fromJson(e)).toList();
return _translations;
}
getSurahNameTranslation(
int surahNumber, String langCode, String fallbackLangCode) {
if (translationsOfSurahNamesMap[langCode] != null) {
return (translationsOfSurahNamesMap[langCode] as List)
.elementAt(surahNumber - 1);
}
return (translationsOfSurahNamesMap[fallbackLangCode] as List)
.elementAt(surahNumber - 1);
}
downloadTranslationFile({
required File file,
required TranslationSource translationSource,
required Function(File file) onDone,
required Function(Exception error) onError,
required Function(double progress) onProgress,
}) async {
try {
int _total = 0;
int _received = 0;
final List<int> _bytes = [];
final _response = await http.Client()
.send(http.Request('GET', Uri.parse(translationSource.downloadUrl!)));
_total = _response.contentLength ?? 0;
_response.stream.listen((value) {
_bytes.addAll(value);
_received += value.length;
onProgress(_received / _total);
}).onDone(() async {
file.writeAsBytesSync(_bytes);
onDone(file);
});
} on Exception catch (e) {
onError(e);
}
}
Future<List<Translator>> getTranslatorsFromDB() async {
final result = await QuranTranslationsDB.instance
.rawQuery('SELECT * FROM ${Translator().tableName}');
return result.map((e) => Translator.fromJson(e)).toList();
}
Future<List<Translation>> getTranslationFromDB(
int surahNumber, int verseNumber, int translatorId) async {
final result = await QuranTranslationsDB.instance.rawQuery(
'SELECT * FROM ${Translation().tableName} where surahNumber = ? and verseNumber = ? and translatorId = ?',
[surahNumber, verseNumber, translatorId]);
// final result = await QuranTranslationsDB.instance
// .rawQuery('SELECT * FROM ${Translation().tableName}');
return result.map((e) => Translation.fromJson(e)).toList();
}
Future<List<Translation>> searchTranslations(String query) async {
final result = await QuranTranslationsDB.instance.rawQuery(
'SELECT * FROM ${Translation().tableName} where translation LIKE ?',
['%$query%']);
return result.map((e) => Translation.fromJson(e)).toList();
}
List<Translation> _tempTranslations = [];
insertTranslationToDB(
{required File file, required Translator translator}) async {
/// find translatorId
final translatorsInDB =
await QuranTranslations.instance.getTranslatorsFromDB();
final alreadyInserted =
translatorsInDB.where((element) => element.name == translator.name);
if (alreadyInserted.isNotEmpty) {
translator = alreadyInserted.first;
} else {
translator.downloaded = true;
final translatorId =
await QuranTranslationsDB.instance.insert(translator);
translator.id = translatorId;
}
final batch = QuranTranslationsDB.instance.newBatch();
_tempTranslations.clear();
await file
.openRead()
.transform(utf8.decoder)
.transform(LineSplitter())
.forEach((l) {
print('line: $l');
final parts = l.split('|');
if (parts.length != 3) return;
final translation = Translation(
translatorId: translator.id,
surahNumber: int.tryParse(parts.first),
verseNumber: int.tryParse(parts[1]),
translation: parts.last,
);
_tempTranslations.add(translation);
});
for (final translation in _tempTranslations) {
QuranTranslationsDB.instance.insertBatch(translation, batch);
}
await batch.commit(noResult: true);
}
Future<void> deleteTranslationAndTranslator(int translatorId) async {
await QuranTranslationsDB.instance.deleteTranslator(translatorId);
await QuranTranslationsDB.instance.deleteTranslation(translatorId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment