Skip to content
This repository has been archived by the owner on Jul 5, 2023. It is now read-only.

Commit

Permalink
Merge branch 'release/0.2.7'
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-audi committed Oct 10, 2021
2 parents c48f318 + 315851a commit fcd4aef
Show file tree
Hide file tree
Showing 13 changed files with 325 additions and 30 deletions.
16 changes: 2 additions & 14 deletions lib/src/slices/api_knowledge/api_knowledge_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import '../../utils/api/helper_api_auth.dart';
import '../../utils/api/helper_api_rsp.dart';
import '../../utils/api/helper_api_utils.dart';
import 'model/company/api_knowledge_model_company.dart';
import 'model/edge/api_knowledge_model_edge.dart';
import 'repository/api_knowledge_repository_company.dart';
Expand All @@ -21,18 +20,7 @@ class ApiKnowledgeService {
await helperApiAuth.proxy(() =>
ApiKnowledgeRepositoryCompany.get(helperApiAuth.bearer, domain));

Future<HelperApiRsp<ApiKnowledgeModelEdge>> addEdge(
ApiKnowledgeModelEdge edge) async =>
Future<HelperApiRsp> addEdges(List<ApiKnowledgeModelEdge> edges) async =>
await helperApiAuth.proxy(
() => ApiKnowledgeRepositoryEdge.post(helperApiAuth.bearer, edge));

Future<List<ApiKnowledgeModelEdge>> addEdges(
List<ApiKnowledgeModelEdge> edges) async {
List<ApiKnowledgeModelEdge> added = new List.empty(growable: true);
for (ApiKnowledgeModelEdge edge in edges) {
HelperApiRsp<ApiKnowledgeModelEdge> rsp = await addEdge(edge);
if (HelperApiUtils.isOk(rsp.code)) added.add(rsp.data);
}
return added;
}
() => ApiKnowledgeRepositoryEdge.post(helperApiAuth.bearer, edges));
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,19 @@ import '../../../config/config_domain.dart';
import '../../../config/config_sentry.dart';
import '../../../utils/api/helper_api_headers.dart';
import '../../../utils/api/helper_api_rsp.dart';
import '../../../utils/helper_json.dart';
import '../model/edge/api_knowledge_model_edge.dart';

class ApiKnowledgeRepositoryEdge {
static final String _path = '/api/latest/edge';

static Future<HelperApiRsp<ApiKnowledgeModelEdge>> post(
String? bearer, ApiKnowledgeModelEdge edge) async {
static Future<HelperApiRsp> post(
String? bearer, List<ApiKnowledgeModelEdge> edges) async {
Response rsp = await ConfigSentry.http.post(
ConfigDomain.asUri(ConfigDomain.knowledge, _path),
headers: HelperApiHeaders(auth: bearer).header,
body: jsonEncode(edge.toJson()));
body: jsonEncode(HelperJson.listToJson(edges)));
Map? rspMap = jsonDecode(rsp.body);
return HelperApiRsp.fromJson(
rspMap as Map<String, dynamic>?,
(json) =>
ApiKnowledgeModelEdge.fromJson(json as Map<String, dynamic>?));
return HelperApiRsp.fromJson(rspMap as Map<String, dynamic>?, (json) => {});
}
}
10 changes: 9 additions & 1 deletion lib/src/slices/data_fetch/data_fetch_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* MIT license. See LICENSE file in root directory.
*/

import 'package:app/src/slices/api_knowledge/api_knowledge_service.dart';
import 'package:app/src/slices/data_push/data_push_service.dart';
import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart';

Expand All @@ -16,20 +18,26 @@ import 'data_fetch_service_email.dart';

class DataFetchService extends ChangeNotifier {
final _log = Logger('DataFetchService');
final DataPushService _dataPushService;
late final DataFetchServiceEmail email;

DataFetchService(
{required ApiOAuthService apiAuthService,
required ApiAppDataService apiAppDataService,
required ApiCompanyService apiCompanyService,
required ApiEmailSenderService apiEmailSenderService,
required ApiEmailMsgService apiEmailMsgService}) {
required ApiEmailMsgService apiEmailMsgService,
required ApiKnowledgeService apiKnowledgeService,
required DataPushService dataPushService})
: this._dataPushService = dataPushService {
this.email = DataFetchServiceEmail(
apiAuthService: apiAuthService,
apiAppDataService: apiAppDataService,
apiEmailMsgService: apiEmailMsgService,
apiEmailSenderService: apiEmailSenderService,
apiCompanyService: apiCompanyService,
apiKnowledgeService: apiKnowledgeService,
dataPushService: _dataPushService,
notifyListeners: notifyListeners);
}

Expand Down
43 changes: 40 additions & 3 deletions lib/src/slices/data_fetch/data_fetch_service_email.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* MIT license. See LICENSE file in root directory.
*/

import 'package:app/src/slices/data_push/data_push_convert.dart';
import 'package:logging/logging.dart';

import '../api_app_data/api_app_data_key.dart';
Expand All @@ -14,9 +15,11 @@ import '../api_email_msg/api_email_msg_service.dart';
import '../api_email_msg/model/api_email_msg_model.dart';
import '../api_email_sender/api_email_sender_service.dart';
import '../api_email_sender/model/api_email_sender_model.dart';
import '../api_knowledge/api_knowledge_service.dart';
import '../api_oauth/api_oauth_interface_provider.dart';
import '../api_oauth/api_oauth_service.dart';
import '../api_oauth/model/api_oauth_model_account.dart';
import '../data_push/data_push_service.dart';
import 'data_fetch_interface_email.dart';
import 'data_fetch_interface_provider.dart';
import 'model/data_fetch_model_page.dart';
Expand All @@ -28,6 +31,8 @@ class DataFetchServiceEmail {
final ApiEmailMsgService _apiEmailMsgService;
final ApiEmailSenderService _apiEmailSenderService;
final ApiCompanyService _apiCompanyService;
final ApiKnowledgeService _apiKnowledgeService;
final DataPushService _dataPushService;
final Function notifyListeners;

DataFetchServiceEmail(
Expand All @@ -36,12 +41,16 @@ class DataFetchServiceEmail {
required ApiEmailMsgService apiEmailMsgService,
required ApiEmailSenderService apiEmailSenderService,
required ApiCompanyService apiCompanyService,
required ApiKnowledgeService apiKnowledgeService,
required DataPushService dataPushService,
required this.notifyListeners})
: this._apiAuthService = apiAuthService,
this._apiAppDataService = apiAppDataService,
this._apiEmailMsgService = apiEmailMsgService,
this._apiEmailSenderService = apiEmailSenderService,
this._apiCompanyService = apiCompanyService;
this._apiCompanyService = apiCompanyService,
this._apiKnowledgeService = apiKnowledgeService,
this._dataPushService = dataPushService;

Future<bool> unsubscribe(ApiOAuthModelAccount account,
String unsubscribeMailTo, String list) async {
Expand Down Expand Up @@ -92,7 +101,7 @@ revolution today.<br />
DateTime.now()
.subtract(Duration(days: 1))
.isAfter(DateTime.fromMillisecondsSinceEpoch(indexEpoch))) {
await _pageList(
await _indexLabel(
interfaceEmail: interfaceEmail,
account: account,
indexEpoch: indexEpoch);
Expand All @@ -105,9 +114,30 @@ revolution today.<br />
}
}

Future<void> _indexLabel(
{required DataFetchInterfaceEmail interfaceEmail,
required ApiOAuthModelAccount account,
int? indexEpoch}) async {
ApiAppDataModel? appDataIndexLabel =
await _apiAppDataService.getByKey(ApiAppDataKey.emailIndexLabel);
String? indexLabel = appDataIndexLabel?.value;
int start =
indexLabel != null ? interfaceEmail.labels.indexOf(indexLabel) : 0;
for (int i = start; i < interfaceEmail.labels.length; i++) {
await _pageList(
interfaceEmail: interfaceEmail,
account: account,
label: interfaceEmail.labels[i],
indexEpoch: indexEpoch);
await _apiAppDataService.save(
ApiAppDataKey.emailIndexLabel, interfaceEmail.labels[i]);
}
}

Future<void> _pageList(
{required DataFetchInterfaceEmail interfaceEmail,
required ApiOAuthModelAccount account,
String? label,
String? page,
int? indexEpoch}) async {
if (page == null) {
Expand All @@ -120,6 +150,7 @@ revolution today.<br />
account: account,
interfaceEmail: interfaceEmail,
afterEpoch: indexEpoch,
label: label,
page: page,
maxResults: 5);
if (res.data != null) {
Expand All @@ -138,6 +169,7 @@ revolution today.<br />
return _pageList(
interfaceEmail: interfaceEmail,
account: account,
label: label,
indexEpoch: indexEpoch,
page: res.next);
}
Expand All @@ -158,8 +190,9 @@ revolution today.<br />
await _apiEmailSenderService.getByEmail(message!.sender!.email!);
if (sender != null) {
_log.fine("Known sender ${sender.name}");
await _saveSender(sender);
message.sender = await _saveSender(sender);
await _apiEmailMsgService.upsert(message);
await _dataPushService.write(DataPushConvert.message(message));
_log.fine('Sender upsert: ' + (sender.company?.domain ?? ''));
notifyListeners();
} else {
Expand Down Expand Up @@ -211,6 +244,7 @@ revolution today.<br />
for (ApiEmailMsgModel message in messages) {
message.sender = inserted;
await _apiEmailMsgService.upsert(message);
await _dataPushService.write(DataPushConvert.message(message));
}
_log.fine('Sender upsert: ' + (sender.company?.domain ?? ''));
notifyListeners();
Expand Down Expand Up @@ -267,11 +301,13 @@ revolution today.<br />
String? from,
int? afterEpoch,
int? maxResults,
String? label,
String? page,
int? retries = 3}) async {
try {
return await interfaceEmail.getList(account,
from: from,
label: label,
afterEpoch: afterEpoch,
maxResults: maxResults,
page: page);
Expand All @@ -290,6 +326,7 @@ revolution today.<br />
afterEpoch: afterEpoch,
maxResults: maxResults,
page: page,
label: label,
retries: retries! - 1,
);
rethrow;
Expand Down
44 changes: 44 additions & 0 deletions lib/src/slices/data_push/data_push_convert.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in root directory.
*/

import 'package:uuid/uuid.dart';

import '../api_email_msg/model/api_email_msg_model.dart';
import 'model/data_push_model.dart';

class DataPushConvert {
static List<DataPushModel> message(ApiEmailMsgModel message) => [
DataPushModel(
fromType: "company",
fromValue: message.sender?.company?.domain,
toType: "content",
toValue: "email",
fingerprint: Uuid().v4()),
DataPushModel(
fromType: "content",
fromValue: "email",
toType: "action",
toValue: "received",
fingerprint: Uuid().v4()),
DataPushModel(
fromType: "action",
fromValue: "received",
toType: "day",
toValue: message.receivedDate?.day.toString(),
fingerprint: Uuid().v4()),
DataPushModel(
fromType: "day",
fromValue: message.receivedDate?.day.toString(),
toType: "month",
toValue: message.receivedDate?.month.toString(),
fingerprint: Uuid().v4()),
DataPushModel(
fromType: "month",
fromValue: message.receivedDate?.month.toString(),
toType: "year",
toValue: message.receivedDate?.year.toString(),
fingerprint: Uuid().v4()),
];
}
44 changes: 44 additions & 0 deletions lib/src/slices/data_push/data_push_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in root directory.
*/

import 'package:app/src/utils/api/helper_api_rsp.dart';
import 'package:app/src/utils/api/helper_api_utils.dart';
import 'package:logging/logging.dart';
import 'package:sqflite_sqlcipher/sqlite_api.dart';

import '../api_knowledge/api_knowledge_service.dart';
import 'model/data_push_model.dart';
import 'repository/data_push_repository.dart';

class DataPushService {
final _log = Logger('DataPushService');
static final int _pushOn = 250;
final DataPushRepository _repository;
final ApiKnowledgeService _apiKnowledgeService;

DataPushService(
{required ApiKnowledgeService apiKnowledgeService,
required Database database})
: this._apiKnowledgeService = apiKnowledgeService,
this._repository = DataPushRepository(database);

Future<void> write(List<DataPushModel> edges, {bool force = false}) async {
await _repository.insert(edges);
int size = await _repository.getSize();
if (size >= _pushOn) {
List<DataPushModel> edgesToPush =
await _repository.getAll(limit: _pushOn);
HelperApiRsp rsp = await _apiKnowledgeService
.addEdges(edgesToPush.map((e) => e.toEdge()).toList());
if (HelperApiUtils.is2xx(rsp.code)) {
List<int> ids = edgesToPush
.where((e) => e.queueId != null)
.map((e) => e.queueId!)
.toList();
await _repository.deleteByIds(ids);
}
}
}
}
70 changes: 70 additions & 0 deletions lib/src/slices/data_push/model/data_push_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in root directory.
*/

import '../../api_knowledge/model/edge/api_knowledge_model_edge.dart';
import '../../api_knowledge/model/edge/api_knowledge_model_edge_vertex.dart';

class DataPushModel {
int? queueId;
String? fromType;
String? fromValue;
String? toType;
String? toValue;
String? fingerprint;
DateTime? created;

DataPushModel(
{this.queueId,
this.fromType,
this.fromValue,
this.toType,
this.toValue,
this.fingerprint,
this.created});

DataPushModel.fromMap(Map<String, dynamic> map)
: this.queueId = map['queue_id'],
this.fromType = map['from_type'],
this.fromValue = map['from_value'],
this.toType = map['to_type'],
this.toValue = map['to_value'],
this.fingerprint = map['fingerprint'] {
int? createdEpoch = map['created_epoch'];
if (createdEpoch != null)
this.created = DateTime.fromMillisecondsSinceEpoch(createdEpoch);
}

DataPushModel.fromEdge(ApiKnowledgeModelEdge edge)
: this.fromValue = edge.from?.value,
this.fromType = edge.from?.type,
this.toValue = edge.to?.value,
this.toType = edge.to?.type,
this.fingerprint = edge.fingerprint;

Map<String, dynamic> toMap() {
return {
'queue_id': this.queueId,
'from_type': this.fromType,
'from_value': this.fromValue,
'to_type': this.toType,
'to_value': this.toValue,
'fingerprint': this.fingerprint,
'created_epoch': created?.millisecondsSinceEpoch,
};
}

ApiKnowledgeModelEdge toEdge() {
return ApiKnowledgeModelEdge(
from: ApiKnowledgeModelEdgeVertex(
type: this.fromType,
value: this.fromValue,
),
to: ApiKnowledgeModelEdgeVertex(
type: this.toType,
value: this.toValue,
),
fingerprint: this.fingerprint);
}
}
Loading

0 comments on commit fcd4aef

Please sign in to comment.