001package org.openimaj.picslurper.output;
002
003import java.io.DataInput;
004import java.io.DataOutput;
005import java.io.File;
006import java.io.FilenameFilter;
007import java.io.IOException;
008import java.io.PrintWriter;
009import java.net.URL;
010import java.util.Arrays;
011import java.util.List;
012import java.util.Scanner;
013
014import org.openimaj.io.ReadWriteable;
015import org.openimaj.picslurper.StatusConsumption;
016
017import twitter4j.Status;
018import twitter4j.internal.json.z_T4JInternalJSONImplFactory;
019import twitter4j.internal.org.json.JSONObject;
020
021import com.google.gson.Gson;
022import com.google.gson.GsonBuilder;
023
024/**
025 * Can serialise itself as bytes or a json string
026 *
027 * @author Sina Samangooei (ss@ecs.soton.ac.uk)
028 *
029 */
030public class WriteableImageOutput implements ReadWriteable, Cloneable {
031        private transient Gson gson = new GsonBuilder().create();
032        private static final String IMAGE_OUTPUT_HEADER = "IMGOUTB";
033        private static final String IMAGE_OUTPUT_HEADER_ASCII = "IMGOUTA";
034        /**
035         *
036         */
037        public Status status;
038        /**
039         *
040         */
041        public URL url;
042        /**
043         *
044         */
045        public File file;
046        /**
047         *
048         */
049        public StatusConsumption stats;
050
051        /**
052         *
053         */
054        public WriteableImageOutput() {
055                // all remain null
056        }
057
058        /**
059         * @param status
060         * @param url
061         * @param file
062         * @param stats
063         */
064        public WriteableImageOutput(Status status, URL url, File file, StatusConsumption stats) {
065                this.status = status;
066                this.url = url;
067                this.file = file;
068                this.stats = stats;
069        }
070
071        @Override
072        public void readBinary(DataInput in) throws IOException {
073                final String statusJson = in.readUTF();
074                try {
075                        this.status = new z_T4JInternalJSONImplFactory(null).createStatus(new JSONObject(statusJson));
076                } catch (final Exception e) {
077                        throw new IOException(e);
078                }
079                this.url = new URL(in.readUTF());
080                this.file = new File(in.readUTF());
081                this.stats = new StatusConsumption();
082                this.stats.readBinary(in);
083
084        }
085
086        @Override
087        public byte[] binaryHeader() {
088                return IMAGE_OUTPUT_HEADER.getBytes();
089        }
090
091        @Override
092        public void writeBinary(DataOutput out) throws IOException {
093                out.writeUTF(gson.toJson(this.status));
094                out.writeUTF(url.toString());
095                out.writeUTF(file.toString());
096                stats.writeBinary(out);
097        }
098
099        @Override
100        public void readASCII(Scanner in) throws IOException {
101                final String statusJson = in.nextLine();
102                try {
103                        this.status = new z_T4JInternalJSONImplFactory(null).createStatus(new JSONObject(statusJson));
104                } catch (final Exception e) {
105                        throw new IOException(e);
106                }
107                this.url = new URL(in.nextLine());
108                this.file = new File(in.nextLine());
109                this.stats = new StatusConsumption();
110                this.stats.readASCII(in);
111        }
112
113        @Override
114        public String asciiHeader() {
115                return IMAGE_OUTPUT_HEADER_ASCII;
116        }
117
118        @Override
119        public void writeASCII(PrintWriter out) throws IOException {
120                out.println(gson.toJson(this.status));
121                out.println(url.toString());
122                out.println(file.toString());
123                stats.writeASCII(out);
124        }
125
126        /**
127         * @return all the images in this ImageOutput's file
128         */
129        public List<File> listImageFiles() {
130                final File[] files = this.file.listFiles(new FilenameFilter() {
131
132                        @Override
133                        public boolean accept(File dir, String name) {
134                                return name.matches("image_.*[.](png|gif)");
135                        }
136                });
137                return Arrays.asList(files);
138        }
139
140        /**
141         * @param root
142         * @return all the images in this ImageOutput's file
143         */
144        public List<File> listImageFiles(String root) {
145                final File[] files = new File(root, this.file.toString()).listFiles(new FilenameFilter() {
146
147                        @Override
148                        public boolean accept(File dir, String name) {
149                                return name.matches("image_.*[.](png|gif)");
150                        }
151                });
152                return Arrays.asList(files);
153        }
154
155        @Override
156        public String toString() {
157                return this.url.toString();
158        }
159
160        @Override
161        public WriteableImageOutput clone() throws CloneNotSupportedException {
162                return new WriteableImageOutput(status, url, new File(file.getAbsolutePath()), stats);
163        }
164}