parent
da366285bb
commit
bb356120fa
|
@ -1,7 +1,7 @@
|
||||||
import 'package:release_schedule/model/movie.dart';
|
import 'package:release_schedule/model/movie.dart';
|
||||||
|
|
||||||
abstract class MovieApi {
|
abstract class MovieApi {
|
||||||
Future<List<MovieData>> getUpcomingMovies([int count]);
|
Future<List<MovieData>> getUpcomingMovies(DateTime startDate, [int count]);
|
||||||
Future<List<MovieData>> searchForMovies(String searchTerm);
|
Future<List<MovieData>> searchForMovies(String searchTerm);
|
||||||
Future<void> addMovieDetails(List<MovieData> movies);
|
Future<void> addMovieDetails(List<MovieData> movies);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:release_schedule/api/api_manager.dart';
|
import 'package:release_schedule/api/api_manager.dart';
|
||||||
import 'package:release_schedule/api/movie_api.dart';
|
import 'package:release_schedule/api/movie_api.dart';
|
||||||
import 'package:release_schedule/model/movie.dart';
|
import 'package:release_schedule/model/movie.dart';
|
||||||
|
|
||||||
class WikidataMovieData extends MovieData {
|
class WikidataMovieData extends MovieData {
|
||||||
int entityId;
|
int entityId;
|
||||||
WikidataMovieData(String title, DateTime releaseDate, this.entityId)
|
WikidataMovieData(String title, DateTime releaseDate,
|
||||||
: super(title, releaseDate);
|
DatePrecision releaseDatePrecision, this.entityId)
|
||||||
|
: super(title, releaseDate, releaseDatePrecision);
|
||||||
|
|
||||||
WikidataMovieData.fromEncodable(Map encodable)
|
WikidataMovieData.fromEncodable(Map encodable)
|
||||||
: entityId = encodable["entityId"],
|
: entityId = encodable["entityId"],
|
||||||
|
@ -25,17 +27,22 @@ class WikidataMovieData extends MovieData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String createUpcomingMovieQuery(int limit) {
|
String createUpcomingMovieQuery(DateTime startDate, int limit) {
|
||||||
|
String date = DateFormat("yyyy-MM-dd").format(startDate);
|
||||||
return """
|
return """
|
||||||
SELECT
|
SELECT
|
||||||
?movie
|
?movie
|
||||||
?movieLabel
|
?movieLabel
|
||||||
(MIN(?releaseDate) as ?minReleaseDate)
|
(MIN(?releaseDate) as ?minReleaseDate)
|
||||||
|
(SAMPLE(?precision) as ?datePrecision)
|
||||||
WHERE {
|
WHERE {
|
||||||
?movie wdt:P31 wd:Q11424; # Q11424 is the item for "film"
|
?movie wdt:P31 wd:Q11424; # Q11424 is the item for "film"
|
||||||
wdt:P577 ?releaseDate; # P577 is the "publication date" property
|
wdt:P577 ?releaseDate; # P577 is the "publication date" property
|
||||||
wdt:P1476 ?title.
|
wdt:P1476 ?title.
|
||||||
FILTER (xsd:date(?releaseDate) >= xsd:date(NOW()))
|
OPTIONAL {
|
||||||
|
?movie p:P577/psv:P577/wikibase:timePrecision ?precision.
|
||||||
|
}
|
||||||
|
FILTER (xsd:date(?releaseDate) >= xsd:date("$date"^^xsd:dateTime))
|
||||||
|
|
||||||
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
|
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
|
||||||
}
|
}
|
||||||
|
@ -44,6 +51,17 @@ ORDER BY ?minReleaseDate
|
||||||
LIMIT $limit""";
|
LIMIT $limit""";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatePrecision precisionFromWikidata(int precision) {
|
||||||
|
return switch (precision) {
|
||||||
|
>= 11 => DatePrecision.day,
|
||||||
|
10 => DatePrecision.month,
|
||||||
|
9 => DatePrecision.year,
|
||||||
|
8 => DatePrecision.decade,
|
||||||
|
< 8 => throw Exception("The precision was too low, value: $precision"),
|
||||||
|
_ => throw Exception("Unexpected precision value: $precision"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class WikidataMovieApi implements MovieApi {
|
class WikidataMovieApi implements MovieApi {
|
||||||
ApiManager searchApi = ApiManager("https://www.wikidata.org/w/api.php");
|
ApiManager searchApi = ApiManager("https://www.wikidata.org/w/api.php");
|
||||||
ApiManager queryApi =
|
ApiManager queryApi =
|
||||||
|
@ -56,9 +74,10 @@ class WikidataMovieApi implements MovieApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<WikidataMovieData>> getUpcomingMovies([int count = 100]) async {
|
Future<List<WikidataMovieData>> getUpcomingMovies(DateTime startDate,
|
||||||
Response response = await queryApi
|
[int count = 100]) async {
|
||||||
.get("&query=${Uri.encodeComponent(createUpcomingMovieQuery(count))}");
|
Response response = await queryApi.get(
|
||||||
|
"&query=${Uri.encodeComponent(createUpcomingMovieQuery(startDate, count))}");
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"The Wikidata request for upcoming movies failed with status ${response.statusCode} ${response.reasonPhrase}");
|
"The Wikidata request for upcoming movies failed with status ${response.statusCode} ${response.reasonPhrase}");
|
||||||
|
@ -72,6 +91,7 @@ class WikidataMovieApi implements MovieApi {
|
||||||
movies.add(WikidataMovieData(
|
movies.add(WikidataMovieData(
|
||||||
entry["movieLabel"]["value"] as String,
|
entry["movieLabel"]["value"] as String,
|
||||||
DateTime.parse(entry["minReleaseDate"]["value"] as String),
|
DateTime.parse(entry["minReleaseDate"]["value"] as String),
|
||||||
|
precisionFromWikidata(int.parse(entry["datePrecision"]["value"])),
|
||||||
int.parse(identifier.substring(1))));
|
int.parse(identifier.substring(1))));
|
||||||
}
|
}
|
||||||
return movies;
|
return movies;
|
||||||
|
|
|
@ -26,9 +26,13 @@ class Review {
|
||||||
typedef ReleaseDateInCountry = (String country, DateTime date);
|
typedef ReleaseDateInCountry = (String country, DateTime date);
|
||||||
typedef TitleInCountry = (String country, String title);
|
typedef TitleInCountry = (String country, String title);
|
||||||
|
|
||||||
|
enum DatePrecision { decade, year, month, day, hour, minute }
|
||||||
|
|
||||||
class MovieData extends ChangeNotifier {
|
class MovieData extends ChangeNotifier {
|
||||||
String _title;
|
String _title;
|
||||||
DateTime _releaseDate;
|
DateTime _releaseDate;
|
||||||
|
DatePrecision _releaseDatePrecision;
|
||||||
|
|
||||||
bool _hasDetails = false;
|
bool _hasDetails = false;
|
||||||
List<ReleaseDateInCountry>? _releaseDates;
|
List<ReleaseDateInCountry>? _releaseDates;
|
||||||
List<String>? _genres;
|
List<String>? _genres;
|
||||||
|
@ -43,6 +47,10 @@ class MovieData extends ChangeNotifier {
|
||||||
return _releaseDate;
|
return _releaseDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatePrecision get releaseDatePrecision {
|
||||||
|
return _releaseDatePrecision;
|
||||||
|
}
|
||||||
|
|
||||||
List<ReleaseDateInCountry>? get releaseDates {
|
List<ReleaseDateInCountry>? get releaseDates {
|
||||||
return _releaseDates;
|
return _releaseDates;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +73,9 @@ class MovieData extends ChangeNotifier {
|
||||||
|
|
||||||
void updateWithNew(MovieData movie) {
|
void updateWithNew(MovieData movie) {
|
||||||
setDetails(
|
setDetails(
|
||||||
|
title: movie.title,
|
||||||
|
releaseDate: movie.releaseDate,
|
||||||
|
releaseDatePrecision: movie.releaseDatePrecision,
|
||||||
releaseDates: movie.releaseDates,
|
releaseDates: movie.releaseDates,
|
||||||
genres: movie.genres,
|
genres: movie.genres,
|
||||||
titles: movie.titles,
|
titles: movie.titles,
|
||||||
|
@ -72,10 +83,22 @@ class MovieData extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDetails(
|
void setDetails(
|
||||||
{List<ReleaseDateInCountry>? releaseDates,
|
{String? title,
|
||||||
|
DateTime? releaseDate,
|
||||||
|
DatePrecision? releaseDatePrecision,
|
||||||
|
List<ReleaseDateInCountry>? releaseDates,
|
||||||
List<String>? genres,
|
List<String>? genres,
|
||||||
List<TitleInCountry>? titles,
|
List<TitleInCountry>? titles,
|
||||||
List<Review>? reviews}) {
|
List<Review>? reviews}) {
|
||||||
|
if (title != null) {
|
||||||
|
_title = title;
|
||||||
|
}
|
||||||
|
if (releaseDate != null) {
|
||||||
|
_releaseDate = releaseDate;
|
||||||
|
}
|
||||||
|
if (releaseDatePrecision != null) {
|
||||||
|
_releaseDatePrecision = releaseDatePrecision;
|
||||||
|
}
|
||||||
if (releaseDates != null) {
|
if (releaseDates != null) {
|
||||||
_releaseDates = releaseDates;
|
_releaseDates = releaseDates;
|
||||||
}
|
}
|
||||||
|
@ -104,6 +127,7 @@ class MovieData extends ChangeNotifier {
|
||||||
return {
|
return {
|
||||||
"title": title,
|
"title": title,
|
||||||
"releaseDate": releaseDate.toIso8601String(),
|
"releaseDate": releaseDate.toIso8601String(),
|
||||||
|
"releaseDatePrecision": _releaseDatePrecision.name,
|
||||||
"releaseDates": releaseDatesByCountry,
|
"releaseDates": releaseDatesByCountry,
|
||||||
"genres": genres,
|
"genres": genres,
|
||||||
"titles": titlesByCountry,
|
"titles": titlesByCountry,
|
||||||
|
@ -115,11 +139,13 @@ class MovieData extends ChangeNotifier {
|
||||||
return title == other.title && releaseDate == other.releaseDate;
|
return title == other.title && releaseDate == other.releaseDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
MovieData(this._title, this._releaseDate);
|
MovieData(this._title, this._releaseDate, this._releaseDatePrecision);
|
||||||
|
|
||||||
MovieData.fromJsonEncodable(Map json)
|
MovieData.fromJsonEncodable(Map json)
|
||||||
: _title = json["title"],
|
: _title = json["title"],
|
||||||
_releaseDate = DateTime.parse(json["releaseDate"]) {
|
_releaseDate = DateTime.parse(json["releaseDate"]),
|
||||||
|
_releaseDatePrecision = DatePrecision.values.firstWhere(
|
||||||
|
(element) => element.name == json["releaseDatePrecision"]) {
|
||||||
setDetails(
|
setDetails(
|
||||||
genres: json["genres"],
|
genres: json["genres"],
|
||||||
releaseDates: json["releaseDates"] != null
|
releaseDates: json["releaseDates"] != null
|
||||||
|
|
|
@ -136,7 +136,8 @@ class MovieManager extends ChangeNotifier {
|
||||||
try {
|
try {
|
||||||
loading = true;
|
loading = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
List<MovieData> movies = await api.getUpcomingMovies();
|
List<MovieData> movies = await api
|
||||||
|
.getUpcomingMovies(DateTime.now().subtract(const Duration(days: 7)));
|
||||||
addMovies(movies);
|
addMovies(movies);
|
||||||
} finally {
|
} finally {
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
Loading…
Reference in New Issue