Skip to content

Commit

Permalink
Merge pull request #1631 from akvo/release/1.9.6
Browse files Browse the repository at this point in the history
Release/1.9.6
  • Loading branch information
rumca committed Apr 20, 2016
2 parents da8091f + 735e695 commit 05fe4d5
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 70 deletions.
11 changes: 3 additions & 8 deletions Dashboard/app/cljs/src/org/akvo/flow/dashboard/t.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;; Copyright (C) 2014 Stichting Akvo (Akvo Foundation)
;; Copyright (C) 2014-2016 Stichting Akvo (Akvo Foundation)
;;
;; This file is part of Akvo FLOW.
;;
Expand All @@ -15,16 +15,11 @@
(ns org.akvo.flow.dashboard.t)

(defmacro t> [key]
`(let [locale# (-> js/window
(aget "parent")
(aget "localStorage")
(aget "locale")
.toUpperCase)
k# ~(name key)
`(let [k# ~(name key)
s# (-> js/window
(aget "parent")
(aget "Ember")
(aget (cljs.core/str "STRINGS" "_" locale#))
(aget (cljs.core/str "STRINGS"))
(aget k#))]
(if s#
s#
Expand Down
14 changes: 9 additions & 5 deletions Dashboard/app/js/lib/controllers/maps-controllers-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ FLOW.placemarkController = Ember.ArrayController.create({
// TODO this is not optimal at high zoom levels, as we will already have loaded the same points on a level before
for (var i = 0; i < bestBB.length; i++){
if (this.get('geocellCache').indexOf(bestBB[i]+"-"+gcLevel) < 0 ) {
// if we don't have it in the cache add it to the list of items to be loaded
// if we don't have it in the cache add it to the list of items to be loaded
listToRetrieve.push(bestBB[i]);

// now add this key to cache
Expand Down Expand Up @@ -130,7 +130,7 @@ FLOW.placemarkController = Ember.ArrayController.create({
if (!Ember.none(FLOW.placemarkController.get('selectedMarker'))){
if (FLOW.placemarkController.selectedMarker.target.options.placemarkId != marker.target.options.placemarkId){
FLOW.placemarkController.selectedMarker.target.options.selected = false;
FLOW.placemarkController.selectedMarker.target.setStyle({color:'#d46f12',
FLOW.placemarkController.selectedMarker.target.setStyle({color:'#d46f12',
fillColor:'#edb660'});
FLOW.placemarkController.set('selectedMarker',null);
}
Expand Down Expand Up @@ -164,7 +164,7 @@ FLOW.countryController = Ember.ArrayController.create({
this.set('content', this.getContent(FLOW.Env.countries));
}
},

/**
Helper function to parse backend countries to countryList
*/
Expand Down Expand Up @@ -215,7 +215,7 @@ FLOW.placemarkDetailController = Ember.ArrayController.create({
this.set('content', Ember.A());
}
},

handlePlacemarkSelection: function () {
var selectedPlacemarkId = null;
if (!Ember.none(FLOW.placemarkController.get('selectedMarker'))) {
Expand All @@ -227,7 +227,7 @@ FLOW.placemarkDetailController = Ember.ArrayController.create({

photoUrl: function () {
var photoDetails, photoUrls = [],
rawPhotoUrl;
rawPhotoUrl, photoJson;

if (!this.get('content').get('isLoaded')) {
return null;
Expand All @@ -244,6 +244,10 @@ FLOW.placemarkDetailController = Ember.ArrayController.create({

photoDetails.forEach(function (photo) {
rawPhotoUrl = photo.get('stringValue') || '';
if (rawPhotoUrl.charAt(0) === '{') {
photoJson = JSON.parse(rawPhotoUrl);
rawPhotoUrl = photoJson.filename;
}
// Since photos have a leading path from devices that we need to trim
photoUrls.push(FLOW.Env.photo_url_root + rawPhotoUrl.split('/').pop());
});
Expand Down
10 changes: 10 additions & 0 deletions Dashboard/app/js/lib/views/maps/map-views-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,16 @@ FLOW.NavMapsView = FLOW.View.extend({
clickedPointContent += srcAttr + signatureJson.image +'"/>';
clickedPointContent += Ember.String.loc('_signed_by') +': '+signatureJson.name;
break;
case "VIDEO":
var videoString = "", videoJson;
if (questionAnswer.charAt(0) === '{') {
videoJson = JSON.parse(questionAnswer);
videoString = videoJson.filename
} else {
videoString = questionAnswer;
}
clickedPointContent += videoString;
break;
case "CASCADE":
case "OPTION":
var cascadeString = "", cascadeJson;
Expand Down
8 changes: 6 additions & 2 deletions Dashboard/app/js/lib/views/views.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ Ember.Handlebars.registerHelper('tooltip', function (i18nKey) {


Ember.Handlebars.registerHelper('placemarkDetail', function () {
var answer, markup, question, cascadeJson, optionJson, cascadeString = "", questionType, imageSrcAttr, signatureJson;
var answer, markup, question, cascadeJson, optionJson, cascadeString = "",
questionType, imageSrcAttr, signatureJson, photoJson;

question = Ember.get(this, 'questionText');
answer = Ember.get(this, 'stringValue') || '';
Expand All @@ -106,6 +107,9 @@ Ember.Handlebars.registerHelper('placemarkDetail', function () {
return item.name;
}).join("|");
}
} else if ((questionType === 'VIDEO' || questionType === 'PHOTO') && answer.charAt(0) === '{') {
photoJson = JSON.parse(answer)
answer = photoJson.filename;
} else if (questionType === 'OPTION' && answer.charAt(0) === '[') {
optionJson = JSON.parse(answer);
answer = optionJson.map(function(item){
Expand Down Expand Up @@ -462,7 +466,7 @@ FLOW.NavigationView = Em.View.extend({
html.className = '';
html.classList.add(FLOW.router.navigationController.selected);
}
}),
}),
}),

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
{{#if view.isPhotoType}}
{{view.photoUrl}} <a {{bindAttr href="view.photoUrl"}} target="_blank">{{t _open_photo}}</a>
{{else}} {{#if view.isVideoType}}
{{QA.value}} <a {{bindAttr href="view.photoUrl" }} target="_blank">{{t _open_video}}</a>
{{view.photoUrl}} <a {{bindAttr href="view.photoUrl" }} target="_blank">{{t _open_video}}</a>
{{else}} {{#if view.isGeoShapeType}}
{{view FLOW.GeoshapeMapView}}
{{else}} {{#if view.isCascadeType}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
{{#if view.isPhotoType}}
{{view.photoUrl}} <a {{bindAttr href="view.photoUrl" }} target="_blank">{{t _open_photo}}</a>
{{else}} {{#if view.isVideoType}}
{{value}} <a {{bindAttr href="view.photoUrl" }} target="_blank">{{t _open_video}}</a>
{{view.photoUrl}} <a {{bindAttr href="view.photoUrl" }} target="_blank">{{t _open_video}}</a>
{{else}} {{#if view.isDateType}}
{{date3 value}}
{{else}} {{#if view.isCascadeType}}
Expand Down
17 changes: 6 additions & 11 deletions GAE/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,6 @@
</target>

<target name="update" depends="compile,datanucleusenhance" description="Uploads the application to App Engine.">
<fail message="[pwd] property is not present, e.g.: ant update -Dpwd=/path/to/password.txt">
<condition>
<not>
<isset property="pwd" />
</not>
</condition>
</fail>

<delete failonerror="false">
<fileset dir="${app_dir}/deploy" includes="**/*.symbolMap"/>
Expand All @@ -183,10 +176,12 @@

<replace file="./war/admin/js/app.js" token="__VERSION__" value="${app.version}" />

<exec dir="." executable="sh" failonerror="true">
<arg value="-c" />
<arg value="${sdk.dir}/bin/appcfg.sh --enable_jar_splitting --email=${email.address} --passin &lt; ${pwd} update war" />
</exec>
<appcfg action="update" war="war">
<options>
<arg value="--enable_jar_splitting"/>
<arg value="--email=${email.address}"/>
</options>
</appcfg>

<exec dir="." executable="sh" failonerror="true">
<arg value="-c" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -814,15 +814,12 @@ public void publishSurveyAsync(Long surveyId) {
queue.add(options);

Survey s = new SurveyDAO().getById(surveyId);
if (s != null) {
Long surveyGroupId = s.getSurveyGroupId();
SurveyGroup sg = new SurveyGroupDAO().getByKey(surveyGroupId);
if (sg != null && sg.getNewLocaleSurveyId().longValue() == surveyId.longValue()) {
// This is the registration form. Schedule datapoint name re-assembly
DataProcessorRestServlet.scheduleDatapointNameAssembly(surveyGroupId, null);
}
SurveyGroup sg = s != null ? new SurveyGroupDAO().getByKey(s.getSurveyGroupId()) : null;
if (sg != null && sg.getNewLocaleSurveyId() != null &&
sg.getNewLocaleSurveyId().longValue() == surveyId.longValue()) {
// This is the registration form. Schedule datapoint name re-assembly
DataProcessorRestServlet.scheduleDatapointNameAssembly(sg.getKey().getId(), null);
}

}

@Override
Expand Down
31 changes: 13 additions & 18 deletions GAE/src/org/waterforpeople/mapping/app/web/RawDataRestServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import javax.servlet.http.HttpServletRequest;

import org.waterforpeople.mapping.app.gwt.client.survey.QuestionDto.QuestionType;
import org.waterforpeople.mapping.app.gwt.server.survey.SurveyServiceImpl;
import org.waterforpeople.mapping.app.gwt.server.surveyinstance.SurveyInstanceServiceImpl;
import org.waterforpeople.mapping.app.web.dto.DataProcessorRequest;
import org.waterforpeople.mapping.app.web.dto.RawDataImportRequest;
Expand Down Expand Up @@ -213,15 +212,15 @@ protected RestResponse handleRequest(RestRequest req) throws Exception {
}
log.log(Level.INFO, "Deleting " + deletedAnswers.size() + " question answers");
qasDao.delete(deletedAnswers);

if (!isMonitoringForm && !isNewInstance) {
// Update datapoint name for this locale
SurveyedLocale sl = slDao.getById(instance.getSurveyedLocaleId());
sl.assembleDisplayName(
qDao.listDisplayNameQuestionsBySurveyId(s.getKey().getId()), updatedAnswers);
slDao.save(sl);
}

if (isNewInstance) {
// create new surveyed locale and launch task to complete processing
SurveyedLocale locale = new SurveyedLocale();
Expand Down Expand Up @@ -371,13 +370,20 @@ protected RestResponse handleRequest(RestRequest req) throws Exception {
}
} else if (RawDataImportRequest.UPDATE_SUMMARIES_ACTION
.equalsIgnoreCase(importReq.getAction())) {
if (importReq.getSurveyId() == null
|| new SurveyDAO().getById(importReq.getSurveyId()) == null) {
// ensure survey id present for summary update
return null;
}
// first rebuild the summaries
log.log(Level.INFO, "Rebuilding summaries for surveyId "
+ importReq.getSurveyId().toString());
TaskOptions options = TaskOptions.Builder.withUrl(
"/app_worker/dataprocessor").param(
DataProcessorRequest.ACTION_PARAM,
DataProcessorRequest.REBUILD_QUESTION_SUMMARY_ACTION);
TaskOptions options = TaskOptions.Builder
.withUrl("/app_worker/dataprocessor")
.param(DataProcessorRequest.ACTION_PARAM,
DataProcessorRequest.REBUILD_QUESTION_SUMMARY_ACTION)
.param(DataProcessorRequest.SURVEY_ID_PARAM, importReq.getSurveyId().toString());

String backendPub = PropertyUtil.getProperty("backendpublish");
if (backendPub != null && "true".equals(backendPub)) {
// change the host so the queue invokes the backend
Expand All @@ -386,21 +392,10 @@ protected RestResponse handleRequest(RestRequest req) throws Exception {
BackendServiceFactory.getBackendService()
.getBackendAddress("dataprocessor"));
}
Long surveyId = importReq.getSurveyId();
if (surveyId != null && surveyId > 0) {
options.param(DataProcessorRequest.SURVEY_ID_PARAM,
surveyId.toString());
}

com.google.appengine.api.taskqueue.Queue queue = com.google.appengine.api.taskqueue.QueueFactory
.getDefaultQueue();
queue.add(options);

// now remap to access point
if (surveyId != null) {
SurveyServiceImpl ssi = new SurveyServiceImpl();
ssi.rerunAPMappings(surveyId);
}
} else if (RawDataImportRequest.SAVE_MESSAGE_ACTION
.equalsIgnoreCase(importReq.getAction())) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ protected void populateFields(HttpServletRequest req) throws Exception {

private static Date parseDate(String s) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
ParsePosition pp = new ParsePosition(0);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.parse(s, pp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
Expand All @@ -44,7 +45,9 @@ protected DataFormatter initialValue() {
private static final ThreadLocal<DateFormat> DATE_RESPONSE_FORMAT = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ private void writeAnswer(
break;

case PHOTO:
case VIDEO:
cells.add(photoCellValue(value, imagePrefix));
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ public class RawDataSpreadsheetImporter implements DataImporter {
private List<String> errorIds;
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

private static final int SIZE_THRESHOLD = 2000 * 400;

/**
* opens a file input stream using the file passed in and tries to return the first worksheet in
* that file
Expand Down Expand Up @@ -145,20 +143,12 @@ public void executeImport(File file, String serverBase, Map<String, String> crit
log.error(line);
}
}
// Count the number of rows in the sheet
Iterator<Row> rowIterator = sheet.rowIterator();
int rowCount = 0;
while (rowIterator.hasNext()) {
rowIterator.next();
rowCount++;
}

Thread.sleep(5000);
log.debug("Updating summaries");
if (rowCount * questionIdToQuestionDto.size() < SIZE_THRESHOLD) {
invokeUrl(serverBase, "action=" + RawDataImportRequest.UPDATE_SUMMARIES_ACTION
+ "&" + RawDataImportRequest.SURVEY_ID_PARAM + "=" + surveyId, true,
criteria.get(KEY_PARAM));
}
invokeUrl(serverBase, "action=" + RawDataImportRequest.UPDATE_SUMMARIES_ACTION
+ "&" + RawDataImportRequest.SURVEY_ID_PARAM + "=" + surveyId, true,
criteria.get(KEY_PARAM));
invokeUrl(serverBase, "action=" + RawDataImportRequest.SAVE_MESSAGE_ACTION + "&"
+ RawDataImportRequest.SURVEY_ID_PARAM + "=" + surveyId, true,
criteria.get(KEY_PARAM));
Expand Down
Binary file modified GAE/war/exporterapplet.jar
Binary file not shown.
17 changes: 17 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ Read more about the [Akvo Platform](http://www.akvo.org/blog/?p=4822).

Akvo FLOW Dashboard release notes
----

#1.9.6
Date: 20 April 2016
# New and noteworthy
* Better timezone handling in export raw data reports. Consistently display dates using ISO 8601 [#257]
* Geotagging in photos: include location information, if available, in media responses [#1527]
* Portuguese translations in FLOW dashboard [#1578]
* Improve performance by dynamically loading languages in dashboard [#1602]
* Switch to Oauth2-based authentication in GAE deployments [#1625]

# Resolved issues
* Ignore blank last cell in raw data reports [#1553]
* Graphical survey summary report gives a decimal in the summary sheet [#1580]
* Update device last contact time to the dashboard [#1585]
* Tasks are unnecessarily rerun for every form response submitted [#1594]
* NPE on non-monitored survey publishing [#1611]

#1.9.5.2
Date: 15 March 2016
# Resolved issues
Expand Down

0 comments on commit 05fe4d5

Please sign in to comment.