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

feat: new restaurants api #1393

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
63aa00c
feat: added up_menus dependency
HenriqueSFernandes Nov 16, 2024
9e8f5c0
feat: Updated day of the week parser to include datetime
HenriqueSFernandes Nov 16, 2024
ece6d19
partially implemented new restaurants api
HenriqueSFernandes Nov 16, 2024
bdc9497
refactor: removed GSheets fetching logic
HenriqueSFernandes Nov 18, 2024
2f4d9dd
refactor: removed debug prints
HenriqueSFernandes Nov 18, 2024
6a4731b
Merge branch 'develop' into feat/new-restaurants-api
HenriqueSFernandes Nov 18, 2024
5b2568d
refactor: disable past meals filtering temporarily
HenriqueSFernandes Nov 18, 2024
72c189f
fix: The new API uses "pescado" for fish and "hortícola" for salad, i…
HenriqueSFernandes Nov 19, 2024
87c7d26
Merge remote-tracking branch 'origin/develop' into feat/new-restauran…
HenriqueSFernandes Nov 29, 2024
9f1457e
feat: removed restautant filtering function
HenriqueSFernandes Dec 1, 2024
3f34f44
Merge branch 'develop' into feat/new-restaurants-api
HenriqueSFernandes Dec 1, 2024
3d021d8
feat: Added suffix to distinguish lunch and dinner
HenriqueSFernandes Dec 1, 2024
b08a26a
refactor: removed dead code
HenriqueSFernandes Dec 1, 2024
27fff36
feat: added restaurant period translation
HenriqueSFernandes Dec 3, 2024
0789126
feat: added period to restaurant model
HenriqueSFernandes Dec 3, 2024
748e3df
fix: fixed period on favourite restaurants
HenriqueSFernandes Dec 3, 2024
6dcdf53
Merge branch 'develop' into feat/new-restaurants-api
HenriqueSFernandes Dec 3, 2024
9d62d9e
refactor: simplified restaurant fetcher
HenriqueSFernandes Dec 3, 2024
af50845
feat: added english translation to meals
HenriqueSFernandes Dec 4, 2024
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
127 changes: 68 additions & 59 deletions packages/uni_app/lib/controller/fetchers/restaurant_fetcher.dart
Original file line number Diff line number Diff line change
@@ -1,47 +1,80 @@
import 'package:intl/intl.dart';
import 'package:uni/controller/networking/network_router.dart';
import 'package:uni/controller/parsers/parser_restaurants.dart';
import 'package:uni/model/entities/meal.dart';
import 'package:uni/model/entities/restaurant.dart';
import 'package:uni/model/utils/day_of_week.dart';
import 'package:uni/session/flows/base/session.dart';
import 'package:up_menus/up_menus.dart';

/// Class for fetching the menu
class RestaurantFetcher {
final String spreadSheetUrl = 'https://docs.google.com/spreadsheets/d/'
'1TJauM0HwIf2RauQU2GmhdZZ1ZicFLMHuBkxWwVOw3Q4';
final String jsonEndpoint = '/gviz/tq?tqx=out:json';

// Format: Date(dd/mm/yyyy), Meal("Almoço", "Jantar), Dish("Sopa", "Carne",
// "Peixe", "Dieta", "Vegetariano", "Salada"), Description(String)
final String sheetsColumnRange = 'A:D';

// List the Restaurant sheet names in the Google Sheets Document
final List<String> restaurantSheets = ['Cantina'];

// Generate the Gsheets endpoints list based on a list of sheets
String buildGSheetsEndpoint(String sheet) {
return Uri.encodeFull(
'$spreadSheetUrl$jsonEndpoint&sheet=$sheet&range=$sheetsColumnRange',
Restaurant convertToRestaurant(
Establishment establishment,
Iterable<DayMenu> dayMenus,
String period,
) {
final currentLocale = Intl.getCurrentLocale();

final meals = <Meal>[];
for (final dayMenu in dayMenus) {
for (final dish in dayMenu.dishes) {
// Extract the information about the meal.
meals.add(
Meal(
dish.dishType.namePt,
currentLocale.startsWith('pt')
? dish.dish.namePt
: dish.dish.nameEn ??
dish.dish
.namePt, // if there isn't an english name, use the portuguese one.
parseDateTime(dayMenu.day),
dayMenu.day,
),
);
}
}
return Restaurant(
establishment.id,
currentLocale.startsWith('pt')
? establishment.namePt
: establishment.nameEn,
period,
'',
meals: meals,
);
}

String getRestaurantGSheetName(Restaurant restaurant) {
return restaurantSheets.firstWhere(
(sheetName) =>
restaurant.name.toLowerCase().contains(sheetName.toLowerCase()),
orElse: () => '',
);
}
Future<List<Restaurant>> fetchSASUPRestaurants() async {
// TODO: change the implementation to accomodate changes for the new UI.
final upMenus = UPMenusApi();
final establishments = await upMenus.establishments.list();
final restaurants = <Restaurant>[];

Future<Restaurant> fetchGSheetsRestaurant(
String url,
String restaurantName,
Session session, {
bool isDinner = false,
}) async {
return getRestaurantFromGSheets(
await NetworkRouter.getWithCookies(url, {}, session),
restaurantName,
isDinner: isDinner,
);
const periods = [
{'period': Period.lunch, 'meal': 'lunch'},
{'period': Period.dinner, 'meal': 'dinner'},
{'period': Period.snackBar, 'meal': 'snackbar'},
{'period': Period.breakfast, 'meal': 'breakfast'},
];

for (final establishment in establishments) {
if (establishment.dayMenu == false) {
continue;
}

for (final period in periods) {
restaurants.add(
convertToRestaurant(
establishment,
await upMenus.dayMenus
.get(establishment.id, period['period']! as Period),
period['meal']! as String,
),
);
}
}
return restaurants;
}

final List<String> sigarraMenuEndpoints = [
Expand All @@ -64,32 +97,8 @@ class RestaurantFetcher {
}

Future<List<Restaurant>> getRestaurants(Session session) async {
final restaurants = await fetchSigarraRestaurants(session);

// Check for restaurants without associated meals and attempt to parse them
// from GSheets
final restaurantsWithoutMeals =
restaurants.where((restaurant) => restaurant.meals.isEmpty).toList();

for (final restaurant in restaurantsWithoutMeals) {
final sheetName = getRestaurantGSheetName(restaurant);
if (sheetName.isEmpty) {
continue;
}

final gSheetsRestaurant = await fetchGSheetsRestaurant(
buildGSheetsEndpoint(sheetName),
restaurant.name,
session,
isDinner: restaurant.name.toLowerCase().contains('jantar'),
);

restaurants
..removeWhere(
(restaurant) => restaurant.name == gSheetsRestaurant.name,
)
..insert(0, gSheetsRestaurant);
}
final restaurants =
await fetchSASUPRestaurants() + await fetchSigarraRestaurants(session);

return restaurants;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class RestaurantDatabase extends AppDatabase<List<Restaurant>> {
return Restaurant(
restaurantId,
map['name'] as String,
map['period'] as String,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because you modify the database table, increase its version. Since it's stills in v1, you need to create migration code. Look at #1380

map['ref'] as String,
meals: meals,
);
Expand All @@ -70,7 +71,7 @@ class RestaurantDatabase extends AppDatabase<List<Restaurant>> {
}
});

return filterPastMeals(restaurants);
return restaurants;
}

Future<List<Meal>> getRestaurantMeals(
Expand Down Expand Up @@ -129,22 +130,3 @@ class RestaurantDatabase extends AppDatabase<List<Restaurant>> {
});
}
}

List<Restaurant> filterPastMeals(List<Restaurant> restaurants) {
final restaurantsCopy = List<Restaurant>.from(restaurants);
// Hide past and next weeks' meals
// (To replicate sigarra's behaviour for the GSheets meals)
final now = DateTime.now().toUtc();
final today = DateTime.utc(now.year, now.month, now.day);
final nextSunday = today.add(Duration(days: DateTime.sunday - now.weekday));

for (final restaurant in restaurantsCopy) {
for (final meals in restaurant.meals.values) {
meals.removeWhere(
(meal) => meal.date.isBefore(today) || meal.date.isAfter(nextSunday),
);
}
}

return restaurantsCopy;
}
47 changes: 1 addition & 46 deletions packages/uni_app/lib/controller/parsers/parser_restaurants.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:convert';

import 'package:html/parser.dart';
import 'package:http/http.dart';
import 'package:intl/intl.dart';
Expand Down Expand Up @@ -72,52 +70,9 @@ List<Restaurant> getRestaurantsFromHtml(Response response) {
null,
restaurantTuple.item2,
restaurantTuple.item1,
'',
meals: meals,
);
}).toList();
return restaurants;
}

Restaurant getRestaurantFromGSheets(
Response response,
String restaurantName, {
bool isDinner = false,
}) {
// Ignore beginning of response: "/*O_o*/\ngoogle.visualization.Query.setResponse("
// Ignore the end of the response: ");"
// Check the structure by accessing the link:
// https://docs.google.com/spreadsheets/d/1TJauM0HwIf2RauQU2GmhdZZ1ZicFLMHuBkxWwVOw3Q4/gviz/tq?tqx=out:json&sheet=Cantina%20de%20Engenharia&range=A:D
final jsonString = response.body.substring(
response.body.indexOf('(') + 1,
response.body.lastIndexOf(')'),
);
final parsedJson = jsonDecode(jsonString) as Map<String, dynamic>;

final mealsList = <Meal>[];

final format = DateFormat('d/M/y');

final table = parsedJson['table'] as Map<String, dynamic>;
final rows = table['rows'] as List<dynamic>;

for (final row in rows) {
final cellList = (row as Map<String, dynamic>)['c'] as List<dynamic>;
if (((cellList[1] as Map<String, dynamic>)['v'] == 'Almoço' && isDinner) ||
((cellList[1] as Map<String, dynamic>)['v'] != 'Almoço' && !isDinner)) {
continue;
}

final meal = Meal(
(cellList[2] as Map<String, dynamic>)['v'] as String,
(cellList[3] as Map<String, dynamic>)['v'] as String,
DayOfWeek.values[format
.parseUtc((cellList[0] as Map<String, dynamic>)['f'] as String)
.weekday -
1],
format.parseUtc((cellList[0] as Map<String, dynamic>)['f'] as String),
);
mealsList.add(meal);
}

return Restaurant(null, restaurantName, '', meals: mealsList);
}
4 changes: 4 additions & 0 deletions packages/uni_app/lib/generated/intl/messages_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class MessageLookup extends MessageLookupByLibrary {
"banner_info": MessageLookupByLibrary.simpleMessage(
"We do now collect anonymous usage statistics in order to improve your experience. You can change it in settings."),
"bibliography": MessageLookupByLibrary.simpleMessage("Bibliography"),
"breakfast": MessageLookupByLibrary.simpleMessage("Breakfast"),
"bs_description": MessageLookupByLibrary.simpleMessage(
"Did you find any bugs in the application?\nDo you have any suggestions for the app?\nTell us so we can improve!"),
"bug_description": MessageLookupByLibrary.simpleMessage(
Expand Down Expand Up @@ -110,6 +111,7 @@ class MessageLookup extends MessageLookupByLibrary {
"description": MessageLookupByLibrary.simpleMessage("Description"),
"desired_email": MessageLookupByLibrary.simpleMessage(
"Email where you want to be contacted"),
"dinner": MessageLookupByLibrary.simpleMessage("Dinner"),
"dona_bia": MessageLookupByLibrary.simpleMessage(
"D. Beatriz\'s stationery store"),
"dona_bia_building": MessageLookupByLibrary.simpleMessage(
Expand Down Expand Up @@ -167,6 +169,7 @@ class MessageLookup extends MessageLookupByLibrary {
"login_with_credentials":
MessageLookupByLibrary.simpleMessage("Login with credentials"),
"logout": MessageLookupByLibrary.simpleMessage("Log out"),
"lunch": MessageLookupByLibrary.simpleMessage("Lunch"),
"menus": MessageLookupByLibrary.simpleMessage("Menus"),
"min_value_reference":
MessageLookupByLibrary.simpleMessage("Minimum value: 1,00 €"),
Expand Down Expand Up @@ -272,6 +275,7 @@ class MessageLookup extends MessageLookupByLibrary {
"sent_error": MessageLookupByLibrary.simpleMessage(
"An error occurred in sending"),
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
"snackbar": MessageLookupByLibrary.simpleMessage("Snackbar"),
"some_error": MessageLookupByLibrary.simpleMessage("Some error!"),
"stcp_stops":
MessageLookupByLibrary.simpleMessage("STCP - Upcoming Trips"),
Expand Down
4 changes: 4 additions & 0 deletions packages/uni_app/lib/generated/intl/messages_pt_PT.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class MessageLookup extends MessageLookupByLibrary {
"banner_info": MessageLookupByLibrary.simpleMessage(
"Agora recolhemos estatísticas de uso anónimas para melhorar a tua experiência. Podes alterá-lo nas definições."),
"bibliography": MessageLookupByLibrary.simpleMessage("Bibliografia"),
"breakfast": MessageLookupByLibrary.simpleMessage("Pequeno Almoço"),
"bs_description": MessageLookupByLibrary.simpleMessage(
"Encontraste algum bug na aplicação?\nTens alguma sugestão para a app?\nConta-nos para que possamos melhorar!"),
"bug_description": MessageLookupByLibrary.simpleMessage(
Expand Down Expand Up @@ -109,6 +110,7 @@ class MessageLookup extends MessageLookupByLibrary {
"description": MessageLookupByLibrary.simpleMessage("Descrição"),
"desired_email": MessageLookupByLibrary.simpleMessage(
"Email em que desejas ser contactado"),
"dinner": MessageLookupByLibrary.simpleMessage("Jantar"),
"dona_bia":
MessageLookupByLibrary.simpleMessage("Papelaria D. Beatriz"),
"dona_bia_building": MessageLookupByLibrary.simpleMessage(
Expand Down Expand Up @@ -166,6 +168,7 @@ class MessageLookup extends MessageLookupByLibrary {
"login_with_credentials": MessageLookupByLibrary.simpleMessage(
"Iniciar sessão com credenciais"),
"logout": MessageLookupByLibrary.simpleMessage("Terminar sessão"),
"lunch": MessageLookupByLibrary.simpleMessage("Almoço"),
"menus": MessageLookupByLibrary.simpleMessage("Ementas"),
"min_value_reference":
MessageLookupByLibrary.simpleMessage("Valor mínimo: 1,00 €"),
Expand Down Expand Up @@ -273,6 +276,7 @@ class MessageLookup extends MessageLookupByLibrary {
"sent_error":
MessageLookupByLibrary.simpleMessage("Ocorreu um erro no envio"),
"settings": MessageLookupByLibrary.simpleMessage("Definições"),
"snackbar": MessageLookupByLibrary.simpleMessage("Snackbar"),
"some_error": MessageLookupByLibrary.simpleMessage("Algum erro!"),
"stcp_stops":
MessageLookupByLibrary.simpleMessage("STCP - Próximas Viagens"),
Expand Down
40 changes: 40 additions & 0 deletions packages/uni_app/lib/generated/l10n.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading