From bf24af1ed9808dc918dc81f0383103b6c51600a6 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Wed, 25 Aug 2010 08:03:05 +0200 Subject: refactoring, mangalist, settings (current problem: refresh other list after changing the settings) --- AndroidManifest.xml | 5 +- res/drawable/ic_menu_close_clear_cancel.png | Bin 0 -> 5306 bytes res/drawable/ic_menu_preferences.png | Bin 0 -> 2144 bytes res/drawable/ic_menu_refresh.png | Bin 0 -> 2450 bytes res/menu/menu.xml | 7 + res/menu/settings.xml | 14 ++ res/values/arrays.xml | 9 + res/values/id.xml | 5 + .../animux/android/andmal/AnimeListActivity.java | 112 ----------- src/de/animux/android/andmal/ListActivity.java | 215 +++++++++++++++++++++ src/de/animux/android/andmal/Settings.java | 13 ++ src/de/animux/android/andmal/api/MalList.java | 79 ++++++++ .../animux/android/andmal/api/MalListParser.java | 40 ++++ src/de/animux/android/andmal/api/MalObject.java | 7 + .../animux/android/andmal/api/MalObjectStore.java | 5 + src/de/animux/android/andmal/api/MalState.java | 5 + src/de/animux/android/andmal/api/anime/Anime.java | 22 ++- .../animux/android/andmal/api/anime/AnimeList.java | 141 ++++++-------- .../android/andmal/api/anime/AnimeListParser.java | 45 +++++ src/de/animux/android/andmal/api/anime/State.java | 4 +- src/de/animux/android/andmal/api/manga/Manga.java | 209 ++++++++++++++++++++ .../animux/android/andmal/api/manga/MangaList.java | 86 +++++++++ .../android/andmal/api/manga/MangaListParser.java | 50 +++++ src/de/animux/android/andmal/api/manga/State.java | 38 ++++ 24 files changed, 907 insertions(+), 204 deletions(-) create mode 100644 res/drawable/ic_menu_close_clear_cancel.png create mode 100644 res/drawable/ic_menu_preferences.png create mode 100644 res/drawable/ic_menu_refresh.png create mode 100644 res/menu/menu.xml create mode 100644 res/menu/settings.xml create mode 100644 res/values/arrays.xml create mode 100644 res/values/id.xml delete mode 100644 src/de/animux/android/andmal/AnimeListActivity.java create mode 100644 src/de/animux/android/andmal/ListActivity.java create mode 100644 src/de/animux/android/andmal/Settings.java create mode 100644 src/de/animux/android/andmal/api/MalList.java create mode 100644 src/de/animux/android/andmal/api/MalListParser.java create mode 100644 src/de/animux/android/andmal/api/MalObject.java create mode 100644 src/de/animux/android/andmal/api/MalObjectStore.java create mode 100644 src/de/animux/android/andmal/api/MalState.java create mode 100644 src/de/animux/android/andmal/api/anime/AnimeListParser.java create mode 100644 src/de/animux/android/andmal/api/manga/Manga.java create mode 100644 src/de/animux/android/andmal/api/manga/MangaList.java create mode 100644 src/de/animux/android/andmal/api/manga/MangaListParser.java create mode 100644 src/de/animux/android/andmal/api/manga/State.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index a1db31e..0b92c22 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -4,14 +4,15 @@ android:versionCode="1" android:versionName="1.0"> - + - + + diff --git a/res/drawable/ic_menu_close_clear_cancel.png b/res/drawable/ic_menu_close_clear_cancel.png new file mode 100644 index 0000000..78222ea Binary files /dev/null and b/res/drawable/ic_menu_close_clear_cancel.png differ diff --git a/res/drawable/ic_menu_preferences.png b/res/drawable/ic_menu_preferences.png new file mode 100644 index 0000000..b8e7141 Binary files /dev/null and b/res/drawable/ic_menu_preferences.png differ diff --git a/res/drawable/ic_menu_refresh.png b/res/drawable/ic_menu_refresh.png new file mode 100644 index 0000000..77d70dd Binary files /dev/null and b/res/drawable/ic_menu_refresh.png differ diff --git a/res/menu/menu.xml b/res/menu/menu.xml new file mode 100644 index 0000000..5dd2311 --- /dev/null +++ b/res/menu/menu.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/res/menu/settings.xml b/res/menu/settings.xml new file mode 100644 index 0000000..8c646a7 --- /dev/null +++ b/res/menu/settings.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/res/values/arrays.xml b/res/values/arrays.xml new file mode 100644 index 0000000..d4e8db0 --- /dev/null +++ b/res/values/arrays.xml @@ -0,0 +1,9 @@ + +Anime +Manga + + +@raw/screen_anime +@raw/screen_manga + + diff --git a/res/values/id.xml b/res/values/id.xml new file mode 100644 index 0000000..065a6fb --- /dev/null +++ b/res/values/id.xml @@ -0,0 +1,5 @@ + + +0 +1 + diff --git a/src/de/animux/android/andmal/AnimeListActivity.java b/src/de/animux/android/andmal/AnimeListActivity.java deleted file mode 100644 index 566fa1d..0000000 --- a/src/de/animux/android/andmal/AnimeListActivity.java +++ /dev/null @@ -1,112 +0,0 @@ -package de.animux.android.andmal; - -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import de.animux.android.andmal.api.anime.Anime; -import de.animux.android.andmal.api.anime.AnimeList; -import de.animux.android.andmal.api.anime.State; -import de.animux.android.andmal.util.SeparatedListAdapter; - -import android.app.Activity; -import android.app.Dialog; -import android.app.ProgressDialog; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.widget.ListView; -import android.widget.SimpleAdapter; - -public class AnimeListActivity extends Activity { - - public final static String ITEM_TITLE = "title"; - public final static String ITEM_CAPTION = "caption"; - - public final static int INITIAL_SYNC = 0; - - private AnimeList animeList; - - private UpdateUIHandler updateUIHandler = new UpdateUIHandler(); - - public Map createItem(String title, String caption) { - Map item = new HashMap(); - item.put(ITEM_TITLE, title); - item.put(ITEM_CAPTION, caption); - return item; - } - - private class UpdateUIHandler extends Handler { - @Override - public void handleMessage(Message msg) { - SeparatedListAdapter adapter = new SeparatedListAdapter( - AnimeListActivity.this); - Map> animes = animeList - .getAnimes(); - - for (State s : State.values()) - addAnimes(adapter, animes.get(s), s.toString()); - - ListView list = new ListView(AnimeListActivity.this); - list.setAdapter(adapter); - - dismissDialog(INITIAL_SYNC); - - AnimeListActivity.this.setContentView(list); - } - } - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - showDialog(INITIAL_SYNC); - - new Thread() { - public void run() { - try { - animeList = new AnimeList("AlexanderS"); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - updateUIHandler.sendEmptyMessage(0); - } - }.start(); - } - - private void addAnimes(SeparatedListAdapter adapter, - Collection animes, String sectionName) { - if (animes != null && animes.size() > 0) { - java.util.List> listSection = new LinkedList>(); - - for (Anime a : animes) { - listSection.add(createItem(a.getTitle(), a.getWatchedEpisodes() - + "/" + a.getEpisodes())); - } - - adapter.addSection(sectionName, new SimpleAdapter(this, - listSection, R.layout.list_item, new String[] { ITEM_TITLE, - ITEM_CAPTION }, new int[] { R.id.list_item_title, - R.id.list_item_other })); - } - } - - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case INITIAL_SYNC: - ProgressDialog dialog = ProgressDialog.show(this, "", - "Loading list. Please wait...", true); - dialog.show(); - return dialog; - default: - return super.onCreateDialog(id); - } - } - -} \ No newline at end of file diff --git a/src/de/animux/android/andmal/ListActivity.java b/src/de/animux/android/andmal/ListActivity.java new file mode 100644 index 0000000..ec21f41 --- /dev/null +++ b/src/de/animux/android/andmal/ListActivity.java @@ -0,0 +1,215 @@ +package de.animux.android.andmal; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import de.animux.android.andmal.api.MalList; +import de.animux.android.andmal.api.MalObject; +import de.animux.android.andmal.api.MalState; +import de.animux.android.andmal.api.anime.AnimeList; +import de.animux.android.andmal.api.manga.MangaList; +import de.animux.android.andmal.util.SeparatedListAdapter; + +import android.app.Activity; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.preference.PreferenceManager; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.ListView; +import android.widget.SimpleAdapter; + +public class ListActivity extends Activity { + + public final static String ITEM_TITLE = "title"; + public final static String ITEM_CAPTION = "caption"; + + public final static int SYNCING = 0; + + private MalList currentList; + + private UpdateUIHandler updateUIHandler = new UpdateUIHandler(); + private SharedPreferences prefs; + + public ListActivity() { + super(); + this.currentList = null; + this.prefs = null; + } + + public Map createItem(String title, String caption) { + Map item = new HashMap(); + item.put(ITEM_TITLE, title); + item.put(ITEM_CAPTION, caption); + return item; + } + + private class UpdateUIHandler extends Handler { + @Override + public void handleMessage(Message msg) { + SeparatedListAdapter adapter = new SeparatedListAdapter( + ListActivity.this); + + if (currentList != null) { + Map> malObjects = currentList + .getObjects(); + + if (malObjects != null) { + for (MalState s : malObjects.keySet()) + addMalObjects(adapter, malObjects.get(s), s.toString()); + + ListView list = new ListView(ListActivity.this); + list.setAdapter(adapter); + ListActivity.this.setContentView(list); + } + } + + dismissDialog(SYNCING); + } + } + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + PreferenceManager.setDefaultValues(this, R.menu.settings, false); + + prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + + if (prefs.getString("MAL_USERNAME", null) == null) { + startActivity(new Intent(this, Settings.class)); + return; + } + + currentList = new AnimeList(prefs.getString("MAL_USERNAME", null), + prefs.getString("MAL_PASSWORD", null)); + refreshDisplay(); + } + + @Override + protected void onResume() { + super.onResume(); + + if (currentList == null) { + if (prefs.getString("USERNAME", null) != null) { + currentList = new AnimeList(prefs.getString("MAL_USERNAME", + null), prefs.getString("MAL_PASSWORD", null)); + } + } else { + currentList.setUsername(prefs.getString("MAL_USERNAME", null)); + currentList.setPassword(prefs.getString("MAL_PASSWORD", null)); + } + + refreshDisplay(); + } + + private synchronized void refreshDisplay() { + if (currentList != null) { + if (currentList.needsRefresh()) { + showDialog(SYNCING); + + new Thread() { + public void run() { + try { + currentList.refresh(); + } catch (Exception e) { + e.printStackTrace(); + } + + updateUIHandler.sendEmptyMessage(0); + } + }.start(); + } else { + updateUIHandler.sendEmptyMessage(0); + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu, menu); + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuItem item; + + item = menu.findItem(R.id.menu_switch_anime); + item.setVisible(currentList instanceof MangaList); + + item = menu.findItem(R.id.menu_switch_manga); + item.setVisible(currentList instanceof AnimeList); + + return true; + } + + private void addMalObjects(SeparatedListAdapter adapter, + Collection malObjects, String sectionName) { + if (malObjects != null && malObjects.size() > 0) { + java.util.List> listSection = new LinkedList>(); + + for (MalObject m : malObjects) { + listSection.add(createItem(m.getTitle(), m.getProgress())); + } + + adapter.addSection(sectionName, new SimpleAdapter(this, + listSection, R.layout.list_item, new String[] { ITEM_TITLE, + ITEM_CAPTION }, new int[] { R.id.list_item_title, + R.id.list_item_other })); + } + } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case SYNCING: + ProgressDialog dialog = ProgressDialog.show(this, "", + "Loading list. Please wait...", true); + dialog.show(); + return dialog; + default: + return super.onCreateDialog(id); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_settings: + startActivity(new Intent(this, Settings.class)); + return true; + case R.id.menu_switch_manga: + currentList = new MangaList(); + break; + case R.id.menu_switch_anime: + currentList = new AnimeList(); + break; + case R.id.menu_refresh: + if (currentList != null) + currentList.setNeedsRefresh(true); + + break; + case R.id.menu_exit: + System.exit(0); + break; + default: + return false; + } + + refreshDisplay(); + return true; + } + +} \ No newline at end of file diff --git a/src/de/animux/android/andmal/Settings.java b/src/de/animux/android/andmal/Settings.java new file mode 100644 index 0000000..b13e083 --- /dev/null +++ b/src/de/animux/android/andmal/Settings.java @@ -0,0 +1,13 @@ +package de.animux.android.andmal; + +import android.os.Bundle; +import android.preference.PreferenceActivity; + +public class Settings extends PreferenceActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.menu.settings); + } +} diff --git a/src/de/animux/android/andmal/api/MalList.java b/src/de/animux/android/andmal/api/MalList.java new file mode 100644 index 0000000..79a37b6 --- /dev/null +++ b/src/de/animux/android/andmal/api/MalList.java @@ -0,0 +1,79 @@ +package de.animux.android.andmal.api; + +import java.util.Collection; +import java.util.Map; + +public abstract class MalList { + + private String username; + + private String password; + + protected boolean needsRefresh; + + private static MalList cache; + + public MalList(String username, String password) { + this.username = username; + this.password = password; + cache = this; + setNeedsRefresh(true); + } + + public MalList() { + if (cache != null) { + this.username = cache.getUsername(); + this.password = cache.getPassword(); + setNeedsRefresh(false); + } + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + if (this.username != null && this.username.equals(username)) + return; + + this.username = username; + this.needsRefresh = true; + + if (cache != this + && (cache.getUsername() == null || !cache.getUsername().equals( + username))) { + cache.setUsername(username); + } + } + + protected String getPassword() { + return this.password; + } + + public void setPassword(String password) { + if (this.password != null && this.password.equals(password)) + return; + + this.password = password; + this.needsRefresh = true; + + if (cache != this + && (cache.getPassword() == null || !cache.getPassword().equals( + password))) { + cache.setPassword(password); + } + } + + public void setNeedsRefresh(boolean needsRefresh) { + this.needsRefresh = needsRefresh; + } + + public boolean needsRefresh() { + return needsRefresh; + } + + abstract public void refresh(); + + abstract public Map> getObjects(); + +} \ No newline at end of file diff --git a/src/de/animux/android/andmal/api/MalListParser.java b/src/de/animux/android/andmal/api/MalListParser.java new file mode 100644 index 0000000..014b718 --- /dev/null +++ b/src/de/animux/android/andmal/api/MalListParser.java @@ -0,0 +1,40 @@ +package de.animux.android.andmal.api; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public abstract class MalListParser extends DefaultHandler { + private StringBuffer currentValue; + + protected MalObjectStore objectStore; + + public MalListParser(MalObjectStore objectStore) { + super(); + + this.objectStore = objectStore; + currentValue = new StringBuffer(); + } + + @Override + public void characters(char[] ch, int start, int length) + throws SAXException { + currentValue.append(new String(ch).substring(start, length - start) + .replaceAll("&", "&")); + } + + @Override + public void endElement(String uri, String localName, String qName) + throws SAXException { + addElement(localName, currentValue.toString()); + currentValue.setLength(0); + } + + @Override + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException { + currentValue.setLength(0); + } + + abstract public void addElement(String name, String value); +} diff --git a/src/de/animux/android/andmal/api/MalObject.java b/src/de/animux/android/andmal/api/MalObject.java new file mode 100644 index 0000000..9ccf279 --- /dev/null +++ b/src/de/animux/android/andmal/api/MalObject.java @@ -0,0 +1,7 @@ +package de.animux.android.andmal.api; + +public abstract class MalObject implements Comparable { + + public abstract String getTitle(); + public abstract String getProgress(); +} diff --git a/src/de/animux/android/andmal/api/MalObjectStore.java b/src/de/animux/android/andmal/api/MalObjectStore.java new file mode 100644 index 0000000..937ac2e --- /dev/null +++ b/src/de/animux/android/andmal/api/MalObjectStore.java @@ -0,0 +1,5 @@ +package de.animux.android.andmal.api; + +public interface MalObjectStore { + public void add(T object); +} diff --git a/src/de/animux/android/andmal/api/MalState.java b/src/de/animux/android/andmal/api/MalState.java new file mode 100644 index 0000000..ed76bc6 --- /dev/null +++ b/src/de/animux/android/andmal/api/MalState.java @@ -0,0 +1,5 @@ +package de.animux.android.andmal.api; + +public interface MalState { + public String toString(); +} diff --git a/src/de/animux/android/andmal/api/anime/Anime.java b/src/de/animux/android/andmal/api/anime/Anime.java index d4f542f..dc4b34e 100644 --- a/src/de/animux/android/andmal/api/anime/Anime.java +++ b/src/de/animux/android/andmal/api/anime/Anime.java @@ -1,6 +1,8 @@ package de.animux.android.andmal.api.anime; -public class Anime implements Comparable { +import de.animux.android.andmal.api.MalObject; + +public class Anime extends MalObject { private int id; private String title; @@ -180,18 +182,28 @@ public class Anime implements Comparable { } @Override - public int compareTo(Anime arg0) { - int compareTitle = arg0.getTitle().compareTo(getTitle()); + public int compareTo(MalObject arg0) { + if ( !(arg0 instanceof Anime)) { + throw new IllegalArgumentException(); + } + + Anime a = (Anime)arg0; + int compareTitle = a.getTitle().compareTo(getTitle()); if (compareTitle != 0) { return compareTitle; } else { - if (arg0.getId() != getId()) { - return getId() - arg0.getId(); + if (a.getId() != getId()) { + return getId() - a.getId(); } } return 0; } + @Override + public String getProgress() { + return getWatchedEpisodes() + "/" + getEpisodes(); + } + } diff --git a/src/de/animux/android/andmal/api/anime/AnimeList.java b/src/de/animux/android/andmal/api/anime/AnimeList.java index 78a1e09..0fbb4ea 100644 --- a/src/de/animux/android/andmal/api/anime/AnimeList.java +++ b/src/de/animux/android/andmal/api/anime/AnimeList.java @@ -1,117 +1,90 @@ package de.animux.android.andmal.api.anime; -import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; -import javax.xml.parsers.FactoryConfigurationError; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - +import de.animux.android.andmal.api.MalList; +import de.animux.android.andmal.api.MalObject; +import de.animux.android.andmal.api.MalObjectStore; +import de.animux.android.andmal.api.MalState; import de.animux.android.andmal.api.anime.State; import de.animux.android.andmal.util.SortedLinkedList; -public class AnimeList extends DefaultHandler { +public class AnimeList extends MalList implements MalObjectStore { - private Anime currentAnime; - private StringBuffer currentValue; + // cache last instance of this class to restore if a new one is created with + // the same username and password + private static AnimeList cache; - private HashMap> animes; + private Map> animes; - public AnimeList(String user) throws IOException, - ParserConfigurationException, SAXException, - FactoryConfigurationError { - currentAnime = null; - currentValue = new StringBuffer(); - - animes = new HashMap>(); - animes.put(State.WATCHING, new SortedLinkedList()); - animes.put(State.COMPLETED, new SortedLinkedList()); - animes.put(State.ONHOLD, new SortedLinkedList()); - animes.put(State.DROPPED, new SortedLinkedList()); - animes.put(State.PLANTOWATCH, new SortedLinkedList()); - - URL url = new URL("http://myanimelist.net/malappinfo.php?status=all&type=anime&u=" + user); - InputStream stream = url.openStream(); - - SAXParser sax = SAXParserFactory.newInstance().newSAXParser(); - sax.parse(stream, this); - } + public AnimeList(String username, String password) { + super(username, password); - public Anime getCurrentAnime() { - return currentAnime; + if (((cache != null) && cache.getUsername().equals(username)) + && cache.getPassword().equals(username)) { + animes = cache.getObjects(); + } else { + cache = this; + needsRefresh = true; + } } - public StringBuffer getCurrentValue() { - return currentValue; - } + public AnimeList() { + super(); - public Map> getAnimes() { - return animes; + if (cache != null && cache.getUsername() != null + && cache.getUsername().equals(this.getUsername())) { + animes = cache.getObjects(); + } + else { + cache = this; + needsRefresh = true; + } } @Override - public void characters(char[] ch, int start, int length) - throws SAXException { - currentValue.append(new String(ch).substring(start, length - start) - .replaceAll("&", "&")); + public void refresh() { + if (this.getUsername() == null) + return; + + animes = new HashMap>(); + animes.put(State.WATCHING, new SortedLinkedList()); + animes.put(State.COMPLETED, new SortedLinkedList()); + animes.put(State.ONHOLD, new SortedLinkedList()); + animes.put(State.DROPPED, new SortedLinkedList()); + animes.put(State.PLANTOWATCH, new SortedLinkedList()); + + try { + URL url = new URL( + "http://myanimelist.net/malappinfo.php?status=all&type=anime&u=" + + this.getUsername()); + InputStream stream = url.openStream(); + + SAXParser sax = SAXParserFactory.newInstance().newSAXParser(); + sax.parse(stream, new AnimeListParser(this)); + needsRefresh = false; + } catch (Exception e) { + e.printStackTrace(); + } } @Override - public void endElement(String uri, String localName, String qName) - throws SAXException { - - if (localName.equals("anime")) { - if (animes.containsKey(State.valueOf(currentAnime.getMyStatus()))) { - animes.get(State.valueOf(currentAnime.getMyStatus())).add(currentAnime); - } - - } else if (localName.equals("series_animedb_id")) { - currentAnime.setId(Integer.valueOf(currentValue.toString())); - } else if (localName.equals("series_title")) { - currentAnime.setTitle(currentValue.toString()); - } else if (localName.equals("series_synonyms")) { - currentAnime.setSynonyms(currentValue.toString()); - } else if (localName.equals("series_type")) { - currentAnime.setType(Integer.valueOf(currentValue.toString())); - } else if (localName.equals("series_episodes")) { - currentAnime.setEpisodes(Integer.valueOf(currentValue.toString())); - } else if (localName.equals("series_status")) { - currentAnime.setStatus(Integer.valueOf(currentValue.toString())); - } else if (localName.equals("series_start")) { - currentAnime.setStart(currentValue.toString()); - } else if (localName.equals("series_end")) { - currentAnime.setEnd(currentValue.toString()); - } else if (localName.equals("series_image")) { - currentAnime.setImage(currentValue.toString()); - } else if (localName.equals("my_id")) { - currentAnime.setMyId(Integer.valueOf(currentValue.toString())); - } else if (localName.equals("my_watched_episodes")) { - currentAnime.setWatchedEpisodes(Integer.valueOf(currentValue - .toString())); - } else if (localName.equals("my_status")) { - currentAnime.setMyStatus(Integer.valueOf(currentValue.toString())); + public void add(Anime object) { + if (animes.containsKey(State.valueOf(object.getMyStatus()))) { + animes.get(State.valueOf(object.getMyStatus())).add(object); } - - currentValue.setLength(0); } @Override - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { - - currentValue.setLength(0); - if (localName.equals("anime")) { - currentAnime = new Anime(); - } + public Map> getObjects() { + return animes; } } diff --git a/src/de/animux/android/andmal/api/anime/AnimeListParser.java b/src/de/animux/android/andmal/api/anime/AnimeListParser.java new file mode 100644 index 0000000..e7545dd --- /dev/null +++ b/src/de/animux/android/andmal/api/anime/AnimeListParser.java @@ -0,0 +1,45 @@ +package de.animux.android.andmal.api.anime; + +import de.animux.android.andmal.api.MalListParser; +import de.animux.android.andmal.api.MalObjectStore; + +public class AnimeListParser extends MalListParser { + + private Anime currentAnime; + + public AnimeListParser(MalObjectStore objectStore) { + super(objectStore); + currentAnime = new Anime(); + } + + public void addElement(String name, String value) { + if (name.equals("anime")) { + objectStore.add(currentAnime); + currentAnime = new Anime(); + } else if (name.equals("series_animedb_id")) { + currentAnime.setId(Integer.valueOf(value)); + } else if (name.equals("series_title")) { + currentAnime.setTitle(value); + } else if (name.equals("series_synonyms")) { + currentAnime.setSynonyms(value); + } else if (name.equals("series_type")) { + currentAnime.setType(Integer.valueOf(value)); + } else if (name.equals("series_episodes")) { + currentAnime.setEpisodes(Integer.valueOf(value)); + } else if (name.equals("series_status")) { + currentAnime.setStatus(Integer.valueOf(value)); + } else if (name.equals("series_start")) { + currentAnime.setStart(value); + } else if (name.equals("series_end")) { + currentAnime.setEnd(value); + } else if (name.equals("series_image")) { + currentAnime.setImage(value); + } else if (name.equals("my_id")) { + currentAnime.setMyId(Integer.valueOf(value)); + } else if (name.equals("my_watched_episodes")) { + currentAnime.setWatchedEpisodes(Integer.valueOf(value)); + } else if (name.equals("my_status")) { + currentAnime.setMyStatus(Integer.valueOf(value)); + } + } +} diff --git a/src/de/animux/android/andmal/api/anime/State.java b/src/de/animux/android/andmal/api/anime/State.java index 639b761..9ba4769 100644 --- a/src/de/animux/android/andmal/api/anime/State.java +++ b/src/de/animux/android/andmal/api/anime/State.java @@ -1,6 +1,8 @@ package de.animux.android.andmal.api.anime; -public enum State { +import de.animux.android.andmal.api.MalState; + +public enum State implements MalState { WATCHING (1, "Watching"), COMPLETED (2, "Completed"), ONHOLD (3, "On Hold"), diff --git a/src/de/animux/android/andmal/api/manga/Manga.java b/src/de/animux/android/andmal/api/manga/Manga.java new file mode 100644 index 0000000..25670df --- /dev/null +++ b/src/de/animux/android/andmal/api/manga/Manga.java @@ -0,0 +1,209 @@ +package de.animux.android.andmal.api.manga; + +import de.animux.android.andmal.api.MalObject; + +public class Manga extends MalObject { + + private int id; + private String title; + private String synonyms; + private int type; + private int chapters; + private int volumes; + private int status; + private String start; + private String end; + private String image; + + private int personalId; + private int personalReadChapters; + private int personalReadVolumes; + private String personalStart; + private String personalEnd; + private int personalScore; + private int personalStatus; + private int personalRereading; + private int personalRereadingChapters; + private int personalLastUpdated; + private String personalTags; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getSynonyms() { + return synonyms; + } + + public void setSynonyms(String synonyms) { + this.synonyms = synonyms; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public int getChapters() { + return chapters; + } + + public void setChapters(int chapters) { + this.chapters = chapters; + } + + public int getVolumes() { + return volumes; + } + + public void setVolumes(int volumes) { + this.volumes = volumes; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getStart() { + return start; + } + + public void setStart(String start) { + this.start = start; + } + + public String getEnd() { + return end; + } + + public void setEnd(String end) { + this.end = end; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public int getPersonalId() { + return personalId; + } + + public void setPersonalId(int personalId) { + this.personalId = personalId; + } + + public int getPersonalReadChapters() { + return personalReadChapters; + } + + public void setPersonalReadChapters(int personalReadChapters) { + this.personalReadChapters = personalReadChapters; + } + + public int getPersonalReadVolumes() { + return personalReadVolumes; + } + + public void setPersonalReadVolumes(int personalReadVolumes) { + this.personalReadVolumes = personalReadVolumes; + } + + public String getPersonalStart() { + return personalStart; + } + + public void setPersonalStart(String personalStart) { + this.personalStart = personalStart; + } + + public String getPersonalEnd() { + return personalEnd; + } + + public void setPersonalEnd(String personalEnd) { + this.personalEnd = personalEnd; + } + + public int getPersonalScore() { + return personalScore; + } + + public void setPersonalScore(int personalScore) { + this.personalScore = personalScore; + } + + public int getPersonalStatus() { + return personalStatus; + } + + public void setPersonalStatus(int personalStatus) { + this.personalStatus = personalStatus; + } + + public int getPersonalRereading() { + return personalRereading; + } + + public void setPersonalRereading(int personalRereading) { + this.personalRereading = personalRereading; + } + + public int getPersonalRereadingChapters() { + return personalRereadingChapters; + } + + public void setPersonalRereadingChapters(int personalRereadingChapters) { + this.personalRereadingChapters = personalRereadingChapters; + } + + public int getPersonalLastUpdated() { + return personalLastUpdated; + } + + public void setPersonalLastUpdated(int personalLastUpdated) { + this.personalLastUpdated = personalLastUpdated; + } + + public String getPersonalTags() { + return personalTags; + } + + public void setPersonalTags(String personalTags) { + this.personalTags = personalTags; + } + + @Override + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public int compareTo(MalObject arg0) { + return 0; + } + + @Override + public String getProgress() { + return getPersonalReadChapters() + "/" + getChapters() + " (" + + getPersonalReadVolumes() + "/" + getVolumes() + ")"; + } +} diff --git a/src/de/animux/android/andmal/api/manga/MangaList.java b/src/de/animux/android/andmal/api/manga/MangaList.java new file mode 100644 index 0000000..00a89e4 --- /dev/null +++ b/src/de/animux/android/andmal/api/manga/MangaList.java @@ -0,0 +1,86 @@ +package de.animux.android.andmal.api.manga; + +import java.io.InputStream; +import java.net.URL; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import de.animux.android.andmal.api.MalList; +import de.animux.android.andmal.api.MalObject; +import de.animux.android.andmal.api.MalObjectStore; +import de.animux.android.andmal.api.MalState; +import de.animux.android.andmal.util.SortedLinkedList; + +public class MangaList extends MalList implements MalObjectStore { + + // cache last instance of this class to restore if a new one is created with + // the same username and password + private static MangaList cache; + private Map> mangas; + + public MangaList(String username, String password) { + super(username, password); + + if (((cache != null) && cache.getUsername().equals(username)) + && cache.getPassword().equals(username)) { + mangas = cache.getObjects(); + } else { + cache = this; + needsRefresh = true; + } + } + + public MangaList() { + super(); + + if (cache != null && cache.getUsername() != null + && cache.getUsername().equals(this.getUsername())) { + mangas = cache.getObjects(); + } else { + cache = this; + needsRefresh = true; + } + } + + @Override + public void refresh() { + if (this.getUsername() == null) + return; + + mangas = new HashMap>(); + mangas.put(State.READING, new SortedLinkedList()); + mangas.put(State.COMPLETED, new SortedLinkedList()); + mangas.put(State.ONHOLD, new SortedLinkedList()); + mangas.put(State.DROPPED, new SortedLinkedList()); + mangas.put(State.PLANTOREAD, new SortedLinkedList()); + + try { + URL url = new URL( + "http://myanimelist.net/malappinfo.php?status=all&type=manga&u=" + + this.getUsername()); + InputStream stream = url.openStream(); + + SAXParser sax = SAXParserFactory.newInstance().newSAXParser(); + sax.parse(stream, new MangaListParser(this)); + needsRefresh = false; + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void add(Manga object) { + if (mangas.containsKey(State.valueOf(object.getPersonalStatus()))) { + mangas.get(State.valueOf(object.getPersonalStatus())).add(object); + } + } + + @Override + public Map> getObjects() { + return mangas; + } +} diff --git a/src/de/animux/android/andmal/api/manga/MangaListParser.java b/src/de/animux/android/andmal/api/manga/MangaListParser.java new file mode 100644 index 0000000..7e0ec4b --- /dev/null +++ b/src/de/animux/android/andmal/api/manga/MangaListParser.java @@ -0,0 +1,50 @@ +package de.animux.android.andmal.api.manga; + +import de.animux.android.andmal.api.MalListParser; +import de.animux.android.andmal.api.MalObjectStore; + +public class MangaListParser extends MalListParser { + + private Manga currentManga; + + public MangaListParser(MalObjectStore objectStore) { + super(objectStore); + currentManga = new Manga(); + } + + @Override + public void addElement(String name, String value) { + if (name.equals("manga")) { + objectStore.add(currentManga); + currentManga = new Manga(); + } else if (name.equals("series_mangadb_id")) { + currentManga.setId(Integer.valueOf(value)); + } else if (name.equals("series_title")) { + currentManga.setTitle(value); + } else if (name.equals("series_synonyms")) { + currentManga.setSynonyms(value); + } else if (name.equals("series_type")) { + currentManga.setType(Integer.valueOf(value)); + } else if (name.equals("series_chapters")) { + currentManga.setChapters(Integer.valueOf(value)); + } else if (name.equals("volumes")) { + currentManga.setVolumes(Integer.valueOf(value)); + } else if (name.equals("series_status")) { + currentManga.setStatus(Integer.valueOf(value)); + } else if (name.equals("series_start")) { + currentManga.setStart(value); + } else if (name.equals("series_end")) { + currentManga.setEnd(value); + } else if (name.equals("series_image")) { + currentManga.setImage(value); + } else if (name.equals("my_id")) { + currentManga.setPersonalId(Integer.valueOf(value)); + } else if (name.equals("my_read_chapters")) { + currentManga.setPersonalReadChapters(Integer.valueOf(value)); + } else if (name.equals("my_read_volumes")) { + currentManga.setPersonalReadVolumes(Integer.valueOf(value)); + } else if (name.equals("my_status")) { + currentManga.setPersonalStatus(Integer.valueOf(value)); + } + } +} diff --git a/src/de/animux/android/andmal/api/manga/State.java b/src/de/animux/android/andmal/api/manga/State.java new file mode 100644 index 0000000..a39fe78 --- /dev/null +++ b/src/de/animux/android/andmal/api/manga/State.java @@ -0,0 +1,38 @@ +package de.animux.android.andmal.api.manga; + +import de.animux.android.andmal.api.MalState; + +public enum State implements MalState { + READING (1, "Reading"), + COMPLETED (2, "Completed"), + ONHOLD (3, "On Hold"), + DROPPED (4, "Dropped"), + PLANTOREAD (6, "Plan to read"); + + private final int id; + private final String name; + + State(int id, String name) { + this.id = id; + this.name = name; + } + + @Override + public String toString() { + return name; + } + + public int getId() { + return id; + } + + static State valueOf(int id) { + for (State s : State.values()) { + if (s.getId() == id) { + return s; + } + } + + return null; + } +} \ No newline at end of file -- cgit v1.2.3