Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] #260 update servers #535

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"gruene",
"housenumber"
],
"files.eol": "\n"
"files.eol": "\n",
"cSpell.enabled": false
}
5 changes: 4 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
include: package:flutter_lints/flutter.yaml

analyzer:
exclude: [build/**, lib/swagger_generated_code/**]
exclude:
- build/**
- lib/swagger_generated_code/**
- lib/**.g.dart
errors:
always_use_package_imports: error
directives_ordering: error
Expand Down
4 changes: 4 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ targets:
$default:
sources:
- swaggers/**
- lib/$lib$
# - $package$
- lib/**
- pubspec.yaml
builders:
chopper_generator:
options:
Expand Down
139 changes: 139 additions & 0 deletions lib/app/services/campaign_action_database.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import 'package:gruene_app/features/campaigns/helper/campaign_action.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

class CampaignActionDatabase {
static final CampaignActionDatabase instance = CampaignActionDatabase._internal();

static Database? _database;

CampaignActionDatabase._internal();

Future<Database> get database async {
return _database ??= await _initDatabase();
}

Future<Database> _initDatabase() async {
final databasePath = await getDatabasesPath();
final path = join(databasePath, 'campaign_action_db.db');
// await File(path).delete();
return await openDatabase(
path,
version: 1,
onCreate: _createDatabase,
);
}

Future<void> _createDatabase(Database db, _) async {
return await db.execute('''
CREATE TABLE ${CampaignActionFields.tableName} (
${CampaignActionFields.id} ${CampaignActionFields.idType},
${CampaignActionFields.poiId} ${CampaignActionFields.intTypeNullable},
${CampaignActionFields.poiTempId} ${CampaignActionFields.intType},
${CampaignActionFields.actionType} ${CampaignActionFields.intType},
${CampaignActionFields.serialized} ${CampaignActionFields.textTypeNullable}
)
''');
}

Future<CampaignAction> create(CampaignAction campaignAction) async {
final db = await instance.database;
final id = await db.insert(CampaignActionFields.tableName, campaignAction.toMap());
return campaignAction.copyWith(id: id);
}

Future<List<CampaignAction>> readAll() async {
final db = await instance.database;
const orderBy = '${CampaignActionFields.poiTempId} ASC, ${CampaignActionFields.id} ASC';
final result = await db.query(CampaignActionFields.tableName, orderBy: orderBy);
return result.map((json) => CampaignAction.fromMap(json)).toList();
}

Future<List<CampaignAction>> readAllByActionType(List<int> posterActions) async {
final db = await instance.database;
const orderBy = '${CampaignActionFields.poiTempId} ASC, ${CampaignActionFields.id} ASC';
final result = await db.query(
CampaignActionFields.tableName,
orderBy: orderBy,
where: '${CampaignActionFields.actionType} IN (${List.filled(posterActions.length, '?').join(',')})',
whereArgs: posterActions,
);
return result.map((json) => CampaignAction.fromMap(json)).toList();
}

Future<List<CampaignAction>> getActionsWithPoiId(String poiId) async {
final db = await instance.database;
const orderBy = '${CampaignActionFields.poiTempId} ASC, ${CampaignActionFields.id} ASC';
final result = await db.query(
CampaignActionFields.tableName,
orderBy: orderBy,
where: '${CampaignActionFields.poiId} = ? OR ${CampaignActionFields.poiTempId} = ?',
whereArgs: [poiId, poiId],
);
return result.map((json) => CampaignAction.fromMap(json)).toList();
}

Future<void> update(CampaignAction campaignAction) async {
final db = await instance.database;
db.update(
CampaignActionFields.tableName,
campaignAction.toMap(),
where: '${CampaignActionFields.id} = ?',
whereArgs: [campaignAction.id],
);
}

Future<void> updatePoiId(int oldId, int newId) async {
final db = await instance.database;
await db.update(
CampaignActionFields.tableName,
{CampaignActionFields.poiId: newId},
where: '${CampaignActionFields.poiId} = ?',
whereArgs: [oldId],
);
}

Future<int> delete(int id) async {
final db = await instance.database;
return await db.delete(
CampaignActionFields.tableName,
where: '${CampaignActionFields.id} = ?',
whereArgs: [id],
);
}

Future<void> close() async {
final db = await instance.database;
db.close();
}

Future<int> getCount() async {
final db = await instance.database;
int count = Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM ${CampaignActionFields.tableName}')) ?? 0;
return count;
}

Future<bool> actionsWithPoiIdExists(String poiId) async {
final db = await instance.database;
final result = await db.query(
CampaignActionFields.tableName,
columns: ['COUNT(*)'],
where: '${CampaignActionFields.poiId} = ? OR ${CampaignActionFields.poiTempId} = ?',
whereArgs: [poiId, poiId],
);
return (Sqflite.firstIntValue(result) ?? 0) > 0;
}
}

class CampaignActionFields {
static const String tableName = 'campaign_action';
static const String idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
static const String textTypeNullable = 'TEXT';
static const String intType = 'INTEGER NOT NULL';
static const String intTypeNullable = 'INTEGER';
static const String id = '_id';
static const String poiId = 'poiId';
static const String poiTempId = 'poiTempId';
static const String actionType = 'actionType';
static const String serialized = 'serialized';
}
19 changes: 19 additions & 0 deletions lib/app/services/converters.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import 'dart:convert';

import 'package:gruene_app/app/services/enums.dart';
import 'package:gruene_app/app/services/nominatim_service.dart';
import 'package:gruene_app/features/campaigns/helper/campaign_action.dart';
import 'package:gruene_app/features/campaigns/models/doors/door_create_model.dart';
import 'package:gruene_app/features/campaigns/models/doors/door_detail_model.dart';
import 'package:gruene_app/features/campaigns/models/doors/door_update_model.dart';
import 'package:gruene_app/features/campaigns/models/flyer/flyer_create_model.dart';
import 'package:gruene_app/features/campaigns/models/flyer/flyer_detail_model.dart';
import 'package:gruene_app/features/campaigns/models/flyer/flyer_update_model.dart';
import 'package:gruene_app/features/campaigns/models/map_layer_model.dart';
import 'package:gruene_app/features/campaigns/models/marker_item_model.dart';
import 'package:gruene_app/features/campaigns/models/posters/poster_create_model.dart';
import 'package:gruene_app/features/campaigns/models/posters/poster_detail_model.dart';
import 'package:gruene_app/features/campaigns/models/posters/poster_list_item_model.dart';
import 'package:gruene_app/features/campaigns/models/posters/poster_update_model.dart';
import 'package:gruene_app/features/campaigns/widgets/enhanced_wheel_slider.dart';
import 'package:gruene_app/features/campaigns/widgets/text_input_field.dart';
import 'package:gruene_app/i18n/translations.g.dart';
Expand All @@ -25,3 +34,13 @@ part 'converters/poi_address_parsing.dart';
part 'converters/focus_area_parsing.dart';
part 'converters/poi_parsing.dart';
part 'converters/slider_range_parsing.dart';
part 'converters/date_time_parsing.dart';
part 'converters/poster_create_model_parsing.dart';
part 'converters/poster_update_model_parsing.dart';
part 'converters/campaign_action_parsing.dart';
part 'converters/map_string_dynamic_converter.dart';
part 'converters/string_extension.dart';
part 'converters/door_update_model_parsing.dart';
part 'converters/door_create_model_parsing.dart';
part 'converters/flyer_create_model_parsing.dart';
part 'converters/flyer_update_model_parsing.dart';
74 changes: 74 additions & 0 deletions lib/app/services/converters/campaign_action_parsing.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
part of '../converters.dart';

extension CampaignActionParsing on CampaignAction {
PosterCreateModel getAsPosterCreate() {
var data = jsonDecode(serialized!) as Map<String, dynamic>;
var model = PosterCreateModel.fromJson(data.convertLatLongField());
return model;
}

PosterUpdateModel getAsPosterUpdate() {
var data = jsonDecode(serialized!) as Map<String, dynamic>;
var model = PosterUpdateModel.fromJson(data.updateIdField(poiId!).convertLatLongField());

return model;
}

DoorCreateModel getAsDoorCreate() {
var data = jsonDecode(serialized!) as Map<String, dynamic>;
var model = DoorCreateModel.fromJson(data.convertLatLongField());

return model;
}

DoorUpdateModel getAsDoorUpdate() {
var data = jsonDecode(serialized!) as Map<String, dynamic>;
var model = DoorUpdateModel.fromJson(data.updateIdField(poiId!).convertLatLongField());

return model;
}

FlyerCreateModel getAsFlyerCreate() {
var data = jsonDecode(serialized!) as Map<String, dynamic>;
var model = FlyerCreateModel.fromJson(data.convertLatLongField());

return model;
}

FlyerUpdateModel getAsFlyerUpdate() {
var data = jsonDecode(serialized!) as Map<String, dynamic>;
var model = FlyerUpdateModel.fromJson(data.updateIdField(poiId!).convertLatLongField());

return model;
}

PosterListItemModel getPosterUpdateAsPosterListItem(DateTime originalCreatedAt) {
var updateModel = getAsPosterUpdate().transformToPosterDetailModel();
return PosterListItemModel(
id: updateModel.id,
thumbnailUrl: updateModel.thumbnailUrl,
imageUrl: updateModel.imageUrl,
address: updateModel.address,
status: updateModel.status.translatePosterStatus(),
lastChangeStatus: t.campaigns.poster.updated,
lastChangeDateTime: '${DateTime.fromMillisecondsSinceEpoch(poiTempId).getAsLocalDateTimeString()}*',
createdAt: originalCreatedAt,
isCached: true,
);
}

PosterListItemModel getPosterCreateAsPosterListItem() {
var createModel = getAsPosterCreate().transformToPosterDetailModel(poiTempId.toString());
return PosterListItemModel(
id: createModel.id,
thumbnailUrl: createModel.thumbnailUrl,
imageUrl: createModel.imageUrl,
address: createModel.address,
status: createModel.status.translatePosterStatus(),
lastChangeStatus: t.campaigns.poster.updated,
lastChangeDateTime: '${DateTime.fromMillisecondsSinceEpoch(poiTempId).getAsLocalDateTimeString()}*',
createdAt: DateTime.fromMillisecondsSinceEpoch(poiTempId),
isCached: true,
);
}
}
13 changes: 13 additions & 0 deletions lib/app/services/converters/date_time_parsing.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
part of '../converters.dart';

extension DateTimeParsing on DateTime {
String getAsLocalDateTimeString() {
DateTime utcDateTime = this;
DateTime localDateTime = utcDateTime.toLocal();
final dateString = DateFormat(t.campaigns.poster.date_format).format(localDateTime);
final timeString = DateFormat(t.campaigns.poster.time_format).format(localDateTime);
return t.campaigns.poster.datetime_display_template
.replaceAll('{date}', dateString)
.replaceAll('{time}', timeString);
}
}
23 changes: 23 additions & 0 deletions lib/app/services/converters/door_create_model_parsing.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
part of '../converters.dart';

extension DoorCreateModelParsing on DoorCreateModel {
DoorDetailModel transformToDoorDetailModel(String temporaryId) {
return DoorDetailModel(
id: temporaryId,
address: address,
closedDoors: closedDoors,
openedDoors: openedDoors,
location: location,
createdAt: '${DateTime.now().getAsLocalDateTimeString()}*', // should mark this as preliminary
isCached: true,
);
}

MarkerItemModel transformToVirtualMarkerItem(int temporaryId) {
return MarkerItemModel.virtual(
id: temporaryId,
status: PoiServiceType.door.name,
location: location,
);
}
}
21 changes: 21 additions & 0 deletions lib/app/services/converters/door_update_model_parsing.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
part of '../converters.dart';

extension DoorUpdateModelParsing on DoorUpdateModel {
DoorDetailModel transformToDoorDetailModel() {
var newDoorDetail = oldDoorDetail.copyWith(
address: address,
closedDoors: closedDoors,
openedDoors: openedDoors,
isCached: true,
);
return newDoorDetail;
}

MarkerItemModel transformToVirtualMarkerItem() {
return MarkerItemModel.virtual(
id: int.parse(id),
status: PoiServiceType.door.name,
location: location,
);
}
}
22 changes: 22 additions & 0 deletions lib/app/services/converters/flyer_create_model_parsing.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
part of '../converters.dart';

extension FlyerCreateModelParsing on FlyerCreateModel {
FlyerDetailModel transformToFlyerDetailModel(String temporaryId) {
return FlyerDetailModel(
id: temporaryId,
address: address,
flyerCount: flyerCount,
location: location,
createdAt: '${DateTime.now().getAsLocalDateTimeString()}*', // should mark this as preliminary
isCached: true,
);
}

MarkerItemModel transformToVirtualMarkerItem(int temporaryId) {
return MarkerItemModel.virtual(
id: temporaryId,
status: PoiServiceType.flyer.name,
location: location,
);
}
}
20 changes: 20 additions & 0 deletions lib/app/services/converters/flyer_update_model_parsing.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
part of '../converters.dart';

extension FlyerUpdateModelParsing on FlyerUpdateModel {
FlyerDetailModel transformToFlyerDetailModel() {
var newFlyerDetail = oldFlyerDetail.copyWith(
address: address,
flyerCount: flyerCount,
isCached: true,
);
return newFlyerDetail;
}

MarkerItemModel transformToVirtualMarkerItem() {
return MarkerItemModel.virtual(
id: int.parse(id),
status: PoiServiceType.flyer.name,
location: location,
);
}
}
Loading