1 package com.simpligility.maven.plugins.android.standalonemojos;
2
3 import com.google.api.client.http.AbstractInputStreamContent;
4 import com.google.api.client.http.FileContent;
5 import com.google.api.services.androidpublisher.AndroidPublisher;
6 import com.google.api.services.androidpublisher.model.Listing;
7 import com.simpligility.maven.plugins.android.AbstractPublisherMojo;
8 import com.simpligility.maven.plugins.android.common.AndroidPublisherHelper;
9
10 import org.apache.maven.plugin.MojoExecutionException;
11 import org.apache.maven.plugin.MojoFailureException;
12 import org.apache.maven.plugins.annotations.Mojo;
13 import org.apache.maven.plugins.annotations.Parameter;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.List;
19
20
21
22
23
24
25 @Mojo( name = "publish-listing", requiresProject = false )
26 public class PublishListingMojo extends AbstractPublisherMojo
27 {
28
29 private static final int MAX_CHARS_TITLE = 50;
30 private static final int MAX_CHARS_SHORT_DESCRIPTION = 80;
31 private static final int MAX_CHARS_FULL_DESCRIPTION = 4000;
32 private static final int MAX_SCREENSHOTS_SIZE = 8;
33
34 private static final String LISTING_PATH = "listing/";
35
36 private static final String IMAGE_TYPE_FEATURE_GRAPHIC = "featureGraphic";
37 private static final String IMAGE_TYPE_ICON = "icon";
38 private static final String IMAGE_TYPE_PHONE_SCREENSHOTS = "phoneScreenshots";
39 private static final String IMAGE_TYPE_PROMO_GRAPHIC = "promoGraphic";
40 private static final String IMAGE_TYPE_SEVEN_INCH_SCREENSHOTS = "sevenInchScreenshots";
41 private static final String IMAGE_TYPE_TEN_INCH_SCREENSHOTS = "tenInchScreenshots";
42 private static final String IMAGE_TYPE_TV_BANNER = "tvBanner";
43 private static final String IMAGE_TYPE_TV_SCREENSHOTS = "tvScreenshots";
44
45 @Parameter( property = "android.publisher.package.name" )
46 private String packageName;
47
48 @Parameter( property = "android.publisher.filename.full.description", defaultValue = "fulldescription.txt" )
49 private String fileNameFullDescription;
50
51 @Parameter( property = "android.publisher.filename.short.description", defaultValue = "shortdescription.txt" )
52 private String fileNameShortDescription;
53
54 @Parameter( property = "android.publisher.filename.title", defaultValue = "title.txt" )
55 private String fileNameTitle;
56
57 @Parameter( property = "android.publisher.upload.images", defaultValue = "false" )
58 private boolean uploadImages;
59
60
61
62
63
64
65 public void execute() throws MojoExecutionException, MojoFailureException
66 {
67 if ( packageName == null || packageName.equals( "" ) )
68 {
69 packageName = extractPackageNameFromAndroidManifest( androidManifestFile );
70 }
71
72 getLog().debug( "Package name: " + packageName );
73
74 initializePublisher( packageName );
75 publishListing();
76 }
77
78 private void publishListing() throws MojoExecutionException, MojoFailureException
79 {
80 warnPlatformDefaultEncoding();
81
82 File[] localeDirs = getLocaleDirs();
83 if ( localeDirs == null )
84 {
85 return ;
86 }
87 File listingDir;
88 try
89 {
90 for ( File localeDir : localeDirs )
91 {
92 listingDir = new File( localeDir, LISTING_PATH );
93 if ( listingDir.exists() )
94 {
95 String fullDescription = readFileWithChecks( listingDir, fileNameFullDescription,
96 MAX_CHARS_FULL_DESCRIPTION, "Full description file is missing." );
97
98 String shortDescription = readFileWithChecks( listingDir, fileNameShortDescription,
99 MAX_CHARS_SHORT_DESCRIPTION, "Short description file is missing." );
100
101 String title = readFileWithChecks( listingDir, fileNameTitle,
102 MAX_CHARS_TITLE, "Title file is missing." );
103
104 if ( title == null || shortDescription == null || fullDescription == null )
105 {
106 throw new MojoFailureException( "Incomplete listing" );
107 }
108
109 getLog().info( "Updating the listing for " + packageName );
110 final Listing listing = new Listing();
111 listing.setTitle( title );
112 listing.setFullDescription( fullDescription );
113 listing.setShortDescription( shortDescription );
114 edits.listings()
115 .update( packageName, editId, localeDir.getName(), listing )
116 .execute();
117
118 if ( uploadImages )
119 {
120
121 uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_FEATURE_GRAPHIC );
122
123
124 uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_ICON );
125
126
127 uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_PROMO_GRAPHIC );
128
129
130 uploadScreenShots( listingDir, localeDir.getName(), IMAGE_TYPE_PHONE_SCREENSHOTS );
131
132
133 uploadScreenShots( listingDir, localeDir.getName(), IMAGE_TYPE_SEVEN_INCH_SCREENSHOTS );
134
135
136 uploadScreenShots( listingDir, localeDir.getName(), IMAGE_TYPE_TEN_INCH_SCREENSHOTS );
137
138
139 uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_TV_BANNER );
140
141
142 uploadScreenShots( listingDir, localeDir.getName(), IMAGE_TYPE_TV_SCREENSHOTS );
143 }
144
145 }
146 else
147 {
148 getLog().warn( "Listing directory is missing." );
149 }
150 }
151
152 edits.commit( packageName, editId ).execute();
153 }
154 catch ( IOException e )
155 {
156 throw new MojoExecutionException( "Problem in the listing content: " + e.getMessage(), e );
157 }
158 }
159
160 private List<AbstractInputStreamContent> getImageListAsStream( File listingDir, String graphicPath )
161 {
162 File graphicDir = new File( listingDir, graphicPath );
163 List<AbstractInputStreamContent> images = new ArrayList<AbstractInputStreamContent>();
164 if ( graphicDir.exists() )
165 {
166 File[] imageFiles = graphicDir.listFiles();
167 for ( File imageFile : imageFiles )
168 {
169 images.add( new FileContent( AndroidPublisherHelper.MIME_TYPE_IMAGE, imageFile ) );
170 }
171 }
172 return images;
173 }
174
175 private AbstractInputStreamContent getImageAsStream( File listingDir, String graphicPath )
176 throws MojoFailureException
177 {
178 File graphicDir = new File( listingDir, graphicPath );
179 if ( graphicDir.exists() )
180 {
181 File[] files = graphicDir.listFiles();
182 if ( files == null || files.length == 0 )
183 {
184 getLog().warn( "There are no images in " + graphicDir.getAbsolutePath() );
185 }
186 else if ( files.length > 1 )
187 {
188 throw new MojoFailureException( "There should be exactly 1 image in " + graphicDir.getAbsolutePath() );
189 }
190 else
191 {
192 File graphicFile = files[0];
193 return new FileContent( AndroidPublisherHelper.MIME_TYPE_IMAGE, graphicFile );
194 }
195 }
196 return null;
197 }
198
199 private void uploadSingleGraphic( File dir, String locale, String imageType )
200 throws MojoExecutionException, MojoFailureException
201 {
202 AbstractInputStreamContent contentGraphic = getImageAsStream( dir, imageType );
203 if ( contentGraphic == null )
204 {
205 return ;
206 }
207
208 AndroidPublisher.Edits.Images images = edits.images();
209 try
210 {
211 getLog().info( "Deleting the old " + imageType );
212
213 images.deleteall( packageName, editId, locale, imageType ).execute();
214
215 getLog().info( "Uploading the " + imageType );
216
217 images.upload( packageName, editId, locale, imageType, contentGraphic ).execute();
218 }
219 catch ( IOException e )
220 {
221 getLog().error( e.getMessage(), e );
222 throw new MojoExecutionException( e.getMessage(), e );
223 }
224 }
225
226 private void uploadScreenShots( File dir, String locale, String imageType )
227 throws MojoFailureException, MojoExecutionException
228 {
229 List<AbstractInputStreamContent> contentGraphicList = getImageListAsStream( dir, imageType );
230 if ( contentGraphicList == null || contentGraphicList.isEmpty() )
231 {
232 getLog().warn( "There are no images in " + dir.getAbsolutePath() + "/" + imageType );
233 return ;
234 }
235
236 AndroidPublisher.Edits.Images images = edits.images();
237 try
238 {
239 getLog().info( "Deleting the old " + imageType );
240
241 images.deleteall( packageName, editId, locale, imageType ).execute();
242
243
244 if ( contentGraphicList.size() > MAX_SCREENSHOTS_SIZE )
245 {
246 String message = "You can only upload 8 screen shots";
247 getLog().error( message );
248 throw new MojoFailureException( message );
249 }
250 else
251 {
252 int i = 1;
253 for ( AbstractInputStreamContent contentGraphic : contentGraphicList )
254 {
255 getLog().info( "Uploading " + imageType + " " + i + " out of " + contentGraphicList.size() );
256 images.upload( packageName, editId, locale, imageType, contentGraphic ).execute();
257 i++;
258 }
259 }
260 }
261 catch ( IOException e )
262 {
263 getLog().error( e.getMessage(), e );
264 throw new MojoExecutionException( e.getMessage(), e );
265 }
266 }
267
268 }