Advertisement
NLinker

Rx Spotify Example Java version

Oct 11th, 2016
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.09 KB | None | 0 0
  1. package com.vertigo.crawler;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Random;
  9. import java.util.function.Function;
  10. import java.util.function.Supplier;
  11. import java.util.stream.Collectors;
  12. import java.util.stream.IntStream;
  13. import java.util.stream.Stream;
  14. import com.google.common.collect.ImmutableList;
  15. import com.wrapper.spotify.models.Album;
  16. import com.wrapper.spotify.models.AlbumType;
  17. import com.wrapper.spotify.models.Artist;
  18. import com.wrapper.spotify.models.Copyright;
  19. import com.wrapper.spotify.models.ExternalUrls;
  20. import com.wrapper.spotify.models.Followers;
  21. import com.wrapper.spotify.models.SimpleAlbum;
  22. import com.wrapper.spotify.models.SimpleArtist;
  23. import com.wrapper.spotify.models.SimpleTrack;
  24. import com.wrapper.spotify.models.Track;
  25. import rx.Observable;
  26. import rx.Observer;
  27.  
  28. import com.vertigo.model.enums.EntityType;
  29. import com.vertigo.model.enums.Provider;
  30. import com.vertigo.model.json.sync.CrawlerTask;
  31. import com.vertigo.test.util.RandomUtil;
  32.  
  33. public class Example {
  34.     private final static Random       RANDOM = new Random(69);
  35.     private final static RandomUtil   RU     = new RandomUtil(RANDOM);
  36.     private final static List<String> GENRES = ImmutableList.of(
  37.         "aggrotech", "ebm", "electro-industrial", "futurepop",
  38.         "ambient psychill", "psychill", "ambient", "metal",
  39.         "crossover thrash", "death metal", "groove metal",
  40.         "nwobhm", "speed metal", "thrash metal", "digital hardcore",
  41.         "industrial", "industrial metal", "industrial rock",
  42.         "neue deutsche harte", "album rock", "alternative metal",
  43.         "classic rock", "hard rock", "nu metal", "power metal",
  44.         "rock", "wrestling");
  45.     private final static List<String> MARKETS = ImmutableList.of(
  46.         "AD", "AR", "AT", "AU", "BE", "BG", "BO", "BR", "CA", "CH",
  47.         "CL", "CO", "CR", "CY", "CZ", "DE", "DK", "DO", "EC", "EE",
  48.         "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HU", "ID",
  49.         "IE", "IS", "IT", "JP", "LI", "LT", "LU", "LV", "MC", "MT",
  50.         "MX", "MY", "NI", "NL", "NO", "NZ", "PA", "PE", "PH", "PL",
  51.         "PT", "PY", "SE", "SG", "SK", "SV", "TR", "TW", "US", "UY"
  52.     );
  53.     private final static Artist VA = get(() -> {
  54.         Artist ar = new Artist();
  55.         ar.setId("0LyfQWJT6nXafLPZqxe9Of");
  56.         ar.setName("Various Artists");
  57.         ar.setFollowers(get(() -> {
  58.             Followers f = new Followers();
  59.             f.setHref(null);
  60.             f.setTotal(215138);
  61.             return f;
  62.         }));
  63.         ar.setExternalUrls(get(() -> {
  64.             ExternalUrls e = new ExternalUrls();
  65.             e.getExternalUrls().put("spotify",
  66.                 "https://open.spotify.com/artist/" + ar.getId());
  67.             return e;
  68.         }));
  69.         ar.setGenres(ImmutableList.of());
  70.         ar.setHref("https://api.spotify.com/v1/artists/" + ar.getId());
  71.         ar.setImages(ImmutableList.of());
  72.         ar.setPopularity(0);
  73.         ar.setUri("spotify:artist:" + ar.getId());
  74.         return ar;
  75.     });
  76.  
  77.     public static <T> T get(Supplier<T> supplier) {
  78.         return supplier.get();
  79.     }
  80.  
  81.     public static SimpleAlbum simplify(Album a) {
  82.         SimpleAlbum sa = new SimpleAlbum();
  83.         sa.setAlbumType(a.getAlbumType());
  84.         sa.setExternalUrls(a.getExternalUrls());
  85.         sa.setHref(a.getHref());
  86.         sa.setId(a.getId());
  87.         sa.setImages(a.getImages());
  88.         sa.setName(a.getName());
  89.         sa.setType(a.getType());
  90.         sa.setUri(a.getUri());
  91.         sa.setAvailableMarkets(ImmutableList.copyOf(a.getAvailableMarkets()));
  92.         return sa;
  93.     }
  94.  
  95.     public static SimpleTrack simplify(Track t) {
  96.         SimpleTrack sa = new SimpleTrack();
  97.         sa.setDiscNumber(t.getDiscNumber());
  98.         sa.setDuration(t.getDuration());
  99.         sa.setExplicit(t.isExplicit());
  100.         sa.setExternalUrls(t.getExternalUrls());
  101.         sa.setHref(t.getHref());
  102.         sa.setId(t.getId());
  103.         sa.setName(t.getName());
  104.         sa.setPreviewUrl(t.getPreviewUrl());
  105.         sa.setTrackNumber(t.getTrackNumber());
  106.         sa.setType(t.getType());
  107.         sa.setUri(t.getUri());
  108.         sa.setAvailableMarkets(ImmutableList.copyOf(t.getAvailableMarkets()));
  109.         return sa;
  110.     }
  111.  
  112.     public static SimpleArtist simplify(Artist a) {
  113.         SimpleArtist sa = new SimpleArtist();
  114.         sa.setExternalUrls(a.getExternalUrls());
  115.         sa.setHref(a.getHref());
  116.         sa.setId(a.getId());
  117.         sa.setName(a.getName());
  118.         sa.setType(a.getType());
  119.         sa.setUri(a.getUri());
  120.         return sa;
  121.     }
  122.  
  123.     public static Artist generateArtist(RandomUtil ru) {
  124.         Artist a = new Artist();
  125.         a.setId(ru.string(8));
  126.         a.setName("artist_" + a.getId());
  127.         a.setPopularity(ru.nextInt(100));
  128.         a.setExternalUrls(get(() -> {
  129.             ExternalUrls eu = new ExternalUrls();
  130.             eu.getExternalUrls().put("spotify",
  131.                 "https://open.spotify.com/artist/" + a.getId());
  132.             return eu;
  133.         }));
  134.         a.setHref("https://api.spotify.com/v1/artists/" + a.getId());
  135.         a.setUri("spotify:artist:" + a.getId());
  136.         a.setGenres(listFrom(ru, GENRES, 3));
  137.         a.setFollowers(get(() -> {
  138.             Followers f = new Followers();
  139.             f.setTotal(ru.nextInt(1000));
  140.             return f;
  141.         }));
  142.         return a;
  143.     }
  144.  
  145.     public static Album generateAlbum(RandomUtil ru,
  146.                                       AlbumType albumType,
  147.                                       List<Artist> creators) {
  148.         Album al = new Album();
  149.         al.setId(ru.string(9));
  150.         al.setName("album_" + al.getId());
  151.         al.setAlbumType(albumType);
  152.         al.setHref("https://api.spotify.com/v1/albums/" + al.getId());
  153.         al.setUri("spotify:album:" + al.getId());
  154.         al.setCopyrights(get(() -> {
  155.             Copyright c1 = new Copyright();
  156.             c1.setText("2016 Alpha Matrix");
  157.             c1.setText("C");
  158.             Copyright c2 = new Copyright();
  159.             c1.setText("2016 Alpha Matrix");
  160.             c1.setText("P");
  161.             return ImmutableList.of(c1, c2);
  162.         }));
  163.         al.setArtists(get(() -> creators.stream()
  164.             .map(Example::simplify)
  165.             .collect(Collectors.toList())));
  166.         return al;
  167.     }
  168.  
  169.     public static Track generateTrack(RandomUtil ru,
  170.                                       Album album,
  171.                                       int trackNumber) {
  172.         Track t = new Track();
  173.         t.setId(ru.string(10));
  174.         t.setName("track_" + t.getId());
  175.         t.setHref("https://api.spotify.com/v1/tracks/" + t.getId());
  176.         t.setUri("spotify:track:" + t.getId());
  177.         t.setArtists(album.getArtists());
  178.         t.setAlbum(simplify(album));
  179.         t.setTrackNumber(trackNumber);
  180.         // from 1 to 1000 seconds
  181.         t.setDuration((ru.nextInt(1000) + 1) * 1000);
  182.         t.setPopularity(ru.nextInt(10));
  183.         t.setAvailableMarkets(album.getAvailableMarkets());
  184.         t.setDiscNumber(0);
  185.         t.setPreviewUrl("https://spotify.com/preview/" + t.getId());
  186.         return t;
  187.     }
  188.  
  189.  
  190.     /**
  191.      * Select random elements from base list.
  192.      * Must be count <= base.size()
  193.      */
  194.     public static <T> List<T> listFrom(RandomUtil ru, List<T> base, int count) {
  195.         int n = base.size();
  196.         List<T> ts = new ArrayList<>(base);
  197.         // remove random elements from there
  198.         for (int i = 0; i < n - count; i++) {
  199.             ts.remove(ru.nextInt(n - i));
  200.         }
  201.         return ts;
  202.     }
  203.  
  204.  
  205.     public static class RxWrapper {
  206.         private final SpotifyWS sws;
  207.         public RxWrapper(SpotifyWS sws) {this.sws = sws;}
  208.         public Observable<Artist> getArtists(List<String> ids) {
  209.             return Observable.from(sws.getArtists(ids));
  210.         }
  211.         public Observable<Album> getAlbums(List<String> ids) {
  212.             return Observable.from(sws.getAlbums(ids));
  213.         }
  214.         public Observable<Track> getTracks(List<String> ids) {
  215.             return Observable.from(sws.getTracks(ids));
  216.         }
  217.         public Observable<List<Track>> getTracks0(List<String> ids) {
  218.             return Observable.just(sws.getTracks(ids));
  219.         }
  220.     }
  221.  
  222.     private static CrawlerTask randomTask(RandomUtil ru) {
  223.         // set only entityType and externalId,
  224.         // the rest of them should be populated by
  225.         CrawlerTask ct = new CrawlerTask();
  226.         ct.setEntityType(EntityType.fromInt(ru.nextInt(11, 13)));
  227.         ct.setExternalId(ru.string(10));
  228.         ct.setProvider(Provider.Spotify);
  229.         return ct;
  230.     }
  231.  
  232.     private static List<CrawlerTask> randomTasks(RandomUtil ru, int n) {
  233.         return IntStream.range(0, n)
  234.             .mapToObj(_i -> randomTask(ru))
  235.             .collect(Collectors.toList());
  236.     }
  237.  
  238.     private static List<String> ids(List<CrawlerTask> cts) {
  239.         return cts.stream()
  240.             .map(CrawlerTask::getExternalId)
  241.             .collect(Collectors.toList());
  242.     }
  243.  
  244.     interface SpotifyWS {
  245.         List<Artist> getArtists(List<String> ids);
  246.         List<Album> getAlbums(List<String> ids);
  247.         List<Track> getTracks(List<String> ids);
  248.     }
  249.  
  250.     /**
  251.      *
  252.      */
  253.     public static class SpotifyWSImpl implements SpotifyWS {
  254.         private final RandomUtil ru;
  255.         private final Map<String, Track> trackMap = new HashMap<>();
  256.         private final Map<String, Album> albumMap = new HashMap<>();
  257.         private final Map<String, Artist> artistMap = new HashMap<>();
  258.  
  259.         public SpotifyWSImpl(RandomUtil ru) {
  260.             this.ru = ru;
  261.             initMediaCollection();
  262.         }
  263.  
  264.         @Override
  265.         public List<Artist> getArtists(List<String> ids) {
  266.             int x = RU.nextInt(100);
  267.             throw new RuntimeException("timeout:" + Integer.toString(x));
  268.         }
  269.  
  270.         @Override
  271.         public List<Album> getAlbums(List<String> ids) {
  272.             int x = RU.nextInt(100);
  273.             throw new RuntimeException("timeout:" + Integer.toString(x));
  274.         }
  275.  
  276.         @Override
  277.         public List<Track> getTracks(List<String> ids) {
  278.             int x = RU.nextInt(100);
  279.             throw new RuntimeException("timeout:" + Integer.toString(x));
  280.         }
  281.  
  282.         private void initMediaCollection() {
  283.             // create all
  284.             List<Artist> artists = IntStream
  285.                 .range(0, 100)
  286.                 .mapToObj(_i -> generateArtist(ru))
  287.                 .collect(Collectors.toList());
  288.             // let each artist to have 5 albums
  289.             // 3 exclusive, 1 with other,
  290.             // 1 with other two
  291.             // and many album-compilations where
  292.             // song is made by different artist
  293.             // e.g. album 3m6QKbHMF5GVBagWlCF1U0
  294.             Stream<Album> albums1 = IntStream
  295.                 .range(0, artists.size())
  296.                 .mapToObj(i -> {
  297.                     Artist       ar  = artists.get(i);
  298.                     List<Artist> ars = ImmutableList.of(ar);
  299.                     artistMap.put(ar.getId(), ar);
  300.                     Album al1 = generateAlbum(ru, AlbumType.SINGLE, ars);
  301.                     Album al2 = generateAlbum(ru, AlbumType.SINGLE, ars);
  302.                     Album al3 = generateAlbum(ru, AlbumType.SINGLE, ars);
  303.                     return ImmutableList.of(al1, al2, al3).stream();
  304.                 })
  305.                 .flatMap(Function.identity());
  306.             // create albums of pairs
  307.             Collections.shuffle(artists);
  308.             Stream<Album> albums2 = IntStream
  309.                 .range(1, artists.size())
  310.                 .mapToObj(i -> {
  311.                     List<Artist> ars = ImmutableList.of(
  312.                         artists.get(i - 1),
  313.                         artists.get(i)
  314.                     );
  315.                     return generateAlbum(ru, AlbumType.ALBUM, ars);
  316.                 });
  317.             // create albums of triples
  318.             Collections.shuffle(artists);
  319.             Stream<Album> albums3 = IntStream
  320.                 .range(2, artists.size())
  321.                 .mapToObj(i -> {
  322.                     List<Artist> ars = ImmutableList.of(
  323.                         artists.get(i - 2),
  324.                         artists.get(i - 1),
  325.                         artists.get(i)
  326.                     );
  327.                     return generateAlbum(ru, AlbumType.ALBUM, ars);
  328.                 });
  329.             // create compilations,
  330.             // albums where the artist is "Various Artist"
  331.             Stream<Album> albums4 = IntStream
  332.                 .range(0, 200)
  333.                 .mapToObj(i -> {
  334.                     List<Artist> ars = ImmutableList.of(VA);
  335.                     return generateAlbum(ru, AlbumType.COMPILATION, ars);
  336.                 });
  337.             // glue all the stuff together
  338.             List<Album> albums = Stream
  339.                 .concat(albums1, Stream
  340.                     .concat(albums2, Stream
  341.                         .concat(albums3,
  342.                             albums4)))
  343.                     .collect(Collectors.toList());
  344.             // now create tracks, let each album has 10 tracks
  345.             Stream<Track> tracks = albums.stream()
  346.                 .flatMap(al ->
  347.                     IntStream.range(0, 10)
  348.                         .mapToObj(i ->
  349.                             generateTrack(ru, al, i)));
  350.  
  351.             // now put the stuff into the maps
  352.             artists.forEach(ar -> artistMap.put(ar.getId(), ar));
  353.             albums.forEach(al -> albumMap.put(al.getId(), al));
  354.             List<Track> tracksList = tracks.collect(Collectors.toList());
  355.             tracksList.forEach(t -> trackMap.put(t.getId(), t));
  356.         }
  357.  
  358.         private void sleep(int x) {
  359.             try {
  360.                 Thread.sleep(10 * x);
  361.             } catch (InterruptedException e) {
  362.                 System.out.println("e = " + e);
  363.             }
  364.         }
  365.     }
  366.  
  367.     public static void main(String[] args) throws Exception {
  368.  
  369.         final SpotifyWSImpl sws = new SpotifyWSImpl(RU);
  370.         final RxWrapper rxw = new RxWrapper(sws);
  371.  
  372.         List<CrawlerTask> tasks = randomTasks(RU, 1000);
  373.         Observable.from(tasks)
  374.             .filter(ct -> ct.getEntityType() == EntityType.Song)
  375.             .buffer(2)
  376.             .flatMap(cts-> rxw.getTracks(ids(cts)))
  377.             .flatMap(t -> {
  378.                 // we got track, now we want the artists and album from it
  379.                 List<SimpleArtist> artists = t.getArtists();
  380.                 SimpleAlbum album = t.getAlbum();
  381.                 return Observable.just(t);
  382.             })
  383.             .subscribe(t -> new Observer<Track>() {
  384.                 @Override
  385.                 public void onCompleted() {
  386.                     System.out.println("Completed t = " + t.getName());
  387.                 }
  388.                 @Override
  389.                 public void onError(Throwable e) {
  390.                     System.out.println("Error t = " + t.getName() + " e = " + e);
  391.                 }
  392.                 @Override
  393.                 public void onNext(Track track) {
  394.                     System.out.println("Next track = " + track);
  395.                 }
  396.             });
  397.     }
  398. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement