cc.metapro.openct.myclass.ClassPresenter.java Source code

Java tutorial

Introduction

Here is the source code for cc.metapro.openct.myclass.ClassPresenter.java

Source

package cc.metapro.openct.myclass;

/*
 *  Copyright 2016 - 2017 OpenCT open source class table
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentManager;
import android.text.TextUtils;
import android.widget.Toast;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.util.List;
import java.util.Map;

import cc.metapro.interactiveweb.utils.HTMLUtils;
import cc.metapro.openct.R;
import cc.metapro.openct.customviews.FormDialog;
import cc.metapro.openct.data.source.local.DBManger;
import cc.metapro.openct.data.source.local.LocalHelper;
import cc.metapro.openct.data.university.CmsFactory;
import cc.metapro.openct.data.university.UniversityUtils;
import cc.metapro.openct.data.university.model.classinfo.Classes;
import cc.metapro.openct.utils.ActivityUtils;
import cc.metapro.openct.utils.Constants;
import cc.metapro.openct.utils.base.MyObserver;
import cc.metapro.openct.utils.webutils.TableUtils;
import cc.metapro.openct.widget.DailyClassWidget;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

class ClassPresenter implements ClassContract.Presenter {

    private final String TAG = ClassPresenter.class.getSimpleName();
    private ClassContract.View mView;
    private Context mContext;

    ClassPresenter(@NonNull ClassContract.View view, Context context) {
        mView = view;
        mView.setPresenter(this);
        mContext = context;
    }

    @Override
    public Disposable loadOnlineInfo(final FragmentManager manager) {
        ActivityUtils.showProgressDialog(mContext, R.string.preparing_school_sys_info);

        Observable<Boolean> observable = LocalHelper.prepareOnlineInfo(Constants.TYPE_CMS, mContext);

        Observer<Boolean> observer = new MyObserver<Boolean>(TAG) {
            @Override
            public void onNext(Boolean needCaptcha) {
                ActivityUtils.dismissProgressDialog();
                if (needCaptcha) {
                    ActivityUtils.showCaptchaDialog(manager, ClassPresenter.this);
                } else {
                    loadUserCenter(manager, "");
                }
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                ActivityUtils.dismissProgressDialog();
                ActivityUtils.showAdvCustomTip(mContext, Constants.TYPE_CLASS);
                Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        };

        observable.observeOn(AndroidSchedulers.mainThread()).subscribe(observer);

        return null;
    }

    @Override
    public Disposable loadUserCenter(final FragmentManager manager, final String code) {
        ActivityUtils.showProgressDialog(mContext, R.string.login_to_system);

        Observable<Document> observable = LocalHelper.login(Constants.TYPE_CMS, mContext, code);

        Observer<Document> observer = new MyObserver<Document>(TAG) {
            @Override
            public void onNext(final Document userCenterDom) {
                super.onNext(userCenterDom);
                Constants.checkAdvCustomInfo(mContext);
                final List<String> urlPatterns = Constants.sDetailCustomInfo.getClassUrlPatterns();
                if (!urlPatterns.isEmpty()) {
                    if (urlPatterns.size() == 1) {
                        // fetch first page from user center, it will find the class info page in most case
                        Element target = HTMLUtils.getElementSimilar(userCenterDom,
                                Jsoup.parse(urlPatterns.get(0)).body().children().first());
                        if (target != null) {
                            loadTargetPage(manager, target.absUrl("href"));
                        } else {
                            ActivityUtils.showLinkSelectionDialog(manager, Constants.TYPE_CLASS, userCenterDom,
                                    ClassPresenter.this);
                        }
                    } else if (urlPatterns.size() > 1) {
                        // fetch more page to reach class info page, especially in QZ Data Soft CMS System
                        Observable<String> extraObservable = Observable.create(new ObservableOnSubscribe<String>() {
                            @Override
                            public void subscribe(ObservableEmitter<String> e) throws Exception {
                                CmsFactory factory = LocalHelper.getCms(mContext);
                                Document lastDom = userCenterDom;
                                Element finalTarget = null;
                                for (String pattern : urlPatterns) {
                                    if (lastDom != null) {
                                        finalTarget = HTMLUtils.getElementSimilar(lastDom,
                                                Jsoup.parse(pattern).body().children().first());
                                    }
                                    if (finalTarget != null) {
                                        lastDom = factory.getPageDom(finalTarget.absUrl("href"));
                                    }
                                }
                                if (finalTarget != null) {
                                    e.onNext(finalTarget.absUrl("href"));
                                } else {
                                    e.onError(new Exception("failed"));
                                }
                            }
                        });

                        Observer<String> extraObserver = new MyObserver<String>(TAG) {
                            @Override
                            public void onNext(String targetUrl) {
                                loadTargetPage(manager, targetUrl);
                            }

                            @Override
                            public void onError(Throwable e) {
                                super.onError(e);
                                Toast.makeText(mContext, R.string.can_not_fetch_target_page, Toast.LENGTH_LONG)
                                        .show();
                                ActivityUtils.showLinkSelectionDialog(manager, Constants.TYPE_CLASS, userCenterDom,
                                        ClassPresenter.this);
                            }
                        };

                        extraObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                                .subscribe(extraObserver);
                    } else {
                        ActivityUtils.showLinkSelectionDialog(manager, Constants.TYPE_CLASS, userCenterDom,
                                ClassPresenter.this);
                    }
                } else {
                    ActivityUtils.showLinkSelectionDialog(manager, Constants.TYPE_CLASS, userCenterDom,
                            ClassPresenter.this);
                }
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                ActivityUtils.showAdvCustomTip(mContext, Constants.TYPE_CLASS);
                Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        };

        observable.observeOn(AndroidSchedulers.mainThread()).subscribe(observer);

        return null;
    }

    @Override
    public Disposable loadTargetPage(final FragmentManager manager, final String url) {
        ActivityUtils.showProgressDialog(mContext, R.string.loading_class_page);

        Observable<Document> observable = Observable.create(new ObservableOnSubscribe<Document>() {
            @Override
            public void subscribe(ObservableEmitter<Document> e) throws Exception {
                e.onNext(LocalHelper.getCms(mContext).getPageDom(url));
            }
        });

        Observer<Document> observer = new MyObserver<Document>(TAG) {
            @Override
            public void onNext(Document document) {
                super.onNext(document);
                FormDialog.newInstance(document, ClassPresenter.this).show(manager, "form_dialog");
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                ActivityUtils.showAdvCustomTip(mContext, Constants.TYPE_CLASS);
                Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        };

        observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);

        return null;
    }

    @Override
    public Disposable loadQuery(final FragmentManager manager, final String actionURL,
            final Map<String, String> queryMap, final boolean needNewPage) {
        ActivityUtils.showProgressDialog(mContext, R.string.loading_classes);

        Observable<Document> observable = Observable.create(new ObservableOnSubscribe<Document>() {
            @Override
            public void subscribe(ObservableEmitter<Document> e) throws Exception {
                e.onNext(LocalHelper.getCms(mContext).queryClassPageDom(actionURL, queryMap, needNewPage));
            }
        });

        Observer<Document> observer = new MyObserver<Document>(TAG) {
            @Override
            public void onNext(Document document) {
                super.onNext(document);
                Constants.checkAdvCustomInfo(mContext);
                String tableId = Constants.sDetailCustomInfo.mClassTableInfo.mClassTableID;
                if (TextUtils.isEmpty(tableId)) {
                    ActivityUtils.showTableChooseDialog(manager, Constants.TYPE_CLASS, document,
                            ClassPresenter.this);
                } else {
                    Map<String, Element> map = TableUtils.getTablesFromTargetPage(document);
                    List<Element> rawClasses = UniversityUtils.getRawClasses(map.get(tableId), mContext);
                    Constants.sClasses = UniversityUtils.generateClasses(mContext, rawClasses,
                            Constants.sDetailCustomInfo.mClassTableInfo);
                    if (Constants.sClasses.size() == 0) {
                        Toast.makeText(mContext, R.string.classes_empty, Toast.LENGTH_LONG).show();
                    } else {
                        storeClasses();
                        loadLocalClasses();
                        Toast.makeText(mContext, R.string.load_online_classes_successful, Toast.LENGTH_LONG).show();
                    }
                }
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                ActivityUtils.showAdvCustomTip(mContext, Constants.TYPE_CLASS);
                Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        };

        observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);

        return null;
    }

    @Override
    public void loadLocalClasses() {
        Observable<Classes> observable = LocalHelper.getClasses(mContext);

        Observer<Classes> observer = new MyObserver<Classes>(TAG) {
            @Override
            public void onNext(Classes enrichedClasses) {
                Constants.sClasses = enrichedClasses;
                try {
                    mView.showClasses(Constants.sClasses, LocalHelper.getCurrentWeek(mContext));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        };

        observable.observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
    }

    private void storeClasses() {
        try {
            DBManger manger = DBManger.getInstance(mContext);
            manger.updateClasses(Constants.sClasses);
            DailyClassWidget.update(mContext);
        } catch (Exception e) {
            Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void start() {
        loadLocalClasses();
    }
}