@@ -80,7 +80,6 @@ private function downloadCities1000(bool $force = false): void {
8080 return ;
8181 }
8282
83- // Download zip file to a tmp file.
8483 $ response = $ this ->clientService ->newClient ()->get ('https://download.nextcloud.com/server/apps/photos/cities1000.zip ' );
8584 $ tmpFile = tmpfile ();
8685 $ cities1000ZipTmpFileName = stream_get_meta_data ($ tmpFile )['uri ' ];
@@ -91,37 +90,64 @@ private function downloadCities1000(bool $force = false): void {
9190 $ zip = new \ZipArchive ;
9291 $ res = $ zip ->open ($ cities1000ZipTmpFileName );
9392 if ($ res !== true ) {
94- throw new \Exception ("Fail to unzip place file: $ res " , $ res );
93+ unlink ($ cities1000ZipTmpFileName );
94+ throw new \Exception ("Failed to unzip place file: $ res " , $ res );
95+ }
96+
97+ $ cities1000TxtStream = $ zip ->getStream ('cities1000.txt ' );
98+ if ($ cities1000TxtStream === false ) {
99+ $ zip ->close ();
100+ unlink ($ cities1000ZipTmpFileName );
101+ throw new \Exception ("Could not extract 'cities1000.txt' from ZIP archive. " );
95102 }
96- $ cities1000TxtSteam = $ zip ->getStream ('cities1000.txt ' );
97103
98104 // Dump the txt file info into a smaller csv file.
99105 $ destinationStream = $ this ->geoNameFolder ()->newFile ('cities1000.csv ' )->write ();
106+ if ($ destinationStream === false || !is_resource ($ destinationStream )) {
107+ fclose ($ cities1000TxtStream );
108+ $ zip ->close ();
109+ unlink ($ cities1000ZipTmpFileName );
110+ throw new \Exception ('Failed to open destination stream for cities1000.csv ' );
111+ }
100112
101- while (($ fields = fgetcsv ($ cities1000TxtSteam , 0 , ' ' )) !== false ) {
102- $ result = fputcsv (
103- $ destinationStream ,
104- [
105- 'id ' => (int )$ fields [0 ],
106- 'name ' => $ fields [1 ],
107- 'latitude ' => (float )$ fields [4 ],
108- 'longitude ' => (float )$ fields [5 ],
109- ]
110- );
111-
112- if ($ result === false ) {
113- throw new \Exception ('Failed to write csv line to tmp stream ' );
113+ try {
114+ while (($ fields = fgetcsv ($ cities1000TxtStream , 0 , "\t" )) !== false ) {
115+ if (count ($ fields ) < 6 ) {
116+ throw new \Exception ('Malformed cities1000.txt row: expected at least 6 fields, got ' . count ($ fields ));
117+ }
118+ $ result = fputcsv (
119+ $ destinationStream ,
120+ [
121+ 'id ' => (int )$ fields [0 ],
122+ 'name ' => $ fields [1 ],
123+ 'latitude ' => (float )$ fields [4 ],
124+ 'longitude ' => (float )$ fields [5 ],
125+ ]
126+ );
127+ if ($ result === false ) {
128+ throw new \Exception ('Failed to write csv line to tmp stream ' );
129+ }
114130 }
131+ } finally {
132+ fclose ($ cities1000TxtStream );
133+ fclose ($ destinationStream );
134+ $ zip ->close ();
135+ unlink ($ cities1000ZipTmpFileName );
115136 }
116-
117- $ zip ->close ();
118137 }
119138
120139 private function loadCities1000 (): array {
121140 $ csvStream = $ this ->geoNameFolder ()->getFile ('cities1000.csv ' )->read ();
141+ if ($ csvStream === false || !is_resource ($ csvStream )) {
142+ throw new \Exception ('Failed to open cities1000.csv for reading. ' );
143+ }
122144 $ cities = [];
123145
124- while (($ fields = fgetcsv ($ csvStream )) !== false ) {
146+ while (($ fields = fgetcsv ($ csvStream , 0 , ', ' , '" ' , '\\' )) !== false ) {
147+ if (count ($ fields ) < 4 ) {
148+ fclose ($ csvStream );
149+ throw new \Exception ('Malformed cities1000.csv row: expected at least 4 fields, got ' . count ($ fields ));
150+ }
125151 $ cities [] = [
126152 'id ' => (int )$ fields [0 ],
127153 'name ' => $ fields [1 ],
@@ -130,6 +156,7 @@ private function loadCities1000(): array {
130156 ];
131157 }
132158
159+ fclose ($ csvStream );
133160 return $ cities ;
134161 }
135162
0 commit comments