Author: Adam Pioterek <adam.pioterek@protonmail.ch>
nougat fix TooLargeTransaction & lowFloor, modification in departure
README.md | 2 app/build.gradle | 1 app/src/main/java/ml/adamsprogs/bimba/VmClient.kt | 7 app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt | 8 app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt | 2 app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt | 6 app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt | 21 app/src/main/res/drawable/ic_info.xml | 9 app/src/main/res/drawable/ic_low_floor.xml | 5 app/src/main/res/layout/row_departure.xml | 33 app/src/main/res/values/strings.xml | 2 build.gradle | 6 database/scraper.py | 26
diff --git a/README.md b/README.md index e6ba045b07165b0f53a51999e7ff1d5f7d6444c6..e5d67ce8f99f57462af593633195031c6300a58d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ * [ ] searching by line number * [ ] stops on map * [ ] refreshing on wakeup * [ ] VM times immediately if online, not through offline timetable -* [ ] detecting holiday +* [x] detecting holiday * [ ] ticket machines on map * [ ] ever-present searchbar * [ ] other things on map diff --git a/app/build.gradle b/app/build.gradle index 92df75a1083d2e5f19138a0aaffef05e1848c1e0..66af321ef5a7e672b3845c5846f5421e5ffa801d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,6 +37,7 @@ implementation 'com.github.arimorty:floatingsearchview:2.1.1' implementation 'org.tukaani:xz:1.6' implementation 'com.google.code.gson:gson:2.8.1' implementation 'com.squareup.okhttp3:okhttp:3.8.1' + //implementation 'com.gu.android:toolargetool:0.1.3@aar' // TooLargeTool } repositories { maven { diff --git a/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt b/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt index ea28e94f6692274d70fe5d5fd937d96d63d2b728..65af3a69ec89aae991893b260629b5fe9b5b54dc 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt @@ -2,6 +2,7 @@ package ml.adamsprogs.bimba import android.app.IntentService import android.content.Intent +import android.util.Log import ml.adamsprogs.bimba.models.* import okhttp3.* import com.google.gson.Gson @@ -48,6 +49,12 @@ } catch(e: IOException) { sendNullResult(requester) return } + + if (responseBody?.get(0) == '<') { + sendNullResult(requester) + return + } + val javaRootMapObject = Gson().fromJson(responseBody, HashMap::class.java) val times = (javaRootMapObject["success"] as Map<*, *>)["times"] as List<*> val date = Calendar.getInstance() diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt index 2361c656a482ae8af9e25fba925adebe39b5e4b9..dfa9714fe459b1ee5143d595d8b8a54492d496be 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt @@ -17,6 +17,9 @@ import android.view.* import android.view.inputmethod.InputMethodManager import ml.adamsprogs.bimba.* import java.util.* +import android.os.Bundle + + class DashActivity : AppCompatActivity(), MessageReceiver.OnTimetableDownloadListener, FavouritesAdapter.OnMenuItemClickListener { @@ -272,5 +275,10 @@ favourites.delete(name) (favouritesList.adapter as FavouritesAdapter).favourites = favourites.favouritesList favouritesList.adapter.notifyDataSetChanged() return true + } + + override fun onSaveInstanceState(outState: Bundle) { + //hack below line to be commented to prevent crash on nougat. + //super.onSaveInstanceState(outState); } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt index 5ffdd690c00edecc66cb3eb9da03cfc6f223c848..56342f6feab9caf4c444e1d6b517128cf2fd07b8 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt @@ -12,6 +12,7 @@ import android.support.v7.widget.* import android.support.v4.app.* import android.support.v4.view.* import android.support.v4.content.res.ResourcesCompat +import android.util.Log import ml.adamsprogs.bimba.models.* import ml.adamsprogs.bimba.* @@ -61,6 +62,7 @@ sectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager, null) thread { sectionsPagerAdapter!!.departures = Departure.createDepartures(stopId) + Log.i("Stop", "Deps created") runOnUiThread { sectionsPagerAdapter?.notifyDataSetChanged() } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt index 21df84c11607746d60a7705b6e7b5117c74c5bf5..aeb84a374901e524f2a24bb439ba52ac2b56393e 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt @@ -3,8 +3,8 @@ import java.util.* import kotlin.collections.ArrayList -data class Departure(val line: String, private val mode: String, val time: String, private val lowFloor: Boolean, - private val modification: String?, val direction: String, val vm: Boolean = false, +data class Departure(val line: String, private val mode: String, val time: String, val lowFloor: Boolean, + val modification: String?, val direction: String, val vm: Boolean = false, var tomorrow: Boolean = false, val onStop: Boolean = false) { override fun toString(): String { @@ -57,7 +57,7 @@ } fun fromString(string: String): Departure { val array = string.split("|") - return Departure(array[0], array[1], array[2], array[3] == "1", array[4], array[5], + return Departure(array[0], array[1], array[2], array[3] == "true", array[4], array[5], array[6] == "true", array[7] == "true", array[8] == "true") } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt index 63af2772ec7bbdbc190eb3e214a83e173d73aab5..0e0501787c5629a2ebac8876a137766a1f850c22 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt @@ -1,8 +1,11 @@ package ml.adamsprogs.bimba.models +import android.app.AlertDialog import android.content.Context +import android.content.DialogInterface import android.support.v4.content.res.ResourcesCompat import android.support.v7.widget.RecyclerView +import android.util.Log import android.view.View import android.view.ViewGroup import android.widget.ImageView @@ -67,6 +70,20 @@ if (departure.vm) icon?.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_departure_vm, context.theme)) else icon?.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_departure_timetable, context.theme)) + + if (departure.lowFloor) + holder?.floorIcon?.visibility = View.VISIBLE + if (departure.modification != "") { + holder?.infoIcon?.visibility = View.VISIBLE + holder?.root?.setOnClickListener { + AlertDialog.Builder(context) + .setPositiveButton(context.getText(android.R.string.ok), + { dialog: DialogInterface, _: Int -> dialog.cancel() }) + .setCancelable(true) + .setMessage(departure.modification) + .create().show() + } + } } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder { @@ -78,9 +95,13 @@ return ViewHolder(rowView) } inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + //todo on click -> show dialogue with modification + val root = itemView.findViewById(R.id.departureRow)!! val lineTextView: TextView = itemView.findViewById(R.id.lineNumber) as TextView val timeTextView: TextView = itemView.findViewById(R.id.departureTime) as TextView val directionTextView: TextView = itemView.findViewById(R.id.departureDirection) as TextView val typeIcon: ImageView = itemView.findViewById(R.id.departureTypeIcon) as ImageView + val infoIcon: ImageView = itemView.findViewById(R.id.departureInfoIcon) as ImageView + val floorIcon: ImageView = itemView.findViewById(R.id.departureFloorIcon) as ImageView } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml new file mode 100644 index 0000000000000000000000000000000000000000..8858b9bf5fdc478adfe08befe7fe830d902d7273 --- /dev/null +++ b/app/src/main/res/drawable/ic_info.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="?attr/colorControlNormal" + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_low_floor.xml b/app/src/main/res/drawable/ic_low_floor.xml new file mode 100644 index 0000000000000000000000000000000000000000..5b8c1afa9709df4dd5c49ab26fca5f27505a9f1f --- /dev/null +++ b/app/src/main/res/drawable/ic_low_floor.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:viewportHeight="120.0" + android:viewportWidth="120.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="?attr/colorControlNormal" + android:pathData="m34.98,94.24c-2.56,-0.26 -2.76,-0.35 -3.18,-1.34 -0.53,-1.28 -0.52,-1.34 0.46,-1.94 0.68,-0.42 1.33,-0.52 3.14,-0.53 1.9,-0 2.39,-0.09 2.98,-0.55 0.38,-0.3 0.7,-0.69 0.7,-0.87 0,-0.18 0.14,-0.46 0.31,-0.63 0.75,-0.75 1.28,-3.48 0.81,-4.19 -0.11,-0.16 -0.95,-0.68 -1.88,-1.14 -0.93,-0.47 -2.26,-1.25 -2.97,-1.75 -0.71,-0.5 -1.4,-0.91 -1.54,-0.91 -0.13,0 -1.48,-1.18 -2.98,-2.61 -2.8,-2.68 -3.83,-4.23 -5.21,-7.84 -0.6,-1.58 -0.79,-4.85 -0.46,-8.18 0.22,-2.3 -0.02,-5.17 -0.69,-7.96 -0.14,-0.58 -0.29,-1.37 -0.33,-1.75 -0.08,-0.68 -0.44,-1.93 -1.03,-3.54 -0.16,-0.44 -0.26,-0.93 -0.22,-1.11 0.04,-0.17 -0.35,-0.96 -0.85,-1.76 -0.82,-1.28 -1.07,-1.48 -2.19,-1.74 -1.54,-0.36 -8.16,-0.21 -9.87,0.23 -1.14,0.29 -1.78,0.22 -5.17,-0.59 -0.71,-0.17 -2.49,-1.92 -2.92,-2.87l-0.48,-1.06 1.55,-1.43c0.85,-0.79 1.61,-1.37 1.68,-1.3 0.07,0.07 0.5,-0.15 0.95,-0.49 0.45,-0.34 1.17,-0.71 1.61,-0.81 0.44,-0.11 0.94,-0.32 1.13,-0.47 0.18,-0.15 1.19,-0.71 2.24,-1.24 1.55,-0.78 2.19,-1.31 3.42,-2.83 1.42,-1.75 1.7,-1.96 4.5,-3.27 2.14,-1 3.42,-1.44 4.52,-1.54 0.84,-0.08 1.53,-0.24 1.53,-0.37 0,-0.13 0.18,-0.23 0.4,-0.23 0.22,0 0.4,0.1 0.4,0.23 0,0.13 0.64,0.29 1.42,0.37 1.67,0.17 3.86,1.21 4.64,2.2 0.31,0.39 0.56,0.62 0.56,0.51 0,-0.58 0.77,0.55 0.94,1.4 0.11,0.54 0.23,1.07 0.26,1.18 0.03,0.11 0.07,0.3 0.09,0.42 0.02,0.12 0.33,0.55 0.69,0.94 0.36,0.39 0.66,0.83 0.66,0.98 0,0.24 1.47,2.28 1.88,2.62 0.09,0.07 0.25,0.43 0.36,0.79 0.25,0.82 1.55,3.48 2.39,4.89 0.35,0.58 0.64,1.36 0.64,1.72 0.01,0.37 0.25,0.81 0.54,0.99 0.38,0.23 0.53,0.62 0.53,1.32 0,0.54 0.24,1.35 0.53,1.78 0.29,0.44 0.53,0.95 0.53,1.15 0,0.43 1.05,1.34 1.56,1.36 0.2,0 1.1,0.47 1.99,1.03 0.89,0.56 2.04,1.11 2.54,1.21 0.51,0.1 1.4,0.4 1.98,0.65 1.21,0.53 4.62,1.68 6.75,2.28 1.4,0.39 4.97,0.78 9.39,1.02 10.84,0.59 14.55,0.74 21.43,0.83 10.51,0.14 14.03,0.45 16.21,1.46 3.16,1.45 5.74,4.88 6.57,8.72 0.2,0.95 0.37,1.93 0.37,2.18 0,0.48 1.21,3.36 2.09,4.97 0.55,1.02 1.68,1.8 2.62,1.83 0.86,0.03 2.03,0.68 2.67,1.49 0.61,0.77 0.58,2.06 -0.11,4.48 -0.49,1.73 -0.56,4.81 -0.15,7.22 0.31,1.82 0.29,2 -0.29,3.23l-0.61,1.3 -1.79,-0.04c-1.02,-0.02 -1.79,-0.15 -1.79,-0.31 0,-0.16 -0.13,-0.14 -0.32,0.05 -0.45,0.45 -2.46,0.4 -2.85,-0.08 -0.26,-0.32 -0.25,-0.42 0.1,-0.56 0.23,-0.09 0.36,-0.27 0.27,-0.41 -0.08,-0.13 0.52,-0.93 1.34,-1.76 1.12,-1.14 1.45,-1.64 1.33,-2.04 -0.09,-0.29 -0.22,-1.78 -0.29,-3.3 -0.11,-2.36 -0.22,-2.86 -0.7,-3.37 -0.31,-0.33 -0.76,-0.6 -1,-0.6 -0.53,0 -1.46,0.97 -1.71,1.79 -0.1,0.33 -0.29,0.53 -0.42,0.45 -0.31,-0.19 -1.02,1.52 -1.03,2.46 -0.01,1.15 -0.32,3.08 -0.54,3.32 -0.38,0.41 -2.36,0.43 -3.11,0.04 -0.41,-0.21 -1.06,-0.39 -1.45,-0.39 -0.39,-0 -0.78,-0.1 -0.85,-0.23 -0.16,-0.26 0.63,-1.04 1.5,-1.47 0.53,-0.27 0.6,-0.52 0.67,-2.54 0.04,-1.23 0.02,-2.49 -0.06,-2.79 -0.22,-0.86 -1.29,-1.17 -4.11,-1.17 -2.37,0 -2.68,-0.06 -3.37,-0.63 -0.94,-0.79 -2.73,-1.73 -3.85,-2.03 -0.47,-0.12 -1.51,-0.41 -2.31,-0.64 -1.53,-0.43 -7.42,-0.51 -8.2,-0.11 -0.22,0.11 -1.41,0.33 -2.65,0.48 -3.74,0.46 -6.72,1.06 -8.77,1.77 -1.07,0.37 -2.47,0.78 -3.11,0.92 -0.64,0.14 -1.29,0.35 -1.46,0.49 -0.16,0.13 -2.79,0.92 -5.85,1.74 -3.06,0.83 -6.09,1.66 -6.75,1.86 -0.65,0.2 -1.85,0.49 -2.65,0.64 -0.8,0.16 -1.84,0.49 -2.32,0.74 -0.85,0.45 -0.86,0.47 -0.87,2.44 -0.01,1.09 -0.17,2.58 -0.36,3.31 -0.31,1.18 -0.44,1.34 -1.25,1.51 -1.05,0.23 -9.94,0.48 -11.48,0.32z" android:strokeWidth="0.26458332"/> +</vector> diff --git a/app/src/main/res/layout/row_departure.xml b/app/src/main/res/layout/row_departure.xml index 21cef242ab886a2888a793b44d70600eaa40b954..8b48c21c1d439e42b7054d3029693739885626cb 100644 --- a/app/src/main/res/layout/row_departure.xml +++ b/app/src/main/res/layout/row_departure.xml @@ -5,7 +5,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" tools:layout_editor_absoluteX="0dp" - tools:layout_editor_absoluteY="25dp"> + tools:layout_editor_absoluteY="25dp" + android:id="@+id/departureRow"> <TextView android:id="@+id/lineNumber" @@ -26,11 +27,11 @@android:id="@+id/departureTypeIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="16dp" android:layout_marginEnd="16dp" + android:layout_marginTop="8dp" android:contentDescription="@string/departure_type_icon_description" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" /> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/departureTime" @@ -53,4 +54,28 @@ android:text="" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/departureTime" /> + + <ImageView + android:id="@+id/departureInfoIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:layout_marginEnd="16dp" + android:contentDescription="@string/departure_info" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:srcCompat="@drawable/ic_info" /> + + <ImageView + android:id="@+id/departureFloorIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:layout_marginEnd="16dp" + android:contentDescription="@string/departure_floor" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/departureInfoIcon" + app:srcCompat="@drawable/ic_low_floor" /> </android.support.constraint.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0ba609e138bef0c8813039fe275f7588748f179b..f8e68025d21585ad31e8b7ee3a250b1f27effc09 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,4 +67,6 @@ "Be sure to consult the messages on\nhttps://www.ztm.poznan.pl/en.\n\n" </string> <string name="departure_row_getting_departures">Getting departures…</string> <string name="valid_through">Valid since: %1$s</string> + <string name="departure_floor">departure floor type (lowFloor)</string> + <string name="departure_info">departure info icon</string> </resources> diff --git a/build.gradle b/build.gradle index 48ce329c8f4650a568c0c0a885aa64d190aa2033..a52487381ec53f408d3143a60dddbfb825a4b7f7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,15 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.1.4-2' + ext.kotlin_version = '1.1.51' repositories { jcenter() maven { url 'https://maven.google.com' } + //maven { url 'https://dl.bintray.com/guardian/android' } // TooLargeTool google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0-beta3' + classpath 'com.android.tools.build:gradle:3.0.0-beta6' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -20,6 +21,7 @@ allprojects { repositories { jcenter() maven { url 'https://maven.google.com' } + //maven { url 'https://dl.bintray.com/guardian/android' } // TooLargeTool google() } } diff --git a/database/scraper.py b/database/scraper.py index 7109b9d730a39c50dfc4babceef440dcbcb85020..0fdf7831ba4a63bf697c6a73a2ae789a9c2da2d4 100755 --- a/database/scraper.py +++ b/database/scraper.py @@ -6,6 +6,8 @@ stops in node: http://www.ztm.poznan.pl/goeuropa-api/node_stops/{node:symbol} stops: http://www.ztm.poznan.pl/goeuropa-api/stops-nodes bike stations: http://www.ztm.poznan.pl/goeuropa-api/bike-stations +alerts: goeuropa-api/alerts/' + lineId; + """ import json import os @@ -92,6 +94,23 @@ def __get_stop_times(self, stop_id, line_id, direction_id): """ get timetable """ + + """ todo get time to next stop: + <div class="route-timeline"> + <ul> + <li…> + <span class="stop-title">{current node_name} (n/ż)?</span> --> if not present, return None + … + </li> + <li…> + … + <span class="time">{time:INT}'</span> + </li> + </ul> + </div> + + """ + index = self.__post('https://www.ztm.poznan.pl/goeuropa-api/stop-info/{}/{}'. format(stop_id, line_id), {'directionId': direction_id}) soup = BeautifulSoup(index.text, 'html.parser') @@ -178,7 +197,8 @@ references node(symbol), number TEXT, lat REAL, lon REAL, \ headsigns TEXT)') cursor.execute('create table lines(id TEXT PRIMARY KEY, number TEXT)') cursor.execute('create table timetables(id TEXT PRIMARY KEY, stop_id TEXT references \ - stop(id), line_id TEXT references line(id), headsign TEXT)') + stop(id), line_id TEXT references line(id), headsign TEXT, \ + numberInRoute INTEGER)') cursor.execute('create table departures(id INTEGER PRIMARY KEY, \ timetable_id TEXT references timetable(id), \ hour INTEGER, minute INTEGER, mode TEXT, \ @@ -211,8 +231,8 @@ for stop in stops: if self.verbose: print("stop {} in route {} in line {}".format(stop_i, route_i, line_i)) timetables = self.__get_stop_times(stop['id'], line_id, direction) - cursor.execute('insert into timetables values(?, ?, ?, ?)', - (timetable_id, stop['id'], line_id, stops[-1]['name'])) + cursor.execute('insert into timetables values(?, ?, ?, ?, ?)', + (timetable_id, stop['id'], line_id, stops[-1]['name'], stop_i)) for mode, times in timetables.items(): cursor.executemany('insert into departures values(null, ?, ?, ?, ?, ?, \ ?)', [(timetable_id, hour, minute, mode, lowfloor, desc)