package io.github.mcxinyu.housi.api; import android.content.Context; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Set; import io.github.mcxinyu.housi.BuildConfig; import io.github.mcxinyu.housi.bean.GitRepos; import io.github.mcxinyu.housi.bean.SourceConfig; import io.github.mcxinyu.housi.util.StaticValues; import okhttp3.ResponseBody; import rx.Observable; import rx.functions.Func1; /** * Created by huangyuefeng on 2017/3/19. * Contact me : [email protected] */ public class SourceApiHelper { private static final String TAG = SourceApiHelper.class.getSimpleName(); private static final SourceApi SOURCE_API = ApiFactory.getSourceApi(); public static Observable<SourceConfig> getSourceConfig() { return SOURCE_API.getSourceConfig(BuildConfig.SOURCE_KEY); } public static Observable<File> getSourceHosts(final Context context, final String source) { return SOURCE_API.getSourceHosts(source) .map(new Func1<ResponseBody, File>() { @Override public File call(ResponseBody responseBody) { if (responseBody == null) { return null; } InputStream is = null; byte[] buf = new byte[1024]; int len = 0; FileOutputStream fos = null; File sourceHostFile = new File(context.getCacheDir().getAbsolutePath() + File.separator + StaticValues.HOSTS_FILE_NAME + (new Date()).getTime()); if (BuildConfig.DEBUG) { sourceHostFile = new File(context.getExternalCacheDir().getAbsolutePath() + File.separator + StaticValues.HOSTS_FILE_NAME + (new Date()).getTime()); } try { is = responseBody.byteStream(); fos = new FileOutputStream(sourceHostFile); while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } fos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) is.close(); } catch (IOException e) { e.printStackTrace(); } try { if (fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } return sourceHostFile; } }); } public static Observable<File> getMultiSourceHosts(final Context context, final Set<String> sources) { return Observable.from(sources) .flatMap(new Func1<String, Observable<File>>() { @Override public Observable<File> call(String s) { return getSourceHosts(context, s); } }) .toList() .flatMap(new Func1<List<File>, Observable<File>>() { @Override public Observable<File> call(List<File> files) { File sourceHostFile = new File(context.getCacheDir().getAbsolutePath() + File.separator + "merge-" + StaticValues.HOSTS_FILE_NAME + (new Date()).getTime()); if (BuildConfig.DEBUG) { sourceHostFile = new File(context.getExternalCacheDir().getAbsolutePath() + File.separator + "merge-" + StaticValues.HOSTS_FILE_NAME + (new Date()).getTime()); } return Observable.just(mergeFiles(sourceHostFile, files)); } }); } public static Observable<String> getSourceUpdateDate(String repos) { return SOURCE_API.getSourceUpdateDate(repos) .map(new Func1<List<GitRepos>, String>() { @Override public String call(List<GitRepos> gitRepos) { if (gitRepos == null || gitRepos.size() == 0) { return "n/a"; } SimpleDateFormat simpleDateFormatInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); SimpleDateFormat simpleDateFormatResult = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); try { return simpleDateFormatResult .format(simpleDateFormatInput .parse(gitRepos.get(0) .getCommit() .getCommitter() .getDate() .replace("Z", "UTC"))); } catch (ParseException e) { e.printStackTrace(); return "n/a"; } } }); } private static File mergeFiles(File outFile, List<File> files) { FileChannel outChannel = null; try { outChannel = new FileOutputStream(outFile).getChannel(); for (File file : files) { FileChannel fc = new FileInputStream(file).getChannel(); ByteBuffer bb = ByteBuffer.allocate(1024); while (fc.read(bb) != -1) { bb.flip(); outChannel.write(bb); bb.clear(); } fc.close(); } } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { if (outChannel != null) { outChannel.close(); } } catch (IOException ignore) { } } return outFile; } }