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