Search code examples
androidkotlinrx-javagithub-api

Github API getting files data from directories


I'm trying to use the Github API in order to get contents of a directory I created.

This is the directory structure I have:

  • images
    • mobile_images
      • img1241251235
        • extractedText.txt
        • img.jpeg (these files might be larger then 1MB)
      • img2142412312
        • extractedText.txt
        • img.jpeg

As you can see I know that in the images/mobile_images/ directory there are a bunch of directories that follow a structure.

From these directories, I want to extract the content of each extractedText.txt file (the text stored in that file) and save the download_url of each img.jpeg.

The steps I follow are:

  1. On the root directory (images/mobile_images) I call this method and get a list of the directories within it (this response). So I get img124..., img214... and so on.

  2. Now that I got all the directories (the imgXX.. ones) I call the same method on each one to get their content. This returns the extractedText.txt and img.jpeg. (the response from step 1.)

So far so good.

Now if I call the same method on a file it should return this. This works for the extractedText.txt files as their size is not bigger than 1 MB, but for the image files, it will throw an error.

I want to obtain a list of objects that will look like this:

Image(val name: String, //this is something I extract from img123...
val date: Long, //this is something I extract from img123...
val extractedText: String, //this should be the text from extractedText.txt
val url: String) //this should be the download_url of img.jpeg file

You can find my current code here.

Everything works fine until that point. When I reach the file I need to check if it's a text file or an image file.

The problem is that I don't know how to manage that "if case" and after that merge the data I get (download_url and extractedText content) into a single image object. This is the part of the code I don't know how to approach:

// from here starts the problem 
 .flatMap(object:
  Function < ResponseBody, Observable < Any >> {
   override fun apply(responseBody: ResponseBody): Observable < Any > {
    return
    if (responseBody.path.contains("txt", true)) {
 // if the file is a text file I need to get the content of the file so I'll call this
     mModel.getFile(responseBody.path) as Observable < Any >
    } else {
 // as I mentioned if the file is an img I only need to get download_url
     responseBody.download_url
    }
   }
  })
 // merge the data into an Image file
 .toList()
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(object: Consumer < MutableList < Image >> {
 // ...
  1. Are there any easier ways to solve this problem?
  2. Is my approach ok?
  3. How can I handle that "if" situation and how can I merge the data into a single Image object?

Solution

  • I managed to implement a temporary solution.

    I wrote two functions that will return:

    1. an Observable of the list containing the data from the method mModel.getFile(responseBody.path)
    2. an Observable of the list containing the responseBody.download_url

    After I get the two observables I merge them using .zip() method with this combine method:

    Observable.zip(getImageDataObservable(),
      getImageDownloadUrlObservable(),
      object: BiFunction < MutableList < Image > , MutableList < Image > , List < Image >> {
       override fun apply(imageData: MutableList < Image > , imageUrl: MutableList < Image > ): List < Image > {
        return combineImageObservables(imageData, imageUrl)
       }
      })
     .subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .subscribe(object: Consumer < List < Image >> {
      override fun accept(images: List < Image > ? ) {
       Log.d(TAG, "images = ${images?.size}")
       Log.d(TAG, images.toString())
    
       if (images != null) {
        mViewDelegate.showImages(images)
       } else {
        mViewDelegate.showError("Try again!")
       }
    
       mViewDelegate.showSuccess("Displaying ${images?.size} images")
       mViewDelegate.hideLoading()
      }
     }, object: Consumer < Throwable > {
      override fun accept(t: Throwable ? ) {
       Log.e(TAG, t.toString(), t)
       if (t != null) {
        mViewDelegate.showError(t.message)
       } else {
        mViewDelegate.showError("Error")
       }
       Crashlytics.logException(t)
       mViewDelegate.hideLoading()
      }
     })