View Javadoc
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   * @author Joris de Groot
23   * @author Benoit Billington
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       * @throws org.apache.maven.plugin.MojoExecutionException
63       * @throws org.apache.maven.plugin.MojoFailureException
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                         // Only one ContentFile allow for featureGraphic
121                         uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_FEATURE_GRAPHIC );
122 
123                         // Only one ContentFile allow for iconGraphic
124                         uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_ICON );
125 
126                         // Only one ContentFile allow for promoGraphic
127                         uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_PROMO_GRAPHIC );
128 
129                         // Upload phoneScreenshots
130                         uploadScreenShots( listingDir, localeDir.getName(), IMAGE_TYPE_PHONE_SCREENSHOTS );
131 
132                         // Upload sevenInchScreenshots
133                         uploadScreenShots( listingDir, localeDir.getName(), IMAGE_TYPE_SEVEN_INCH_SCREENSHOTS );
134 
135                         // Upload tenInchScreenshots
136                         uploadScreenShots( listingDir, localeDir.getName(), IMAGE_TYPE_TEN_INCH_SCREENSHOTS );
137 
138                         // Only one ContentFile allow for tvBanner
139                         uploadSingleGraphic( listingDir, localeDir.getName(), IMAGE_TYPE_TV_BANNER );
140 
141                         // Upload tvScreenShots
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             // Delete current image in play store
213             images.deleteall( packageName, editId, locale, imageType ).execute();
214 
215             getLog().info( "Uploading the " + imageType );
216             // After that upload the new image
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             // Delete all images in play store
241             images.deleteall( packageName, editId, locale, imageType ).execute();
242 
243             // After that upload the new images
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 }