package model; import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import Classes.ApiCall; import Classes.Category; import Classes.Event; import Classes.SortTypes; import Interfaces.Callback; import Interfaces.DelayedCallback; import Interfaces.EventObserver; import Interfaces.Observable; import javafx.util.Pair; public class NewsListModel implements Observable{ //instance du singleton private static NewsListModel instance; //Clé d'API private String APIKey; //catégorie choise parl'utilisateur private Category cat = Category.all; //est ce que le modele est en train de récupérer les sources private Boolean isRetreivingSources = false; //est ce que l'api a rencontré une erreur private Boolean apiError = false; //liste des sources private ArrayList sources; //liste des observers private HashMap observers; //liste des news finale private ArrayList news; //critère de tri private SortTypes sortType = SortTypes.relevancy; //critère de recherche de l'utilisateur private String query = ""; private NewsListModel(String APIKey) { this.APIKey = APIKey; //comme la liste des sources retournée par l'API est de 20 éléments max, pas la peine de déclarer une arraylist sans borne this.sources = new ArrayList(20); this.observers = new HashMap(); this.news = new ArrayList(); } public static NewsListModel getInstance() { if(NewsListModel.instance == null) { NewsListModel.instance = new NewsListModel("0e72f765c5c84313ae31a5a7e9e61735"); } return NewsListModel.instance; } public void setCategory(Category cat) { if(cat == Category.all) { this.sources = null; this.cat = cat; return; } //on vide la liste des sources this.sources = new ArrayList(20); this.cat = cat; //on créé l'URL d'appel de l'API String lang = LangModel.getInstance().getToLang().name(); String URL = "http://beta.newsapi.org/v2/sources?language="+lang; //on rajoute la catégorie if(cat != Category.all) { URL += "&category="+cat.name(); } //on rajoute la clé d'api URL += "&apiKey="+this.APIKey; //création de l'appel ApiCall api = new ApiCall(URL,"GET",new Callback() { @Override public void onSuccess(JSONObject response) { //on récupère toutes les sources (dans la limite de 20 sources) JSONArray arr = response.getJSONArray("sources"); for(int i = 0;i(); NewsListModel.this.notifyObservers(new Event("NewsModel","NewsQuerySuccess")); return; } //si la recherche de source s'est fini avec une erreur, pas la peine de chercher des articles if(this.apiError) { NewsListModel.this.notifyObservers(new Event("NewsModel","NewsQueryFailed")); this.apiError = false; return; } this.query = q; final String encodedQuery; try { encodedQuery = java.net.URLEncoder.encode(q,"UTF-8"); } catch (UnsupportedEncodingException e1) { this.notifyObservers(new Event("NewsModel","NewsQueryFailed")); return; } //on créer l'URL de l'appel String lang = LangModel.getInstance().getToLang().name(); String URL = "http://beta.newsapi.org/v2/everything?apiKey="+this.APIKey+"&language="+lang+"&q="+encodedQuery+"&sortBy="+this.sortType.name(); //on ajoute la liste des sources a l'URL de la requete if(NewsListModel.this.sources != null && NewsListModel.this.sources.size() != 0) { String sources = "&sources="; for(String s : NewsListModel.this.sources) { sources += s+","; } //on enlève la dernière virgule sources = sources.replaceAll(",$", ""); URL += sources; } ApiCall api = new ApiCall(URL,"GET",new Callback() { @Override public void onSuccess(JSONObject response) { //on parcours le JSON en créant les objets NewsModel corespondant NewsListModel.this.news = new ArrayList(); JSONArray arr = response.getJSONArray("articles"); for(int i = 0;i> call() { //si l'appel d'api précédent a échoué, on fait échouer l'appel actuel avec une URL vide if(NewsListModel.this.apiError) { //on reset la variable d'erreur pour que l'utilisateur puisse re-essayer plus tard NewsListModel.this.apiError = false; return new Pair>("",null); } String lang = LangModel.getInstance().getToLang().name(); String URL = "http://beta.newsapi.org/v2/everything?apiKey="+NewsListModel.this.APIKey+"&language="+lang +"&q="+encodedQuery+"&sortBy="+NewsListModel.this.sortType.name(); //on ajoute la liste des sources a l'URL de la requete if(NewsListModel.this.sources != null && NewsListModel.this.sources.size() != 0) { String sources = "&sources="; for(String s : NewsListModel.this.sources) { sources += s+","; } //on enlève la dernière virgule sources = sources.replaceAll(",$", ""); URL += sources; } return new Pair>(URL,null); } }); this.addObserver("newsApiCall",api); } api.send(); } public void setSortType(SortTypes t) { this.sortType = t; this.query(this.query); } public void notifyObservers(Event e) { for(Object key : this.observers.keySet().toArray()) { this.observers.get(key).handleEvent(e); } } public String getQuery() { return this.query; } public ArrayList getNews(){ return this.news; } @Override public void addObserver(String key, EventObserver o) { this.observers.put(key, o); } @Override public void removeObserver(String key) { this.observers.remove(key); } }