first commit
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../models/movie.dart';
|
||||
|
||||
class ApiService {
|
||||
static const String apiKey = '70101da29bbd7fafb66f0ed06dd88794';
|
||||
static const String accessToken = 'eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI3MDEwMWRhMjliYmQ3ZmFmYjY2ZjBlZDA2ZGQ4ODc5NCIsIm5iZiI6MTc0NzgxNDY5MS44NDA5OTk4LCJzdWIiOiI2ODJkODkyMzYyOTliNjFlNzM2NDk2ODkiLCJzY29wZXMiOlsiYXBpX3JlYWQiXSwidmVyc2lvbiI6MX0.nGl7SvvrI6FlcQ7uOGJzrejN-_s7G0kdvnVCzSGGwm8';
|
||||
static const String baseUrl = 'https://api.themoviedb.org/3';
|
||||
static const String imageBaseUrl = 'https://image.tmdb.org/t/p/w500';
|
||||
|
||||
static Future<List<Movie>> getPopularMovies() async {
|
||||
try {
|
||||
final response = await http.get(
|
||||
Uri.parse('$baseUrl/movie/popular?api_key=$apiKey'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $accessToken',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
final List<dynamic> movies = data['results'];
|
||||
|
||||
return movies.map((movie) => Movie.fromJson(movie)).toList();
|
||||
} else {
|
||||
throw Exception('Échec du chargement des films: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Erreur lors de la récupération des films: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<Movie>> getTopRatedMovies() async {
|
||||
try {
|
||||
final response = await http.get(
|
||||
Uri.parse('$baseUrl/movie/top_rated?api_key=$apiKey'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $accessToken',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
final List<dynamic> movies = data['results'];
|
||||
|
||||
return movies.map((movie) => Movie.fromJson(movie)).toList();
|
||||
} else {
|
||||
throw Exception('Échec du chargement des films: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Erreur lors de la récupération des films: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<Movie>> getNowPlayingMovies() async {
|
||||
try {
|
||||
final response = await http.get(
|
||||
Uri.parse('$baseUrl/movie/now_playing?api_key=$apiKey'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $accessToken',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
final List<dynamic> movies = data['results'];
|
||||
|
||||
return movies.map((movie) => Movie.fromJson(movie)).toList();
|
||||
} else {
|
||||
throw Exception('Échec du chargement des films: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Erreur lors de la récupération des films: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<Movie>> getUpcomingMovies() async {
|
||||
try {
|
||||
final response = await http.get(
|
||||
Uri.parse('$baseUrl/movie/upcoming?api_key=$apiKey'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $accessToken',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
final List<dynamic> movies = data['results'];
|
||||
|
||||
return movies.map((movie) => Movie.fromJson(movie)).toList();
|
||||
} else {
|
||||
throw Exception('Échec du chargement des films: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Erreur lors de la récupération des films: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
import 'package:postgres/postgres.dart';
|
||||
import '../models/movie.dart';
|
||||
import 'local_storage_service.dart';
|
||||
|
||||
class DatabaseService {
|
||||
static const String host = 'localhost';
|
||||
static const String database = 'flutterBDD';
|
||||
static const String username = 'postgres';
|
||||
static const String password = 'root';
|
||||
static const int port = 5432;
|
||||
|
||||
static Connection? _connection;
|
||||
static bool _useLocalStorage = false;
|
||||
|
||||
static Future<Connection> get connection async {
|
||||
if (_connection == null && !_useLocalStorage) {
|
||||
try {
|
||||
_connection = await Connection.open(
|
||||
Endpoint(
|
||||
host: host,
|
||||
port: port,
|
||||
database: database,
|
||||
username: username,
|
||||
password: password,
|
||||
),
|
||||
);
|
||||
await _createTables();
|
||||
} catch (e) {
|
||||
print('Erreur de connexion à PostgreSQL: $e');
|
||||
print('Utilisation du stockage local à la place...');
|
||||
_useLocalStorage = true;
|
||||
throw Exception('PostgreSQL non disponible, utilisation du stockage local');
|
||||
}
|
||||
}
|
||||
if (_useLocalStorage) {
|
||||
throw Exception('Utilisation du stockage local');
|
||||
}
|
||||
return _connection!;
|
||||
}
|
||||
|
||||
static Future<void> _createTables() async {
|
||||
final conn = await connection;
|
||||
|
||||
await conn.execute('''
|
||||
CREATE TABLE IF NOT EXISTS favorites (
|
||||
id SERIAL PRIMARY KEY,
|
||||
movie_id INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
image_url TEXT,
|
||||
category TEXT,
|
||||
director TEXT,
|
||||
release_date TEXT,
|
||||
rating REAL,
|
||||
original_title TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''');
|
||||
}
|
||||
|
||||
static Future<bool> addToFavorites(Movie movie) async {
|
||||
try {
|
||||
final conn = await connection;
|
||||
|
||||
final existing = await conn.execute(
|
||||
Sql.named('SELECT id FROM favorites WHERE movie_id = @movieId'),
|
||||
parameters: {'movieId': movie.id},
|
||||
);
|
||||
|
||||
if (existing.isNotEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await conn.execute(
|
||||
Sql.named('''
|
||||
INSERT INTO favorites (
|
||||
movie_id, title, description, image_url, category,
|
||||
director, release_date, rating, original_title
|
||||
) VALUES (
|
||||
@movieId, @title, @description, @imageUrl, @category,
|
||||
@director, @releaseDate, @rating, @originalTitle
|
||||
)
|
||||
'''),
|
||||
parameters: {
|
||||
'movieId': movie.id,
|
||||
'title': movie.title,
|
||||
'description': movie.description,
|
||||
'imageUrl': movie.imageUrl,
|
||||
'category': movie.category,
|
||||
'director': movie.director,
|
||||
'releaseDate': movie.releaseDate,
|
||||
'rating': movie.rating,
|
||||
'originalTitle': movie.originalTitle,
|
||||
},
|
||||
);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Erreur PostgreSQL, utilisation du stockage local: $e');
|
||||
return await LocalStorageService.addToFavorites(movie);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> removeFromFavorites(int movieId) async {
|
||||
try {
|
||||
final conn = await connection;
|
||||
|
||||
final result = await conn.execute(
|
||||
Sql.named('DELETE FROM favorites WHERE movie_id = @movieId'),
|
||||
parameters: {'movieId': movieId},
|
||||
);
|
||||
|
||||
return result.length > 0;
|
||||
} catch (e) {
|
||||
print('Erreur PostgreSQL, utilisation du stockage local: $e');
|
||||
return await LocalStorageService.removeFromFavorites(movieId);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> isFavorite(int movieId) async {
|
||||
try {
|
||||
final conn = await connection;
|
||||
|
||||
final result = await conn.execute(
|
||||
Sql.named('SELECT id FROM favorites WHERE movie_id = @movieId'),
|
||||
parameters: {'movieId': movieId},
|
||||
);
|
||||
|
||||
return result.isNotEmpty;
|
||||
} catch (e) {
|
||||
print('Erreur PostgreSQL, utilisation du stockage local: $e');
|
||||
return await LocalStorageService.isFavorite(movieId);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<Movie>> getFavorites() async {
|
||||
try {
|
||||
final conn = await connection;
|
||||
|
||||
final results = await conn.execute(
|
||||
Sql('SELECT * FROM favorites ORDER BY created_at DESC'),
|
||||
);
|
||||
|
||||
return results.map((row) => Movie(
|
||||
id: row[1] as int,
|
||||
title: row[2] as String,
|
||||
description: row[3] as String,
|
||||
imageUrl: row[4] as String,
|
||||
category: row[5] as String,
|
||||
director: row[6] as String,
|
||||
releaseDate: row[7] as String,
|
||||
rating: (row[8] as double?) ?? 0.0,
|
||||
originalTitle: row[9] as String,
|
||||
isFeatured: false,
|
||||
)).toList();
|
||||
} catch (e) {
|
||||
print('Erreur PostgreSQL, utilisation du stockage local: $e');
|
||||
return await LocalStorageService.getFavorites();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> close() async {
|
||||
if (_connection != null) {
|
||||
await _connection!.close();
|
||||
_connection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import 'dart:convert';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../models/movie.dart';
|
||||
|
||||
class LocalStorageService {
|
||||
static const String _favoritesKey = 'favorite_movies';
|
||||
|
||||
static Future<bool> addToFavorites(Movie movie) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final favoritesJson = prefs.getStringList(_favoritesKey) ?? [];
|
||||
|
||||
final existing = favoritesJson.any((json) {
|
||||
final movieData = jsonDecode(json);
|
||||
return movieData['id'] == movie.id;
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final movieJson = jsonEncode({
|
||||
'id': movie.id,
|
||||
'title': movie.title,
|
||||
'description': movie.description,
|
||||
'imageUrl': movie.imageUrl,
|
||||
'category': movie.category,
|
||||
'director': movie.director,
|
||||
'releaseDate': movie.releaseDate,
|
||||
'rating': movie.rating,
|
||||
'originalTitle': movie.originalTitle,
|
||||
'addedAt': DateTime.now().toIso8601String(),
|
||||
});
|
||||
|
||||
favoritesJson.add(movieJson);
|
||||
await prefs.setStringList(_favoritesKey, favoritesJson);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Erreur lors de l\'ajout aux favoris: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> removeFromFavorites(int movieId) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final favoritesJson = prefs.getStringList(_favoritesKey) ?? [];
|
||||
|
||||
final updatedFavorites = favoritesJson.where((json) {
|
||||
final movieData = jsonDecode(json);
|
||||
return movieData['id'] != movieId;
|
||||
}).toList();
|
||||
|
||||
if (updatedFavorites.length != favoritesJson.length) {
|
||||
await prefs.setStringList(_favoritesKey, updatedFavorites);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Erreur lors de la suppression des favoris: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> isFavorite(int movieId) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final favoritesJson = prefs.getStringList(_favoritesKey) ?? [];
|
||||
|
||||
return favoritesJson.any((json) {
|
||||
final movieData = jsonDecode(json);
|
||||
return movieData['id'] == movieId;
|
||||
});
|
||||
} catch (e) {
|
||||
print('Erreur lors de la vérification des favoris: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<Movie>> getFavorites() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final favoritesJson = prefs.getStringList(_favoritesKey) ?? [];
|
||||
|
||||
return favoritesJson.map((json) {
|
||||
final movieData = jsonDecode(json);
|
||||
return Movie(
|
||||
id: movieData['id'],
|
||||
title: movieData['title'],
|
||||
description: movieData['description'],
|
||||
imageUrl: movieData['imageUrl'],
|
||||
category: movieData['category'],
|
||||
director: movieData['director'],
|
||||
releaseDate: movieData['releaseDate'],
|
||||
rating: (movieData['rating'] ?? 0.0).toDouble(),
|
||||
originalTitle: movieData['originalTitle'] ?? '',
|
||||
isFeatured: false,
|
||||
);
|
||||
}).toList();
|
||||
} catch (e) {
|
||||
print('Erreur lors de la récupération des favoris: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user