diff options
45 files changed, 2188 insertions, 1701 deletions
diff --git a/android/Fix My Street/AndroidManifest.xml b/android/Fix My Street/AndroidManifest.xml new file mode 100644 index 000000000..0cdee1687 --- /dev/null +++ b/android/Fix My Street/AndroidManifest.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> + <!-- version info etc --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.fixmystreet" android:versionCode="10" + android:versionName="1.01"> + +<uses-sdk android:minSdkVersion="3" /> + <!-- Permissions --> + <uses-permission android:name="android.permission.CAMERA" /> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> + <uses-permission android:name="android.permission.INTERNET" /> + + <application android:icon="@drawable/house_icon" + android:label="Fix My Street" android:debuggable="false"> + + <!-- Main screen --> + <activity android:name=".Home" android:label="@string/app_name" + android:theme="@style/Theme.Filler"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + + <!-- Details page --> + <activity android:name=".Details" android:label="Fix My Street - Add details" + android:theme="@style/Theme.Filler"> + <intent-filter> + <action android:name="android.intent.action.DETAILS" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <!-- Success page --> + <activity android:name=".Success" android:label="Fix My Street - Success" + android:theme="@style/Theme.Filler"> + <intent-filter> + <action android:name="android.intent.action.SUCCESS" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <!-- About page --> + <activity android:name=".About" android:label="Fix My Street - About" + android:theme="@style/Theme.Filler"> + <intent-filter> + <action android:name="android.intent.action.ABOUT" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <!-- Help page --> + <activity android:name=".Help" android:label="Fix My Street - Help" + android:theme="@style/Theme.Filler"> + <intent-filter> + <action android:name="android.intent.action.HELP" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + </application> +</manifest>
\ No newline at end of file diff --git a/android/Fix My Street/META-INF/LICENSE b/android/Fix My Street/META-INF/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/android/Fix My Street/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/android/Fix My Street/META-INF/MANIFEST.MF b/android/Fix My Street/META-INF/MANIFEST.MF new file mode 100644 index 000000000..20dbb8237 --- /dev/null +++ b/android/Fix My Street/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0
+Archiver-Version: Plexus Archiver
+Created-By: Apache Maven
+Built-By: maurer
+Build-Jdk: 1.5.0_08
+Implementation-Title: Apache Mime4j
+Implementation-Vendor: The Apache Software Foundation
+Implementation-Version: 0.3
+Specification-Title: Apache Mime4j
+Specification-Vendor: The Apache Software Foundation
+Specification-Version: 0.3
+url: http://james.apache.org/mime4j
+
diff --git a/android/Fix My Street/META-INF/NOTICE b/android/Fix My Street/META-INF/NOTICE new file mode 100644 index 000000000..66dd74366 --- /dev/null +++ b/android/Fix My Street/META-INF/NOTICE @@ -0,0 +1,30 @@ +// ------------------------------------------------------------------ +// NOTICE file corresponding to the section 4d of The Apache License, +// Version 2.0, in this case for Apache JAMES Mime4j +// ------------------------------------------------------------------ + +Apache JAMES Mime4j +Copyright 2004-2007 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org). + +This product includes/uses software, Apache Commons Logging (http://jakarta.apache.org/commons/logging/), +developed by The Apache Software Foundation (http://www.apache.org/) +License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html) + +This product includes/uses software, Apache Commons IO (http://jakarta.apache.org/commons/io/), +developed by The Apache Software Foundation (http://www.apache.org/) +License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html) + +This product includes/uses software, Apache Log4j (http://logging.apache.org/log4j/), +developed by The Apache Software Foundation (http://www.apache.org/) +License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html) + + +This product includes/uses software, JUnit (http://www.junit.org/), +developed by Kent Beck, Erich Gamma, and David Saff +License: Common Public License Version 1.0 (http://www.opensource.org/licenses/cpl.php) + +This file is automatically generated by dependencies declared in pom.xml + diff --git a/android/Fix My Street/META-INF/maven/org.apache.james/apache-mime4j/pom.properties b/android/Fix My Street/META-INF/maven/org.apache.james/apache-mime4j/pom.properties new file mode 100644 index 000000000..453194f40 --- /dev/null +++ b/android/Fix My Street/META-INF/maven/org.apache.james/apache-mime4j/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven
+#Thu May 24 18:04:26 CEST 2007
+version=0.3
+groupId=org.apache.james
+artifactId=apache-mime4j
diff --git a/android/Fix My Street/META-INF/maven/org.apache.james/apache-mime4j/pom.xml b/android/Fix My Street/META-INF/maven/org.apache.james/apache-mime4j/pom.xml new file mode 100644 index 000000000..60317a20a --- /dev/null +++ b/android/Fix My Street/META-INF/maven/org.apache.james/apache-mime4j/pom.xml @@ -0,0 +1,297 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+ <parent>
+ <artifactId>james-project</artifactId>
+ <groupId>org.apache.james</groupId>
+ <version>1.1</version>
+ <!-- Either this really points to the james-project/pom.xml or you
+ will have to tune the local repository, later, in this file -->
+ <relativePath>../james-project/project/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.james</groupId>
+ <artifactId>apache-mime4j</artifactId>
+ <name>Apache JAMES Mime4j</name>
+ <version>0.3</version>
+ <description>Java stream based MIME message parser</description>
+ <url>http://james.apache.org/mime4j</url>
+ <issueManagement>
+ <url>http://issues.apache.org/jira/browse/MIME4J</url>
+ </issueManagement>
+ <inceptionYear>2004</inceptionYear>
+ <distributionManagement>
+ <site>
+ <id>mime4j-website</id>
+ <url>scp://minotaur.apache.org/www/james.apache.org/mime4j/</url>
+ </site>
+ </distributionManagement>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/james/mime4j/tags/apache-mime4j-0.3</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/james/mime4j/tags/apache-mime4j-0.3</developerConnection>
+ <url>http://svn.apache.org/viewvc/james/mime4j/tags/apache-mime4j-0.3</url>
+ </scm>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>javacc-maven-plugin</artifactId>
+ <version>2.1</version>
+ <executions>
+ <execution>
+ <id>generate-jjtree</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>jjtree</goal>
+ </goals>
+ <configuration>
+ <!-- <nodePackage>org.apache.jsieve.parser.generated</nodePackage> -->
+ <outputDirectory>${project.build.directory}/generated-sources/jjtree/org/apache/james/mime4j/field/address/parser</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-javacc</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>javacc</goal>
+ </goals>
+ <configuration>
+ <sourceDirectory>${project.build.directory}/generated-sources/jjtree/org/apache/james/mime4j/field/address/parser</sourceDirectory>
+ <packageName>org.apache.james.mime4j.field.address.parser</packageName>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-javacc2</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>javacc</goal>
+ </goals>
+ <configuration>
+ <sourceDirectory>${basedir}/src/main/javacc/org/apache/james/mime4j/field/datetime</sourceDirectory>
+ <packageName>org.apache.james.mime4j.field.datetime.parser</packageName>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-javacc3</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>javacc</goal>
+ </goals>
+ <configuration>
+ <sourceDirectory>${basedir}/src/main/javacc/org/apache/james/mime4j/field/contenttype</sourceDirectory>
+ <packageName>org.apache.james.mime4j.field.contenttype.parser</packageName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.4</source>
+ <target>1.4</target>
+ <encoding>iso8859-1</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Specification-Title>Apache Mime4j</Specification-Title>
+ <Specification-Version>0.3</Specification-Version>
+ <Specification-Vendor>The Apache Software Foundation</Specification-Vendor>
+ <Implementation-Title>Apache Mime4j</Implementation-Title>
+ <Implementation-Version>0.3</Implementation-Version>
+ <Implementation-Vendor>The Apache Software Foundation</Implementation-Vendor>
+ <url>${pom.url}</url>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <id>create-javadocs</id> <!-- this is used for inheritance merges -->
+ <phase>package</phase> <!-- append to the packaging phase. -->
+ <goals>
+ <goal>javadoc</goal> <!-- goals == mojos -->
+ <goal>jar</goal> <!-- goals == mojos -->
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-1</version>
+ <configuration>
+ <descriptorSourceDirectory>${basedir}/src/assemble/</descriptorSourceDirectory>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id> <!-- this is used for inheritance merges -->
+ <phase>package</phase> <!-- append to the packaging phase. -->
+ <goals>
+ <goal>attached</goal> <!-- goals == mojos -->
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- Add NOTICE and LICENSE to generated JAR -->
+ <plugin>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.0-alpha-5</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.apache:apache-jar-resource-bundle:1.2</resourceBundle>
+ </resourceBundles>
+ <properties>
+ <!-- <preProjectText>PRE PROCESS TEXT</preProjectText> -->
+ <!-- Our src distribution includes also the test dependencies and
+ maven remote resources doen't take this into account, so we
+ manualy add the junit disclaimer -->
+ <postProjectText>
+ This product includes/uses software, JUnit (http://www.junit.org/),
+developed by Kent Beck, Erich Gamma, and David Saff
+License: Common Public License Version 1.0 (http://www.opensource.org/licenses/cpl.php)
+
+This file is automatically generated by dependencies declared in pom.xml
+ </postProjectText>
+ <addLicense>true</addLicense>
+ </properties>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- Use the assembly or we won't have the LICENSE/NOTICE
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ -->
+ <!--
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ -->
+ </plugins>
+ </build>
+ <repositories>
+ <repository>
+ <id>local-mime4j-stage-repository</id>
+ <name>Local mime4j stage repository</name>
+ <!-- Please note that due to http://jira.codehaus.org/browse/MNG-2896 -->
+ <!-- If you don't have james-project checked out in ../james-project -->
+ <!-- you will have to place your absolute path to the project instead -->
+ <!-- of ${basedir}, or, otherwise, manually install the parent poms -->
+ <!--
+ mvn -fignorepom.xml install:install-file
+ -Dfile=stage\org.apache.james\poms\james-parent-1.1.pom
+ -Dpackaging=pom
+ -DgroupId=org.apache.james
+ -DartifactId=james-parent
+ -Dversion=1.1
+ mvn -fignorepom.xml install:install-file
+ -Dfile=stage\org.apache.james\poms\james-project-1.1.pom
+ -Dpackaging=pom
+ -DgroupId=org.apache.james
+ -DartifactId=james-project
+ -Dversion=1.1
+ -->
+ <url>file://${basedir}/stage</url>
+ <layout>legacy</layout>
+ <snapshots>
+ <enabled>true</enabled>
+ <checksumPolicy>ignore</checksumPolicy>
+ </snapshots>
+ <releases>
+ <enabled>true</enabled>
+ <checksumPolicy>ignore</checksumPolicy>
+ </releases>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>logkit</groupId>
+ <artifactId>logkit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>avalon-framework</groupId>
+ <artifactId>avalon-framework</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <type>jar</type>
+ <!-- Removed as a workaround for an unidentified M2 bug -->
+ <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.2</version>
+ </dependency>
+ </dependencies>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jxr-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>
\ No newline at end of file diff --git a/android/Fix My Street/bin/Fix My Street.apk b/android/Fix My Street/bin/Fix My Street.apk Binary files differdeleted file mode 100644 index 01bce8f62..000000000 --- a/android/Fix My Street/bin/Fix My Street.apk +++ /dev/null diff --git a/android/Fix My Street/bin/classes.dex b/android/Fix My Street/bin/classes.dex Binary files differdeleted file mode 100644 index f9d783b71..000000000 --- a/android/Fix My Street/bin/classes.dex +++ /dev/null diff --git a/android/Fix My Street/bin/resources.ap_ b/android/Fix My Street/bin/resources.ap_ Binary files differdeleted file mode 100644 index a482f9ea3..000000000 --- a/android/Fix My Street/bin/resources.ap_ +++ /dev/null diff --git a/android/Fix My Street/default.properties b/android/Fix My Street/default.properties new file mode 100644 index 000000000..08ad68f11 --- /dev/null +++ b/android/Fix My Street/default.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Indicates whether an apk should be generated for each density. +split.density=false +# Project target. +target=android-4 +apk-configurations= diff --git a/android/Fix My Street/res/drawable/blue_filler.xml b/android/Fix My Street/res/drawable/blue_filler.xml index 6e90b805f..5d2282a08 100644 --- a/android/Fix My Street/res/drawable/blue_filler.xml +++ b/android/Fix My Street/res/drawable/blue_filler.xml @@ -1,3 +1,3 @@ -<bitmap xmlns:android="http://schemas.android.com/apk/res/android" - android:src="@drawable/filler" android:tileMode="repeat" /> - +<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/filler" android:tileMode="repeat" />
+
diff --git a/android/Fix My Street/res/layout/about.xml b/android/Fix My Street/res/layout/about.xml index d95ffa470..1e413520b 100644 --- a/android/Fix My Street/res/layout/about.xml +++ b/android/Fix My Street/res/layout/about.xml @@ -1,45 +1,45 @@ -<?xml version="1.0" encoding="utf-8"?> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" android:layout_height="fill_parent" - android:padding="0dip" android:fillViewport="true"> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:padding="0dip"> - - <TextView android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="What is Fix My Street?" - android:paddingBottom="5dip" android:paddingTop="5dip" - android:paddingLeft="5dip" android:paddingRight="5dip" - android:textStyle="bold" /> - - <TextView android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="Fix My Street helps you report problems in your local area - like potholes or broken streetlights - to your council." - android:paddingBottom="5dip" android:paddingLeft="5dip" - android:paddingRight="5dip" /> - - <TextView android:id="@+id/faq" android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="Fix My Street is mainly a website, run by mySociety, a project of a registered charity. For more information, see http://www.fixmystreet.com/faq." - android:paddingBottom="5dip" android:paddingLeft="5dip" - android:paddingRight="5dip" android:linksClickable="true" /> - - - <TextView android:id="@+id/faq" android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="This application is version 0.8 of Fix My Street for Android, written as a volunteer project by Anna Powell-Smith." - android:paddingBottom="5dip" android:paddingLeft="5dip" - android:paddingRight="5dip" android:linksClickable="true" /> - - <TextView android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text=" " - android:layout_weight="1" /> - - <ImageView android:layout_width="fill_parent" android:scaleType="centerCrop" - android:layout_gravity="bottom" android:layout_height="wrap_content" - android:src="@drawable/street_background_smaller"></ImageView> - </LinearLayout> - +<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:padding="0dip" android:fillViewport="true">
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:padding="0dip">
+
+ <TextView android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="What is Fix My Street?"
+ android:paddingBottom="5dip" android:paddingTop="5dip"
+ android:paddingLeft="5dip" android:paddingRight="5dip"
+ android:textStyle="bold" />
+
+ <TextView android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Fix My Street helps you report problems in your local area - like potholes or broken streetlights - to your council."
+ android:paddingBottom="5dip" android:paddingLeft="5dip"
+ android:paddingRight="5dip" />
+
+ <TextView android:id="@+id/faq" android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Fix My Street is mainly a website, run by mySociety, a project of a registered charity. For more information, see http://www.fixmystreet.com/faq."
+ android:paddingBottom="5dip" android:paddingLeft="5dip"
+ android:paddingRight="5dip" android:linksClickable="true" />
+
+
+ <TextView android:id="@+id/faq2" android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text=""
+ android:paddingBottom="5dip" android:paddingLeft="5dip"
+ android:paddingRight="5dip" android:linksClickable="true" />
+
+ <TextView android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text=" "
+ android:layout_weight="1" />
+
+ <ImageView android:layout_width="fill_parent" android:scaleType="centerCrop"
+ android:layout_gravity="bottom" android:layout_height="wrap_content"
+ android:src="@drawable/street_background_smaller"></ImageView>
+ </LinearLayout>
+
</ScrollView>
\ No newline at end of file diff --git a/android/Fix My Street/res/layout/details.xml b/android/Fix My Street/res/layout/details.xml index 6a5bbe9aa..4464ed3f1 100644 --- a/android/Fix My Street/res/layout/details.xml +++ b/android/Fix My Street/res/layout/details.xml @@ -1,71 +1,71 @@ -<?xml version="1.0" encoding="utf-8"?> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" android:layout_height="fill_parent" - android:fillViewport="true"> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:padding="0dip"> - - <!-- And a name --> - <TextView android:id="@+id/name_save" android:layout_width="fill_parent" - android:paddingTop="5dip" android:paddingLeft="5dip" - android:paddingRight="5dip" android:layout_height="wrap_content" - android:text="Short title for problem (you can add more later):" /> - - <!-- Subject --> - - <LinearLayout android:layout_width="fill_parent" - android:layout_height="wrap_content" android:orientation="horizontal" - android:padding="5dip"> - <TextView android:id="@+id/subject_label" - android:layout_width="80sp" android:layout_height="24sp" - android:text="Title:" /> - <EditText android:id="@+id/subject_text" - android:layout_width="fill_parent" android:layout_height="40sp" - android:singleLine="True" android:capitalize="sentences" /> - </LinearLayout> - - <!-- And a name --> - <TextView android:id="@+id/name_save" android:layout_width="fill_parent" - android:paddingLeft="5dip" android:paddingRight="5dip" - android:layout_height="wrap_content" android:text="We'll save these for next time:" /> - - <LinearLayout android:layout_width="fill_parent" - android:layout_height="wrap_content" android:orientation="horizontal" - android:padding="5dip"> - <TextView android:id="@+id/name_label" android:layout_width="80sp" - android:layout_height="24sp" android:text="Your name:" /> - <EditText android:id="@+id/name_text" android:layout_width="fill_parent" - android:layout_height="40sp" android:singleLine="True" - android:capitalize="words" /> - </LinearLayout> - - <!-- An email address --> - - <LinearLayout android:layout_width="fill_parent" - android:layout_height="wrap_content" android:orientation="horizontal" - android:padding="5dip"> - <TextView android:id="@+id/email_label" - android:layout_width="80sp" android:layout_height="24sp" - android:text="Your email:" /> - <EditText android:id="@+id/email_text" android:layout_width="fill_parent" - android:layout_height="40sp" android:singleLine="True" - android:capitalize="none" /> - </LinearLayout> - - <Button android:id="@+id/submit_button" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="Save details" - android:padding="5dip" /> - - <TextView android:layout_width="fill_parent" - android:layout_weight="1" android:layout_height="wrap_content" - android:text=" " /> - - <ImageView android:layout_width="fill_parent" - android:scaleType="centerCrop" android:layout_gravity="bottom" - android:layout_height="wrap_content" android:src="@drawable/street_background_smaller"></ImageView> - </LinearLayout> - +<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:fillViewport="true">
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:padding="0dip">
+
+ <!-- And a name -->
+ <TextView android:id="@+id/name_save" android:layout_width="fill_parent"
+ android:paddingTop="5dip" android:paddingLeft="5dip"
+ android:paddingRight="5dip" android:layout_height="wrap_content"
+ android:text="Short title for problem (you can add more later):" />
+
+ <!-- Subject -->
+
+ <LinearLayout android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:orientation="horizontal"
+ android:padding="5dip">
+ <TextView android:id="@+id/subject_label"
+ android:layout_width="80sp" android:layout_height="24sp"
+ android:text="Title:" />
+ <EditText android:id="@+id/subject_text"
+ android:layout_width="fill_parent" android:layout_height="40sp"
+ android:singleLine="True" android:capitalize="sentences" />
+ </LinearLayout>
+
+ <!-- And a name -->
+ <TextView android:id="@+id/name_save" android:layout_width="fill_parent"
+ android:paddingLeft="5dip" android:paddingRight="5dip"
+ android:layout_height="wrap_content" android:text="We'll save these for next time:" />
+
+ <LinearLayout android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:orientation="horizontal"
+ android:padding="5dip">
+ <TextView android:id="@+id/name_label" android:layout_width="80sp"
+ android:layout_height="24sp" android:text="Your name:" />
+ <EditText android:id="@+id/name_text" android:layout_width="fill_parent"
+ android:layout_height="40sp" android:singleLine="True"
+ android:capitalize="words" />
+ </LinearLayout>
+
+ <!-- An email address -->
+
+ <LinearLayout android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:orientation="horizontal"
+ android:padding="5dip">
+ <TextView android:id="@+id/email_label"
+ android:layout_width="80sp" android:layout_height="24sp"
+ android:text="Your email:" />
+ <EditText android:id="@+id/email_text" android:layout_width="fill_parent"
+ android:layout_height="40sp" android:singleLine="True"
+ android:capitalize="none" />
+ </LinearLayout>
+
+ <Button android:id="@+id/submit_button" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="Save details"
+ android:padding="5dip" />
+
+ <TextView android:layout_width="fill_parent"
+ android:layout_weight="1" android:layout_height="wrap_content"
+ android:text=" " />
+
+ <ImageView android:layout_width="fill_parent"
+ android:scaleType="centerCrop" android:layout_gravity="bottom"
+ android:layout_height="wrap_content" android:src="@drawable/street_background_smaller"></ImageView>
+ </LinearLayout>
+
</ScrollView>
\ No newline at end of file diff --git a/android/Fix My Street/res/layout/help.xml b/android/Fix My Street/res/layout/help.xml index b14da6b1b..2ae8052d9 100644 --- a/android/Fix My Street/res/layout/help.xml +++ b/android/Fix My Street/res/layout/help.xml @@ -1,38 +1,38 @@ -<?xml version="1.0" encoding="utf-8"?> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" android:layout_height="fill_parent" - android:fillViewport="true"> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:padding="0dip" - android:scrollbars="vertical"> - - <TextView android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="What do I do?" - android:paddingBottom="5dip" android:paddingTop="5dip" - android:paddingLeft="5dip" android:paddingRight="5dip" - android:textStyle="bold" /> - - <TextView android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="@string/instructions" - android:paddingBottom="5dip" android:paddingLeft="5dip" - android:paddingRight="5dip" /> - - <TextView android:id="@+id/faq" android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="For any other questions, see http://www.fixmystreet.com/faq, or email anna@mysociety.org." - android:paddingBottom="5dip" android:paddingTop="5dip" - android:paddingLeft="5dip" android:paddingRight="5dip" - android:textStyle="bold" android:linksClickable="true" /> - - <TextView android:layout_width="fill_parent" android:layout_weight="1" - android:layout_height="wrap_content" android:text=" " - /> - - <ImageView android:layout_width="fill_parent" android:scaleType="centerCrop" - android:layout_gravity="bottom" android:layout_height="wrap_content" - android:src="@drawable/street_background_smaller"></ImageView> - </LinearLayout> +<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:fillViewport="true">
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:padding="0dip"
+ android:scrollbars="vertical">
+
+ <TextView android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="What do I do?"
+ android:paddingBottom="5dip" android:paddingTop="5dip"
+ android:paddingLeft="5dip" android:paddingRight="5dip"
+ android:textStyle="bold" />
+
+ <TextView android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="@string/instructions"
+ android:paddingBottom="5dip" android:paddingLeft="5dip"
+ android:paddingRight="5dip" />
+
+ <TextView android:id="@+id/faq" android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="For any other questions, see http://www.fixmystreet.com/faq, or email anna@mysociety.org."
+ android:paddingBottom="5dip" android:paddingTop="5dip"
+ android:paddingLeft="5dip" android:paddingRight="5dip"
+ android:textStyle="bold" android:linksClickable="true" />
+
+ <TextView android:layout_width="fill_parent" android:layout_weight="1"
+ android:layout_height="wrap_content" android:text=" "
+ />
+
+ <ImageView android:layout_width="fill_parent" android:scaleType="centerCrop"
+ android:layout_gravity="bottom" android:layout_height="wrap_content"
+ android:src="@drawable/street_background_smaller"></ImageView>
+ </LinearLayout>
</ScrollView>
\ No newline at end of file diff --git a/android/Fix My Street/res/layout/home.xml b/android/Fix My Street/res/layout/home.xml index 6e661461b..bcaae0669 100644 --- a/android/Fix My Street/res/layout/home.xml +++ b/android/Fix My Street/res/layout/home.xml @@ -1,36 +1,44 @@ -<?xml version="1.0" encoding="utf-8"?> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" android:layout_height="fill_parent" - android:fillViewport="true"> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:paddingTop="10dip"> - - <Button android:id="@+id/camera_button" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="Take photo" - android:drawableRight="@drawable/add" /> - - <Button android:id="@+id/details_button" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="Add details" - android:drawableRight="@drawable/add" android:paddingRight="10dip" - android:paddingLeft="10dip" /> - - <View android:layout_width="1dip" android:layout_height="10dip" - android:src="@drawable/spacer" /> - - <Button android:id="@+id/report_button" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="Report to Fix My Street" - android:paddingRight="10dip" android:paddingLeft="10dip" /> - <TextView android:layout_width="fill_parent" android:layout_weight="1" - android:layout_height="wrap_content" android:text=" " - /> - - <ImageView android:id="@+id/background_image" android:scaleType="centerCrop" - android:layout_width="fill_parent" android:layout_gravity="bottom" - android:layout_height="wrap_content" android:src="@drawable/street_background_smaller"></ImageView> - - </LinearLayout> - +<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:fillViewport="true">
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:paddingTop="10dip">
+
+ <Button android:id="@+id/camera_button" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="Take photo"
+ android:drawableRight="@drawable/add" />
+
+ <Button android:id="@+id/details_button" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="Add details"
+ android:drawableRight="@drawable/add" android:paddingRight="10dip"
+ android:paddingLeft="10dip" />
+
+ <View android:layout_width="1dip" android:layout_height="10dip"
+ android:src="@drawable/spacer" />
+
+ <TextView android:paddingRight="10dip" android:paddingLeft="10dip"
+ android:layout_width="wrap_content" android:textColor="#87190f"
+ android:id="@+id/progress_text" android:layout_height="wrap_content"
+ android:text="Waiting for a GPS fix... Please make sure you can see the sky." />
+
+ <Button android:id="@+id/report_button" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="Report to Fix My Street"
+ android:paddingRight="10dip" android:paddingLeft="10dip" />
+
+
+ <TextView android:layout_width="fill_parent"
+ android:layout_weight="1" android:layout_height="wrap_content"
+ android:text=" " />
+
+ <ImageView android:id="@+id/background_image"
+ android:scaleType="centerCrop" android:layout_width="fill_parent"
+ android:layout_gravity="bottom" android:layout_height="wrap_content"
+ android:src="@drawable/street_background_smaller"></ImageView>
+
+ </LinearLayout>
+
</ScrollView>
\ No newline at end of file diff --git a/android/Fix My Street/res/layout/success.xml b/android/Fix My Street/res/layout/success.xml index a80283cef..4c24055cc 100644 --- a/android/Fix My Street/res/layout/success.xml +++ b/android/Fix My Street/res/layout/success.xml @@ -1,44 +1,44 @@ -<?xml version="1.0" encoding="utf-8"?> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" android:layout_height="fill_parent" - android:fillViewport="true"> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:padding="0dip"> - - <!-- - <Button android:id="@+id/about_button" - android:layout_width="fill_parent" - android:layout_height="wrap_content" android:text="About Fix My - Street" /> - --> - - <TextView android:id="@+id/hello_text" android:layout_width="fill_parent" - android:paddingBottom="5dip" android:paddingTop="5dip" - android:paddingLeft="5dip" android:paddingRight="5dip" - android:layout_height="wrap_content" android:text="Now check your email!" - android:textStyle="bold" /> - - <TextView android:id="@+id/hello_text" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:paddingBottom="5dip" - android:paddingTop="5dip" android:paddingLeft="5dip" - android:paddingRight="5dip" - android:text="You'll receive an email from us soon. Please click on the confirmation link, and provide a few more details." /> - - <TextView android:id="@+id/hello_text" android:layout_width="fill_parent" - android:layout_height="wrap_content" android:paddingBottom="5dip" - android:paddingTop="5dip" android:paddingLeft="5dip" - android:paddingRight="5dip" - android:text="If the email doesn't arrive within a few hours, please check your spam folder - sometimes the emails can be marked as spam." /> - - <TextView android:layout_width="fill_parent" android:layout_weight="1" - android:layout_height="wrap_content" android:text=" " - /> - - <ImageView android:layout_width="fill_parent" android:scaleType="centerCrop" - android:layout_gravity="bottom" android:layout_height="wrap_content" - android:src="@drawable/street_background_smaller"></ImageView> - </LinearLayout> +<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:fillViewport="true">
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:padding="0dip">
+
+ <!--
+ <Button android:id="@+id/about_button"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:text="About Fix My
+ Street" />
+ -->
+
+ <TextView android:id="@+id/hello_text" android:layout_width="fill_parent"
+ android:paddingBottom="5dip" android:paddingTop="5dip"
+ android:paddingLeft="5dip" android:paddingRight="5dip"
+ android:layout_height="wrap_content" android:text="Now check your email!"
+ android:textStyle="bold" />
+
+ <TextView android:id="@+id/hello_text" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:paddingBottom="5dip"
+ android:paddingTop="5dip" android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:text="You'll receive an email from us soon. Please click on the confirmation link, check the location carefully, and provide a few more details." />
+
+ <TextView android:id="@+id/hello_text" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:paddingBottom="5dip"
+ android:paddingTop="5dip" android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:text="If the email doesn't arrive within a few hours, please check your spam folder - sometimes the emails can be marked as spam." />
+
+ <TextView android:layout_width="fill_parent" android:layout_weight="1"
+ android:layout_height="wrap_content" android:text=" "
+ />
+
+ <ImageView android:layout_width="fill_parent" android:scaleType="centerCrop"
+ android:layout_gravity="bottom" android:layout_height="wrap_content"
+ android:src="@drawable/street_background_smaller"></ImageView>
+ </LinearLayout>
</ScrollView>
\ No newline at end of file diff --git a/android/Fix My Street/res/values/colors.xml b/android/Fix My Street/res/values/colors.xml deleted file mode 100644 index 8f2f4dab3..000000000 --- a/android/Fix My Street/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ -<resources> - <color name="transparent">#8f00</color> - <color name="sky_blue">#87CEFA</color> - <color name="translucent_blue">#3A95E6</color> -<!-- #9DE0FF--> -</resources>
\ No newline at end of file diff --git a/android/Fix My Street/res/values/strings.xml b/android/Fix My Street/res/values/strings.xml index 78c16eecb..0c88c4ea7 100644 --- a/android/Fix My Street/res/values/strings.xml +++ b/android/Fix My Street/res/values/strings.xml @@ -2,18 +2,7 @@ <resources> <!-- Welcome screen --> <string name="app_name">Fix My Street</string> - <string name="hello">Fix My Street</string> - <string name="confirm_location">Confirming location...</string> - <string name="confirm_location_done">Confirmed location</string> - <string name="take_a_picture">Take a picture of the problem</string> - <string name="details">Add details</string> - <string name="report">Report</string> - <string name="about">About Fix My Street</string> - <string name="close">Close</string> - <string name="imageUrl">Enter a URL here</string> -<!-- Details screen --> - <string name="details_screen">Tell us about the problem (all fields required):</string> - <string name="submit">Submit</string> + <!-- About screen --> - <string name="instructions">1. Click \'Take photo\', then on the camera button to take a photo.\n2. Click \'Add details\', then give the problem a name (e.g. \'Broken street light\'), and add your own name and email address. \n3. Click \'Report\' to upload the problem to Fix My Street. \n4. Check your email. You\'ll need to click on a link to confirm the problem and add a few more details. </string> + <string name="instructions">1. Click \'Take photo\', then on the camera button to take a photo.\n2. Click \'Add details\', then give the problem a name (e.g. \'Broken street light\'), and add your own name and email address. \n3. Wait for a GPS fix (it\'ll take longer if it\'s cloudy). Then, click the \'Report\' button to upload the problem to Fix My Street. \n4. Check your email. You\'ll need to click on a link to confirm the problem and add a few more details. </string> </resources> diff --git a/android/Fix My Street/res/values/themes.xml b/android/Fix My Street/res/values/themes.xml index 39584c6a9..65ba3b328 100644 --- a/android/Fix My Street/res/values/themes.xml +++ b/android/Fix My Street/res/values/themes.xml @@ -1,6 +1,6 @@ -<resources> - <style name="Theme.Filler" parent="android:Theme"> - <item name="android:windowBackground">@drawable/blue_filler</item> - <item name="android:textColor">#000000</item> - </style> +<resources>
+ <style name="Theme.Filler" parent="android:Theme">
+ <item name="android:windowBackground">@drawable/blue_filler</item>
+ <item name="android:textColor">#000000</item>
+ </style>
</resources>
\ No newline at end of file diff --git a/android/Fix My Street/src/com/android/fixmystreet/About.java b/android/Fix My Street/src/com/android/fixmystreet/About.java index 9ddffadf6..07d323ce8 100644 --- a/android/Fix My Street/src/com/android/fixmystreet/About.java +++ b/android/Fix My Street/src/com/android/fixmystreet/About.java @@ -1,61 +1,73 @@ -package com.android.fixmystreet; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.text.util.Linkify; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.TextView; - -public class About extends Activity { - - private Bundle extras = null; - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.about); - extras = getIntent().getExtras(); - - // add links - TextView noteView = (TextView) findViewById(R.id.faq); - Linkify.addLinks(noteView, Linkify.ALL); - } - - // **************************************************** - // Options menu functions - // **************************************************** - - // TODO - add Bundles for these? - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - MenuItem homeItem = menu.add(0, 0, 0, "Home"); - MenuItem aboutItem = menu.add(0, 1, 0, "Help"); - aboutItem.setIcon(android.R.drawable.ic_menu_info_details); - homeItem.setIcon(android.R.drawable.ic_menu_edit); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case 0: - Intent i = new Intent(About.this, Home.class); - if (extras != null) { - i.putExtras(extras); - } - startActivity(i); - return true; - case 1: - Intent j = new Intent(About.this, Help.class); - if (extras != null) { - j.putExtras(extras); - } - startActivity(j); - return true; - } - return false; - } +package com.android.fixmystreet;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.text.util.Linkify;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TextView;
+
+public class About extends Activity {
+
+ private Bundle extras = null;
+ String versionName = "";
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.about);
+ extras = getIntent().getExtras();
+
+ try {
+ versionName = getPackageManager().getPackageInfo(getPackageName(),
+ 0).versionName;
+ } catch (NameNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ // add links
+ TextView noteView = (TextView) findViewById(R.id.faq);
+ TextView noteView2 = (TextView) findViewById(R.id.faq2);
+ noteView2.setText("This application is version " + versionName + " of Fix My Street for Android, written by Anna Powell-Smith. Thanks to Paul for testing.");
+ Linkify.addLinks(noteView, Linkify.ALL);
+ }
+
+ // ****************************************************
+ // Options menu functions
+ // ****************************************************
+
+ // TODO - add Bundles for these?
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuItem homeItem = menu.add(0, 0, 0, "Home");
+ MenuItem aboutItem = menu.add(0, 1, 0, "Help");
+ aboutItem.setIcon(android.R.drawable.ic_menu_info_details);
+ homeItem.setIcon(android.R.drawable.ic_menu_edit);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case 0:
+ Intent i = new Intent(About.this, Home.class);
+ if (extras != null) {
+ i.putExtras(extras);
+ }
+ startActivity(i);
+ return true;
+ case 1:
+ Intent j = new Intent(About.this, Help.class);
+ if (extras != null) {
+ j.putExtras(extras);
+ }
+ startActivity(j);
+ return true;
+ }
+ return false;
+ }
}
\ No newline at end of file diff --git a/android/Fix My Street/src/com/android/fixmystreet/Details.java b/android/Fix My Street/src/com/android/fixmystreet/Details.java index 83c5cc78c..802be0342 100644 --- a/android/Fix My Street/src/com/android/fixmystreet/Details.java +++ b/android/Fix My Street/src/com/android/fixmystreet/Details.java @@ -1,249 +1,252 @@ -// ******************************************************************************** -//details.java -//This file is where most of the work of the application happens. It collects the -//subject of the problem, plus the user's name and email, from the Android form. -//It uploads them to FixMyStreet, and shows a success or failure message. -// -//******************************************************************************** - -package com.android.fixmystreet; - -import java.util.regex.*; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -//import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.EditText; - -public class Details extends Activity { - private EditText nameET; - private EditText emailET; - private EditText subjectET; - String storedName; - String storedEmail; - private String subject; - private String name; - private String email; - private View submitButton; - //private static final String LOG_TAG = "Details"; - public static final String PREFS_NAME = "FMS_Settings"; - final int NAME_WARNING = 999; - final int SUBJECT_WARNING = 998; - final int EMAIL_WARNING = 997; - private Bundle extras; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // set up the page - setContentView(R.layout.details); - nameET = (EditText) findViewById(R.id.name_text); - emailET = (EditText) findViewById(R.id.email_text); - subjectET = (EditText) findViewById(R.id.subject_text); - submitButton = this.findViewById(R.id.submit_button); - - // set the button listeners - setListeners(); - - // fill in name/email, if already defined - // NB - from settings, rather than from bundle... - SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); - name = settings.getString("myName", ""); - email = settings.getString("myEmail", ""); - nameET.setText(name); - emailET.setText(email); - - extras = getIntent().getExtras(); - if (extras != null) { - // Details extras - subject = extras.getString("subject"); - } - if (subject != null) { - subjectET.setText(subject); - } - } - - private void setListeners() { - // Save info and pass back to Home activity - submitButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - subject = subjectET.getText().toString(); - email = emailET.getText().toString(); - name = nameET.getText().toString(); - if (!textFieldsAreValid(subject)) { - showDialog(SUBJECT_WARNING); - } else if (!textFieldsAreValid(name)) { - showDialog(NAME_WARNING); - } else if (!isValidEmailAddress(email)) { - showDialog(EMAIL_WARNING); - } else { - if (true) { - Intent i = new Intent(Details.this, Home.class); - extras.putString("name", name); - extras.putString("email", email); - extras.putString("subject", subject); - i.putExtras(extras); - startActivity(i); - } - } - } - }); - } - - // ********************************************************************** - // textFieldsAreValid: Make sure that fields aren't blank - // ********************************************************************** - public static boolean textFieldsAreValid(String field) { - if (field == null || field.length() == 0 || field.trim().length() == 0) { - return false; - } - return true; - } - - // ********************************************************************** - // isValidEmailAddress: Check the email address is OK - // ********************************************************************** - public static boolean isValidEmailAddress(String emailAddress) { - String emailRegEx; - Pattern pattern; - // Regex for a valid email address - emailRegEx = "^[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,4}$"; - // Compare the regex with the email address - pattern = Pattern.compile(emailRegEx); - Matcher matcher = pattern.matcher(emailAddress); - if (!matcher.find()) { - return false; - } - return true; - } - - // ********************************************************************** - // onCreateDialog: Dialog warnings - // ********************************************************************** - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case SUBJECT_WARNING: - return new AlertDialog.Builder(Details.this).setTitle("Subject") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }).setMessage("Please enter a subject!").create(); - case NAME_WARNING: - return new AlertDialog.Builder(Details.this) - .setTitle("Name") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }) - .setMessage( - "Please enter your name. We'll remember it for next time.") - .create(); - - case EMAIL_WARNING: - return new AlertDialog.Builder(Details.this) - .setTitle("Email") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }) - .setMessage( - "Please enter a valid email address. We'll remember it for next time.") - .create(); - - } - return null; - } - - // Save user's name and email, if already defined - @Override - protected void onStop() { - super.onStop(); - - name = nameET.getText().toString(); - email = emailET.getText().toString(); - - // Save user preferences - SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); - SharedPreferences.Editor editor = settings.edit(); - editor.putString("myName", name); - editor.putString("myEmail", email); - - // Don't forget to commit your edits!!! - editor.commit(); - } - - // Look at this - is it working ok - // public boolean testProviders() { - // Log.e(LOG_TAG, "testProviders"); - // // StringBuilder sb = new StringBuilder("Enabled Providers"); - // // List<String> providers = locationmanager.getProviders(true); - // // for (String provider : providers) { - // // Log.e(LOG_TAG, "Provider = " + provider); - // // listener = new LocationListener() { - // // public void onLocationChanged(Location location) { - // // } - // // - // // public void onProviderDisabled(String provider) { - // // } - // // - // // public void onProviderEnabled(String provider) { - // // } - // // - // // public void onStatusChanged(String provider, int status, - // // Bundle extras) { - // // } - // // }; - // // - // // locationmanager.requestLocationUpdates(provider, 0, 0, listener); - // // - // // sb.append("\n*").append(provider).append(": "); - // // - // // Location location = locationmanager.getLastKnownLocation(provider); - // // - // // if (location != null) { - // // latitude = location.getLatitude(); - // // longitude = location.getLongitude(); - // // latString = latitude.toString(); - // // longString = longitude.toString(); - // // Log.e(LOG_TAG, "Latitude = " + latString); - // // Log.e(LOG_TAG, "Longitude = " + longString); - // // if (provider == "gps") { - // // // Only bother with GPS if available - // // return true; - // // } - // // } else { - // // Log.e(LOG_TAG, "Location is null"); - // // return false; - // // } - // // } - // // LocationManager lm = (LocationManager) - // // context.getSystemService(Context.LOCATION_SERVICE); - // // - // // Location loc = lm.getLastKnownLocation("gps"); - // // if (loc == null) - // // { - // // locType = "Network"; - // // loc = lm.getLastKnownLocation("network"); - // // } - // // - // // textMsg.setText(sb); - // - // return true; - // } -} +// ********************************************************************************
+//details.java
+//This file is where most of the work of the application happens. It collects the
+//subject of the problem, plus the user's name and email, from the Android form.
+//It uploads them to FixMyStreet, and shows a success or failure message.
+//
+//********************************************************************************
+
+package com.android.fixmystreet;
+
+import java.util.regex.*;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.EditText;
+
+public class Details extends Activity {
+ private EditText nameET;
+ private EditText emailET;
+ private EditText subjectET;
+ String storedName;
+ String storedEmail;
+ private String subject;
+ private String name;
+ private String email;
+ private View submitButton;
+ //private static final String LOG_TAG = "Details";
+ public static final String PREFS_NAME = "Settings";
+ final int NAME_WARNING = 999;
+ final int SUBJECT_WARNING = 998;
+ final int EMAIL_WARNING = 997;
+ private Bundle extras;
+ private Boolean havePicture = false;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // set up the page
+ setContentView(R.layout.details);
+ nameET = (EditText) findViewById(R.id.name_text);
+ emailET = (EditText) findViewById(R.id.email_text);
+ subjectET = (EditText) findViewById(R.id.subject_text);
+ submitButton = this.findViewById(R.id.submit_button);
+
+ // set the button listeners
+ setListeners();
+
+ // fill in name/email, if already defined
+ // NB - from settings, rather than from bundle...
+ SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
+ name = settings.getString("myName", "");
+ email = settings.getString("myEmail", "");
+ nameET.setText(name);
+ emailET.setText(email);
+
+ extras = getIntent().getExtras();
+ if (extras != null) {
+ // Details extras
+ subject = extras.getString("subject");
+ havePicture = extras.getBoolean("photo", havePicture);
+// Log.d(LOG_TAG, "extras havePicture" + havePicture);
+ }
+ if (subject != null) {
+ subjectET.setText(subject);
+ }
+ }
+
+ private void setListeners() {
+ // Save info and pass back to Home activity
+ submitButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ subject = subjectET.getText().toString();
+ email = emailET.getText().toString();
+ name = nameET.getText().toString();
+ if (!textFieldsAreValid(subject)) {
+ showDialog(SUBJECT_WARNING);
+ } else if (!textFieldsAreValid(name)) {
+ showDialog(NAME_WARNING);
+ } else if (!isValidEmailAddress(email)) {
+ showDialog(EMAIL_WARNING);
+ } else {
+ if (true) {
+ Intent i = new Intent(Details.this, Home.class);
+ extras.putString("name", name);
+ extras.putString("email", email);
+ extras.putString("subject", subject);
+ extras.putBoolean("photo", havePicture);
+ i.putExtras(extras);
+ startActivity(i);
+ }
+ }
+ }
+ });
+ }
+
+ // **********************************************************************
+ // textFieldsAreValid: Make sure that fields aren't blank
+ // **********************************************************************
+ public static boolean textFieldsAreValid(String field) {
+ if (field == null || field.length() == 0 || field.trim().length() == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ // **********************************************************************
+ // isValidEmailAddress: Check the email address is OK
+ // **********************************************************************
+ public static boolean isValidEmailAddress(String emailAddress) {
+ String emailRegEx;
+ Pattern pattern;
+ // Regex for a valid email address
+ emailRegEx = "^[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,4}$";
+ // Compare the regex with the email address
+ pattern = Pattern.compile(emailRegEx);
+ Matcher matcher = pattern.matcher(emailAddress);
+ if (!matcher.find()) {
+ return false;
+ }
+ return true;
+ }
+
+ // **********************************************************************
+ // onCreateDialog: Dialog warnings
+ // **********************************************************************
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ switch (id) {
+ case SUBJECT_WARNING:
+ return new AlertDialog.Builder(Details.this).setTitle("Subject")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ }).setMessage("Please enter a subject!").create();
+ case NAME_WARNING:
+ return new AlertDialog.Builder(Details.this)
+ .setTitle("Name")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ })
+ .setMessage(
+ "Please enter your name. We'll remember it for next time.")
+ .create();
+
+ case EMAIL_WARNING:
+ return new AlertDialog.Builder(Details.this)
+ .setTitle("Email")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ })
+ .setMessage(
+ "Please enter a valid email address. We'll remember it for next time.")
+ .create();
+
+ }
+ return null;
+ }
+
+ // Save user's name and email, if already defined
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ name = nameET.getText().toString();
+ email = emailET.getText().toString();
+
+ // Save user preferences
+ SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
+ SharedPreferences.Editor editor = settings.edit();
+ editor.putString("myName", name);
+ editor.putString("myEmail", email);
+
+ // Don't forget to commit your edits!!!
+ editor.commit();
+ }
+
+ // Look at this - is it working ok
+ // public boolean testProviders() {
+ // Log.e(LOG_TAG, "testProviders");
+ // // StringBuilder sb = new StringBuilder("Enabled Providers");
+ // // List<String> providers = locationmanager.getProviders(true);
+ // // for (String provider : providers) {
+ // // Log.e(LOG_TAG, "Provider = " + provider);
+ // // listener = new LocationListener() {
+ // // public void onLocationChanged(Location location) {
+ // // }
+ // //
+ // // public void onProviderDisabled(String provider) {
+ // // }
+ // //
+ // // public void onProviderEnabled(String provider) {
+ // // }
+ // //
+ // // public void onStatusChanged(String provider, int status,
+ // // Bundle extras) {
+ // // }
+ // // };
+ // //
+ // // locationmanager.requestLocationUpdates(provider, 0, 0, listener);
+ // //
+ // // sb.append("\n*").append(provider).append(": ");
+ // //
+ // // Location location = locationmanager.getLastKnownLocation(provider);
+ // //
+ // // if (location != null) {
+ // // latitude = location.getLatitude();
+ // // longitude = location.getLongitude();
+ // // latString = latitude.toString();
+ // // longString = longitude.toString();
+ // // Log.e(LOG_TAG, "Latitude = " + latString);
+ // // Log.e(LOG_TAG, "Longitude = " + longString);
+ // // if (provider == "gps") {
+ // // // Only bother with GPS if available
+ // // return true;
+ // // }
+ // // } else {
+ // // Log.e(LOG_TAG, "Location is null");
+ // // return false;
+ // // }
+ // // }
+ // // LocationManager lm = (LocationManager)
+ // // context.getSystemService(Context.LOCATION_SERVICE);
+ // //
+ // // Location loc = lm.getLastKnownLocation("gps");
+ // // if (loc == null)
+ // // {
+ // // locType = "Network";
+ // // loc = lm.getLastKnownLocation("network");
+ // // }
+ // //
+ // // textMsg.setText(sb);
+ //
+ // return true;
+ // }
+}
diff --git a/android/Fix My Street/src/com/android/fixmystreet/Help.java b/android/Fix My Street/src/com/android/fixmystreet/Help.java index 3153ffe3c..6445992d8 100644 --- a/android/Fix My Street/src/com/android/fixmystreet/Help.java +++ b/android/Fix My Street/src/com/android/fixmystreet/Help.java @@ -1,59 +1,59 @@ -package com.android.fixmystreet; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.text.util.Linkify; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.TextView; - -public class Help extends Activity { - private Bundle extras = null; - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - extras = getIntent().getExtras(); - setContentView(R.layout.help); - TextView noteView = (TextView) findViewById(R.id.faq); - Linkify.addLinks(noteView, Linkify.ALL); - } - - // **************************************************** - // Options menu functions - // **************************************************** - - // TODO - add Bundles for these? - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - MenuItem homeItem = menu.add(0, 0, 0, "Home"); - MenuItem aboutItem = menu.add(0, 1, 0, "About"); - homeItem.setIcon(android.R.drawable.ic_menu_edit); - aboutItem.setIcon(android.R.drawable.ic_menu_info_details); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case 0: - Intent i = new Intent(Help.this, Home.class); - if (extras != null) { - i.putExtras(extras); - } - startActivity(i); - return true; - case 1: - Intent j = new Intent(Help.this, About.class); - if (extras != null) { - j.putExtras(extras); - } - startActivity(j); - return true; - } - return false; - } -} +package com.android.fixmystreet;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.util.Linkify;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TextView;
+
+public class Help extends Activity {
+ private Bundle extras = null;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ extras = getIntent().getExtras();
+ setContentView(R.layout.help);
+ TextView noteView = (TextView) findViewById(R.id.faq);
+ Linkify.addLinks(noteView, Linkify.ALL);
+ }
+
+ // ****************************************************
+ // Options menu functions
+ // ****************************************************
+
+ // TODO - add Bundles for these?
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuItem homeItem = menu.add(0, 0, 0, "Home");
+ MenuItem aboutItem = menu.add(0, 1, 0, "About");
+ homeItem.setIcon(android.R.drawable.ic_menu_edit);
+ aboutItem.setIcon(android.R.drawable.ic_menu_info_details);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case 0:
+ Intent i = new Intent(Help.this, Home.class);
+ if (extras != null) {
+ i.putExtras(extras);
+ }
+ startActivity(i);
+ return true;
+ case 1:
+ Intent j = new Intent(Help.this, About.class);
+ if (extras != null) {
+ j.putExtras(extras);
+ }
+ startActivity(j);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/android/Fix My Street/src/com/android/fixmystreet/Home.java b/android/Fix My Street/src/com/android/fixmystreet/Home.java index 38875fd2b..e0543c77f 100644 --- a/android/Fix My Street/src/com/android/fixmystreet/Home.java +++ b/android/Fix My Street/src/com/android/fixmystreet/Home.java @@ -1,726 +1,719 @@ -// ************************************************************************** -// Home.java -// ************************************************************************** -package com.android.fixmystreet; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource; -import org.apache.commons.httpclient.methods.multipart.FilePart; -import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; -import org.apache.commons.httpclient.methods.multipart.Part; -import org.apache.commons.httpclient.methods.multipart.StringPart; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; - -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.os.Handler; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Button; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.provider.MediaStore; -import android.view.View; -import android.view.View.OnClickListener; - -public class Home extends Activity { - // **************************************************** - // Local variables - // **************************************************** - //private static final String LOG_TAG = "Home"; - private Button btnReport; - private Button btnDetails; - private Button btnPicture; - // Info that's been passed from other activities - private Boolean haveDetails = false; - private Boolean havePicture = false; - private String name = null; - private String email = null; - private String subject = null; - // Location info - LocationManager locationmanager; - LocationListener listener; - private Double latitude; - private Double longitude; - private String latString = ""; - private String longString = ""; - // hacky way of checking the results - private static int globalStatus = 13; - private static final int SUCCESS = 0; - private static final int LOCATION_NOT_FOUND = 1; - private static final int UPLOAD_ERROR = 2; - private static final int UPLOAD_ERROR_SERVER = 3; - private static final int LOCATION_NOT_ACCURATE = 4; - private static final int PHOTO_NOT_FOUND = 5; - private String serverResponse; - // Thread handling - ProgressDialog myProgressDialog = null; - private ProgressDialog pd; - final Handler mHandler = new Handler(); - final Runnable mUpdateResults = new Runnable() { - public void run() { - pd.dismiss(); - updateResultsInUi(); - } - }; - private Bundle extras; - //private Bitmap bmp = null; - - // Called when the activity is first created - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.home); - - testProviders(); - // showDialog(); - - btnDetails = (Button) findViewById(R.id.details_button); - btnPicture = (Button) findViewById(R.id.camera_button); - btnReport = (Button) findViewById(R.id.report_button); - btnReport.setVisibility(View.GONE); - - if (icicle != null) { - havePicture = icicle.getBoolean("photo"); - } - - extras = getIntent().getExtras(); - checkBundle(); - setListeners(); - } - - @Override - protected void onPause() { - //Log.d("onPause, havePicture = " + havePicture); - removeListeners(); - saveState(); - super.onPause(); - } - - @Override - protected void onStop() { - //Log.d(LOG_TAG, "onStop, havePicture = " + havePicture); - removeListeners(); - super.onStop(); - } - - @Override - public void onRestart() { - //Log.d(LOG_TAG, "onRestart, havePicture = " + havePicture); - testProviders(); - checkBundle(); - super.onRestart(); - } - - // **************************************************** - // checkBundle - check the extras that have been passed - // is the user able to upload things yet, or not? - // **************************************************** - private void checkBundle() { - //Log.d(LOG_TAG, "checkBundle"); - - // Get the status icons... - Resources res = getResources(); - Drawable checked = res.getDrawable(R.drawable.done); - - if (extras != null) { - // Details extras - name = extras.getString("name"); - email = extras.getString("email"); - subject = extras.getString("subject"); - havePicture = extras.getBoolean("photo"); - - // Do we have the details? - if ((name != null) && (email != null) && (subject != null)) { - haveDetails = true; - //Log.d(LOG_TAG, "Have all details"); - checked.setBounds(0, 0, checked.getIntrinsicWidth(), checked - .getIntrinsicHeight()); - // envelope.setBounds(0, 0, envelope.getIntrinsicWidth(), - // envelope - // .getIntrinsicHeight()); - btnDetails.setText("Details added: '" + subject + "'"); - btnDetails.setCompoundDrawables(null, null, checked, null); - } else { - //Log.d(LOG_TAG, "Don't have details"); - } - } else { - extras = new Bundle(); - //Log.d(LOG_TAG, "no Bundle at all"); - } - //Log.d(LOG_TAG, "havePicture = " + havePicture); - - // Do we have the photo? - if (havePicture) { - - checked.setBounds(0, 0, checked.getIntrinsicWidth(), checked - .getIntrinsicHeight()); - // camera.setBounds(0, 0, camera.getIntrinsicWidth(), camera - // .getIntrinsicHeight()); - btnPicture.setCompoundDrawables(null, null, checked, null); - btnPicture.setText("Photo taken"); - // code for if we wanted to show a thumbnail - works but crashes - // ImageView iv = (ImageView) findViewById(R.id.thumbnail); - // try { - // Log.d(LOG_TAG, "Trying to look for FMS photo"); - // FileInputStream fstream = null; - // fstream = new FileInputStream(Environment - // .getExternalStorageDirectory() - // + "/" + "FMS_photo.jpg"); - // Log.d("Looking for file at ", Environment - // .getExternalStorageDirectory() - // + "/" + "FMS_photo.jpg"); - // bmp = BitmapFactory.decodeStream(fstream); - // // bmp = BitmapFactory - // // .decodeStream(openFileInput("FMS_photo.jpg")); - // iv.setImageBitmap(bmp); - // System.gc(); - // } catch (FileNotFoundException e) { - // // TODO Auto-generated catch block - // Log.d(LOG_TAG, "FMS photo not found"); - // e.printStackTrace(); - // } - } - - // We have details and photo - show the Report button - if (haveDetails && havePicture) { - btnReport.setVisibility(View.VISIBLE); - } - } - - // **************************************************** - // setListeners - set the button listeners - // **************************************************** - - private void setListeners() { - btnDetails.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - Intent i = new Intent(Home.this, Details.class); - extras.putString("name", name); - extras.putString("email", email); - extras.putString("subject", subject); - i.putExtras(extras); - startActivity(i); - } - }); - btnPicture.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - File photo = new File( - Environment.getExternalStorageDirectory(), - "FMS_photo.jpg"); - if (photo.exists()) { - photo.delete(); - } - Intent imageCaptureIntent = new Intent( - MediaStore.ACTION_IMAGE_CAPTURE); - imageCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri - .fromFile(photo)); - startActivityForResult(imageCaptureIntent, 1); - } - }); - btnReport.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - uploadToFMS(); - } - }); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - //Log.d(LOG_TAG, "onActivityResult"); - //Log.d(LOG_TAG, "Activity.RESULT_OK code = " + Activity.RESULT_OK); - //Log.d(LOG_TAG, "resultCode = " + resultCode + "requestCode = " - // + requestCode); - if (resultCode == Activity.RESULT_OK && requestCode == 1) { - havePicture = true; - extras.putBoolean("photo", true); - } - //testProviders(); - //Log.d(LOG_TAG, "havePicture = " + havePicture.toString()); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - //Log.d(LOG_TAG, "onSaveInstanceState"); - if (havePicture != null) { - // Log.d(LOG_TAG, "mRowId = " + mRowId); - outState.putBoolean("photo", havePicture); - } - // if (name != null) { - // // Log.d(LOG_TAG, "mRowId = " + mRowId); - // outState.putString("name", name); - // } - // if (email != null) { - // // Log.d(LOG_TAG, "mRowId = " + mRowId); - // outState.putString("email", email); - // } - // if (subject != null) { - // // Log.d(LOG_TAG, "mRowId = " + mRowId); - // outState.putString("subject", subject); - // } - } - - // TODO - save bits and pieces here - private void saveState() { - // Log.d(LOG_TAG, "saveState"); - // String body = mBodyText.getText().toString(); - // String title = mTitleText.getText().toString(); - // // Log.d(LOG_TAG, "title valid"); - // if (mRowId == null) { - // // Log.d(LOG_TAG, "mRowId = null, creating note"); - // long id = mDbHelper.createNote(body, title); - // if (id > 0) { - // mRowId = id; - // // Log.d(LOG_TAG, "Set mRowId to " + mRowId); - // } - // } else { - // // Log.d(LOG_TAG, "mRowId = " + mRowId + ", updating note"); - // mDbHelper.updateNote(mRowId, body, title); - // } - } - - // ********************************************************************** - // uploadToFMS: uploads details, handled via a background thread - // Also checks the age and accuracy of the GPS data first - // ********************************************************************** - private void uploadToFMS() { - //Log.d(LOG_TAG, "uploadToFMS"); - pd = ProgressDialog - .show( - this, - "Uploading, please wait...", - "Uploading. This can take up to a minute, depending on your connection speed. Please be patient!", - true, false); - Thread t = new Thread() { - public void run() { - doUploadinBackground(); - mHandler.post(mUpdateResults); - } - }; - t.start(); - } - - private void updateResultsInUi() { - if (globalStatus == UPLOAD_ERROR) { - showDialog(UPLOAD_ERROR); - } else if (globalStatus == UPLOAD_ERROR_SERVER) { - showDialog(UPLOAD_ERROR_SERVER); - } else if (globalStatus == LOCATION_NOT_FOUND) { - showDialog(LOCATION_NOT_FOUND); - } else if (globalStatus == PHOTO_NOT_FOUND) { - showDialog(PHOTO_NOT_FOUND); - } else if (globalStatus == LOCATION_NOT_ACCURATE) { - showDialog(LOCATION_NOT_ACCURATE); - } else { - // Success! - Proceed to the success activity! - Intent i = new Intent(Home.this, Success.class); - i.putExtra("latString", latString); - i.putExtra("lonString", longString); - startActivity(i); - } - } - - // ********************************************************************** - // onCreateDialog: Dialog warnings - // ********************************************************************** - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case UPLOAD_ERROR: - return new AlertDialog.Builder(Home.this) - .setTitle("Upload error") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }) - .setMessage( - "Sorry, there was an error uploading - maybe the network connection is down? Please try again later.") - .create(); - case UPLOAD_ERROR_SERVER: - return new AlertDialog.Builder(Home.this) - .setTitle("Upload error") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }) - .setMessage( - "Sorry, there was an error uploading. Please try again later. The server response was: " - + serverResponse).create(); - case LOCATION_NOT_FOUND: - return new AlertDialog.Builder(Home.this) - .setTitle("GPS problem") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }) - .setMessage( - "Could not get location! Can you see the sky? Please try again later.") - .create(); - case PHOTO_NOT_FOUND: - return new AlertDialog.Builder(Home.this).setTitle("No photo") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }).setMessage("Photo not found!").create(); - case LOCATION_NOT_ACCURATE: - return new AlertDialog.Builder(Home.this) - .setTitle("GPS problem") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - } - }) - .setMessage( - "Sorry, your GPS location is not accurate enough. Can you see the sky?") - .create(); - } - return null; - } - - // ********************************************************************** - // doUploadinBackground: POST request to FixMyStreet - // ********************************************************************** - private boolean doUploadinBackground() { - //Log.d(LOG_TAG, "doUploadinBackground"); - - String responseString = null; - PostMethod method; - - // DefaultHttpClient httpClient; - // HttpPost httpPost; - // HttpResponse response; - // HttpEntity entity; - // UrlEncodedFormEntity urlentity; - // // get the photo data from the URI - // // Uri uri = (Uri) content.getParcelable("URI"); - // Context context = getApplicationContext(); - // ContentResolver cR = context.getContentResolver(); - // - // // Get the type of the file - // MimeTypeMap mime = MimeTypeMap.getSingleton(); - // String type = mime.getExtensionFromMimeType(cR.getType(uri)); - // - // // Get the InputStream - // InputStream in = null; - // - // try { - // in = cR.openInputStream(uri); - // } catch (FileNotFoundException e) { - // // TODO Auto-generated catch block - // e.printStackTrace(); - // } - // - // if (in == null) { - // globalStatus = PHOTO_NOT_FOUND; - // return false; - // } - // - // // Setting the InputStream Body - // InputStreamBody body = new InputStreamBody(in, "image." + type); - - // TODO - check location updates - Location location = locationmanager - .getLastKnownLocation(LocationManager.GPS_PROVIDER); - - if (location != null) { - // TODO - put back in - long currentTime = System.currentTimeMillis(); - long gpsTime = location.getTime(); - long timeDiffSecs = (currentTime - gpsTime) / 1000; - //Log.e(LOG_TAG, "Location accuracy = " + location.getAccuracy()); - //Log.e(LOG_TAG, "Location age = " + timeDiffSecs); - if ((location.getAccuracy() > 150) || (timeDiffSecs > 15)) { - //Log.e(LOG_TAG, "Location not accurate"); - globalStatus = LOCATION_NOT_ACCURATE; - return false; - } - latitude = location.getLatitude(); - longitude = location.getLongitude(); - latString = latitude.toString(); - longString = longitude.toString(); - //Log.e(LOG_TAG, "Latitude = " + latString); - //Log.e(LOG_TAG, "Longitude = " + longString); - } else { - //Log.e(LOG_TAG, "Location is null"); - globalStatus = LOCATION_NOT_FOUND; - return false; - } - - // TEMP - testing - // latString = "51.5"; - // longString = "-0.116667"; - - method = new PostMethod("http://www.fixmystreet.com/import"); - - try { - - // Bitmap bitmap; - // ByteArrayOutputStream imageByteStream; - byte[] imageByteArray = null; - // ByteArrayPartSource fileSource; - - HttpClient client = new HttpClient(); - client.getHttpConnectionManager().getParams().setConnectionTimeout( - 100000); - - // InputStream in = - // this.getResources().openRawResource(R.drawable.tom); - // bitmap = android.provider.MediaStore.Images.Media.getBitmap( - // getContentResolver(), uri); - // imageByteStream = new ByteArrayOutputStream(); - - // if (bitmap == null) { - // Log.d(LOG_TAG, "No bitmap"); - // } - - // Compress bmp to jpg, write to the bytes output stream - // bitmap.compress(Bitmap.CompressFormat.JPEG, 80, imageByteStream); - - // Turn the byte stream into a byte array, write to imageData - // imageByteArray = imageByteStream.toByteArray(); - - File f = new File(Environment.getExternalStorageDirectory(), - "FMS_photo.jpg"); - - // TODO - add a check here - if (!f.exists()) { - } - imageByteArray = getBytesFromFile(f); - -// Log -// .d(LOG_TAG, "len of data is " + imageByteArray.length -// + " bytes"); - - // fileSource = new ByteArrayPartSource("photo", imageData); - FilePart photo = new FilePart("photo", new ByteArrayPartSource( - "photo", imageByteArray)); - - photo.setContentType("image/jpeg"); - photo.setCharSet(null); - - Part[] parts = { new StringPart("service", "your Android phone"), - new StringPart("subject", subject), - new StringPart("name", name), - new StringPart("email", email), - new StringPart("lat", latString), - new StringPart("lon", longString), photo }; - - method.setRequestEntity(new MultipartRequestEntity(parts, method - .getParams())); - - client.executeMethod(method); - responseString = method.getResponseBodyAsString(); - method.releaseConnection(); - - Log.e("httpPost", "Response status: " + responseString); - Log.e("httpPost", "Latitude = " + latString + " and Longitude = " - + longString); - - // textMsg.setText("Bitmap (bitmap) = " + bitmap.toString() - // + " AND imageByteArray (byte[]) = " - // + imageByteArray.toString() - // + " AND imageByteStream (bytearrayoutputstream) = " - // + imageByteStream.toString()); - - } catch (Exception ex) { - //Log.v(LOG_TAG, "Exception", ex); - globalStatus = UPLOAD_ERROR; - serverResponse = ""; - return false; - } finally { - method.releaseConnection(); - } - - if (responseString.equals("SUCCESS")) { - // launch the Success page - globalStatus = SUCCESS; - return true; - } else { - // print the response string? - serverResponse = responseString; - globalStatus = UPLOAD_ERROR; - return false; - } - } - - public void testProviders() { - //Log.e(LOG_TAG, "testProviders"); - // Register for location listener - String location_context = Context.LOCATION_SERVICE; - locationmanager = (LocationManager) getSystemService(location_context); - // StringBuilder sb = new StringBuilder("Enabled Providers"); - // List<String> providers = locationmanager.getProviders(true); - // for (String provider : providers) { - listener = new LocationListener() { - public void onLocationChanged(Location location) { - } - - public void onProviderDisabled(String provider) { - } - - public void onProviderEnabled(String provider) { - } - - public void onStatusChanged(String provider, int status, - Bundle extras) { - } - }; - locationmanager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, - 0, listener); - if (!locationmanager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { - buildAlertMessageNoGps(); - } - } - - private void buildAlertMessageNoGps() { - final AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder - .setMessage( - "Your GPS seems to be disabled. Do you want to turn it on now?") - .setCancelable(false).setPositiveButton("Yes", - new DialogInterface.OnClickListener() { - public void onClick( - @SuppressWarnings("unused") final DialogInterface dialog, - @SuppressWarnings("unused") final int id) { - Intent j = new Intent(); - j - .setAction("android.settings.LOCATION_SOURCE_SETTINGS"); - startActivity(j); - } - }).setNegativeButton("No", - new DialogInterface.OnClickListener() { - public void onClick(final DialogInterface dialog, - @SuppressWarnings("unused") final int id) { - dialog.cancel(); - } - }); - final AlertDialog alert = builder.create(); - alert.show(); - } - - public void removeListeners() { - //Log.e(LOG_TAG, "removeListeners"); - if (locationmanager != null) { - locationmanager.removeUpdates(listener); - } - locationmanager = null; - //Log.d(LOG_TAG, "Removed " + listener.toString()); - } - - // **************************************************** - // Options menu functions - // **************************************************** - - // TODO - add Bundles for these? - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - MenuItem helpItem = menu.add(0, 0, 0, "Help"); - MenuItem aboutItem = menu.add(0, 1, 0, "About"); - aboutItem.setIcon(android.R.drawable.ic_menu_info_details); - helpItem.setIcon(android.R.drawable.ic_menu_help); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case 0: - Intent i = new Intent(Home.this, Help.class); - if (extras != null) { - i.putExtras(extras); - } - startActivity(i); - return true; - case 1: - Intent j = new Intent(Home.this, About.class); - if (extras != null) { - j.putExtras(extras); - } - startActivity(j); - return true; - } - return false; - } - - // read the photo file into a byte array... - public static byte[] getBytesFromFile(File file) throws IOException { - InputStream is = new FileInputStream(file); - - // Get the size of the file - long length = file.length(); - - // You cannot create an array using a long type. - // It needs to be an int type. - // Before converting to an int type, check - // to ensure that file is not larger than Integer.MAX_VALUE. - if (length > Integer.MAX_VALUE) { - // File is too large - } - - // Bitmap bitmap; - // ByteArrayOutputStream imageByteStream; - // byte[] imageByteArray = null; - - // InputStream in = - // this.getResources().openRawResource(R.drawable.tom); - // bitmap = android.provider.MediaStore.Images.Media.getBitmap( - // getContentResolver(), uri); - // imageByteStream = new ByteArrayOutputStream(); - - // Compress bmp to jpg, write to the bytes output stream - // bitmap.compress(Bitmap.CompressFormat.JPEG, 80, imageByteStream); - - // Turn the byte stream into a byte array, write to imageData - // imageByteArray = imageByteStream.toByteArray(); - - // Create the byte array to hold the data - byte[] bytes = new byte[(int) length]; - - // Read in the bytes - int offset = 0; - int numRead = 0; - while (offset < bytes.length - && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { - offset += numRead; - } - - // Ensure all the bytes have been read in - if (offset < bytes.length) { - throw new IOException("Could not completely read file " - + file.getName()); - } - - // Close the input stream and return bytes - is.close(); - return bytes; - } -} +// **************************************************************************
+// Home.java
+// **************************************************************************
+package com.android.fixmystreet;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.StringPart;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Button;
+import android.widget.TextView;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.provider.MediaStore;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+public class Home extends Activity {
+ // ****************************************************
+ // Local variables
+ // ****************************************************
+ private static final String LOG_TAG = "Home";
+ public static final String PREFS_NAME = "FMS_Settings";
+ private Button btnReport;
+ private Button btnDetails;
+ private Button btnPicture;
+ // Info that's been passed from other activities
+ private Boolean haveDetails = false;
+ private Boolean havePicture = false;
+ private String name = null;
+ private String email = null;
+ private String subject = null;
+ // Location info
+ LocationManager locationmanager = null;
+ LocationListener listener;
+ Location location;
+ private Double latitude;
+ private Double longitude;
+ private String latString = "";
+ private String longString = "";
+ long firstGPSFixTime = 0;
+ long latestGPSFixTime = 0;
+ long previousGPSFixTime = 0;
+ private Boolean locationDetermined = false;
+ int locAccuracy;
+ long locationTimeStored = 0;
+ // hacky way of checking the results
+ private static int globalStatus = 13;
+ private static final int SUCCESS = 0;
+ private static final int LOCATION_NOT_FOUND = 1;
+ private static final int UPLOAD_ERROR = 2;
+ private static final int UPLOAD_ERROR_SERVER = 3;
+ private static final int PHOTO_NOT_FOUND = 5;
+ private static final int UPON_UPDATE = 6;
+ private static final int COUNTRY_ERROR = 7;
+ private String serverResponse;
+ SharedPreferences settings;
+ String versionName = null;
+ // Thread handling
+ ProgressDialog myProgressDialog = null;
+ private ProgressDialog pd;
+ final Handler mHandler = new Handler();
+ final Runnable mUpdateResults = new Runnable() {
+ public void run() {
+ pd.dismiss();
+ updateResultsInUi();
+ }
+ };
+ private Bundle extras;
+ private TextView textProgress;
+ private String exception_string = "";
+
+ // Called when the activity is first created
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.home);
+ // Log.d(LOG_TAG, "onCreate, havePicture = " + havePicture);
+ settings = getSharedPreferences(PREFS_NAME, 0);
+ testProviders();
+
+ btnDetails = (Button) findViewById(R.id.details_button);
+ btnPicture = (Button) findViewById(R.id.camera_button);
+ btnReport = (Button) findViewById(R.id.report_button);
+ btnReport.setVisibility(View.GONE);
+ textProgress = (TextView) findViewById(R.id.progress_text);
+ textProgress.setVisibility(View.GONE);
+
+ if (icicle != null) {
+ havePicture = icicle.getBoolean("photo");
+ Log.d(LOG_TAG, "icicle not null, havePicture = " + havePicture);
+ } else {
+ Log.d(LOG_TAG, "icicle null");
+ }
+ extras = getIntent().getExtras();
+ checkBundle();
+ setListeners();
+
+ // Show update message - but not to new users
+ int vc = 0;
+ try {
+ vc = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
+ versionName = getPackageManager().getPackageInfo(getPackageName(),
+ 0).versionName;
+ } catch (NameNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ // TODO - add this code next time!
+ boolean hasSeenUpdateVersion = settings.getBoolean(
+ "hasSeenUpdateVersion" + vc, false);
+ boolean hasSeenOldVersion = settings.getBoolean("hasSeenUpdateVersion"
+ + (vc - 1), false);
+ if (!hasSeenUpdateVersion && hasSeenOldVersion) {
+ showDialog(UPON_UPDATE);
+ SharedPreferences.Editor editor = settings.edit();
+ editor.putBoolean("hasSeenUpdateVersion" + vc, true);
+ editor.commit();
+ }
+
+ // Check country: show warning if not in Great Britain
+ TelephonyManager mTelephonyMgr = (TelephonyManager) this
+ .getSystemService(Context.TELEPHONY_SERVICE);
+ String country = mTelephonyMgr.getNetworkCountryIso();
+ //Log.d(LOG_TAG, "country = " + country);
+ if (!(country.matches("gb"))) {
+ showDialog(COUNTRY_ERROR);
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ // Log.d(LOG_TAG, "onPause, havePicture = " + havePicture);
+ super.onPause();
+ removeListeners();
+ }
+
+ @Override
+ protected void onStop() {
+ // Log.d(LOG_TAG, "onStop, havePicture = " + havePicture);
+ super.onStop();
+ removeListeners();
+ }
+
+ @Override
+ public void onRestart() {
+ // Log.d(LOG_TAG, "onRestart, havePicture = " + havePicture);
+ testProviders();
+ checkBundle();
+ super.onRestart();
+ }
+
+ // ****************************************************
+ // checkBundle - check the extras that have been passed
+ // is the user able to upload things yet, or not?
+ // ****************************************************
+ private void checkBundle() {
+ // Log.d(LOG_TAG, "checkBundle");
+ // Get the status icons...
+ Resources res = getResources();
+ Drawable checked = res.getDrawable(R.drawable.done);
+ if (extras != null) {
+ // Log.d(LOG_TAG, "Checking extras");
+ // Details extras
+ name = extras.getString("name");
+ email = extras.getString("email");
+ subject = extras.getString("subject");
+ if (!havePicture) {
+ havePicture = extras.getBoolean("photo");
+ }
+ // Do we have the details?
+ if ((name != null) && (email != null) && (subject != null)) {
+ haveDetails = true;
+ // Log.d(LOG_TAG, "Have all details");
+ checked.setBounds(0, 0, checked.getIntrinsicWidth(), checked
+ .getIntrinsicHeight());
+ // envelope.setBounds(0, 0, envelope.getIntrinsicWidth(),
+ // envelope
+ // .getIntrinsicHeight());
+ btnDetails.setText("Details added: '" + subject + "'");
+ btnDetails.setCompoundDrawables(null, null, checked, null);
+ } else {
+ // Log.d(LOG_TAG, "Don't have details");
+ }
+ } else {
+ extras = new Bundle();
+ // Log.d(LOG_TAG, "no Bundle at all");
+ }
+ // Log.d(LOG_TAG, "havePicture = " + havePicture);
+
+ // Do we have the photo?
+ if (havePicture) {
+
+ checked.setBounds(0, 0, checked.getIntrinsicWidth(), checked
+ .getIntrinsicHeight());
+ // camera.setBounds(0, 0, camera.getIntrinsicWidth(), camera
+ // .getIntrinsicHeight());
+ btnPicture.setCompoundDrawables(null, null, checked, null);
+ btnPicture.setText("Photo taken");
+ }
+ if (havePicture && haveDetails) {
+ textProgress.setVisibility(View.VISIBLE);
+ }
+ }
+
+ // ****************************************************
+ // setListeners - set the button listeners
+ // ****************************************************
+
+ private void setListeners() {
+ btnDetails.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ Intent i = new Intent(Home.this, Details.class);
+ extras.putString("name", name);
+ extras.putString("email", email);
+ extras.putString("subject", subject);
+ extras.putBoolean("photo", havePicture);
+
+ i.putExtras(extras);
+ startActivity(i);
+ }
+ });
+ btnPicture.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ File photo = new File(
+ Environment.getExternalStorageDirectory(),
+ "FMS_photo.jpg");
+ if (photo.exists()) {
+ photo.delete();
+ }
+ Intent imageCaptureIntent = new Intent(
+ MediaStore.ACTION_IMAGE_CAPTURE);
+ imageCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri
+ .fromFile(photo));
+ startActivityForResult(imageCaptureIntent, 1);
+ }
+ });
+ btnReport.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ locationDetermined = true;
+ uploadToFMS();
+ }
+ });
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Log.d(LOG_TAG, "onActivityResult");
+ // Log.d(LOG_TAG, "Activity.RESULT_OK code = " + Activity.RESULT_OK);
+ // Log.d(LOG_TAG, "resultCode = " + resultCode + "requestCode = "
+ // + requestCode);
+ if (resultCode == Activity.RESULT_OK && requestCode == 1) {
+ havePicture = true;
+ extras.putBoolean("photo", true);
+ Resources res = getResources();
+ Drawable checked = res.getDrawable(R.drawable.done);
+ checked.setBounds(0, 0, checked.getIntrinsicWidth(), checked
+ .getIntrinsicHeight());
+ btnPicture.setCompoundDrawables(null, null, checked, null);
+ btnPicture.setText("Photo taken");
+ }
+ Log.d(LOG_TAG, "havePicture = " + havePicture.toString());
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ Log.d(LOG_TAG, "onSaveInstanceState, havePicture " + havePicture);
+ // Log.d(LOG_TAG, "onSaveInstanceState");
+ if (havePicture != null) {
+ // Log.d(LOG_TAG, "mRowId = " + mRowId);
+ outState.putBoolean("photo", havePicture);
+ }
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ // Restore UI state from the savedInstanceState.
+ // This bundle has also been passed to onCreate.
+ havePicture = savedInstanceState.getBoolean("photo");
+ Log.d(LOG_TAG, "onRestoreInstanceState, havePicture " + havePicture);
+ }
+
+ // **********************************************************************
+ // uploadToFMS: uploads details, handled via a background thread
+ // Also checks the age and accuracy of the GPS data first
+ // **********************************************************************
+ private void uploadToFMS() {
+ // Log.d(LOG_TAG, "uploadToFMS");
+ pd = ProgressDialog
+ .show(
+ this,
+ "Uploading, please wait...",
+ "Uploading. This can take up to a minute, depending on your connection speed. Please be patient!",
+ true, false);
+ Thread t = new Thread() {
+ public void run() {
+ doUploadinBackground();
+ mHandler.post(mUpdateResults);
+ }
+ };
+ t.start();
+ }
+
+ private void updateResultsInUi() {
+ if (globalStatus == UPLOAD_ERROR) {
+ showDialog(UPLOAD_ERROR);
+ } else if (globalStatus == UPLOAD_ERROR_SERVER) {
+ showDialog(UPLOAD_ERROR_SERVER);
+ } else if (globalStatus == LOCATION_NOT_FOUND) {
+ showDialog(LOCATION_NOT_FOUND);
+ } else if (globalStatus == PHOTO_NOT_FOUND) {
+ showDialog(PHOTO_NOT_FOUND);
+ } else {
+ // Success! - Proceed to the success activity!
+ Intent i = new Intent(Home.this, Success.class);
+ i.putExtra("latString", latString);
+ i.putExtra("lonString", longString);
+ startActivity(i);
+ }
+ }
+
+ // **********************************************************************
+ // onCreateDialog: Dialog warnings
+ // **********************************************************************
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ switch (id) {
+ case COUNTRY_ERROR:
+ return new AlertDialog.Builder(Home.this)
+ .setTitle("Country or network error")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ })
+ .setMessage(
+ "Sorry, FixMyStreet currently only works in Britain. You won't be able to submit reports from your current location. (You may also see this error if you aren't connected to the network.)")
+ .create();
+ case UPLOAD_ERROR:
+ return new AlertDialog.Builder(Home.this)
+ .setTitle("Upload error")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ })
+ .setMessage(
+ "Sorry, there was an error uploading - maybe the network connection is down? Please try again later. Exception: " + exception_string + " " + serverResponse)
+ .create();
+ case UPLOAD_ERROR_SERVER:
+ return new AlertDialog.Builder(Home.this)
+ .setTitle("Upload error")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ })
+ .setMessage(
+ "Sorry, there was an error uploading. Please try again later. The server response was: "
+ + serverResponse).create();
+ case LOCATION_NOT_FOUND:
+ return new AlertDialog.Builder(Home.this)
+ .setTitle("Location problem")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ })
+ .setMessage(
+ "Could not get location! Can you see the sky? Please try again later.")
+ .create();
+ case PHOTO_NOT_FOUND:
+ return new AlertDialog.Builder(Home.this).setTitle("No photo")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ }).setMessage("Photo not found!").create();
+ case UPON_UPDATE:
+ if (versionName == null) {
+ versionName = "";
+ }
+ return new AlertDialog.Builder(Home.this).setTitle("What's new?")
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+ }
+ }).setMessage(
+ "New features in version" + versionName
+ + ": better GPS fix.").create();
+ }
+ return null;
+ }
+
+ // **********************************************************************
+ // doUploadinBackground: POST request to FixMyStreet
+ // **********************************************************************
+ private boolean doUploadinBackground() {
+ // Log.d(LOG_TAG, "doUploadinBackground");
+
+ String responseString = null;
+ PostMethod method;
+
+ method = new PostMethod("http://www.fixmystreet.com/import");
+
+ try {
+
+ byte[] imageByteArray = null;
+ HttpClient client = new HttpClient();
+ client.getHttpConnectionManager().getParams().setConnectionTimeout(
+ 100000);
+
+ File f = new File(Environment.getExternalStorageDirectory(),
+ "FMS_photo.jpg");
+
+ // TODO - add a check here
+ if (!f.exists()) {
+ }
+ imageByteArray = getBytesFromFile(f);
+
+ // Log
+ // .d(LOG_TAG, "len of data is " + imageByteArray.length
+ // + " bytes");
+
+ FilePart photo = new FilePart("photo", new ByteArrayPartSource(
+ "photo", imageByteArray));
+
+ photo.setContentType("image/jpeg");
+ photo.setCharSet(null);
+
+ Part[] parts = { new StringPart("service", "Android phone"),
+ new StringPart("subject", subject),
+ new StringPart("name", name),
+ new StringPart("email", email),
+ new StringPart("lat", latString),
+ new StringPart("lon", longString), photo };
+
+ // Log.d(LOG_TAG, "sending off with lat " + latString + " and lon "
+ // + longString);
+
+ method.setRequestEntity(new MultipartRequestEntity(parts, method
+ .getParams()));
+ client.executeMethod(method);
+ responseString = method.getResponseBodyAsString();
+ method.releaseConnection();
+
+ Log.e("httpPost", "Response status: " + responseString);
+ Log.e("httpPost", "Latitude = " + latString + " and Longitude = "
+ + longString);
+
+ } catch (Exception ex) {
+ Log.v(LOG_TAG, "Exception", ex);
+ exception_string = ex.getMessage();
+ globalStatus = UPLOAD_ERROR;
+ serverResponse = "";
+ return false;
+ } finally {
+ method.releaseConnection();
+ }
+
+ if (responseString.equals("SUCCESS")) {
+ // launch the Success page
+ globalStatus = SUCCESS;
+ return true;
+ } else {
+ // print the response string?
+ serverResponse = responseString;
+ globalStatus = UPLOAD_ERROR;
+ return false;
+ }
+ }
+
+ private boolean checkLoc(Location location) {
+ // get accuracy
+ // Log.d(LOG_TAG, "checkLocation");
+ float tempAccuracy = location.getAccuracy();
+ locAccuracy = (int) tempAccuracy;
+ // get time - store the GPS time the first time
+ // it is reported, then check it against future reported times
+ latestGPSFixTime = location.getTime();
+ if (firstGPSFixTime == 0) {
+ firstGPSFixTime = latestGPSFixTime;
+ }
+ if (previousGPSFixTime == 0) {
+ previousGPSFixTime = latestGPSFixTime;
+ }
+ long timeDiffSecs = (latestGPSFixTime - previousGPSFixTime) / 1000;
+
+ // Log.d(LOG_TAG, "~~~~~~~ checkLocation, accuracy = " + locAccuracy
+ // + ", firstGPSFixTime = " + firstGPSFixTime + ", gpsTime = "
+ // + latestGPSFixTime + ", timeDiffSecs = " + timeDiffSecsInt);
+
+ // Check our location - no good if the GPS accuracy is more than 24m
+ if ((locAccuracy > 24) || (timeDiffSecs == 0)) {
+ if (timeDiffSecs == 0) {
+ // nor do we want to report if the GPS time hasn't changed at
+ // all - it is probably out of date
+ textProgress
+ .setText("Waiting for a GPS fix: phone says last fix is out of date. Please make sure you can see the sky.");
+ } else {
+ textProgress
+ .setText("Waiting for a GPS fix: phone says last fix had accuracy of "
+ + locAccuracy
+ + "m. (We need accuracy of 24m.) Please make sure you can see the sky.");
+ }
+ } else if (locAccuracy == 0) {
+ // or if no accuracy data is available
+ textProgress
+ .setText("Waiting for a GPS fix... Please make sure you can see the sky.");
+ } else {
+ // but if all the requirements have been met, proceed
+ latitude = location.getLatitude();
+ longitude = location.getLongitude();
+ latString = latitude.toString();
+ longString = longitude.toString();
+ if (haveDetails && havePicture) {
+ btnReport.setVisibility(View.VISIBLE);
+ btnReport.setText("GPS found! Report to Fix My Street");
+ textProgress.setVisibility(View.GONE);
+ } else {
+ textProgress.setText("GPS found!");
+ }
+ previousGPSFixTime = latestGPSFixTime;
+ return true;
+ }
+ previousGPSFixTime = latestGPSFixTime;
+ // textProgress.setText("~~~~~~~ checkLocation, accuracy = "
+ // + locAccuracy + ", locationTimeStored = " + locationTimeStored
+ // + ", gpsTime = " + gpsTime);
+ return false;
+ }
+
+ public boolean testProviders() {
+ // Log.e(LOG_TAG, "testProviders");
+ // Register for location listener
+ String location_context = Context.LOCATION_SERVICE;
+ locationmanager = (LocationManager) getSystemService(location_context);
+ // Criteria criteria = new Criteria();
+ // criteria.setAccuracy(Criteria.ACCURACY_FINE);
+ // criteria.setAltitudeRequired(false);
+ // criteria.setBearingRequired(false);
+ // criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
+ // criteria.setSpeedRequired(false);
+ // String provider = locationmanager.getBestProvider(criteria, true);
+ if (!locationmanager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
+ buildAlertMessageNoGps();
+ return false;
+ }
+ listener = new LocationListener() {
+ public void onLocationChanged(Location location) {
+ // keep checking the location + updating text - until we have
+ // what we need
+ if (!locationDetermined) {
+ checkLoc(location);
+ }
+ }
+
+ public void onProviderDisabled(String provider) {
+ }
+
+ public void onProviderEnabled(String provider) {
+ }
+
+ public void onStatusChanged(String provider, int status,
+ Bundle extras) {
+ }
+ };
+ locationmanager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
+ 0, listener);
+ return true;
+ }
+
+ private void buildAlertMessageNoGps() {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder
+ .setMessage(
+ "Your GPS seems to be disabled. Do you want to turn it on now?")
+ .setCancelable(false).setPositiveButton("Yes",
+ new DialogInterface.OnClickListener() {
+ public void onClick(
+ @SuppressWarnings("unused") final DialogInterface dialog,
+ @SuppressWarnings("unused") final int id) {
+ Intent j = new Intent();
+ j
+ .setAction("android.settings.LOCATION_SOURCE_SETTINGS");
+ startActivity(j);
+ }
+ }).setNegativeButton("No",
+ new DialogInterface.OnClickListener() {
+ public void onClick(final DialogInterface dialog,
+ @SuppressWarnings("unused") final int id) {
+ dialog.cancel();
+ }
+ });
+ final AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ public void removeListeners() {
+ // Log.e(LOG_TAG, "removeListeners");
+ if ((locationmanager != null) && (listener != null)) {
+ locationmanager.removeUpdates(listener);
+ }
+ locationmanager = null;
+ // Log.d(LOG_TAG, "Removed " + listener.toString());
+ }
+
+ // ****************************************************
+ // Options menu functions
+ // ****************************************************
+
+ // TODO - add Bundles for these?
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuItem helpItem = menu.add(0, 0, 0, "Help");
+ MenuItem aboutItem = menu.add(0, 1, 0, "About");
+ aboutItem.setIcon(android.R.drawable.ic_menu_info_details);
+ helpItem.setIcon(android.R.drawable.ic_menu_help);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case 0:
+ Intent i = new Intent(Home.this, Help.class);
+ if (extras != null) {
+ i.putExtras(extras);
+ }
+ startActivity(i);
+ return true;
+ case 1:
+ Intent j = new Intent(Home.this, About.class);
+ if (extras != null) {
+ j.putExtras(extras);
+ }
+ startActivity(j);
+ return true;
+ }
+ return false;
+ }
+
+ // read the photo file into a byte array...
+ public static byte[] getBytesFromFile(File file) throws IOException {
+ InputStream is = new FileInputStream(file);
+
+ // Get the size of the file
+ long length = file.length();
+
+ // You cannot create an array using a long type.
+ // It needs to be an int type.
+ // Before converting to an int type, check
+ // to ensure that file is not larger than Integer.MAX_VALUE.
+ if (length > Integer.MAX_VALUE) {
+ // File is too large
+ }
+
+ // Create the byte array to hold the data
+ byte[] bytes = new byte[(int) length];
+
+ // Read in the bytes
+ int offset = 0;
+ int numRead = 0;
+ while (offset < bytes.length
+ && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
+ offset += numRead;
+ }
+
+ // Ensure all the bytes have been read in
+ if (offset < bytes.length) {
+ throw new IOException("Could not completely read file "
+ + file.getName());
+ }
+
+ // Close the input stream and return bytes
+ is.close();
+ return bytes;
+ }
+}
diff --git a/android/Fix My Street/src/com/android/fixmystreet/R.java b/android/Fix My Street/src/com/android/fixmystreet/R.java deleted file mode 100644 index 54fde9562..000000000 --- a/android/Fix My Street/src/com/android/fixmystreet/R.java +++ /dev/null @@ -1,74 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package com.android.fixmystreet; - -public final class R { - public static final class attr { - } - public static final class color { - public static final int sky_blue=0x7f040001; - public static final int translucent_blue=0x7f040002; - public static final int transparent=0x7f040000; - } - public static final class drawable { - public static final int add=0x7f020000; - public static final int blue_filler=0x7f020001; - public static final int done=0x7f020002; - public static final int filler=0x7f020003; - public static final int house_icon=0x7f020004; - public static final int spacer=0x7f020005; - public static final int street_background_smaller=0x7f020006; - } - public static final class id { - public static final int background_image=0x7f07000c; - public static final int camera_button=0x7f070009; - public static final int details_button=0x7f07000a; - public static final int email_label=0x7f070006; - public static final int email_text=0x7f070007; - public static final int faq=0x7f070000; - public static final int hello_text=0x7f07000d; - public static final int name_label=0x7f070004; - public static final int name_save=0x7f070001; - public static final int name_text=0x7f070005; - public static final int report_button=0x7f07000b; - public static final int subject_label=0x7f070002; - public static final int subject_text=0x7f070003; - public static final int submit_button=0x7f070008; - } - public static final class layout { - public static final int about=0x7f030000; - public static final int details=0x7f030001; - public static final int help=0x7f030002; - public static final int home=0x7f030003; - public static final int success=0x7f030004; - } - public static final class string { - public static final int about=0x7f050007; - /** Welcome screen - */ - public static final int app_name=0x7f050000; - public static final int close=0x7f050008; - public static final int confirm_location=0x7f050002; - public static final int confirm_location_done=0x7f050003; - public static final int details=0x7f050005; - /** Details screen - */ - public static final int details_screen=0x7f05000a; - public static final int hello=0x7f050001; - public static final int imageUrl=0x7f050009; - /** About screen - */ - public static final int instructions=0x7f05000c; - public static final int report=0x7f050006; - public static final int submit=0x7f05000b; - public static final int take_a_picture=0x7f050004; - } - public static final class style { - public static final int Theme_Filler=0x7f060000; - } -} diff --git a/android/Fix My Street/src/com/android/fixmystreet/Settings.java b/android/Fix My Street/src/com/android/fixmystreet/Settings.java deleted file mode 100644 index 1c3e8df90..000000000 --- a/android/Fix My Street/src/com/android/fixmystreet/Settings.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.android.fixmystreet; - -import android.app.Activity; -import android.os.Bundle; -import android.content.SharedPreferences; - -public class Settings extends Activity { - public static final String PREFS_NAME = "Settings"; - - - @Override - protected void onCreate(Bundle state){ - super.onCreate(state); - } - - @Override - protected void onStop(){ - super.onStop(); - - String name = ""; - String email = ""; - - // Save user preferences. We need an Editor object to - // make changes. All objects are from android.context.Context - SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); - SharedPreferences.Editor editor = settings.edit(); - editor.putString("myName", name); - editor.putString("myEmail", email); - - // Don't forget to commit your edits!!! - editor.commit(); - } - } diff --git a/android/Fix My Street/src/com/android/fixmystreet/Stored.java b/android/Fix My Street/src/com/android/fixmystreet/Stored.java deleted file mode 100644 index db83c905f..000000000 --- a/android/Fix My Street/src/com/android/fixmystreet/Stored.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.android.fixmystreet; - -import android.content.Context; -import android.os.Bundle; -import android.preference.PreferenceActivity; -import android.preference.PreferenceManager; - -public class Stored extends PreferenceActivity { - // Option names and default values - private static final String OPT_EMAIL = "email"; - private static final boolean OPT_EMAIL_DEF = true; - private static final String OPT_NAME = "name"; - private static final boolean OPT_NAME_DEF = true; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // addPreferencesFromResource(R.xml.settings); - } - - // Get email, if stored - public static boolean getEmail(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(OPT_EMAIL, OPT_EMAIL_DEF); - } - - // Get name, if stored - public static boolean getName(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(OPT_NAME, OPT_NAME_DEF); - } -}
\ No newline at end of file diff --git a/android/Fix My Street/src/com/android/fixmystreet/Success.java b/android/Fix My Street/src/com/android/fixmystreet/Success.java index ca3dcee77..a941d4687 100644 --- a/android/Fix My Street/src/com/android/fixmystreet/Success.java +++ b/android/Fix My Street/src/com/android/fixmystreet/Success.java @@ -1,57 +1,57 @@ -//************************************************************* -// -//************************************************************* - -package com.android.fixmystreet; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -//import android.util.Log; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; - -public class Success extends Activity { - - //private static final String LOG_TAG = "Success"; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.success); - } - - // **************************************************** - // Options menu functions - // **************************************************** - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - MenuItem helpItem = menu.add(0, 0, 0, "Home"); - helpItem.setIcon(android.R.drawable.ic_menu_edit); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case 0: - Intent i = new Intent(Success.this, Home.class); - startActivity(i); - return true; - } - return false; - } - - // disable the Back key in case things get submitted twice - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - return true; - } - return false; - } - +//*************************************************************
+//
+//*************************************************************
+
+package com.android.fixmystreet;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+//import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class Success extends Activity {
+
+ //private static final String LOG_TAG = "Success";
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.success);
+ }
+
+ // ****************************************************
+ // Options menu functions
+ // ****************************************************
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuItem helpItem = menu.add(0, 0, 0, "Home");
+ helpItem.setIcon(android.R.drawable.ic_menu_edit);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case 0:
+ Intent i = new Intent(Success.this, Home.class);
+ startActivity(i);
+ return true;
+ }
+ return false;
+ }
+
+ // disable the Back key in case things get submitted twice
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ return true;
+ }
+ return false;
+ }
+
}
\ No newline at end of file diff --git a/bin/send-questionnaires b/bin/send-questionnaires index 840f70b2c..eb67cd5d1 100755 --- a/bin/send-questionnaires +++ b/bin/send-questionnaires @@ -70,7 +70,7 @@ foreach my $row (@$unsent) { next unless (Cobrand::email_host($cobrand)); my ($councils, $missing) = $row->{council} =~ /^([\d,]+)(?:\|([\d,]+))?/; my @councils = split /,/, $councils; - my $areas_info = mySociety::MaPit::get_voting_areas_info(\@all_councils); + my $areas_info = mySociety::MaPit::call('areas', \@all_councils); my $template = File::Slurp::read_file("$FindBin::Bin/../templates/emails/questionnaire"); my %h = map { $_ => $row->{$_} } qw/name title detail category/; diff --git a/bin/send-questionnaires-eha b/bin/send-questionnaires-eha index 18375b8c6..2e0af8f4f 100755 --- a/bin/send-questionnaires-eha +++ b/bin/send-questionnaires-eha @@ -25,7 +25,6 @@ use mySociety::Config; use mySociety::DBHandle qw(dbh select_all); use mySociety::Email; use mySociety::Locale; -use mySociety::MaPit; use mySociety::EmailUtil; use mySociety::Random qw(random_bytes); diff --git a/bin/send-reports b/bin/send-reports index 9abc9c6c0..c91de5e33 100755 --- a/bin/send-reports +++ b/bin/send-reports @@ -15,6 +15,7 @@ require 5.8.0; use FindBin; use lib "$FindBin::Bin/../perllib"; use lib "$FindBin::Bin/../commonlib/perllib"; +use Encode; use Error qw(:try); use File::Slurp; use CGI; # Trying awkward kludge @@ -107,7 +108,7 @@ foreach my $row (@$unsent) { if ($site eq 'emptyhomes') { my $council = $row->{council}; - $areas_info = mySociety::MaPit::get_voting_areas_info([ $council ]); + $areas_info = mySociety::MaPit::call('areas', $council); my $name = $areas_info->{$council}->{name}; my ($council_email, $confirmed, $note) = dbh()->selectrow_array( "SELECT email,confirmed,note FROM contacts WHERE deleted='f' @@ -131,7 +132,7 @@ foreach my $row (@$unsent) { my @all_councils = split /,|\|/, $row->{council}; my ($councils, $missing) = $row->{council} =~ /^([\d,]+)(?:\|([\d,]+))?/; my @councils = split /,/, $councils; - $areas_info = mySociety::MaPit::get_voting_areas_info(\@all_councils); + $areas_info = mySociety::MaPit::call('areas', \@all_councils); my (@dear, %recips); my $all_confirmed = 1; foreach my $council (@councils) { @@ -266,7 +267,7 @@ if ($verbose) { # Will do for now :) sub essex_contact { my ($E, $N) = @_; - my $district = mySociety::MaPit::get_voting_areas_by_location({easting=>$E, northing=>$N}, 'polygon', 'DIS'); + my $district = mySociety::MaPit::call('point', "27700/$E,$N", type => 'DIS'); ($district) = keys %$district; my $email; $email = 'eastarea' if $district == 2315 || $district == 2312; @@ -280,7 +281,7 @@ sub essex_contact { # Oxfordshire has different contact addresses depending upon the district sub oxfordshire_contact { my ($E, $N) = @_; - my $district = mySociety::MaPit::get_voting_areas_by_location({easting=>$E, northing=>$N}, 'polygon', 'DIS'); + my $district = mySociety::MaPit::call('point', "27700/$E,$N", type => 'DIS'); ($district) = keys %$district; my $email; $email = 'northernarea' if $district == 2419 || $district == 2420 || $district == 2421; @@ -315,9 +316,11 @@ sub post_easthants_message { $eh_service ||= EastHantsWSDL->on_fault(sub { my($soap, $res) = @_; die ref $res ? $res->faultstring : $soap->transport->status, "\n"; }); try { # ServiceName, RemoteCreatedBy, Salutation, FirstName, Name, Email, Telephone, HouseNoName, Street, Town, County, Country, Postcode, Comments, FurtherInfo, ImageURL + my $message = ent(encode_utf8($h{message})); + my $name = ent(encode_utf8($h{name})); my $result = $eh_service->INPUTFEEDBACK( - $h{category}, 'FixMyStreet', '', '', ent($h{name}), $h{email}, $h{phone}, - '', '', '', '', '', '', ent($h{message}), 'Yes', $h{image_url} + $h{category}, 'FixMyStreet', '', '', $name, $h{email}, $h{phone}, + '', '', '', '', '', '', $message, 'Yes', $h{image_url} ); $return = 0 if $result eq 'Report received'; } otherwise { diff --git a/commonlib b/commonlib -Subproject f000f0ae278047e632cb7fac995a9e4a1544328 +Subproject 15c5561b2162121a24f8223b0eac6dcc37b8b39 diff --git a/conf/general-example b/conf/general-example index 283d8787b..f8c71c846 100644 --- a/conf/general-example +++ b/conf/general-example @@ -49,7 +49,12 @@ define('OPTION_GEO_CACHE', '/cache/'); define('OPTION_GOOGLE_MAPS_API_KEY', ''); define('OPTION_MAPIT_URL', 'http://services.mysociety.org/mapit'); -define('OPTION_TILES_URL', 'http://tilma.mysociety.org/tileserver/10k-full-london'); +define('OPTION_TILES_TYPE', '10k-full-london'); +define('OPTION_TILES_TIFF_SIZE_METRES', 5000); +define('OPTION_TILES_TIFF_SIZE_PIXELS', 7874); +define('OPTION_TILES_WIDTH', 254); +define('OPTION_TILES_URL', 'http://tilma.mysociety.org/tileserver/' . OPTION_TILES_TYPE . '/'); + define('OPTION_EVEL_URL', 'http://services.mysociety.org/evel'); define('OPTION_GAZE_URL', 'http://gaze.mysociety.org/gaze'); diff --git a/perllib/Cobrand.pm b/perllib/Cobrand.pm index 3fc88d9dc..4433858bb 100644 --- a/perllib/Cobrand.pm +++ b/perllib/Cobrand.pm @@ -90,8 +90,6 @@ my %fns = ( 'root_path_js' => { default => "'var root_path = \"\";'" }, # Return the title to be used in page heads. 'site_title' => { default => "''" }, - # Return the license information - 'license_info' => { default => 'undef' }, # Return the maximum number of items to be given in the list of reports on the map 'on_map_list_limit' => { default => 'undef' }, # Return a boolean indicating whether the cobrand allows photo uploads diff --git a/perllib/Page.pm b/perllib/Page.pm index cafd9ba91..70b320548 100644 --- a/perllib/Page.pm +++ b/perllib/Page.pm @@ -47,6 +47,11 @@ BEGIN { mySociety::Config::set_file("$dir/../conf/general"); } +use constant TILE_WIDTH => mySociety::Config::get('TILES_WIDTH'); +use constant TIF_SIZE_M => mySociety::Config::get('TILES_TIFF_SIZE_METRES'); +use constant TIF_SIZE_PX => mySociety::Config::get('TILES_TIFF_SIZE_PIXELS'); +use constant SCALE_FACTOR => TIF_SIZE_M / (TIF_SIZE_PX / TILE_WIDTH); + my $lastmodified; sub do_fastcgi { @@ -409,7 +414,7 @@ sub display_map { $params{pins} ||= ''; $params{pre} ||= ''; $params{post} ||= ''; - my $mid_point = 254; + my $mid_point = TILE_WIDTH; # Map is 2 TILE_WIDTHs in size, square. if ($q->{site} eq 'barnet') { # Map is c. 380px wide $mid_point = 189; } @@ -455,31 +460,42 @@ EOF } else { $img_type = '<img'; } - my $imgw = '254px'; - my $imgh = '254px'; + my $imgw = TILE_WIDTH . 'px'; + my $tile_width = TILE_WIDTH; + my $tile_type = mySociety::Config::get('TILES_TYPE'); $out .= <<EOF; <script type="text/javascript"> -var fms_x = $x - 2; var fms_y = $y - 2; -var start_x = $px; var start_y = $py; $root_path_js +var fixmystreet = { + 'x': $x - 2, + 'y': $y - 2, + 'start_x': $px, + 'start_y': $py, + 'tile_type': '$tile_type', + 'tilewidth': $tile_width, + 'tileheight': $tile_width +}; </script> <div id="map_box"> $params{pre} <div id="map"><div id="drag"> - $img_type alt="NW map tile" id="t2.2" name="tile_$tl" src="$tl_src" style="top:0px; left:0;">$img_type alt="NE map tile" id="t2.3" name="tile_$tr" src="$tr_src" style="top:0px; left:$imgw;"><br>$img_type alt="SW map tile" id="t3.2" name="tile_$bl" src="$bl_src" style="top:$imgh; left:0;">$img_type alt="SE map tile" id="t3.3" name="tile_$br" src="$br_src" style="top:$imgh; left:$imgw;"> + $img_type alt="NW map tile" id="t2.2" name="tile_$tl" src="$tl_src" style="top:0px; left:0;">$img_type alt="NE map tile" id="t2.3" name="tile_$tr" src="$tr_src" style="top:0px; left:$imgw;"><br>$img_type alt="SW map tile" id="t3.2" name="tile_$bl" src="$bl_src" style="top:$imgw; left:0;">$img_type alt="SE map tile" id="t3.3" name="tile_$br" src="$br_src" style="top:$imgw; left:$imgw;"> <div id="pins">$params{pins}</div> </div> EOF - if (Cobrand::show_watermark($cobrand)) { + if (Cobrand::show_watermark($cobrand) && mySociety::Config::get('TILES_TYPE') ne 'streetview') { $out .= '<div id="watermark"></div>'; } $out .= compass($q, $x, $y); - my $copyright = _('Crown copyright. All rights reserved. Ministry of Justice'); - my $license_info = Cobrand::license_info($cobrand); - $license_info = "100037819 2008" unless $license_info; + my $copyright; + if (mySociety::Config::get('TILES_TYPE') eq 'streetview') { + $copyright = _('Map contains Ordnance Survey data © Crown copyright and database right 2010.'); + } else { + $copyright = _('© Crown copyright. All rights reserved. Ministry of Justice 100037819 2008.'); + } $out .= <<EOF; </div> - <p id="copyright">© $copyright $license_info</p> + <p id="copyright">$copyright</p> $params{post} EOF $out .= '</div>'; @@ -613,8 +629,8 @@ sub os_to_px { # BL is bottom left tile reference of displayed map sub tile_to_px { my ($p, $bl, $invert) = @_; - $p = 254 * ($p - $bl); - $p = 508 - $p if $invert; + $p = TILE_WIDTH * ($p - $bl); + $p = 2 * TILE_WIDTH - $p if $invert; $p = int($p + .5 * ($p <=> 0)); return $p; } @@ -622,18 +638,18 @@ sub tile_to_px { # Tile co-ordinates are linear scale of OS E/N # Will need more generalising when more zooms appear sub os_to_tile { - return $_[0] / (5000/31); + return $_[0] / SCALE_FACTOR; } sub tile_to_os { - return $_[0] * (5000/31); + return $_[0] * SCALE_FACTOR; } sub click_to_tile { my ($pin_tile, $pin, $invert) = @_; - $pin -= 254 while $pin > 254; - $pin += 254 while $pin < 0; - $pin = 254 - $pin if $invert; # image submits measured from top down - return $pin_tile + $pin / 254; + $pin -= TILE_WIDTH while $pin > TILE_WIDTH; + $pin += TILE_WIDTH while $pin < 0; + $pin = TILE_WIDTH - $pin if $invert; # image submits measured from top down + return $pin_tile + $pin / TILE_WIDTH; } sub os_to_px_with_adjust { @@ -799,7 +815,7 @@ sub display_problem_meta_line($$) { if ($problem->{whensent}) { $problem->{council} =~ s/\|.*//g; my @councils = split /,/, $problem->{council}; - my $areas_info = mySociety::MaPit::get_voting_areas_info(\@councils); + my $areas_info = mySociety::MaPit::call('areas', \@councils); my $council = join(' and ', map { $areas_info->{$_}->{name} } @councils); $out .= '<small class="council_sent_info">'; $out .= $q->br() . sprintf(_('Sent to %s %s later'), $council, prettify_duration($problem->{whensent}, 'minute')); @@ -898,6 +914,19 @@ sub display_problem_updates($$) { return $out; } +sub mapit_check_error { + my $location = shift; + if ($location->{error}) { + return _('That postcode was not recognised, sorry.') if $location->{code} =~ /^4/; + return $location->{error}; + } + my $island = $location->{coordsyst}; + if ($island eq 'I') { + return _("We do not cover Northern Ireland, I'm afraid, as our licence doesn't include any maps for the region."); + } + return 0; +} + # geocode STRING QUERY # Given a user-inputted string, try and convert it into co-ordinates using either # MaPit if it's a postcode, or Google Maps API otherwise. Returns an array of @@ -908,10 +937,8 @@ sub geocode { my ($s, $q) = @_; my ($x, $y, $easting, $northing, $error); if (mySociety::PostcodeUtil::is_valid_postcode($s)) { - try { - my $location = mySociety::MaPit::get_location($s); - my $island = $location->{coordsyst}; - throw RABX::Error(_("We do not cover Northern Ireland, I'm afraid, as our licence doesn't include any maps for the region.")) if $island eq 'I'; + my $location = mySociety::MaPit::call('postcode', $s); + unless ($error = mapit_check_error($location)) { $easting = $location->{easting}; $northing = $location->{northing}; my $xx = Page::os_to_tile($easting); @@ -920,14 +947,6 @@ sub geocode { $y = int($yy); $x -= 1 if ($xx - $x < 0.5); $y -= 1 if ($yy - $y < 0.5); - } catch RABX::Error with { - my $e = shift; - if ($e->value() && ($e->value() == mySociety::MaPit::BAD_POSTCODE - || $e->value() == mySociety::MaPit::POSTCODE_NOT_FOUND)) { - $error = _('That postcode was not recognised, sorry.'); - } else { - $error = $e; - } } } else { ($x, $y, $easting, $northing, $error) = geocode_string($s, $q); diff --git a/perllib/Problems.pm b/perllib/Problems.pm index 7ce082129..161306845 100644 --- a/perllib/Problems.pm +++ b/perllib/Problems.pm @@ -253,7 +253,7 @@ sub problems_matching_criteria { $problem->{council} = \@council_ids; } } - my $areas_info = mySociety::MaPit::get_voting_areas_info(\@councils); + my $areas_info = mySociety::MaPit::call('areas', \@councils); foreach my $problem (@$problems){ if ($problem->{council}) { my @council_names = map { $areas_info->{$_}->{name}} @{$problem->{council}} ; diff --git a/templates/website/faq.html b/templates/website/faq.html index c9a59dea6..a0f364550 100755 --- a/templates/website/faq.html +++ b/templates/website/faq.html @@ -148,12 +148,12 @@ mySociety’s primary mission is to build Internet projects which give peopl benefits in the civic and community aspects of their lives. Our first project was <a href="http://www.writetothem.com/">WriteToThem</a>, where you can write to any of your elected representatives, for free. The charity is called UK Citizens Online Democracy and is charity number 1076346. mySociety -can be contacted by email at <a href="mailto:team@mysociety.org">team@mysociety.org</a>, +can be contacted by email at <a href="mailto:hello@mysociety.org">hello@mysociety.org</a>, or by post at:<br> -mySociety.org<br> -12 Duke's Road<br> -London<br> -WC1H 9AD<br> +mySociety<br> +PO Box 839<br> +Oxford<br> +OX1 9LG<br> UK</dd> <dt><img src="/i/moj.png" align="right" alt="Ministry of Justice" hspace="10">Who pays for it?</dt> <dd>FixMyStreet was paid for via the Department for diff --git a/web-admin/index.cgi b/web-admin/index.cgi index 8ac3eb132..b7946d600 100755 --- a/web-admin/index.cgi +++ b/web-admin/index.cgi @@ -189,17 +189,11 @@ sub admin_councils_list ($) { # Table of councils print $q->h2("Councils"); - my @councils; my $ignore = 'LGD'; $ignore .= '|CTY' if $q->{site} eq 'emptyhomes'; my @types = grep { !/$ignore/ } @$mySociety::VotingArea::council_parent_types; # LGD are NI councils - foreach my $type (@types) { - my $areas = mySociety::MaPit::get_areas_by_type($type); - push @councils, @$areas; - } - my $councils = mySociety::MaPit::get_voting_areas_info(\@councils); - my @councils_ids = keys %$councils; - @councils_ids = sort { $councils->{$a}->{name} cmp $councils->{$b}->{name} } @councils_ids; + my $areas = mySociety::MaPit::call('areas', \@types); + my @councils_ids = sort { $areas->{$a}->{name} cmp $areas->{$b}->{name} } keys %$areas; my $bci_info = dbh()->selectall_hashref(" select area_id, count(*) as c, count(case when deleted then 1 else null end) as deleted, count(case when confirmed then 1 else null end) as confirmed @@ -214,7 +208,7 @@ sub admin_councils_list ($) { print $q->p(join($q->br(), map { $q->a({ href => NewURL($q, area_id => $_, page => 'councilcontacts') }, - $councils->{$_}->{name}) . " " . + $areas->{$_}->{name}) . " " . ($bci_info->{$_} && $q->{site} ne 'emptyhomes' ? $bci_info->{$_}->{c} . ' addresses' : '') @@ -306,7 +300,7 @@ sub admin_council_contacts ($$) { $q->delete_all(); # No need for state! # Title - my $mapit_data = mySociety::MaPit::get_voting_area_info($area_id); + my $mapit_data = mySociety::MaPit::call('area', $area_id); my $title = 'Council contacts for ' . $mapit_data->{name}; print html_head($q, $title); print $q->h1($title); @@ -314,7 +308,7 @@ sub admin_council_contacts ($$) { # Example postcode, link to list of problem reports my $links_html; - my $example_postcode = mySociety::MaPit::get_example_postcode($area_id); + my $example_postcode = mySociety::MaPit::call('area/example_postcode', $area_id); if ($example_postcode) { $links_html .= $q->a({ href => mySociety::Config::get('BASE_URL') . '/?pc=' . $q->escape($example_postcode) }, "Example postcode " . $example_postcode) . " | "; @@ -387,7 +381,7 @@ sub admin_council_edit ($$$) { my $bci_data = select_all("select * from contacts where area_id = ? and category = ?", $area_id, $category); $bci_data = $bci_data->[0]; my $bci_history = select_all("select * from contacts_history where area_id = ? and category = ? order by contacts_history_id", $area_id, $category); - my $mapit_data = mySociety::MaPit::get_voting_area_info($area_id); + my $mapit_data = mySociety::MaPit::call('area', $area_id); # Title my $title = 'Council contacts for ' . $mapit_data->{name}; @@ -395,7 +389,7 @@ sub admin_council_edit ($$$) { print $q->h1($title); # Example postcode - my $example_postcode = mySociety::MaPit::get_example_postcode($area_id); + my $example_postcode = mySociety::MaPit::call('area/example_postcode', $area_id); if ($example_postcode) { print $q->p("Example postcode: ", $q->a({ href => mySociety::Config::get('BASE_URL') . '/?pc=' . $q->escape($example_postcode) }, diff --git a/web/alert.cgi b/web/alert.cgi index 59b6607a4..c755c9715 100755 --- a/web/alert.cgi +++ b/web/alert.cgi @@ -104,13 +104,12 @@ sub alert_list { my @types = (@$mySociety::VotingArea::council_parent_types, @$mySociety::VotingArea::council_child_types); my %councils = map { $_ => 1 } @$mySociety::VotingArea::council_parent_types; - my $areas = mySociety::MaPit::get_voting_areas_by_location({easting=>$e, northing=>$n}, 'polygon', \@types); + my $areas = mySociety::MaPit::call('point', "27700/$e,$n", type => \@types); my $cobrand = Page::get_cobrand($q); my ($success, $error_msg) = Cobrand::council_check($cobrand, $areas, $q, 'alert'); if (!$success){ return alert_front_page($q, $error_msg); } - $areas = mySociety::MaPit::get_voting_areas_info([ keys %$areas ]); return alert_front_page($q, _('That location does not appear to be covered by a council, perhaps it is offshore - please try somewhere more specific.')) if keys %$areas == 0; @@ -126,9 +125,9 @@ sub alert_list { $ward = $_; } } - push @options, [ 'council', $council->{area_id}, Page::short_name($council->{name}), + push @options, [ 'council', $council->{id}, Page::short_name($council->{name}), sprintf(_("Problems within %s"), $council->{name}) ]; - push @options, [ 'ward', $council->{area_id}.':'.$ward->{area_id}, Page::short_name($council->{name}) . '/' + push @options, [ 'ward', $council->{id}.':'.$ward->{id}, Page::short_name($council->{name}) . '/' . Page::short_name($ward->{name}), sprintf(_("Problems within %s ward"), $ward->{name}) ]; $options_start = "<div><ul id='rss_feed'>"; @@ -142,7 +141,7 @@ sub alert_list { foreach (values %$areas) { $council = $_; } - push @options, [ 'council', $council->{area_id}, Page::short_name($council->{name}), + push @options, [ 'council', $council->{id}, Page::short_name($council->{name}), sprintf(_("Problems within %s"), $council->{name}) ]; $options_start = "<div><ul id='rss_feed'>"; @@ -165,24 +164,24 @@ sub alert_list { } } push @options, - [ 'area', $district->{area_id}, Page::short_name($district->{name}), $district->{name} ], - [ 'area', $district->{area_id}.':'.$d_ward->{area_id}, Page::short_name($district->{name}) . '/' + [ 'area', $district->{id}, Page::short_name($district->{name}), $district->{name} ], + [ 'area', $district->{id}.':'.$d_ward->{id}, Page::short_name($district->{name}) . '/' . Page::short_name($d_ward->{name}), "$d_ward->{name} ward, $district->{name}" ], - [ 'area', $county->{area_id}, Page::short_name($county->{name}), $county->{name} ], - [ 'area', $county->{area_id}.':'.$c_ward->{area_id}, Page::short_name($county->{name}) . '/' + [ 'area', $county->{id}, Page::short_name($county->{name}), $county->{name} ], + [ 'area', $county->{id}.':'.$c_ward->{id}, Page::short_name($county->{name}) . '/' . Page::short_name($c_ward->{name}), "$c_ward->{name} ward, $county->{name}" ]; $options_start = '<div id="rss_list">'; $options = $q->p($q->strong(_('Problems within the boundary of:'))) . $q->ul(alert_list_options($q, @options)); @options = (); push @options, - [ 'council', $district->{area_id}, Page::short_name($district->{name}), $district->{name} ], - [ 'ward', $district->{area_id}.':'.$d_ward->{area_id}, Page::short_name($district->{name}) . '/' . Page::short_name($d_ward->{name}), + [ 'council', $district->{id}, Page::short_name($district->{name}), $district->{name} ], + [ 'ward', $district->{id}.':'.$d_ward->{id}, Page::short_name($district->{name}) . '/' . Page::short_name($d_ward->{name}), "$district->{name}, within $d_ward->{name} ward" ]; if ($q->{site} ne 'emptyhomes') { push @options, - [ 'council', $county->{area_id}, Page::short_name($county->{name}), $county->{name} ], - [ 'ward', $county->{area_id}.':'.$c_ward->{area_id}, Page::short_name($county->{name}) . '/' + [ 'council', $county->{id}, Page::short_name($county->{name}), $county->{name} ], + [ 'ward', $county->{id}.':'.$c_ward->{id}, Page::short_name($county->{name}) . '/' . Page::short_name($c_ward->{name}), "$county->{name}, within $c_ward->{name} ward" ]; $options .= $q->p($q->strong(_('Or problems reported to:'))) . $q->ul(alert_list_options($q, @options)); diff --git a/web/contact.cgi b/web/contact.cgi index bb4ed4913..6b82422a1 100755 --- a/web/contact.cgi +++ b/web/contact.cgi @@ -110,12 +110,12 @@ sub contact_details { <div class="contact-details"> <p>$sitename is a service provided by mySociety, which is the project of a registered charity. The charity is called UK Citizens Online Democracy and is charity number 1076346.</p> -<p>mySociety can be contacted by email at <a href="mailto:team\@mysociety.org">team\@mysociety.org</a>, +<p>mySociety can be contacted by email at <a href="mailto:hello@mysociety.org">hello@mysociety.org</a>, or by post at:</p> -<p>mySociety.org<br> -12 Duke's Road<br> -London<br> -WC1H 9AD<br> +<p>mySociety<br> +PO Box 839<br> +Oxford<br> +OX1 9LG<br> UK</p> </div> EOF diff --git a/web/css/core.css b/web/css/core.css index 4eb8496e2..08e6eca0d 100644 --- a/web/css/core.css +++ b/web/css/core.css @@ -191,7 +191,7 @@ fieldset div, #fieldset div { #map_box { float: right; - width: 510px; + width: 502px; /* Two pixels more than width of #map */ position: relative; padding-left: 20px; background-color: #ffffff; @@ -205,8 +205,8 @@ p#copyright { #map { border: solid 1px #000000; - width: 508px; - height: 508px; + width: 500px; /* Twice a tile width */ + height: 500px; overflow: hidden; position: relative; background-color: #f1f1f1; @@ -214,8 +214,8 @@ p#copyright { #drag { position: absolute; - width: 508px; - height: 508px; + width: 500px; + height: 500px; right: 0; top: 0; } diff --git a/web/index.cgi b/web/index.cgi index e39dd8921..f9428efa3 100755 --- a/web/index.cgi +++ b/web/index.cgi @@ -306,16 +306,13 @@ sub submit_problem { my $areas; if ($input{easting} && $input{northing}) { - $areas = mySociety::MaPit::get_voting_areas_by_location( - { easting=>$input{easting}, northing=>$input{northing} }, - 'polygon', [qw(WMC CTY CED DIS DIW MTD MTW COI COP LGD LGE UTA UTE UTW LBO LBW LAC SPC WAC NIE)] - ); + $areas = mySociety::MaPit::call('point', "27700/$input{easting},$input{northing}"); if ($input{council} =~ /^[\d,]+(\|[\d,]+)?$/) { my $no_details = $1 || ''; my %va = map { $_ => 1 } @$mySociety::VotingArea::council_parent_types; my %councils; foreach (keys %$areas) { - $councils{$_} = 1 if $va{$areas->{$_}}; + $councils{$_} = 1 if $va{$areas->{$_}->{type}}; } my @input_councils = split /,|\|/, $input{council}; foreach (@input_councils) { @@ -515,9 +512,7 @@ sub display_form { $parent_types = [qw(DIS LBO MTD UTA LGD COI)] # No CTY if $q->{site} eq 'emptyhomes'; # XXX: I think we want in_gb_locale around the next line, needs testing - my $all_councils = mySociety::MaPit::get_voting_areas_by_location( - { easting => $easting, northing => $northing }, - 'polygon', $parent_types); + my $all_councils = mySociety::MaPit::call('point', "27700/$easting,$northing", type => $parent_types); # Let cobrand do a check my ($success, $error_msg) = Cobrand::council_check($cobrand, $all_councils, $q, 'submit_problem'); @@ -531,17 +526,15 @@ sub display_form { # Norwich is responsible for everything in its areas, no Norfolk delete $all_councils->{2233} if $all_councils->{2391}; - $all_councils = [ keys %$all_councils ]; return display_location($q, _('That spot does not appear to be covered by a council. If you have tried to report an issue past the shoreline, for example, -please specify the closest point on land.')) unless @$all_councils; - my $areas_info = mySociety::MaPit::get_voting_areas_info($all_councils); +please specify the closest point on land.')) unless %$all_councils; # Look up categories for this council or councils my $category = ''; my (%council_ok, @categories); my $categories = select_all("select area_id, category from contacts - where deleted='f' and area_id in (" . join(',', @$all_councils) . ')'); + where deleted='f' and area_id in (" . join(',', keys %$all_councils) . ')'); if ($q->{site} ne 'emptyhomes') { @$categories = sort { $a->{category} cmp $b->{category} } @$categories; foreach (@$categories) { @@ -574,7 +567,7 @@ please specify the closest point on land.')) unless @$all_councils; # Work out what help text to show, depending on whether we have council details my @councils = keys %council_ok; my $details; - if (@councils == @$all_councils) { + if (@councils == scalar keys %$all_councils) { $details = 'all'; } elsif (@councils == 0) { $details = 'none'; @@ -629,7 +622,7 @@ If this is not the correct location, simply click on the map again. ')); $vars{page_heading} = $q->h1(_('Reporting a problem')); if ($details eq 'all') { - my $council_list = join('</strong> or <strong>', map { $areas_info->{$_}->{name} } @$all_councils); + my $council_list = join('</strong> or <strong>', map { $_->{name} } values %$all_councils); if ($q->{site} eq 'emptyhomes'){ $vars{text_help} = '<p>' . sprintf(_('All the information you provide here will be sent to <strong>%s</strong>. On the site, we will show the subject and details of the problem, plus your @@ -639,18 +632,18 @@ name if you give us permission.'), $council_list); The subject and details of the problem will be public, plus your name if you give us permission.'), $council_list); } - $vars{text_help} .= '<input type="hidden" name="council" value="' . join(',',@$all_councils) . '">'; + $vars{text_help} .= '<input type="hidden" name="council" value="' . join(',', keys %$all_councils) . '">'; } elsif ($details eq 'some') { my $e = Cobrand::contact_email($cobrand); my %councils = map { $_ => 1 } @councils; my @missing; - foreach (@$all_councils) { + foreach (keys %$all_councils) { push @missing, $_ unless $councils{$_}; } my $n = @missing; - my $list = join(' or ', map { $areas_info->{$_}->{name} } @missing); + my $list = join(' or ', map { $all_councils->{$_}->{name} } @missing); $vars{text_help} = '<p>All the information you provide here will be sent to <strong>' - . join('</strong> or <strong>', map { $areas_info->{$_}->{name} } @councils) + . join('</strong> or <strong>', map { $all_councils->{$_}->{name} } @councils) . '</strong>. The subject and details of the problem will be public, plus your name if you give us permission.'; $vars{text_help} .= ' We do <strong>not</strong> yet have details for the other council'; @@ -661,8 +654,8 @@ problems for $list and emailing it to us at <a href='mailto:$e'>$e</a>."; . '|' . join(',', @missing) . '">'; } else { my $e = Cobrand::contact_email($cobrand); - my $list = join(' or ', map { $areas_info->{$_}->{name} } @$all_councils); - my $n = @$all_councils; + my $list = join(' or ', map { $_->{name} } values %$all_councils); + my $n = scalar keys %$all_councils; if ($q->{site} ne 'emptyhomes') { $vars{text_help} = '<p>We do not yet have details for the council'; $vars{text_help} .= ($n>1) ? 's that cover' : ' that covers'; @@ -812,9 +805,7 @@ sub display_location { return front_page($q, $error) if ($error); my $parent_types = $mySociety::VotingArea::council_parent_types; if ($easting && $northing) { - my $all_councils = mySociety::MaPit::get_voting_areas_by_location( - { easting => $easting, northing => $northing }, - 'polygon', $parent_types); + my $all_councils = mySociety::MaPit::call('point', "27700/$easting,$northing", type => $parent_types); my ($success, $error_msg) = Cobrand::council_check($cobrand, $all_councils, $q, 'display_location'); if (!$success){ return front_page($q, $error_msg); @@ -31,14 +31,14 @@ YAHOO.util.Event.onContentReady('compass', function() { if (document.getElementById('map').offsetWidth > 510) return; var points = this.getElementsByTagName('a'); - YAHOO.util.Event.addListener(points[1], 'click', compass_pan, { x:0, y:tileheight }); - YAHOO.util.Event.addListener(points[3], 'click', compass_pan, { x:tilewidth, y:0 }); - YAHOO.util.Event.addListener(points[5], 'click', compass_pan, { x:-tilewidth, y:0 }); - YAHOO.util.Event.addListener(points[7], 'click', compass_pan, { x:0, y:-tileheight }); - YAHOO.util.Event.addListener(points[0], 'click', compass_pan, { x:tilewidth, y:tileheight }); - YAHOO.util.Event.addListener(points[2], 'click', compass_pan, { x:-tilewidth, y:tileheight }); - YAHOO.util.Event.addListener(points[6], 'click', compass_pan, { x:tilewidth, y:-tileheight }); - YAHOO.util.Event.addListener(points[8], 'click', compass_pan, { x:-tilewidth, y:-tileheight }); + YAHOO.util.Event.addListener(points[1], 'click', compass_pan, { x:0, y:fixmystreet.tileheight }); + YAHOO.util.Event.addListener(points[3], 'click', compass_pan, { x:fixmystreet.tilewidth, y:0 }); + YAHOO.util.Event.addListener(points[5], 'click', compass_pan, { x:-fixmystreet.tilewidth, y:0 }); + YAHOO.util.Event.addListener(points[7], 'click', compass_pan, { x:0, y:-fixmystreet.tileheight }); + YAHOO.util.Event.addListener(points[0], 'click', compass_pan, { x:fixmystreet.tilewidth, y:fixmystreet.tileheight }); + YAHOO.util.Event.addListener(points[2], 'click', compass_pan, { x:-fixmystreet.tilewidth, y:fixmystreet.tileheight }); + YAHOO.util.Event.addListener(points[6], 'click', compass_pan, { x:fixmystreet.tilewidth, y:-fixmystreet.tileheight }); + YAHOO.util.Event.addListener(points[8], 'click', compass_pan, { x:-fixmystreet.tilewidth, y:-fixmystreet.tileheight }); YAHOO.util.Event.addListener(points[4], 'click', compass_pan, { home:1, orig_x:drag_x, orig_y:drag_y }); }); @@ -47,7 +47,7 @@ YAHOO.util.Event.onContentReady('map', function() { // if (document.getElementById('mapForm') && (/safari/.test(ua) || /Konqueror/.test(ua))) return; if (document.getElementById('map').offsetWidth > 510) return; new YAHOO.util.DDMap('map'); - update_tiles(start_x, start_y, true); + update_tiles(fixmystreet.start_x, fixmystreet.start_y, true); }); @@ -57,8 +57,8 @@ YAHOO.util.Event.onContentReady('mapForm', function() { this.onsubmit = function() { return false; }; } - this.x.value = fms_x + 2; - this.y.value = fms_y + 2; + this.x.value = fixmystreet.x + 2; + this.y.value = fixmystreet.y + 2; /* if (swfu && swfu.getStats().files_queued > 0) { swfu.startUpload(); @@ -142,21 +142,21 @@ YAHOO.util.Event.addListener('all_pins_link', 'click', function(e) { if (this.innerHTML == 'Include stale reports') { this.innerHTML = 'Hide stale reports'; document.getElementById('all_pins').value = '1'; - load_pins(fms_x, fms_y); + load_pins(fixmystreet.x, fixmystreet.y); } else if (this.innerHTML == 'Cynnwys hen adroddiadau') { this.innerHTML = 'Cuddio hen adroddiadau'; document.getElementById('all_pins').value = '1'; welsh = 1; - load_pins(fms_x, fms_y); + load_pins(fixmystreet.x, fixmystreet.y); } else if (this.innerHTML == 'Cuddio hen adroddiadau') { this.innerHTML = 'Cynnwys hen adroddiadau'; welsh = 1; document.getElementById('all_pins').value = ''; - load_pins(fms_x, fms_y); + load_pins(fixmystreet.x, fixmystreet.y); } else if (this.innerHTML == 'Hide stale reports') { this.innerHTML = 'Include stale reports'; document.getElementById('all_pins').value = ''; - load_pins(fms_x, fms_y); + load_pins(fixmystreet.x, fixmystreet.y); } if (welsh) { document.getElementById('hide_pins_link').innerHTML = 'Cuddio pinnau'; @@ -254,8 +254,6 @@ var swfu_settings = { // I love the global var tile_x = 0; var tile_y = 0; -var tilewidth = 254; -var tileheight = 254; var myAnim; function pan(x, y) { @@ -285,22 +283,22 @@ function update_tiles(dx, dy, force) { drag.style.left = drag_x + 'px'; drag.style.top = drag_y + 'px'; - var horizontal = Math.floor(old_drag_x/tilewidth) - Math.floor(drag_x/tilewidth); - var vertical = Math.floor(old_drag_y/tileheight) - Math.floor(drag_y/tileheight); + var horizontal = Math.floor(old_drag_x/fixmystreet.tilewidth) - Math.floor(drag_x/fixmystreet.tilewidth); + var vertical = Math.floor(old_drag_y/fixmystreet.tileheight) - Math.floor(drag_y/fixmystreet.tileheight); if (!horizontal && !vertical && !force) return; - fms_x += horizontal; + fixmystreet.x += horizontal; tile_x += horizontal; - fms_y -= vertical; + fixmystreet.y -= vertical; tile_y += vertical; - var url = [ root_path + '/tilma/tileserver/10k-full/', fms_x, '-', (fms_x+5), ',', fms_y, '-', (fms_y+5), '/JSON' ].join(''); + var url = [ root_path + '/tilma/tileserver/' + fixmystreet.tile_type + '/', fixmystreet.x, '-', (fixmystreet.x+5), ',', fixmystreet.y, '-', (fixmystreet.y+5), '/JSON' ].join(''); YAHOO.util.Connect.asyncRequest('GET', url, { success: urls_loaded, failure: urls_not_loaded, argument: [tile_x, tile_y] }); if (force) return; - load_pins(fms_x, fms_y); + load_pins(fixmystreet.x, fixmystreet.y); } function load_pins(x, y) { @@ -349,8 +347,8 @@ function urls_loaded(o) { if (tiles[i][j] == null) continue; var jj = (j + o.argument[0]); var id = [ 't', ii, '.', jj ].join(''); - var xx = fms_x+j; - var yy = fms_y+5-i; + var xx = fixmystreet.x+j; + var yy = fixmystreet.y+5-i; var img = document.getElementById(id); if (img) { if (!img.galleryimg) { img.galleryimg = false; } @@ -359,15 +357,15 @@ function urls_loaded(o) { continue; } img = cloneNode(); - img.style.top = ((ii-2)*tileheight) + 'px'; - img.style.left = ((jj-2)*tilewidth) + 'px'; + img.style.top = ((ii-2)*fixmystreet.tileheight) + 'px'; + img.style.left = ((jj-2)*fixmystreet.tilewidth) + 'px'; img.name = [ 'tile_', xx, '.', yy ].join('') img.id = id; if (browser) { img.style.visibility = 'hidden'; img.onload=function() { this.style.visibility = 'visible'; } } - img.src = 'http://tilma.mysociety.org/tileserver/10k-full/' + tiles[i][j]; + img.src = 'http://tilma.mysociety.org/tileserver/' + fixmystreet.tile_type + '/' + tiles[i][j]; tileCache[id] = { x: xx, y: yy, t: img }; drag.appendChild(img); } @@ -387,8 +385,8 @@ function cloneNode() { } img.onclick = drag_check; img.style.position = 'absolute'; - img.style.width = tilewidth + 'px'; - img.style.height = tileheight + 'px'; + img.style.width = fixmystreet.tilewidth + 'px'; + img.style.height = fixmystreet.tileheight + 'px'; img.galleryimg = false; img.alt = 'Loading...'; } else { @@ -400,7 +398,7 @@ function cloneNode() { var tileCache=[]; function cleanCache() { for (var i in tileCache) { - if (tileCache[i].x < fms_x || tileCache[i].x > fms_x+5 || tileCache[i].y < fms_y || tileCache[i].y > fms_y+5) { + if (tileCache[i].x < fixmystreet.x || tileCache[i].x > fixmystreet.x+5 || tileCache[i].y < fixmystreet.y || tileCache[i].y > fixmystreet.y+5) { var t = tileCache[i].t; t.parentNode.removeChild(t); // de-leak? delete tileCache[i]; diff --git a/web/questionnaire.cgi b/web/questionnaire.cgi index f7b7df0e1..1da410b80 100755 --- a/web/questionnaire.cgi +++ b/web/questionnaire.cgi @@ -14,7 +14,6 @@ use Error qw(:try); use CrossSell; use mySociety::AuthToken; use mySociety::Locale; -use mySociety::MaPit; use mySociety::Web qw(ent); sub main { diff --git a/web/reports.cgi b/web/reports.cgi index 6c5796079..7246c9792 100755 --- a/web/reports.cgi +++ b/web/reports.cgi @@ -33,28 +33,27 @@ sub main { my ($one_council, $area_type, $area_name); if ($q_council =~ /^(\d\d)([a-z]{2})?([a-z]{2})?$/i) { - my $va_info = mySociety::MaPit::get_voting_area_info(uc $q_council); + my $va_info = mySociety::MaPit::call('area', uc $q_council); $area_name = Page::short_name($va_info->{name}); if (length($q_council) == 6) { - $va_info = mySociety::MaPit::get_voting_area_info($va_info->{parent_area_id}); + $va_info = mySociety::MaPit::call('area', $va_info->{parent_area}); $area_name = Page::short_name($va_info->{name}) . '/' . $area_name; } $rss = '/rss' if $rss; print $q->redirect($base_url . $rss . '/reports/' . $area_name); return; } elsif ($q_council =~ /\D/) { - (my $qc = $q_council) =~ s/ and / & /; - my $areas = mySociety::MaPit::get_voting_area_by_name($qc, $mySociety::VotingArea::council_parent_types, 10); + my $areas = mySociety::MaPit::call('areas', $q_council, type => $mySociety::VotingArea::council_parent_types, min_generation=>10 ); if (keys %$areas == 1) { ($one_council) = keys %$areas; $area_type = $areas->{$one_council}->{type}; $area_name = $areas->{$one_council}->{name}; } else { foreach (keys %$areas) { - if ($areas->{$_}->{name} =~ /^\Q$qc\E (Borough|City|District|County) Council$/) { + if ($areas->{$_}->{name} =~ /^\Q$q_council\E (Borough|City|District|County) Council$/) { $one_council = $_; $area_type = $areas->{$_}->{type}; - $area_name = $qc; + $area_name = $q_council; } } } @@ -63,7 +62,7 @@ sub main { return; } } elsif ($q_council =~ /^\d+$/) { - my $va_info = mySociety::MaPit::get_voting_area_info($q_council); + my $va_info = mySociety::MaPit::call('area', $q_council); $area_name = $va_info->{name}; print $q->redirect($base_url . '/reports/' . Page::short_name($area_name)); return; @@ -74,9 +73,9 @@ sub main { my $q_ward = $q->param('ward') || ''; my $ward; if ($one_council && $q_ward) { - my $qw = mySociety::MaPit::get_voting_area_by_name($q_ward, $mySociety::VotingArea::council_child_types, 10); + my $qw = mySociety::MaPit::call('areas', $q_ward, type => $mySociety::VotingArea::council_child_types, min_generation => 10); foreach my $id (sort keys %$qw) { - if ($qw->{$id}->{parent_area_id} == $one_council) { + if ($qw->{$id}->{parent_area} == $one_council) { $ward = $id; last; } @@ -116,21 +115,21 @@ sub main { return; } - my %councils; + my $areas_info; if ($one_council) { - %councils = ( $one_council => 1 ); + $areas_info = mySociety::MaPit::call('areas', $one_council); } else { # Show all councils on main report page my $ignore = 'LGD'; $ignore .= '|CTY' if $q->{site} eq 'emptyhomes'; my @types = grep { !/$ignore/ } @$mySociety::VotingArea::council_parent_types; - %councils = map { $_ => 1 } @{mySociety::MaPit::get_areas_by_type(\@types, 10)}; + $areas_info = mySociety::MaPit::call('areas', [ @types ], min_generation=>10 ); } my $problems = Problems::council_problems($ward, $one_council); my (%fixed, %open); - my $re_councils = join('|', keys %councils); + my $re_councils = join('|', keys %$areas_info); foreach my $row (@$problems) { if (!$row->{council}) { # Problem was not sent to any council, add to possible councils @@ -148,7 +147,6 @@ sub main { } } - my $areas_info = mySociety::MaPit::get_voting_areas_info([keys %councils]); if (!$one_council) { print Page::header($q, title=>_('Summary reports'), expires=>'+1h'); print $q->p( @@ -162,7 +160,7 @@ sub main { print '<th>' . _('Old problems,<br>state unknown') . '</th>'; } print '<th>' . _('Recently fixed') . '</th><th>' . _('Older fixed') . '</th></tr>'; - foreach (sort { $areas_info->{$a}->{name} cmp $areas_info->{$b}->{name} } keys %councils) { + foreach (sort { $areas_info->{$a}->{name} cmp $areas_info->{$b}->{name} } keys %$areas_info) { print '<tr align="center"'; ++$c; if ($areas_info->{$_}->{generation_high}==10) { diff --git a/web/rss.cgi b/web/rss.cgi index a2810aee8..7060d1709 100755 --- a/web/rss.cgi +++ b/web/rss.cgi @@ -43,7 +43,7 @@ sub main { $out = mySociety::Alert::generate_rss($type, $xsl, $qs, [$id], undef, $cobrand. $q); } elsif ($type eq 'area_problems') { my $id = $q->param('id'); - my $va_info = mySociety::MaPit::get_voting_area_info($id); + my $va_info = mySociety::MaPit::call('area', $id); my $qs = '/'.$id; $out = mySociety::Alert::generate_rss($type, $xsl, $qs, [$id], { NAME => $va_info->{name} }, $cobrand, $q); } elsif ($type eq 'all_problems') { |