Bimba.git

commit b2342ecada04f3b6582608026ef72098dcbad847

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)