Antoine DORIAN преди 1 година
родител
ревизия
ab6245a427

+ 14
- 21
README.md Целия файл

@@ -1,29 +1,22 @@
1 1
 # mediahub
2 2
 
3
+Bilan: 
4
+<br>Voici ma Solution a l"exercice de recherche d'information dans des fichiers TSV en utilisant la bibliotheque Akka Stream realiser en Java et Scala
5
+<br>Le service de recherche est fait en Scala, celui-ci est intègrer dans une solution Springboot en Java
3 6
 
4
-Instruction :
5
-Vous allez avoir droit à 5 fichier.
7
+Instruction:
8
+<br>Pour le bon fonctionement du projet, il est necessaire de telecharger les fichiers suivant et de les placer dans le repertoire resources, ne pas dezipper les fichiers (main\resources): 
6 9
 
7
-Ces 5 fichiers Charles pense qu'il faudra les charger dans dictionnary, dans 5 map et ensuite vous allez devoir les requêté à l’aide d’akkastream.
10
+- https://datasets.imdbws.com/name.basics.tsv.gz
11
+- https://datasets.imdbws.com/title.episode.tsv.gz
12
+- https://datasets.imdbws.com/title.ratings.tsv.gz
13
+- https://datasets.imdbws.com/title.principals.tsv.gz
14
+- https://datasets.imdbws.com/title.basics.tsv.gz
8 15
 
9
-Le principe d’akka est que sa permet de créer un pipe, vous avez la même logique que des streams en java. Donc le principe est que vous avez deux, trois recherche à opérer et vous allez faire un cor ( une api business) qui permet de faire une recherche et qu’il faudra écrire en SCALA.
16
+Afin de lancer la solution, il suffit de lancer MediahubApplication qui se trouve dans la partie Java du projet
10 17
 
11
-L’idéal serait d’écrire tous le service en scala, regarder sur internet comment créer un service en scala.
18
+Les deux endpoints disponibles pour tester le service sont:
12 19
 
13
-Sinon,  vous faites un springboot qui va appeler ce core dev en scala. Ce qui est certain c’est que le core doit être écrit en scala sur la base de l’api stream AKKA.
20
+- http://localhost:8080/api/teamMembers?movieTitle=Carmencita
21
+- http://localhost:8080/api/tvSeries
14 22
 
15
-Le sentiment de Charles est qu’il faut bien montrer le principe du pipe, c’est à dire que vous allez avoir potentiellement 5 map et l’idée est d’avoir un seul stream qui va permettre de les requêtes et de concaténer les  résultats, pour en faire un résultat final qui va être envoyé au service.
16
-
17
-Vous en discuterez lundi avec Charles pour savoir de quelle façon le faire.
18
-
19
-
20
-
21
-Pour résumer :
22
-
23
-Un core qui va être développé en scala au travers de la librairie Akkastream ( akkastream va permettre de requêter les différend fichier comme étant des source de donnée).
24
-
25
-Sur la base de cette source-là vous allez avoir des sources de données que vous allez concaténer au travers d’un stream et c’est sur ce stream là que vous allez faire vos recherches.
26
-
27
-A voir comment vous allez gérer ça lundi avec Charles.
28
-
29
-Ce service, il faudra l’exposer avec un springboot qui prépose juste une API requête qui appellera ce cœur business.

+ 13
- 1
src/main/java/com/mediahub/controller/MovieController.java Целия файл

@@ -29,7 +29,7 @@ public class MovieController {
29 29
                 principalList = (movieServiceTrait.principalsForMovieName(movieTitle).toList());
30 30
             }
31 31
 
32
-            return new ResponseEntity<>(new JsonCustomMapping().mapper(principalList), HttpStatus.OK);
32
+            return new ResponseEntity<>(new JsonCustomMapping().mapperPrincipal(principalList), HttpStatus.OK);
33 33
 
34 34
         } catch (Exception e) {
35 35
             return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
@@ -37,5 +37,17 @@ public class MovieController {
37 37
 
38 38
     }
39 39
 
40
+    @GetMapping("/tvSeries")
41
+    public ResponseEntity getTvSeries() {
42
+        scala.collection.immutable.List<MovieService.TvSeries> tvSeriesList;
43
+
44
+        try {
45
+            tvSeriesList = (movieServiceTrait.tvSeriesWithGreatestNumberOfEpisodes().toList());
46
+            return new ResponseEntity<>(new JsonCustomMapping().mapperSeries(tvSeriesList), HttpStatus.OK);
47
+        } catch (Exception e) {
48
+            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
49
+        }
50
+
51
+    }
40 52
 
41 53
 }

+ 4
- 1
src/main/scala/com/mediahub/JsonCustomMapping.scala Целия файл

@@ -5,8 +5,11 @@ import org.json4s.native.Json
5 5
 
6 6
 class JsonCustomMapping extends MovieService {
7 7
 
8
-  def mapper(list:  List[Principal]): String = {
8
+  def mapperPrincipal(list:  List[Principal]): String = {
9 9
      Json(DefaultFormats).write(list)
10 10
   }
11 11
 
12
+  def mapperSeries(list: List[TvSeries]): String = {
13
+    Json(DefaultFormats).write(list)
14
+  }
12 15
 }

+ 19
- 23
src/main/scala/com/mediahub/MovieQueryService.scala Целия файл

@@ -16,6 +16,7 @@ import scala.collection.{immutable, mutable}
16 16
 import scala.concurrent.Await
17 17
 import scala.concurrent.duration.DurationInt
18 18
 import scala.language.postfixOps
19
+import scala.util.Try
19 20
 
20 21
 
21 22
 @Component
@@ -40,11 +41,6 @@ class MovieQueryService extends MovieServiceTrait {
40 41
       .via(CsvToMap.toMapAsStringsCombineAll(headerPlaceholder = Option.empty))
41 42
   }
42 43
 
43
-
44
-  val res = getSeriesTitle(titleEpisodeResource)
45
-  val r = getTitleByIds(titleBasicsResource, res)
46
-  println(r)
47
-
48 44
   override def principalsForMovieName(name: String): List[Principal] = {
49 45
 
50 46
     val titleId: String = getIdOfTitle(titleBasicsResource, name)
@@ -53,8 +49,11 @@ class MovieQueryService extends MovieServiceTrait {
53 49
     personsList
54 50
   }
55 51
 
56
-  override def tvSeriesWithGreatestNumberOfEpisodes(): List[TvSeries] = ???
57
-    //val personsIdList: List[String] = getSeriestitle(titleEpisodeResource)
52
+  override def tvSeriesWithGreatestNumberOfEpisodes(): List[TvSeries] = {
53
+    val seriesTitleMap = getSeriesTitle(titleEpisodeResource)
54
+    val titleListMaxEpisode = getTitleByIds(titleBasicsResource, seriesTitleMap)
55
+    titleListMaxEpisode
56
+  }
58 57
 
59 58
 
60 59
 
@@ -76,25 +75,22 @@ class MovieQueryService extends MovieServiceTrait {
76 75
     result.value.get.get.get
77 76
   }
78 77
 
79
-  def getTitleByIds(file: File, titleIdMap: mutable.Map[String, Int]): Seq[Option[String]] = {
80
-    val result = fileSource(file)
81
-      .mapAsync(50) {
82
-        res =>
83
-          Source.single(res)
84
-            .via(lineParser)
85
-            .filter(row => titleIdMap.contains(row.getOrElse("tconst", "")))
86
-            .map(a => a.get("primaryTitle"))
87
-            .withAttributes(supervisionStrategy(resumingDecider))
88
-            .runWith(Sink.collection)
89
-      }
90
-      .withAttributes(supervisionStrategy(resumingDecider))
91
-      .runWith(Sink.head)
78
+  def getTitleByIds(file: File, titleIdMap: mutable.Map[String, Int]): List[TvSeries] = {
79
+    val result = Source.single(file)
80
+      .flatMapConcat(f => FileIO.fromPath(Paths.get(f.getPath), 1 * 1024 * 1024))
81
+      .via(Compression.gunzip())
82
+      .via(CsvParsing.lineScanner(CsvParsing.Tab, CsvParsing.DoubleQuote, CsvParsing.DoubleQuote))
83
+      .via(CsvToMap.toMapAsStringsCombineAll(StandardCharsets.UTF_8, Option.empty))
84
+      .filter(row => titleIdMap.keySet.toList.contains(row.getOrElse("tconst", "")))
85
+      .map(a => TvSeries(a("originalTitle"), Try(a.getOrElse("startYear","").toInt).getOrElse(0), a.getOrElse("endYear","").toIntOption, a.get("genres").toList))
86
+      .runWith(Sink.collection)
92 87
 
93 88
     Await.result(result, 5 minutes)
94 89
     result.value.get.get.toList
95 90
   }
91
+
96 92
   def getIdOfPersons(file: File, titleId: String): immutable.Iterable[Option[String]] = {
97
-    val te = fileSource(file)
93
+    val result = fileSource(file)
98 94
       .mapAsync(50) {
99 95
         res =>
100 96
           Source.single(res)
@@ -107,7 +103,7 @@ class MovieQueryService extends MovieServiceTrait {
107 103
       .withAttributes(supervisionStrategy(resumingDecider))
108 104
       .runWith(Sink.head)
109 105
 
110
-    Await.result(te, 5 minutes)
106
+    Await.result(result, 5 minutes)
111 107
   }
112 108
 
113 109
 
@@ -118,7 +114,7 @@ class MovieQueryService extends MovieServiceTrait {
118 114
       .via(CsvParsing.lineScanner(CsvParsing.Tab, CsvParsing.DoubleQuote, CsvParsing.DoubleQuote))
119 115
       .via(CsvToMap.toMapAsStringsCombineAll(StandardCharsets.UTF_8, Option.empty))
120 116
       .filter(row => personsIdList.contains(row.getOrElse("nconst", "")))
121
-      .map(a => Principal(a("primaryName"), a("birthYear").toInt, a("deathYear").toIntOption, a.get("primaryProfession").toList))
117
+      .map(a => Principal(a("primaryName"), Try(a("birthYear").toInt).getOrElse(0), a("deathYear").toIntOption, a.get("primaryProfession").toList))
122 118
       .runWith(Sink.collection)
123 119
 
124 120
     Await.result(result, 5 minutes)

Powered by TurnKey Linux.