001package ball.tv.epg.sd;
002/*-
003 * ##########################################################################
004 * TV H/W, EPGs, and Recording
005 * $Id: SDProtocol.java 5830 2020-04-18 18:35:22Z ball $
006 * $HeadURL: svn+ssh://svn.hcf.dev/var/spool/scm/repository.svn/ball-tv/trunk/src/main/java/ball/tv/epg/sd/SDProtocol.java $
007 * %%
008 * Copyright (C) 2013 - 2020 Allen D. Ball
009 * %%
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 *
014 *      http://www.apache.org/licenses/LICENSE-2.0
015 *
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 * ##########################################################################
022 */
023import ball.databind.JSONBean;
024import ball.http.annotation.Protocol;
025import ball.tv.epg.entity.Headend;
026import ball.tv.epg.entity.Lineup;
027import ball.tv.epg.entity.Program;
028import ball.tv.epg.entity.Schedule;
029import com.fasterxml.jackson.databind.JsonNode;
030import java.io.File;
031import java.io.IOException;
032import java.net.URI;
033import java.util.Collection;
034import java.util.Date;
035import java.util.List;
036import java.util.Map;
037import javax.ws.rs.ApplicationPath;
038import javax.ws.rs.DELETE;
039import javax.ws.rs.GET;
040import javax.ws.rs.HeaderParam;
041import javax.ws.rs.POST;
042import javax.ws.rs.PUT;
043import javax.ws.rs.Path;
044import javax.ws.rs.PathParam;
045import javax.ws.rs.QueryParam;
046import lombok.Getter;
047import lombok.NoArgsConstructor;
048import org.apache.http.HttpEntity;
049import org.apache.http.HttpResponse;
050import org.apache.http.client.ClientProtocolException;
051import org.apache.http.client.HttpResponseException;
052import org.apache.http.entity.FileEntity;
053
054import static org.apache.commons.lang3.StringUtils.EMPTY;
055
056/**
057 * Protocol specification for
058 * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201 SchedulesDirect/JSON-Service}.
059 *
060 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
061 * @version $Revision: 5830 $
062 */
063@Protocol(charset = "UTF-8")
064@ApplicationPath("https://json.schedulesdirect.org/")
065public interface SDProtocol {
066
067    /**
068     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#obtain-a-token target=newtab Obtain a token}
069     *
070     * @param   entity          The user's credentials.
071     *
072     * @return  The {@link PostTokenResponse}.
073     *
074     * @throws  IOException     See {@link ball.http.ProtocolClient}.
075     * @throws  HttpResponseException
076     *                          See {@link ball.http.ProtocolClient}.
077     * @throws  ClientProtocolException
078     *                          See {@link ball.http.ProtocolClient}.
079     */
080    @POST @Path("20141201/token")
081    public PostTokenResponse postToken(HttpEntity entity)
082        throws HttpResponseException, ClientProtocolException, IOException;
083
084    /**
085     * {@link #postToken(HttpEntity)} return type.
086     *
087     * {@bean.info}
088     */
089    @NoArgsConstructor @Getter
090    public static class PostTokenResponse extends JSONBean {
091        private static final long serialVersionUID = 3688926764075780717L;
092
093        /** @serial */ private String response = null;
094        /** @serial */ private int code = -1;
095        /** @serial */ private String message = null;
096        /** @serial */ private String serverID = null;
097        /** @serial */ private Date datetime = null;
098        /** @serial */ private String token = null;
099    }
100
101    /**
102     * See {@link #postToken(HttpEntity)}.
103     *
104     * @param   file            The user's credential {@link File}.
105     *
106     * @return  The {@link PostTokenResponse}.
107     *
108     * @throws  IOException     See {@link ball.http.ProtocolClient}.
109     * @throws  HttpResponseException
110     *                          See {@link ball.http.ProtocolClient}.
111     * @throws  ClientProtocolException
112     *                          See {@link ball.http.ProtocolClient}.
113     */
114    default PostTokenResponse postToken(File file) throws HttpResponseException,
115                                                          ClientProtocolException,
116                                                          IOException {
117        return postToken(new FileEntity(file));
118    }
119
120    /**
121     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#getting-status target=newtab Gettting status}
122     *
123     * @param   token           The token.
124     *
125     * @return  The {@link GetStatusResponse}.
126     *
127     * @throws  IOException     See {@link ball.http.ProtocolClient}.
128     * @throws  HttpResponseException
129     *                          See {@link ball.http.ProtocolClient}.
130     * @throws  ClientProtocolException
131     *                          See {@link ball.http.ProtocolClient}.
132     */
133    @GET @Path("20141201/status")
134    public GetStatusResponse getStatus(@HeaderParam(EMPTY) String token)
135        throws HttpResponseException, ClientProtocolException, IOException;
136
137    /**
138     * {@link #getStatus(String)} return type.
139     *
140     * {@bean.info}
141     */
142    @NoArgsConstructor @Getter
143    public static class GetStatusResponse extends JSONBean {
144        private static final long serialVersionUID = -8726397073906352187L;
145
146        /** @serial */ private JsonNode account = null;
147        /** @serial */ private List<LineupElement> lineups = null;
148        /** @serial */ private Date lastDataUpdate = null;
149        /** @serial */ private JsonNode notifications = null;
150        /** @serial */ private JsonNode systemStatus = null;
151        /** @serial */ private String serverID = null;
152        /** @serial */ private Date datetime = null;
153        /** @serial */ private int code = -1;
154    }
155
156    /**
157     * {@link #getStatus(String)} line-up element.
158     *
159     * {@bean.info}
160     */
161    @NoArgsConstructor @Getter
162    public static class LineupElement extends JSONBean {
163        private static final long serialVersionUID = 2893786465448798250L;
164
165        /** @serial */ private String lineup = null;
166        /** @serial */ private Date modified = null;
167        /** @serial */ private String uri = null;
168    }
169
170    /**
171     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#determine-if-the-client-is-the-correct-version target=newtab Determine if the client is the correct version}
172     *
173     * @param   client          The client identifier.
174     *
175     * @return  The {@link GetVersionResponse}.
176     *
177     * @throws  IOException     See {@link ball.http.ProtocolClient}.
178     * @throws  HttpResponseException
179     *                          See {@link ball.http.ProtocolClient}.
180     * @throws  ClientProtocolException
181     *                          See {@link ball.http.ProtocolClient}.
182     */
183    @GET @Path("20141201/version/{client}")
184    public GetVersionResponse getVersion(@PathParam(EMPTY) String client)
185        throws HttpResponseException, ClientProtocolException, IOException;
186
187    /**
188     * {@link #getVersion(String)} return type.
189     *
190     * {@bean.info}
191     */
192    @NoArgsConstructor @Getter
193    public static class GetVersionResponse extends JSONBean {
194        private static final long serialVersionUID = -852152896406517237L;
195
196        /** @serial */ private String response = null;
197        /** @serial */ private int code = -1;
198        /** @serial */ private String client = null;
199        /** @serial */ private String version = null;
200        /** @serial */ private String serverID = null;
201        /** @serial */ private Date datetime = null;
202    }
203
204    /**
205     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#obtain-the-list-of-available-services target=newtab Obtain the list of available services}
206     *
207     * @return  The {@link JsonNode}.
208     *
209     * @throws  IOException     See {@link ball.http.ProtocolClient}.
210     * @throws  HttpResponseException
211     *                          See {@link ball.http.ProtocolClient}.
212     * @throws  ClientProtocolException
213     *                          See {@link ball.http.ProtocolClient}.
214     */
215    @GET @Path("20141201/available")
216    public JsonNode getAvailable()
217        throws HttpResponseException, ClientProtocolException, IOException;
218
219    /**
220     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#obtain-the-list-of-available-services target=newtab Obtain the list of available services}
221     *
222     * @return  The {@link JsonNode}.
223     *
224     * @throws  IOException     See {@link ball.http.ProtocolClient}.
225     * @throws  HttpResponseException
226     *                          See {@link ball.http.ProtocolClient}.
227     * @throws  ClientProtocolException
228     *                          See {@link ball.http.ProtocolClient}.
229     */
230    @GET @Path("20141201/available/countries")
231    public JsonNode getAvailableCountries()
232        throws HttpResponseException, ClientProtocolException, IOException;
233
234    /**
235     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#obtain-the-list-of-available-services target=newtab Obtain the list of available services}
236     *
237     * @return  The {@link JsonNode}.
238     *
239     * @throws  IOException     See {@link ball.http.ProtocolClient}.
240     * @throws  HttpResponseException
241     *                          See {@link ball.http.ProtocolClient}.
242     * @throws  ClientProtocolException
243     *                          See {@link ball.http.ProtocolClient}.
244     */
245    @GET @Path("20141201/available/languages")
246    public JsonNode getAvailableLanguages()
247        throws HttpResponseException, ClientProtocolException, IOException;
248
249    /**
250     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#obtain-the-list-of-headends-in-a-postal-code target=newtab Obtain the list of headends in a postal code}
251     *
252     * @param   token           The token.
253     * @param   country         The country.
254     * @param   postalcode      The postal (ZIP) code.
255     *
256     * @return  The {@link JsonNode}.
257     *
258     * @throws  IOException     See {@link ball.http.ProtocolClient}.
259     * @throws  HttpResponseException
260     *                          See {@link ball.http.ProtocolClient}.
261     * @throws  ClientProtocolException
262     *                          See {@link ball.http.ProtocolClient}.
263     */
264    @GET @Path("20141201/headends")
265    public List<Headend> getHeadends(@HeaderParam(EMPTY) String token,
266                                     @QueryParam(EMPTY) String country,
267                                     @QueryParam(EMPTY) String postalcode)
268        throws HttpResponseException, ClientProtocolException, IOException;
269
270    /**
271     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#list-the-lineups-a-user-has-added-to-their-account target=newtab List the lineups a user has added to their account}
272     *
273     * @param   token           The token.
274     *
275     * @return  The {@link GetLineupsResponse}.
276     *
277     * @throws  IOException     See {@link ball.http.ProtocolClient}.
278     * @throws  HttpResponseException
279     *                          See {@link ball.http.ProtocolClient}.
280     * @throws  ClientProtocolException
281     *                          See {@link ball.http.ProtocolClient}.
282     */
283    @GET @Path("20141201/lineups")
284    public GetLineupsResponse getLineups(@HeaderParam(EMPTY) String token)
285        throws HttpResponseException, ClientProtocolException, IOException;
286
287    /**
288     * {@link #getLineups(String)} return type.
289     *
290     * {@bean.info}
291     */
292    @NoArgsConstructor @Getter
293    public static class GetLineupsResponse extends JSONBean {
294        private static final long serialVersionUID = -3795459753818150095L;
295
296        /** @serial */ private int code = -1;
297        /** @serial */ private String serverID = null;
298        /** @serial */ private Date datetime = null;
299        /** @serial */ private JsonNode lineups = null;
300    }
301
302    /**
303     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#delete-a-lineup-from-a-users-account target=newtab Delete a lineup from a user's account}
304     *
305     * @param   token           The token.
306     * @param   lineup          The line-up to be deleted.
307     *
308     * @return  The {@link JsonNode}.
309     *
310     * @throws  IOException     See {@link ball.http.ProtocolClient}.
311     * @throws  HttpResponseException
312     *                          See {@link ball.http.ProtocolClient}.
313     * @throws  ClientProtocolException
314     *                          See {@link ball.http.ProtocolClient}.
315     */
316    @DELETE @Path("20141201/lineups/{lineup}")
317    public JsonNode deleteLineup(@HeaderParam(EMPTY) String token,
318                                 @PathParam(EMPTY) String lineup)
319        throws HttpResponseException, ClientProtocolException, IOException;
320
321    /**
322     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#add-a-lineup-to-a-users-schedules-direct-account target=newtab Add a lineup to a user's Schedules Direct account}
323     *
324     * @param   token           The token.
325     * @param   lineup          The line-up to add.
326     *
327     * @return  The {@link JsonNode}.
328     *
329     * @throws  IOException     See {@link ball.http.ProtocolClient}.
330     * @throws  HttpResponseException
331     *                          See {@link ball.http.ProtocolClient}.
332     * @throws  ClientProtocolException
333     *                          See {@link ball.http.ProtocolClient}.
334     */
335    @PUT @Path("20141201/lineups/{lineup}")
336    public JsonNode putLineup(@HeaderParam(EMPTY) String token,
337                              @PathParam(EMPTY) String lineup)
338        throws HttpResponseException, ClientProtocolException, IOException;
339
340    /**
341     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#stationid--channel-mapping-for-a-lineup target=newtab StationID / channel mapping for a lineup}
342     *
343     * @param   token           The token.
344     * @param   verboseMap      Whether or not tp provide a verbose map.
345     * @param   lineup          The lineup (may be {@code null}).
346     *
347     * @return  The {@link Lineup}.
348     *
349     * @throws  IOException     See {@link ball.http.ProtocolClient}.
350     * @throws  HttpResponseException
351     *                          See {@link ball.http.ProtocolClient}.
352     * @throws  ClientProtocolException
353     *                          See {@link ball.http.ProtocolClient}.
354     */
355    @GET @Path("20141201/lineups/{lineup}")
356    public Lineup getLineup(@HeaderParam(EMPTY) String token,
357                            @HeaderParam(EMPTY) Boolean verboseMap,
358                            @PathParam(EMPTY) String lineup)
359        throws HttpResponseException, ClientProtocolException, IOException;
360
361    /**
362     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#automapping-a-lineup target=newtab Automapping a lineup}
363     *
364     * @param   token           The token.
365     * @param   entity          The {@link HttpEntity}.
366     *
367     * @return  The {@link JsonNode}.
368     *
369     * @throws  IOException     See {@link ball.http.ProtocolClient}.
370     * @throws  HttpResponseException
371     *                          See {@link ball.http.ProtocolClient}.
372     * @throws  ClientProtocolException
373     *                          See {@link ball.http.ProtocolClient}.
374     */
375    @POST @Path("20141201/map/lineup/")
376    public JsonNode postLineup(@HeaderParam(EMPTY) String token,
377                               HttpEntity entity)
378        throws HttpResponseException, ClientProtocolException, IOException;
379
380    /**
381     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#automapping-a-lineup target=newtab Automapping a lineup}
382     * Submit a line-up.
383     *
384     * @param   token           The token.
385     * @param   lineup          The lineup.
386     * @param   entity          The {@link HttpEntity}.
387     *
388     * @return  The {@link JsonNode}.
389     *
390     * @throws  IOException     See {@link ball.http.ProtocolClient}.
391     * @throws  HttpResponseException
392     *                          See {@link ball.http.ProtocolClient}.
393     * @throws  ClientProtocolException
394     *                          See {@link ball.http.ProtocolClient}.
395     */
396    @POST @Path("20141201/map/lineup/{lineup}")
397    public JsonNode postLineup(@HeaderParam(EMPTY) String token,
398                               @PathParam(EMPTY) String lineup,
399                               HttpEntity entity)
400        throws HttpResponseException, ClientProtocolException, IOException;
401
402    /**
403     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#download-program-information target=newtab Download program information}
404     *
405     * @param   token           The token.
406     * @param   ids             The program IDs.
407     *
408     * @return  The {@link List} of {@link Program}s.
409     *
410     * @throws  IOException     See {@link ball.http.ProtocolClient}.
411     * @throws  HttpResponseException
412     *                          See {@link ball.http.ProtocolClient}.
413     * @throws  ClientProtocolException
414     *                          See {@link ball.http.ProtocolClient}.
415     */
416    @POST @Path("20141201/programs")
417    public List<Program> postPrograms(@HeaderParam(EMPTY) String token,
418                                      Collection<String> ids)
419        throws HttpResponseException, ClientProtocolException, IOException;
420
421    /**
422     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#downloading-a-generic-description-of-a-program target=newtab Downloading a generic description of a program}
423     *
424     * @param   token           The token.
425     * @param   ids             The program IDs.
426     *
427     * @return  The {@link JsonNode}.
428     *
429     * @throws  IOException     See {@link ball.http.ProtocolClient}.
430     * @throws  HttpResponseException
431     *                          See {@link ball.http.ProtocolClient}.
432     * @throws  ClientProtocolException
433     *                          See {@link ball.http.ProtocolClient}.
434     */
435    @POST @Path("20141201/metadata/description")
436    public JsonNode postProgramsDescription(@HeaderParam(EMPTY) String token,
437                                            Collection<String> ids)
438        throws HttpResponseException, ClientProtocolException, IOException;
439
440    /**
441     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#retrieving-json-index-based-on-programid target=newtab Retrieving JSON index based on programID}
442     *
443     * @param   token           The token.
444     * @param   ids             The program IDs.
445     *
446     * @return  The {@link JsonNode}.
447     *
448     * @throws  IOException     See {@link ball.http.ProtocolClient}.
449     * @throws  HttpResponseException
450     *                          See {@link ball.http.ProtocolClient}.
451     * @throws  ClientProtocolException
452     *                          See {@link ball.http.ProtocolClient}.
453     */
454    @POST @Path("20141201/metadata/programs")
455    public JsonNode postProgramsMetadata(@HeaderParam(EMPTY) String token,
456                                         Collection<String> ids)
457        throws HttpResponseException, ClientProtocolException, IOException;
458
459    /**
460     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#retrieving-json-index-based-on-rootid target=newtab Retrieving JSON index based on rootId}
461     *
462     * @param   root          The root ID.
463     *
464     * @return  The {@link JsonNode}.
465     *
466     * @throws  IOException     See {@link ball.http.ProtocolClient}.
467     * @throws  HttpResponseException
468     *                          See {@link ball.http.ProtocolClient}.
469     * @throws  ClientProtocolException
470     *                          See {@link ball.http.ProtocolClient}.
471     */
472    @GET @Path("20141201/metadata/programs/{root}")
473    public JsonNode getProgramMetadata(@PathParam(EMPTY) String root)
474        throws HttpResponseException, ClientProtocolException, IOException;
475
476    /**
477     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#download-the-schedules-for-stationids target=newtab Download the schedules for stationIDs}
478     *
479     * @param   token           The token.
480     * @param   collection      The {@link Collection} (use
481     *                          {@link SDClient.PostSchedulesMap}{@code .values()}).
482     *
483     * @return  The {@link List} of {@link Schedules}.
484     *
485     * @throws  IOException     See {@link ball.http.ProtocolClient}.
486     * @throws  HttpResponseException
487     *                          See {@link ball.http.ProtocolClient}.
488     * @throws  ClientProtocolException
489     *                          See {@link ball.http.ProtocolClient}.
490     */
491    @POST @Path("20141201/schedules")
492    public List<Schedules> postSchedules(@HeaderParam(EMPTY) String token,
493                                         Collection<Map<String,Object>> collection)
494        throws HttpResponseException, ClientProtocolException, IOException;
495 
496    /**
497     * {@link #postSchedules(String,Collection)} return type.
498     *
499     * {@bean.info}
500     */
501    @NoArgsConstructor @Getter
502    public static class Schedules extends JSONBean {
503        private static final long serialVersionUID = -7884152874678564916L;
504
505        /** @serial */ private int stationID = -1;
506        /** @serial */ private List<Schedule> programs = null;
507
508        public List<Schedule> getPrograms() {
509            if (programs != null) {
510                programs.stream().forEach(s -> s.setStationID(stationID));
511            }
512
513            return programs;
514        }
515    }
516
517    /**
518     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#download-the-md5-and-lastmodified-for-stationids target=newtab Download the MD5 and lastModified for stationIDs}
519     *
520     * @param   token           The token.
521     * @param   collection      The {@link Collection} (use
522     *                          {@link SDClient.PostSchedulesMap}{@code .values()}).
523     *
524     * @return  The {@link JsonNode}.
525     *
526     * @throws  IOException     See {@link ball.http.ProtocolClient}.
527     * @throws  HttpResponseException
528     *                          See {@link ball.http.ProtocolClient}.
529     * @throws  ClientProtocolException
530     *                          See {@link ball.http.ProtocolClient}.
531     */
532    @POST @Path("20141201/schedules/md5")
533    public JsonNode postSchedulesMD5(@HeaderParam(EMPTY) String token,
534                                     Collection<Map<String,Object>> collection)
535        throws HttpResponseException, ClientProtocolException, IOException;
536
537    /**
538     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#retrieving-images-for-a-particular-celebrity target=newtab Retrieving images for a particular celebrity}
539     *
540     * @param   celebrity       The celebrity.
541     *
542     * @return  The {@link JsonNode}.
543     *
544     * @throws  IOException     See {@link ball.http.ProtocolClient}.
545     * @throws  HttpResponseException
546     *                          See {@link ball.http.ProtocolClient}.
547     * @throws  ClientProtocolException
548     *                          See {@link ball.http.ProtocolClient}.
549     */
550    @GET @Path("20141201/metadata/celebrity/{celebrity}")
551    public JsonNode getCelebrityMetadata(@PathParam(EMPTY) String celebrity)
552        throws HttpResponseException, ClientProtocolException, IOException;
553
554    /**
555     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#retrieving-an-image target=newtab Retrieving an image}
556     *
557     * @param   uri             The relative URI path.
558     *
559     * @return  The {@link HttpResponse}.
560     *
561     * @throws  IOException     See {@link ball.http.ProtocolClient}.
562     * @throws  HttpResponseException
563     *                          See {@link ball.http.ProtocolClient}.
564     * @throws  ClientProtocolException
565     *                          See {@link ball.http.ProtocolClient}.
566     */
567    @GET @Path("20141201/image/assets/{uri}")
568    public HttpResponse getImage(@PathParam(EMPTY) String uri)
569        throws HttpResponseException, ClientProtocolException, IOException;
570
571    /**
572     * {@link.uri https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#retrieving-an-image target=newtab Retrieving an image}
573     *
574     * @param   uri             The {@link URI}.
575     *
576     * @return  The {@link HttpResponse}.
577     *
578     * @throws  IOException     See {@link ball.http.ProtocolClient}.
579     * @throws  HttpResponseException
580     *                          See {@link ball.http.ProtocolClient}.
581     * @throws  ClientProtocolException
582     *                          See {@link ball.http.ProtocolClient}.
583     */
584    @GET
585    public HttpResponse getImage(URI uri)
586        throws HttpResponseException, ClientProtocolException, IOException;
587}