|
1 | 1 | package fr.free.nrw.commons
|
2 | 2 |
|
3 | 3 | import androidx.core.text.HtmlCompat
|
4 |
| -import fr.free.nrw.commons.depictions.Media.DepictedImagesFragment |
5 |
| -import fr.free.nrw.commons.media.Depictions |
| 4 | +import fr.free.nrw.commons.depictions.Media.DepictedImagesFragment.PAGE_ID_PREFIX |
| 5 | +import fr.free.nrw.commons.media.IdAndCaptions |
6 | 6 | import fr.free.nrw.commons.media.MediaClient
|
7 | 7 | import io.reactivex.Single
|
8 |
| -import io.reactivex.functions.Function5 |
9 | 8 | import timber.log.Timber
|
10 | 9 | import javax.inject.Inject
|
11 | 10 | import javax.inject.Singleton
|
12 | 11 |
|
13 | 12 | /**
|
14 | 13 | * Fetch additional media data from the network that we don't store locally.
|
15 | 14 | *
|
16 |
| - * This includes things like category lists and multilingual descriptions, |
17 |
| - * which are not intrinsic to the media and may change due to editing. |
| 15 | + * |
| 16 | + * This includes things like category lists and multilingual descriptions, which are not intrinsic |
| 17 | + * to the media and may change due to editing. |
18 | 18 | */
|
19 | 19 | @Singleton
|
20 | 20 | class MediaDataExtractor @Inject constructor(private val mediaClient: MediaClient) {
|
21 | 21 |
|
22 |
| - /** |
23 |
| - * Simplified method to extract all details required to show media details. |
24 |
| - * It fetches media object, deletion status, talk page and captions for the filename |
25 |
| - * @param filename for which the details are to be fetched |
26 |
| - * @return full Media object with all details including deletion status and talk page |
27 |
| - */ |
28 |
| - fun fetchMediaDetails(filename: String, pageId: String?): Single<Media> { |
29 |
| - return Single.zip( |
30 |
| - getMediaFromFileName(filename), |
31 |
| - mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/$filename"), |
32 |
| - getDiscussion(filename), |
33 |
| - if (pageId != null) |
34 |
| - getCaption(DepictedImagesFragment.PAGE_ID_PREFIX + pageId) |
35 |
| - else Single.just(MediaClient.NO_CAPTION), |
36 |
| - getDepictions(filename), |
37 |
| - Function5 { media: Media, deletionStatus: Boolean, discussion: String, caption: String, depictions: Depictions -> |
38 |
| - combineToMedia( |
39 |
| - media, |
40 |
| - deletionStatus, |
41 |
| - discussion, |
42 |
| - caption, |
43 |
| - depictions |
44 |
| - ) |
| 22 | + fun fetchDepictionIdsAndLabels(media: Media) = |
| 23 | + mediaClient.getEntities(media.depictionIds) |
| 24 | + .map { |
| 25 | + it.entities() |
| 26 | + .mapValues { entry -> entry.value.labels().mapValues { it.value.value() } } |
45 | 27 | }
|
46 |
| - ) |
47 |
| - } |
| 28 | + .map { it.map { (key, value) -> IdAndCaptions(key, value) } } |
| 29 | + .onErrorReturn { emptyList() } |
48 | 30 |
|
49 |
| - private fun combineToMedia( |
50 |
| - media: Media, |
51 |
| - deletionStatus: Boolean, |
52 |
| - discussion: String, |
53 |
| - caption: String, |
54 |
| - depictions: Depictions |
55 |
| - ): Media { |
56 |
| - media.discussion = discussion |
57 |
| - media.caption = caption |
58 |
| - media.depictions = depictions |
59 |
| - if (deletionStatus) { |
60 |
| - media.isRequestedDeletion = true |
61 |
| - } |
62 |
| - return media |
63 |
| - } |
| 31 | + fun checkDeletionRequestExists(media: Media) = |
| 32 | + mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/" + media.filename) |
64 | 33 |
|
65 |
| - /** |
66 |
| - * Obtains captions using filename |
67 |
| - * @param wikibaseIdentifier |
68 |
| - * |
69 |
| - * @return caption for the image in user's locale |
70 |
| - * Ex: "a nice painting" (english locale) and "No Caption" in case the caption is not available for the image |
71 |
| - */ |
72 |
| - private fun getCaption(wikibaseIdentifier: String): Single<String> { |
73 |
| - return mediaClient.getCaptionByWikibaseIdentifier(wikibaseIdentifier) |
74 |
| - } |
75 |
| - |
76 |
| - /** |
77 |
| - * Fetch depictions from the MediaWiki API |
78 |
| - * @param filename the filename we will return the caption for |
79 |
| - * @return Depictions |
80 |
| - */ |
81 |
| - private fun getDepictions(filename: String): Single<Depictions> { |
82 |
| - return mediaClient.getDepictions(filename) |
83 |
| - .doOnError { throwable: Throwable? -> |
84 |
| - Timber.e( |
85 |
| - throwable, |
86 |
| - "error while fetching depictions" |
87 |
| - ) |
| 34 | + fun fetchDiscussion(media: Media) = |
| 35 | + mediaClient.getPageHtml(media.filename.replace("File", "File talk")) |
| 36 | + .map { HtmlCompat.fromHtml(it, HtmlCompat.FROM_HTML_MODE_LEGACY).toString() } |
| 37 | + .onErrorReturn { |
| 38 | + Timber.d("Error occurred while fetching discussion") |
| 39 | + "" |
88 | 40 | }
|
89 |
| - } |
90 | 41 |
|
91 |
| - /** |
92 |
| - * Method can be used to fetch media for a given filename |
93 |
| - * @param filename Eg. File:Test.jpg |
94 |
| - * @return return data rich Media object |
95 |
| - */ |
96 |
| - fun getMediaFromFileName(filename: String?): Single<Media> { |
97 |
| - return mediaClient.getMedia(filename) |
98 |
| - } |
| 42 | + fun refresh(media: Media): Single<Media> { |
| 43 | + return Single.ambArray( |
| 44 | + mediaClient.getMediaById(PAGE_ID_PREFIX + media.pageId) |
| 45 | + .onErrorResumeNext { Single.never() }, |
| 46 | + mediaClient.getMedia(media.filename) |
| 47 | + .onErrorResumeNext { Single.never() } |
| 48 | + ) |
99 | 49 |
|
100 |
| - /** |
101 |
| - * Fetch talk page from the MediaWiki API |
102 |
| - * @param filename |
103 |
| - * @return |
104 |
| - */ |
105 |
| - private fun getDiscussion(filename: String): Single<String> { |
106 |
| - return mediaClient.getPageHtml(filename.replace("File", "File talk")) |
107 |
| - .map { discussion: String? -> |
108 |
| - HtmlCompat.fromHtml( |
109 |
| - discussion!!, |
110 |
| - HtmlCompat.FROM_HTML_MODE_LEGACY |
111 |
| - ).toString() |
112 |
| - } |
113 |
| - .onErrorReturn { throwable: Throwable? -> |
114 |
| - Timber.e(throwable, "Error occurred while fetching discussion") |
115 |
| - "" |
116 |
| - } |
117 | 50 | }
|
118 |
| - |
119 | 51 | }
|
0 commit comments