/**
AirCasting - Share your Air!
Copyright (C) 2011-2012 HabitatMap, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact the authors by email at <info@habitatmap.org>
*/
package pl.llp.aircasting.helper;
import android.util.Log;
import pl.llp.aircasting.android.Logger;
import pl.llp.aircasting.model.Measurement;
import pl.llp.aircasting.model.MeasurementStream;
import pl.llp.aircasting.model.Session;
import pl.llp.aircasting.util.Constants;
import android.net.Uri;
import android.os.Environment;
import com.csvreader.CsvWriter;
import com.google.common.base.Strings;
import com.google.common.io.Closer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static java.lang.String.valueOf;
public class CSVHelper
{
public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
// Gmail app hack - it requires all file attachments to begin with /mnt/sdcard
public static final String SESSION_ZIP_FILE = "aircasting_session_archive";
public static final String SESSION_FALLBACK_FILE = "session_data";
private static final int MINIMUM_SESSION_NAME_LENGTH = 2;
private final String ZIP_EXTENSION = ".zip";
private final String CSV_EXTENSION = ".csv";
final Closer closer = Closer.create();
public Uri prepareCSV(Session session) throws IOException
{
try
{
File storage = Environment.getExternalStorageDirectory();
File dir = new File(storage, "aircasting_sessions");
dir.mkdirs();
File file = new File(dir, fileName(session.getTitle()) + ZIP_EXTENSION);
OutputStream outputStream = new FileOutputStream(file);
closer.register(outputStream);
ZipOutputStream zippedOutputStream = new ZipOutputStream(outputStream);
zippedOutputStream.putNextEntry(new ZipEntry(fileName(session.getTitle()) + CSV_EXTENSION));
Writer writer = new OutputStreamWriter(zippedOutputStream);
CsvWriter csvWriter = new CsvWriter(writer, ',');
write(session).toWriter(csvWriter);
csvWriter.flush();
csvWriter.close();
Uri uri = Uri.fromFile(file);
if(Constants.isDevMode())
{
Logger.i("File path [" + uri + "]");
}
return uri;
}
finally
{
closer.close();
}
}
String fileName(String title)
{
StringBuilder result = new StringBuilder();
if (!Strings.isNullOrEmpty(title))
{
try
{
Matcher matcher = Pattern.compile("([_\\-a-zA-Z0-9])*").matcher(title.toLowerCase());
while(matcher.find())
{
result.append(matcher.group());
}
}
catch (IllegalStateException ignore)
{
}
}
return result.length() > MINIMUM_SESSION_NAME_LENGTH ? result.toString() : SESSION_FALLBACK_FILE;
}
private SessionWriter write(Session session)
{
return new SessionWriter(session);
}
}
class SessionWriter
{
final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat(CSVHelper.TIMESTAMP_FORMAT);
Session session;
SessionWriter(Session session)
{
this.session = session;
}
void toWriter(CsvWriter writer) throws IOException
{
Iterable<MeasurementStream> streams = session.getActiveMeasurementStreams();
for (MeasurementStream stream : streams)
{
writeSensorHeader(writer);
writeSensor(stream, writer);
writeMeasurementHeader(writer);
for (Measurement measurement : stream.getMeasurements())
{
writeMeasurement(writer, measurement);
}
}
}
private void writeMeasurementHeader(CsvWriter writer) throws IOException
{
writer.write("Timestamp");
writer.write("geo:lat");
writer.write("geo:long");
writer.write("Value");
writer.endRecord();
}
private void writeMeasurement(CsvWriter writer, Measurement measurement) throws IOException
{
writer.write(TIMESTAMP_FORMAT.format(measurement.getTime()));
writer.write(valueOf(measurement.getLongitude()));
writer.write(valueOf(measurement.getLatitude()));
writer.write(valueOf(measurement.getValue()));
writer.endRecord();
}
private void writeSensor(MeasurementStream stream, CsvWriter writer) throws IOException
{
writer.write(stream.getSensorName());
writer.write(stream.getPackageName());
writer.write(stream.getMeasurementType());
writer.write(valueOf(stream.getUnit()));
writer.endRecord();
}
private void writeSensorHeader(CsvWriter writer) throws IOException
{
writer.write("sensor:model");
writer.write("sensor:package");
writer.write("sensor:capability");
writer.write("sensor:units");
writer.endRecord();
}
}