From da19f29cef74a4fda8329315d12dbc9ce28cc301 Mon Sep 17 00:00:00 2001 From: Lauren Siegert Date: Sun, 13 Nov 2011 13:31:44 -0500 Subject: [PATCH] menu, changed schedule + updating --- AndroidManifest.xml | 2 +- default.properties => project.properties | 6 +- res/drawable-ldpi/ic_menu_info_details.png | Bin 0 -> 1499 bytes res/drawable-ldpi/ic_menu_refresh.png | Bin 0 -> 1695 bytes res/drawable-mdpi/ic_menu_info_details.png | Bin 0 -> 1237 bytes res/drawable-mdpi/ic_menu_refresh.png | Bin 0 -> 1278 bytes res/menu/menu.xml | 15 + res/values/strings.xml | 5 + src/com/lsiegert/DatabaseHelper.java | 197 ------------ src/com/lsiegert/DownloadGameUpdatesTask.java | 153 +++++++++ src/com/lsiegert/GamesDbAdapter.java | 293 ++++++++++-------- src/com/lsiegert/NUHockey.java | 124 +------- src/com/lsiegert/RSSActivity.java | 1 - src/com/lsiegert/ScheduleActivity.java | 155 +++++++-- src/com/lsiegert/ScheduleAdapter.java | 1 - 15 files changed, 483 insertions(+), 469 deletions(-) rename default.properties => project.properties (79%) create mode 100644 res/drawable-ldpi/ic_menu_info_details.png create mode 100644 res/drawable-ldpi/ic_menu_refresh.png create mode 100644 res/drawable-mdpi/ic_menu_info_details.png create mode 100644 res/drawable-mdpi/ic_menu_refresh.png create mode 100644 res/menu/menu.xml delete mode 100644 src/com/lsiegert/DatabaseHelper.java create mode 100644 src/com/lsiegert/DownloadGameUpdatesTask.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 581b6ee..a31b5ae 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,7 +2,7 @@ + android:versionName="2.5"> !di?qogHNBme+_GzM+sB%sEA zh>HmFIiQ1_00)TYP&NQSd4{^4paKS?JwgRU{|ejAE0+7sh+u@DfWN$et770=0Dwp( z#s=Yn?wDYDP~BV)#xO{`-CDIzk?;QcZ5#^;X4t7S``hw)j$CY}1J9*lo~*rggaAP*%0w$~5q|5-xzYFI4W^P0XwTilE_n~c^eO3PO)Pf@Lo$wv!dCsNSQG-g;PH)%ny$F1 zm*3;v9J@Vb%OP25hT5iH;M1%6#ZnsH(;c7tI$v1fS!tXJr}5U|MmT&M{ zC?j^pJMjv(RB=oRBNQ(+0-PUz-p`JSZVVol|iAsSkf< z<{9y<*hRY{?JjR=)ZO56OqZEd1Gox5}yrGqnEx4$!c|_UyDhen(PmQmIM5LrP4sT%@EVu)OuET+6%ODAAZ4 z%|qSq5R%@}1YUb{;3@y;J`v8;wf7*`$>_6)%Bcq-!Ka|(O8<~|^{BHgV z>{n_8yyMAy$gephej-)2=LEjVXFa33+a27J#1Tn9aXqyBaCXY(BP17BBz23>y4{ZR zjT@qYmP9*Cl5Ok~2s9hzJITCdPtC;jqi3WW*k|pt&sw3w2QX+zD>JWw9UuS0nUcR* z*xSRmHb%~Tj0*@#kwqKWXEuHW z=BBkITc6}`TWtA~3tCZ}s@hKXi@k65RA<-Q&r?5*KJ}_t?uF#nLOc{%CSb;T&#uz5 z9PP$O;<*|80lV{qK-O!cE)-b(ixZ{*S9_*Im11Ifnq{JSJA1v-*}~yoWfzxRs)C$} zz}Hh_P-*fP#BOC)tUp8ye-%S11=kkfu8&*~SuaN%(3Mxn=w&do4{sdI!(=_7+>82B zk;xm6T`auoUHr%Lv|H|GD}0>4dkZ{zW17x7D6(=j&qV7suAAX{@=}>8tlRL)F;Ktd zz)p42-Zh+`Bv4L+xw(LSSuoi&H<+#=?C4Gi{X6q9tA_T_*^DeYNQZtoV!CJ&P?T`p z#o^Rs-O{w2RKopv+G`?n%QRrf-n7k&*WBe+SfB`d-W9#~RCSkO{&{$tL#((DE@n&K zHj7hO?QcJ(vKa@Wd^i}mT16bWR=Lv+;lncZU+FM}Ca7eonX(s8(YyF>px6~Xn%Egt0DvA82GxPVbf9`JFc=(a0M|Fvff~c1&@9FBvHutXX}oL_{76nDf^SqvC&^qe1i&EeZ7QvNZvF!qke*Ed literal 0 HcmV?d00001 diff --git a/res/drawable-ldpi/ic_menu_refresh.png b/res/drawable-ldpi/ic_menu_refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..b25dc061616a316beea1da94d8f15d2b6ed6a146 GIT binary patch literal 1695 zcmZ{kX*e6`7RRHtt17K3s*I&VL=#IqiK<~}1lJx-)RxFnq=Lkfn54bY8md8qs;zn% zwU$;jZ48;2#}YbXOoOUrtW|E+Zj?sdm{0e9xF62>J@5NF|L1%=S$;l9byYo8005wl z@^A}~(e$vC$E0UMM9TQ^1Q=l&xpOrN9}%v08c2sQLV04*c&XW`Ly|E zGEJ(~mTb{;kn$A)hwtRC?kr5uX6DX(l)E<1Uf4IBj9J)FWjH=seT{Ml96$S>>c@mW!u)=@-Le*TD0>D9)^=xHv}?9wl6%}Uw7I?&%8C!acu*x z`f}R!QA*Uo-z~yg)(r_24d*p8wbK8%8R^e!L6wJJ{T!p9=~#A5xsK^WOKp3>#eD5z z+Ty9>58?#k+g%pEqBOixC34s;-s_nV6QQa$TedOr%EBpr9Ua9VpGRtMKg|GJl0b3X zuPu6DVNU(BSIWM0v083h+k$MjwfcVb=ZkGYM}6R&vhILKaRK*~Af-QLLTk+%nJv=$ z@h2WU^}O+OEV)K2tm$}saL0SH^$=q-o|EW9&r_SR?f*=7FA@}4+K&&^DYKkz=LXMA zRlHm3PsGk4Mr+jgarfHGn_6d&U9(~j;NYFT^gKK$eeC5Bv7zAkLp}A?T1D*KU(d2H z1oou1Nz)0rVy}tr(9u*auC3`6-Lgwa`*!4Wm3IPX)V?un#+Y<47a=XzD>#*#$kDUA zuRN=5Vwq;cN=P=&UtIne5cA|1gj`?Q-O4k{XbS{pb(S$tP4&01jDf<-n!f0D*EPb^ zYpu9ayHRV$`=c{C2ksRql18&We-lmDA1brO_NDwMDbw@O*m_u>qUAd`3{y}!Mg;Dz zl=NzSS>k!Q)H3ah4K%{j$XOfw@%Iob3 zd85=xx!!>AVkT0CwPtJxN?WT7@<~PpXQdq98wYVI}3i-SF1Pd`}8^_ zcI#U)uYpx51jW=>o({)n(&k0BQRncXo&h7#2JliKyEH=5t7++NlUexFb^jyg=cNNv zdp+BTm(x}GtU??kN6Z%1y4;;Es2klMBz4D8U9BZXwCjv^+LeXmDAvjILb9$|HR>On zEp@*V(l)k&(~VDHa*{VOF9y#w^5NsNO+yB0jwumiyOs1UuG0-FdYGTD5pj@|y?wFQ znJ(~Ze_Ya~Q{|#PRQS(;*u_kPH#E-P;w16e-IF!#-fyMo;wG=Xt1D=BPv6qW7~>Aq zI)7Osb6NoPrDR-Vx7H1r0xL~TPhnb%Ixxd_qr=S?1P*XWR&gu8L;;BYg_}Abfqf-h z=0JroSm5iT4Yshr(n7_1^f$xyxrZ~ICT-&Gto+iJPtDX`S|hSE~P%y+M2nt0&>=3s0V2A?(0=cJCKmI>~>r_HCiShpf)1F#~ z$6n)b11Xw9Cnh5Bl%zxe#2Ok%Cx0(f$Nx)FsCXg`V3$;@Y%DXnhbE9pqNm^zi2xUZ fOd6rCk4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JeT~8Os5RcKO*~zCK~&O-7Ao~AbGr#YwNN@>wa^8idq+xeyUAxLKAoKuMdaPg4%UB_!b2A z2??HJ{Q0av;M?w97ST3b#-$rdIc~qEdhUx#{R6h7)tgNm6`NO_c$fRz?`i(U z8FPI985vqIx9*$n^n0&h?)1aXYoCAJl%d$%%^CMh-BGhXw|;ZJm;J1~7nANkl{aP# z^9X-Ajajv{F;&R7?*0MQB{BNCryK(2-T!&+=+pX)FMj#OrEj#=uS>^svzoh2Vt=cz zoW1C*cH9Kp!@Bc7KWEm>`L4PuB{j76bIi1Nk}p;-x1K)x+nIyk@89|O=zQXGc{rz&hk^3rj;tcC+Kly`KqOj**EsK1w83JwrB6W;%f=7*Q%Hu z7EZ3u|6yS~ueP+|cGA+Qtfd?>lbM&g|H(BelkJi{n%!`+Z}!&Yt;w?HGg;PKo>~}@ z94_tt$EB;lhwEiwy8B7J*wCz6BiHD?g5JCd?SCVg692F0^?ar2&AYaDwmt7OvGTOj z6<+MwjzL*tiSmku*= z*a$ZqtQ6AIdVBlgxxgE8Nvba*j-Ozi$_VpI$C96`T zj|&}P+pu=Zsyxm`4&P7CGh4|m7QTURIp?!S%BGi1FMkw#HtRrQY@uuH24BB#7v3t# zr999$^yW<~f49D#eYi;N>g^}D7%%^t{#l`7`cBKl&$BWwS&Z8H~w|8`F zHwFFs)u{G<$v*R|cM?l4r7t_cwdvLrx6^jqZ7Q?=tZVc>p|^L_jR3BW#Y(%kzqg(n zzwGU&(oLyKc8f)Rm9=T@oxRnWkN^L-wQ*v)3j3xgH?|5+DZLkdKd%1Fe#Ntw*1hgL zB5r$9{wMdx7d5{UbhEZEn78I9Z_u{Pt4%BWO220w7oPFzZ{pd2*(y>>{Q47~tn;ZT zoOj_`u*{}276(iO7;@C+|4FKR@n&QA?aTfD8LA#GJkPNHbY%}>cptHiD0s_>~&paw~h u4Z-k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~G#o2QFoh{y4zQ@wMhgo+%me_nUrJl|?d@U4cI z&C66+coe3&8|36XRdu=G64uqvy3gPsOKRexV=e`a{Rv4)Jrg@vE@o)$a!^%t)N~SO zYU0djoYo}EmF%5vb>>WYe>c@^%@6#CE zbTU$6p4~e&^RwEyj?mrnmi!66`B&V!FKBP-w=aLz3G7)VeTvuj;(8RAJ`B zz8Gc=bK@mk-)r+LYpVHYL>M;)bv`Kem%1p}8+!h)=1g zJ#8(xyx?T*j`G{<=HC80`7v89!Jk+zU@nHKh@mE>g7O#ze zM_K-ukq|V^p&;x=b?SpIo?n)mDyQC`boAf){+0zSYBu!`-W|L1{oSY9UCCUrF|wyV z>8(1MbTUzsAu~v##D%wE)o(Sks5$z-ELF7J-kR2$-(Bo>w$H~gVAV4BkJWp&$?ZCL z@lb|agQ|mW;-NW9(^m)|7Mya`BExI)-;{+0KC`6{CN-?&o|jShyIFo~?Z1~^Qy=Ov zlvEwxYkMytZ}DE%m&exk?Guc7&YHBkM`Y=O1D(Fr_cuMU+%@xT)3g9d26lO;Lg$6o zmtD?sXHqG354_Ryq^^gtoAc^74df} z`j5(-xWuWcnY;L(iv1(=qt7IzIXZ%$DGBdASM!{2mqF950EOFsVk}#^@4Yjg!xpHU znjAOr#GUoeeb07sDnxni-oA-j{?v=@#ZB$g_giL9bhXo-leOGlD^s_Z;i=@`iUmsH zlea5z$bNeA^7C!W{wc*vAAVTmYizdbM>})=`~|$9mc}s5P<5YD5;UP{$17`nKAHUj zD^6d}GKu`1@c8s&@u)w3?^n({y<5_uXtCSO`>d*;`s@|o68O|Sdo#aC$kCWDb~-th*Z#}aD;4g28KgS* zlwjoSthW)N*JJF?u03?YefdA58&&V#EPS!vdH0I-ClXW~mfeml-}<$^{QJ83UwoT= zxQ_Sor2X-p^U&nwniB!<^OTr;IQEOwY;coWv16Su2h)R-y8kyS{+u~u`vnIFf#W(8 zG)`>~;c)wRdxy#->j}3_{)>k*&1A8#oAMA?G^m!iMwFx^mZVxG7o`Fz1|tJQLtO(y zT_cMSBO@ylb1PG0T>}d%1A`@gMJG`-wJDNutX$cEtjw370~qErUQ il>DSr1<%~X^wgl##FWaylc_d9MGT&#M literal 0 HcmV?d00001 diff --git a/res/menu/menu.xml b/res/menu/menu.xml new file mode 100644 index 0000000..87dd30c --- /dev/null +++ b/res/menu/menu.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index d0fa27c..d1abd0d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5,5 +5,10 @@ Schedule RSS Your Stats + Info + Update + Check off the games you\'ve been to on the Schedule tab. + Change Season + Sort 5 diff --git a/src/com/lsiegert/DatabaseHelper.java b/src/com/lsiegert/DatabaseHelper.java deleted file mode 100644 index 32e1f1a..0000000 --- a/src/com/lsiegert/DatabaseHelper.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.lsiegert; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import android.content.Context; -import android.database.Cursor; -import android.database.SQLException; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteException; -import android.database.sqlite.SQLiteOpenHelper; - -public class DatabaseHelper extends SQLiteOpenHelper{ - - //The Android's default system path of your application database. - private static String DB_PATH = "/data/data/com.lsiegert/databases/"; - - private static String DB_NAME = "NUHockey.sqlite"; - - public SQLiteDatabase myDb; - - private final Context myContext; - - /** - * Constructor - * Takes and keeps a reference of the passed context in order to access to the application assets and resources. - * @param context - */ - public DatabaseHelper(Context context) { - super(context, DB_NAME, null, R.string.databaseVersion); - this.myContext = context; - } - - /** - * Creates a empty database on the system and rewrites it with your own database. - * */ - public void createDatabase() throws IOException{ - - boolean dbExists = checkDatabase(); - SQLiteDatabase db_Read = null; - - if(dbExists){ - //do nothing - database already exists - }else{ - db_Read = this.getReadableDatabase(); - db_Read.close(); - - try { - copyDatabase(); - } catch (IOException e) { - throw new Error("Error copying database"); - } - } - - } - - /** - * Check if the database already exists to avoid re-copying the file each time you open the application. - * @return true if it exists, false if it doesn't - */ - private boolean checkDatabase(){ - - SQLiteDatabase checkDB = null; - try{ - String myPath = DB_PATH + DB_NAME; - checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); - - } catch(SQLiteException e){ - //database does't exist yet. - } - - if(checkDB != null){ - checkDB.close(); - } - - return checkDB != null ? true : false; - - } - - /** - * Copies your database from your local assets-folder to the just created empty database in the - * system folder, from where it can be accessed and handled. - * */ - private void copyDatabase() throws IOException{ - InputStream myInput = myContext.getAssets().open(DB_NAME); - String outFileName = DB_PATH + DB_NAME; - OutputStream myOutput = new FileOutputStream(outFileName); - - byte[] buffer = new byte[1024]; - int length; - while ((length = myInput.read(buffer))>0){ - myOutput.write(buffer, 0, length); - } - - myOutput.flush(); - myOutput.close(); - myInput.close(); - } - - public void openDatabase() throws SQLException{ - String myPath = DB_PATH + DB_NAME; - myDb = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); - } - - @Override - public synchronized void close() { - if(myDb != null) - myDb.close(); - super.close(); - } - - @Override - public void onCreate(SQLiteDatabase db) { - checkDatabase(); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - onCreate(db); - } - - public Cursor getAllPlayers() { - return myDb.query("Players", null, null, null, null, null, "number"); - } - - public Cursor getAllGames() { - return myDb.query("Games", null, null, null, null, null, "date"); - } - - public Cursor getAllSeasons() { - String query = "select distinct season from Games order by season desc"; - return myDb.rawQuery(query, null); - } - - // location should be either home, away, or neutral - public Cursor getGamesByLocation(String location) { - return myDb.query("Games", null, "location = ?", new String[]{location}, null, null, "date"); - } - - // Get all games for the given season - public Cursor getGamesBySeason(String season) { - return myDb.query("Games", null, "season = ?", new String[]{season}, null, null, "date"); - } - - // W-L-T record across all games the user has attended - public String getRecord() { - String wins = "select _id from Games where nuscore > oppscore and attended=1"; - String losses = "select _id from Games where nuscore < oppscore and attended=1"; - String ties = "select _id from Games where nuscore = oppscore and attended=1"; - int w = myDb.rawQuery(wins, null).getCount(); - int l = myDb.rawQuery(losses, null).getCount(); - int t = myDb.rawQuery(ties, null).getCount(); - return w + "-" + l + "-" + t; - } - - // W-L-T record across games the user has attended, by location - public String getRecordByLocation(String location){ - String wins = "select _id from Games where nuscore > oppscore and attended=1 and location=?"; - String losses = "select _id from Games where nuscore < oppscore and attended=1 and location=?"; - String ties = "select _id from Games where nuscore = oppscore and attended=1 and location=?"; - String[] args = new String[]{location}; - int w = myDb.rawQuery(wins, args).getCount(); - int l = myDb.rawQuery(losses, args).getCount(); - int t = myDb.rawQuery(ties, args).getCount(); - return w + "-" + l + "-" + t; - } - - public int getNumOfTeams() { - String query = "select distinct opponent from Games where attended=1"; - return myDb.rawQuery(query, null).getCount(); - } - - public int getNumOfGoals() { - String query = "select nuscore from Games where attended=1"; - Cursor allGoals = myDb.rawQuery(query, null); - allGoals.moveToFirst(); - int totalGoals = 0; - while (!allGoals.isAfterLast()) { - totalGoals = totalGoals + allGoals.getInt(0); - allGoals.moveToNext(); - } - return totalGoals; - } - - public int getNumOfShutouts() { - String query = "select _id from Games where attended=1 and oppscore=0"; - return myDb.rawQuery(query, null).getCount(); - } - - public int getNumOfWinsAtagganis() { - String query ="select _id from Games where attended=1 and " + - "nuscore>oppscore and opponent='boston university' and location='away'"; - return myDb.rawQuery(query, null).getCount(); - } -} \ No newline at end of file diff --git a/src/com/lsiegert/DownloadGameUpdatesTask.java b/src/com/lsiegert/DownloadGameUpdatesTask.java new file mode 100644 index 0000000..aad8147 --- /dev/null +++ b/src/com/lsiegert/DownloadGameUpdatesTask.java @@ -0,0 +1,153 @@ +package com.lsiegert; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; + +import android.app.ProgressDialog; +import android.content.Context; +import android.os.AsyncTask; +import android.util.Log; + +public class DownloadGameUpdatesTask extends AsyncTask { + private Context context; + private ProgressDialog dialog; + private static final String TAG = "NUHockey"; + + public DownloadGameUpdatesTask(Context c) { + context = c; + } + + @Override + protected void onPreExecute() { + dialog = ProgressDialog.show(context, "", "Fetching game updates...", true); + } + + @Override + protected Void doInBackground(Void... params){ + try { + checkForGameUpdates(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void result) { + dialog.dismiss(); + } + + private void checkForGameUpdates() throws Exception { + // If fetching, let's tell the user we are doing something. Show a waiting thing. + + GamesDbAdapter gamesDba = new GamesDbAdapter(context); + + try { + Log.d(TAG, "starting game updates"); + gamesDba.open(); + + // First, let's look and see how long ago we last checked + // If it was more than 3 days ago, let's fetch updates. Otherwise, finish. + + // Let's get the list of updates from our server + List> updates = fetchGameUpdates(gamesDba.getLastUpdated());; + + // Once we have them, remember the exact time. + Date now = new Date(); + + // For each update, determine what the hell it wants us to do and apply it to the gamesDba + for (int i = 0; i < updates.size(); i++) { + Map game = updates.get(i); + String op = game.get("operation"); + int id = Integer.parseInt(game.get("id")); + String date = game.get("date"); + String opponent = game.get("opponent"); + String season = game.get("season"); + int nuscore = parseOrInvalid(game.get("nuscore")); + int oppscore = parseOrInvalid(game.get("oppscore")); + String location = game.get("location"); + + if (op.equalsIgnoreCase("NEW")) { + Log.d(TAG, "Creating game: " + id); + gamesDba.createGame(id, date, season, opponent, nuscore, oppscore, location); + } else if (op.equalsIgnoreCase("UPDATED")) { + Log.d(TAG, "Updating game: " + id); + gamesDba.updateGame(id, date, season, opponent, nuscore, oppscore, location); + } else if (op.equalsIgnoreCase("DELETED")) { + Log.d(TAG, "Deleting game: " + id); + gamesDba.deleteGame(id); + } + } + + // When finished, this was the last time we updated. Save. + gamesDba.saveLastUpdated(now); + } finally { + gamesDba.close(); + dialog.dismiss(); + } + } + + private int parseOrInvalid(String s) { + try { + return Integer.parseInt(s); + } catch(NumberFormatException e) { + return -1; + } + } + + private List> fetchGameUpdates(Date lastChecked) throws Exception { + BufferedReader in = null; + SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); + List> updates = new ArrayList>(); + String date = df.format(lastChecked); + + // Make some sort of http request + HttpClient client = new DefaultHttpClient(); + HttpGet request = new HttpGet(); + URI uri = new URI("http://morning-planet-4215.heroku.com/gameupdates/" + date + ".txt"); + request.setURI(uri); + Log.d(TAG, "Making the request to " + uri.toString()); + HttpResponse response = client.execute(request); + Log.d(TAG, "Response: " + response.getStatusLine().toString()); + + InputStream content = response.getEntity().getContent(); + in = new BufferedReader(new InputStreamReader(content)); + + String line = ""; + + // We are going to get some sort of lines. For each line, create a Map. + while ((line = in.readLine()) != null) { + Log.d(TAG, "Parsing line: " + line); + Map m = new HashMap(); + String[] parts = line.split(","); + if (parts.length == 8) { + m.put("operation", parts[0]); + m.put("id", parts[1]); + m.put("date", parts[2]); + m.put("season", parts[3]); + m.put("opponent", parts[4]); + m.put("nuscore", parts[5]); + m.put("oppscore", parts[6]); + m.put("location", parts[7]); + updates.add(m); + } else { + Log.e(TAG, "Line doesn't have 8 parts"); + } + } + // Return a list of Maps that can be used by the methods of gamesDba + return updates; + } +} diff --git a/src/com/lsiegert/GamesDbAdapter.java b/src/com/lsiegert/GamesDbAdapter.java index 1ea5b60..47d8c0e 100644 --- a/src/com/lsiegert/GamesDbAdapter.java +++ b/src/com/lsiegert/GamesDbAdapter.java @@ -14,7 +14,7 @@ public class GamesDbAdapter { private static final String TAG = "NUHockey"; - + public static final String ID = "_id"; public static final String LOCATION = "location"; public static final String OPPSCORE = "oppscore"; @@ -22,117 +22,161 @@ public class GamesDbAdapter { public static final String SEASON = "season"; public static final String NUSCORE = "nuscore"; public static final String DATE = "date"; - public static final String UPDATED ="updated"; + public static final String UPDATED = "updated"; public static final String ATTENDED = "attended"; - - public static final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - + + public static final SimpleDateFormat df = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + private final Context mCtx; private SQLiteOpenHelper mDbHelper; private SQLiteDatabase mDb; - + public GamesDbAdapter(Context ctx) { mCtx = ctx; } - - public GamesDbAdapter open() throws SQLException { - mDbHelper = new DatabaseHelper(mCtx); - mDb = mDbHelper.getWritableDatabase(); - return this; - } - - public void close() { - mDbHelper.close(); - } - - public long createGame(int id, String date, String season, String opponent, int nuscore, int oppscore, String location) { - ContentValues initialValues = new ContentValues(); - initialValues.put(ID, id); - initialValues.put(DATE, date); - initialValues.put(SEASON, season); - initialValues.put(OPPONENT, opponent); - initialValues.put(NUSCORE, nuscore); - initialValues.put(OPPSCORE, oppscore); - initialValues.put(LOCATION, location); - - return mDb.insert("games", null, initialValues); - } - - public boolean updateGame(int id, String date, String season, String opponent, int nuscore, int oppscore, String location) { - ContentValues values = new ContentValues(); - values.put(ID, id); - values.put(DATE, date); - values.put(SEASON, season); - values.put(OPPONENT, opponent); - values.put(NUSCORE, nuscore); - values.put(OPPSCORE, oppscore); - values.put(LOCATION, location); - - return mDb.update("games", values, ID + "=" + id, null) > 0; - } - - public boolean deleteGame(int id) { - return mDb.delete("games", ID + "=" + id, null) > 0; - } - - public Date getLastUpdated() throws ParseException{ - Log.d(TAG, "getting last updated date"); - Cursor c = mDb.query("updated", new String[] { UPDATED }, null, null, null, null, null); - if (c != null) { - boolean hasFirstRow = c.moveToFirst(); - if (hasFirstRow) { - String s = c.getString(0); - return df.parse(s); - } - } - return new Date(0); - } - - public boolean saveLastUpdated(Date date){ - ContentValues values = new ContentValues(); - values.put(ID, 1); - values.put(UPDATED, df.format(date)); - - return mDb.replace("updated", UPDATED, values) > 0; - } - - public boolean toggleAttended(int gameId, boolean isChecked){ - if (isChecked) { - ContentValues values = new ContentValues(); - values.put(ATTENDED, gameId); - return mDb.insert("attended", ATTENDED, values) >= 0; - } else { - return mDb.delete("attended", ATTENDED+"="+gameId, null) == 1; - } - } - - public Cursor getAllPlayers() { + + public GamesDbAdapter open() throws SQLException { + mDbHelper = new DatabaseHelper(mCtx); + mDb = mDbHelper.getWritableDatabase(); + return this; + } + + public void close() { + mDbHelper.close(); + } + + public long createGame(int id, String date, String season, String opponent, + int nuscore, int oppscore, String location) { + ContentValues initialValues = new ContentValues(); + initialValues.put(ID, id); + initialValues.put(DATE, date); + initialValues.put(SEASON, season); + initialValues.put(OPPONENT, opponent); + initialValues.put(NUSCORE, nuscore); + initialValues.put(OPPSCORE, oppscore); + initialValues.put(LOCATION, location); + + return mDb.insert("games", null, initialValues); + } + + public boolean updateGame(int id, String date, String season, + String opponent, int nuscore, int oppscore, String location) { + ContentValues values = new ContentValues(); + values.put(ID, id); + values.put(DATE, date); + values.put(SEASON, season); + values.put(OPPONENT, opponent); + values.put(NUSCORE, nuscore); + values.put(OPPSCORE, oppscore); + values.put(LOCATION, location); + + return mDb.update("games", values, ID + "=" + id, null) > 0; + } + + public boolean deleteGame(int id) { + return mDb.delete("games", ID + "=" + id, null) > 0; + } + + public Date getLastUpdated() throws ParseException { + Log.d(TAG, "getting last updated date"); + Cursor c = mDb.query("updated", new String[] { UPDATED }, null, null, + null, null, null); + if (c != null) { + boolean hasFirstRow = c.moveToFirst(); + if (hasFirstRow) { + String s = c.getString(0); + return df.parse(s); + } + } + c.close(); + return new Date(0); + } + + public boolean saveLastUpdated(Date date) { + ContentValues values = new ContentValues(); + values.put(ID, 1); + values.put(UPDATED, df.format(date)); + + return mDb.replace("updated", UPDATED, values) > 0; + } + + public boolean toggleAttended(int gameId, boolean isChecked) { + if (isChecked) { + ContentValues values = new ContentValues(); + values.put(ATTENDED, gameId); + return mDb.insert("attended", ATTENDED, values) >= 0; + } else { + return mDb.delete("attended", ATTENDED + "=" + gameId, null) == 1; + } + } + + public Cursor getAllPlayers() { return null; } - + public Cursor getAllGames() { return mDb.query("games", null, null, null, null, null, "date"); } - + public Cursor getAllSeasons() { String query = "select distinct season from games order by season desc"; return mDb.rawQuery(query, null); } + public Cursor getAllOpponents() { + String query = "select distinct opponent from games order by opponent"; + return mDb.rawQuery(query, null); + } + // location should be either home, away, or neutral public Cursor getGamesByLocation(String location) { - return mDb.query("games", null, "location = ?", new String[]{location}, null, null, "date"); + return mDb.query("games", null, "location = ?", + new String[] { location }, null, null, "date"); } - + // Get all games for the given season public Cursor getGamesBySeason(String season) { - String query = "select games._id, games.date, games.season, games.opponent, " + - "games.nuscore, games.oppscore, games.location, attended.attended" + - " from games left outer join attended on games._id=attended.attended" + - " where season = ? order by date"; - return mDb.rawQuery(query, new String[]{season}); + String query = "select games._id, games.date, games.season, games.opponent, " + + "games.nuscore, games.oppscore, games.location, attended.attended" + + " from games left outer join attended on games._id=attended.attended" + + " where season = ? order by date"; + return mDb.rawQuery(query, new String[] { season }); + } + + // Get all games for the given opponent + public Cursor getGamesByOpponent(String opponent) { + String query = "select games._id, games.date, games.season, games.opponent, " + + "games.nuscore, games.oppscore, games.location, attended.attended" + + " from games left outer join attended on games._id=attended.attended" + + " where opponent = ? order by date"; + return mDb.rawQuery(query, new String[] { opponent }); + } + + // W-L-T record across all completed games in the given season + public String getRecordBySeason(String season) { + String wins = "select games._id from games where nuscore > oppscore and season=?"; + String losses = "select games._id from games where nuscore < oppscore and season=?"; + String ties = "select games._id from games where nuscore != -1 and nuscore = oppscore and season=?"; + String[] seasons = new String[] { season }; + int w = mDb.rawQuery(wins, seasons).getCount(); + int l = mDb.rawQuery(losses, seasons).getCount(); + int t = mDb.rawQuery(ties, seasons).getCount(); + return w + "-" + l + "-" + t; } + // W-L-T record across all completed games against the given opponent + public String getRecordByOpponent(String opponent) { + String wins = "select games._id from games where nuscore > oppscore and opponent=?"; + String losses = "select games._id from games where nuscore < oppscore and opponent=?"; + String ties = "select games._id from games where nuscore != -1 and nuscore = oppscore and opponent=?"; + String[] opponents = new String[] { opponent }; + int w = mDb.rawQuery(wins, opponents).getCount(); + int l = mDb.rawQuery(losses, opponents).getCount(); + int t = mDb.rawQuery(ties, opponents).getCount(); + return w + "-" + l + "-" + t; + } + // W-L-T record across all games the user has attended public String getRecord() { String wins = "select games._id from games, attended where nuscore > oppscore and games._id=attended.attended"; @@ -143,24 +187,24 @@ public String getRecord() { int t = mDb.rawQuery(ties, null).getCount(); return w + "-" + l + "-" + t; } - + // W-L-T record across games the user has attended, by location - public String getRecordByLocation(String location){ + public String getRecordByLocation(String location) { String wins = "select games._id from games, attended where nuscore > oppscore and games._id=attended.attended and location=?"; String losses = "select games._id from games, attended where nuscore < oppscore and games._id=attended.attended and location=?"; String ties = "select games._id from games, attended where nuscore = oppscore and games._id=attended.attended and location=?"; - String[] args = new String[]{location}; + String[] args = new String[] { location }; int w = mDb.rawQuery(wins, args).getCount(); int l = mDb.rawQuery(losses, args).getCount(); int t = mDb.rawQuery(ties, args).getCount(); return w + "-" + l + "-" + t; } - + public int getNumOfTeams() { String query = "select distinct opponent from games, attended where games._id=attended.attended"; return mDb.rawQuery(query, null).getCount(); } - + public int getNumOfGoals() { String query = "select nuscore from games, attended where games._id=attended.attended"; Cursor allGoals = mDb.rawQuery(query, null); @@ -170,48 +214,43 @@ public int getNumOfGoals() { totalGoals = totalGoals + allGoals.getInt(0); allGoals.moveToNext(); } + allGoals.close(); return totalGoals; } - + public int getNumOfShutouts() { String query = "select games._id from games, attended where games._id=attended.attended and oppscore=0"; return mDb.rawQuery(query, null).getCount(); } - + public int getNumOfWinsAtagganis() { - String query ="select games._id from games, attended where games._id=attended.attended and " + - "nuscore>oppscore and opponent='boston university' and location='away'"; + String query = "select games._id from games, attended where games._id=attended.attended and " + + "nuscore>oppscore and opponent='boston university' and location='away'"; return mDb.rawQuery(query, null).getCount(); } - + private static class DatabaseHelper extends SQLiteOpenHelper { - private static final String DATABASE_NAME = "gamedata"; - private static final int DATABASE_VERSION = 1; - - private static final String GAMES_TABLE_CREATE = - "create table games(" + - ID + " integer primary key, " + - DATE + " text not null," + - SEASON + " text not null," + - OPPONENT + " text not null," + - NUSCORE + " integer," + - OPPSCORE + " integer," + - LOCATION + " text not null" + - ");"; - - private static final String UPDATED_TABLE_CREATE = - "create table updated(" + - ID + " integer primary key autoincrement, " + - UPDATED + " text not null" + - ");"; - - private static final String ATTENDED_TABLE_CREATE = - "create table attended(" + - ID + " integer primary key autoincrement, " + - ATTENDED + " integer not null" + - ");"; - - + private static final String DATABASE_NAME = "gamedata"; + private static final int DATABASE_VERSION = 1; + + private static final String GAMES_TABLE_CREATE = "create table games(" + + ID + " integer primary key, " + DATE + " text not null," + + SEASON + " text not null," + OPPONENT + " text not null," + + NUSCORE + " integer," + OPPSCORE + " integer," + LOCATION + + " text not null" + ");"; + + private static final String UPDATED_TABLE_CREATE = "create table updated(" + + ID + + " integer primary key autoincrement, " + + UPDATED + + " text not null" + ");"; + + private static final String ATTENDED_TABLE_CREATE = "create table attended(" + + ID + + " integer primary key autoincrement, " + + ATTENDED + + " integer not null" + ");"; + public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @@ -228,8 +267,8 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS games"); db.execSQL("DROP TABLE IF EXISTS updated"); db.execSQL("DROP TABLE IF EXISTS attended"); - onCreate(db); + onCreate(db); } - + } } diff --git a/src/com/lsiegert/NUHockey.java b/src/com/lsiegert/NUHockey.java index 24e6784..37df1e7 100644 --- a/src/com/lsiegert/NUHockey.java +++ b/src/com/lsiegert/NUHockey.java @@ -1,22 +1,8 @@ package com.lsiegert; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URI; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; - -import android.app.ProgressDialog; import android.app.TabActivity; import android.content.Intent; import android.content.res.Resources; @@ -24,7 +10,7 @@ import android.util.Log; import android.widget.TabHost; -public class NUHockey extends TabActivity { +public class NUHockey extends TabActivity{ private static final String TAG = "NUHockey"; /** Called when the activity is first created. */ @@ -75,119 +61,17 @@ public void onCreate(Bundle savedInstanceState) { tabHost.setCurrentTab(1); } + - private void checkForUpdates() throws Exception { + private void checkForUpdates() { // First we check for any game updates - checkForGameUpdates(); + new DownloadGameUpdatesTask(NUHockey.this).execute(); // Then check for roster updates // checkForRosterUpdates(); } - private void checkForGameUpdates() throws Exception { - // If fetching, let's tell the user we are doing something. Show a waiting thing. - ProgressDialog dialog = ProgressDialog.show(NUHockey.this, "", - "Fetching game updates...", true); - - GamesDbAdapter gamesDba = new GamesDbAdapter(this); - - try { - Log.d(TAG, "starting game updates"); - gamesDba.open(); - - // First, let's look and see how long ago we last checked - // If it was more than 3 days ago, let's fetch updates. Otherwise, finish. - - // Let's get the list of updates from our server - List> updates = fetchGameUpdates(gamesDba.getLastUpdated());; - - // Once we have them, remember the exact time. - Date now = new Date(); - - // For each update, determine what the hell it wants us to do and apply it to the gamesDba - for (int i = 0; i < updates.size(); i++) { - Map game = updates.get(i); - String op = game.get("operation"); - int id = Integer.parseInt(game.get("id")); - String date = game.get("date"); - String opponent = game.get("opponent"); - String season = game.get("season"); - int nuscore = parseOrInvalid(game.get("nuscore")); - int oppscore = parseOrInvalid(game.get("oppscore")); - String location = game.get("location"); - - if (op.equalsIgnoreCase("NEW")) { - Log.d(TAG, "Creating game: " + id); - gamesDba.createGame(id, date, season, opponent, nuscore, oppscore, location); - } else if (op.equalsIgnoreCase("UPDATED")) { - Log.d(TAG, "Updating game: " + id); - gamesDba.updateGame(id, date, season, opponent, nuscore, oppscore, location); - } else if (op.equalsIgnoreCase("DELETED")) { - Log.d(TAG, "Deleting game: " + id); - gamesDba.deleteGame(id); - } - } - - // When finished, this was the last time we updated. Save. - gamesDba.saveLastUpdated(now); - } finally { - gamesDba.close(); - dialog.dismiss(); - } - } - - private int parseOrInvalid(String s) { - try { - return Integer.parseInt(s); - } catch(NumberFormatException e) { - return -1; - } - } - - private List> fetchGameUpdates(Date lastChecked) throws Exception { - BufferedReader in = null; - SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); - List> updates = new ArrayList>(); - String date = df.format(lastChecked); - - // Make some sort of http request - HttpClient client = new DefaultHttpClient(); - HttpGet request = new HttpGet(); - URI uri = new URI("http://morning-planet-4215.heroku.com/gameupdates/" + date + ".txt"); - request.setURI(uri); - Log.d(TAG, "Making the request to " + uri.toString()); - HttpResponse response = client.execute(request); - Log.d(TAG, "Response: " + response.getStatusLine().toString()); - - InputStream content = response.getEntity().getContent(); - in = new BufferedReader(new InputStreamReader(content)); - - String line = ""; - - // We are going to get some sort of lines. For each line, create a Map. - while ((line = in.readLine()) != null) { - Log.d(TAG, "Parsing line: " + line); - Map m = new HashMap(); - String[] parts = line.split(","); - if (parts.length == 8) { - m.put("operation", parts[0]); - m.put("id", parts[1]); - m.put("date", parts[2]); - m.put("season", parts[3]); - m.put("opponent", parts[4]); - m.put("nuscore", parts[5]); - m.put("oppscore", parts[6]); - m.put("location", parts[7]); - updates.add(m); - } else { - Log.e(TAG, "Line doesn't have 8 parts"); - } - } - // Return a list of Maps that can be used by the methods of gamesDba - return updates; - } - private void checkForRosterUpdates() { // RosterDbAdapter rosterDba = new RosterDbAdapter(this); diff --git a/src/com/lsiegert/RSSActivity.java b/src/com/lsiegert/RSSActivity.java index 76bf541..a25373a 100644 --- a/src/com/lsiegert/RSSActivity.java +++ b/src/com/lsiegert/RSSActivity.java @@ -1,6 +1,5 @@ package com.lsiegert; -import java.net.URL; import java.util.ArrayList; import java.util.List; diff --git a/src/com/lsiegert/ScheduleActivity.java b/src/com/lsiegert/ScheduleActivity.java index b7ce2cb..482a2bb 100644 --- a/src/com/lsiegert/ScheduleActivity.java +++ b/src/com/lsiegert/ScheduleActivity.java @@ -1,42 +1,159 @@ package com.lsiegert; +import android.app.AlertDialog; import android.app.ListActivity; +import android.content.DialogInterface; import android.database.Cursor; import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.widget.ListView; +import android.widget.Toast; public class ScheduleActivity extends ListActivity { private GamesDbAdapter dbHelper = null; private ListView listView = null; + private static final String TAG = "NUHockey"; + private SeparatedListAdapter adapter = null; @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - listView = getListView(); - listView.setItemsCanFocus(true); - listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - - if (dbHelper == null) { - dbHelper = new GamesDbAdapter(this); - } + listView = getListView(); + listView.setItemsCanFocus(true); + listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); + + if (dbHelper == null) { + dbHelper = new GamesDbAdapter(this); + } dbHelper.open(); - - SeparatedListAdapter adapter = new SeparatedListAdapter(this); + + Cursor seasons = getAllSeasons(); + startManagingCursor(seasons); + String season = seasons.getString(0); + showGamesBySeason(season); + } + + private Cursor getAllSeasons() { Cursor seasons = dbHelper.getAllSeasons(); startManagingCursor(seasons); - seasons.moveToFirst(); - while (!seasons.isAfterLast()) { - String season = seasons.getString(0); - Cursor games = dbHelper.getGamesBySeason(season); + return seasons; + } + + private void showGamesBySeason(String season) { + adapter = new SeparatedListAdapter(this); + String record = dbHelper.getRecordBySeason(season); + Cursor games = dbHelper.getGamesBySeason(season); + startManagingCursor(games); + ScheduleAdapter scheduleAdapter = new ScheduleAdapter(this, R.layout.schedule_row, games, null, null, dbHelper); + adapter.addSection(season + " (" + record + ")", scheduleAdapter); + setListAdapter(adapter); + } + + private void showGamesByOpponent() { + adapter = new SeparatedListAdapter(this); + Cursor opponents = dbHelper.getAllOpponents(); + startManagingCursor(opponents); + + opponents.moveToFirst(); + while (!opponents.isAfterLast()) { + String opponent = opponents.getString(0); + String record = dbHelper.getRecordByOpponent(opponent); + Cursor games = dbHelper.getGamesByOpponent(opponent); startManagingCursor(games); ScheduleAdapter scheduleAdapter = new ScheduleAdapter(this, R.layout.schedule_row, games, null, null, dbHelper); - adapter.addSection(season, scheduleAdapter); - seasons.moveToNext(); + adapter.addSection(opponent + " (" + record + ")", scheduleAdapter); + opponents.moveToNext(); } - + setListAdapter(adapter); - } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.info: + showInfo(); + return true; + case R.id.changeseason: + changeSeason(); + return true; + case R.id.sort: + sort(); + return true; + case R.id.update: + try { + checkForUpdates(); + } catch (Exception e) { + Log.d(TAG, "checking for updates failed"); + e.printStackTrace(); + } + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private void showInfo() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(R.string.info_text) + .setCancelable(true); + AlertDialog alert = builder.create(); + alert.show(); + } + + private void sort() { + final CharSequence[] items = {"Season", "Opponent"}; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("View games by"); + builder.setItems(items, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + //Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); + String s = items[item].toString(); + if (s.equalsIgnoreCase("Season")) { + showGamesBySeason("2011-12"); + } else { + showGamesByOpponent(); + } + listView.requestLayout(); + } + }); + AlertDialog alert = builder.create(); + alert.show(); + } + + private void changeSeason() { + final CharSequence[] items = {"2011-12", "2010-11", "2009-10", "2008-09", "2007-08", "2006-07", "2005-06", "2004-05"}; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Choose a season"); + builder.setItems(items, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + //Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); + showGamesBySeason(items[item].toString()); + listView.requestLayout(); + } + }); + AlertDialog alert = builder.create(); + alert.show(); + } + + + private void checkForUpdates() { + new DownloadGameUpdatesTask(ScheduleActivity.this).execute(); + } } \ No newline at end of file diff --git a/src/com/lsiegert/ScheduleAdapter.java b/src/com/lsiegert/ScheduleAdapter.java index 9f8d634..c745c79 100644 --- a/src/com/lsiegert/ScheduleAdapter.java +++ b/src/com/lsiegert/ScheduleAdapter.java @@ -1,6 +1,5 @@ package com.lsiegert; -import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.graphics.Color;