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