Add nextcloud news feed insertion and account choice in the add feed activity

This commit is contained in:
Shinokuni 2019-06-23 13:33:10 +02:00
parent b0b8e4202a
commit e12cf1ec7f
11 changed files with 214 additions and 40 deletions

View File

@ -7,8 +7,10 @@ import android.util.Patterns;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.AdapterView;
import android.widget.Button; import android.widget.Button;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -27,8 +29,10 @@ import com.readrops.app.database.entities.Account;
import com.readrops.app.database.entities.Feed; import com.readrops.app.database.entities.Feed;
import com.readrops.app.utils.FeedInsertionResult; import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.ParsingResult; import com.readrops.app.utils.ParsingResult;
import com.readrops.app.utils.SharedPreferencesManager;
import com.readrops.app.utils.Utils; import com.readrops.app.utils.Utils;
import com.readrops.app.viewmodels.AddFeedsViewModel; import com.readrops.app.viewmodels.AddFeedsViewModel;
import com.readrops.app.views.AccountArrayAdapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -49,6 +53,9 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
private ProgressBar feedInsertionProgressBar; private ProgressBar feedInsertionProgressBar;
private RecyclerView insertionResultsRecyclerView; private RecyclerView insertionResultsRecyclerView;
private Spinner accountSpinner;
private AccountArrayAdapter arrayAdapter;
private ItemAdapter<ParsingResult> parseItemsAdapter; private ItemAdapter<ParsingResult> parseItemsAdapter;
private ItemAdapter<FeedInsertionResult> insertionResultsAdapter; private ItemAdapter<FeedInsertionResult> insertionResultsAdapter;
@ -69,6 +76,7 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
resultsTextView = findViewById(R.id.add_feed_results_text_view); resultsTextView = findViewById(R.id.add_feed_results_text_view);
feedInsertionProgressBar = findViewById(R.id.add_feed_insert_progressbar); feedInsertionProgressBar = findViewById(R.id.add_feed_insert_progressbar);
insertionResultsRecyclerView = findViewById(R.id.add_feed_inserted_results_recyclerview); insertionResultsRecyclerView = findViewById(R.id.add_feed_inserted_results_recyclerview);
accountSpinner = findViewById(R.id.add_feed_account_spinner);
load.setOnClickListener(this); load.setOnClickListener(this);
validate.setOnClickListener(this); validate.setOnClickListener(this);
@ -145,6 +153,25 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
insertionResultsRecyclerView.setAdapter(FastAdapter.with(insertionResultsAdapter)); insertionResultsRecyclerView.setAdapter(FastAdapter.with(insertionResultsAdapter));
insertionResultsRecyclerView.setLayoutManager(layoutManager1); insertionResultsRecyclerView.setLayoutManager(layoutManager1);
viewModel.getAccounts().observe(this, accounts -> {
arrayAdapter = new AccountArrayAdapter(this, accounts);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
accountSpinner.setAdapter(arrayAdapter);
accountSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
});
feedsToUpdate = new ArrayList<>(); feedsToUpdate = new ArrayList<>();
} }
@ -233,8 +260,12 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
feedsToInsert.add(result); feedsToInsert.add(result);
} }
// TODO : choose the right account Account account = (Account) accountSpinner.getSelectedItem();
viewModel.addFeeds(feedsToInsert, new Account())
account.setLogin(SharedPreferencesManager.readString(this, account.getLoginKey()));
account.setPassword(SharedPreferencesManager.readString(this, account.getPasswordKey()));
viewModel.addFeeds(feedsToInsert, account)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableSingleObserver<List<FeedInsertionResult>>() { .subscribe(new DisposableSingleObserver<List<FeedInsertionResult>>() {
@ -245,7 +276,7 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
Toast.makeText(AddFeedActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
} }
}); });
} }

View File

@ -45,9 +45,6 @@ public abstract class Database extends RoomDatabase {
@Override @Override
public void onCreate(@NonNull SupportSQLiteDatabase db) { public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db); super.onCreate(db);
Folder folder = new Folder("reserved");
//new Thread(() -> database.folderDao().insert(folder)).start();
} }
@Override @Override

View File

@ -20,8 +20,8 @@ import org.jsoup.Jsoup;
@Entity(foreignKeys = {@ForeignKey(entity = Folder.class, parentColumns = "id", @Entity(foreignKeys = {@ForeignKey(entity = Folder.class, parentColumns = "id",
childColumns = "folder_id", onDelete = ForeignKey.SET_NULL), childColumns = "folder_id", onDelete = ForeignKey.SET_NULL),
@ForeignKey(entity = Account.class, parentColumns = "id", childColumns = "account_id", @ForeignKey(entity = Account.class, parentColumns = "id", childColumns = "account_id",
onDelete = ForeignKey.CASCADE)}) onDelete = ForeignKey.CASCADE)})
public class Feed implements Parcelable { public class Feed implements Parcelable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ -38,10 +38,12 @@ public class Feed implements Parcelable {
private String lastUpdated; private String lastUpdated;
@ColumnInfo(name = "text_color") @ColumnInfo(name = "text_color")
private @ColorInt int textColor; private @ColorInt
int textColor;
@ColumnInfo(name = "background_color") @ColumnInfo(name = "background_color")
private @ColorInt int backgroundColor; private @ColorInt
int backgroundColor;
@ColumnInfo(name = "icon_url") @ColumnInfo(name = "icon_url")
private String iconUrl; private String iconUrl;
@ -52,7 +54,7 @@ public class Feed implements Parcelable {
private String lastModified; private String lastModified;
@ColumnInfo(name = "folder_id", index = true) @ColumnInfo(name = "folder_id", index = true)
private int folderId; private Integer folderId; // nullable foreign key so Integer instead of int
private int remoteId; private int remoteId;
@ -149,7 +151,8 @@ public class Feed implements Parcelable {
this.lastUpdated = lastUpdated; this.lastUpdated = lastUpdated;
} }
public @ColorInt int getTextColor() { public @ColorInt
int getTextColor() {
return textColor; return textColor;
} }
@ -157,7 +160,8 @@ public class Feed implements Parcelable {
this.textColor = textColor; this.textColor = textColor;
} }
public @ColorInt int getBackgroundColor() { public @ColorInt
int getBackgroundColor() {
return backgroundColor; return backgroundColor;
} }
@ -189,11 +193,11 @@ public class Feed implements Parcelable {
this.lastModified = lastModified; this.lastModified = lastModified;
} }
public int getFolderId() { public Integer getFolderId() {
return folderId; return folderId;
} }
public void setFolderId(int folderId) { public void setFolderId(Integer folderId) {
this.folderId = folderId; this.folderId = folderId;
} }
@ -234,9 +238,7 @@ public class Feed implements Parcelable {
feed.setEtag(rssFeed.getEtag()); feed.setEtag(rssFeed.getEtag());
feed.setLastModified(rssFeed.getLastModified()); feed.setLastModified(rssFeed.getLastModified());
// as sqlite doesn't support null foreign keys, a default folder is linked to the feed feed.setFolderId(null);
// This default folder was inserted at room db creation (see Database.java)
feed.setFolderId(1);
return feed; return feed;
} }
@ -254,7 +256,7 @@ public class Feed implements Parcelable {
feed.setEtag(atomFeed.getEtag()); feed.setEtag(atomFeed.getEtag());
feed.setLastModified(atomFeed.getLastModified()); feed.setLastModified(atomFeed.getLastModified());
feed.setFolderId(1); feed.setFolderId(null);
return feed; return feed;
} }
@ -266,13 +268,12 @@ public class Feed implements Parcelable {
feed.setUrl(jsonFeed.getFeedUrl()); feed.setUrl(jsonFeed.getFeedUrl());
feed.setSiteUrl(jsonFeed.getHomePageUrl()); feed.setSiteUrl(jsonFeed.getHomePageUrl());
feed.setDescription(jsonFeed.getDescription()); feed.setDescription(jsonFeed.getDescription());
//feed.setLastUpdated(jsonFeed.); maybe later ?
feed.setEtag(jsonFeed.getEtag()); feed.setEtag(jsonFeed.getEtag());
feed.setLastModified(jsonFeed.getLastModified()); feed.setLastModified(jsonFeed.getLastModified());
feed.setIconUrl(jsonFeed.getFaviconUrl()); feed.setIconUrl(jsonFeed.getFaviconUrl());
feed.setFolderId(1); feed.setFolderId(null);
return feed; return feed;
} }

View File

@ -1,6 +1,7 @@
package com.readrops.app.repositories; package com.readrops.app.repositories;
import android.app.Application; import android.app.Application;
import android.database.sqlite.SQLiteConstraintException;
import android.util.TimingLogger; import android.util.TimingLogger;
import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Account;
@ -18,9 +19,11 @@ import com.readrops.readropslibrary.services.nextcloudnews.NextNewsAPI;
import com.readrops.readropslibrary.services.nextcloudnews.SyncData; import com.readrops.readropslibrary.services.nextcloudnews.SyncData;
import com.readrops.readropslibrary.services.nextcloudnews.SyncResult; import com.readrops.readropslibrary.services.nextcloudnews.SyncResult;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsUser; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsUser;
import com.readrops.readropslibrary.utils.UnknownFormatException;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
@ -116,7 +119,41 @@ public class NextNewsRepository extends ARepository {
@Override @Override
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account) { public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account) {
return null; return Single.create(emitter -> {
List<FeedInsertionResult> feedInsertionResults = new ArrayList<>();
NextNewsAPI newsAPI = new NextNewsAPI();
for (ParsingResult result : results) {
FeedInsertionResult insertionResult = new FeedInsertionResult();
try {
Credentials credentials = new Credentials(account.getLogin(), account.getPassword(), account.getUrl());
NextNewsFeeds nextNewsFeeds = newsAPI.createFeed(credentials, result.getUrl(), 0);
if (nextNewsFeeds != null) {
List<Feed> newFeeds = insertFeeds(nextNewsFeeds.getFeeds(), account);
// there is always only one object in the list, see nextcloud news api doc
insertionResult.setFeed(newFeeds.get(0));
} else
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.UNKNOWN_ERROR);
} catch (Exception e) {
if (e instanceof IOException)
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.NETWORK_ERROR);
else if (e instanceof UnknownFormatException)
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.FORMAT_ERROR);
else if (e instanceof SQLiteConstraintException)
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.DB_ERROR);
else
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.UNKNOWN_ERROR);
}
feedInsertionResults.add(insertionResult);
}
emitter.onSuccess(feedInsertionResults);
});
} }
@Override @Override
@ -134,7 +171,7 @@ public class NextNewsRepository extends ARepository {
return null; return null;
} }
private void insertFeeds(List<NextNewsFeed> feeds, Account account) { private List<Feed> insertFeeds(List<NextNewsFeed> feeds, Account account) {
List<Feed> newFeeds = new ArrayList<>(); List<Feed> newFeeds = new ArrayList<>();
for (NextNewsFeed nextNewsFeed : feeds) { for (NextNewsFeed nextNewsFeed : feeds) {
@ -142,14 +179,14 @@ public class NextNewsRepository extends ARepository {
if (!database.feedDao().remoteFeedExists(nextNewsFeed.getId(), account.getId())) { if (!database.feedDao().remoteFeedExists(nextNewsFeed.getId(), account.getId())) {
Feed feed = FeedMatcher.nextNewsFeedToFeed(nextNewsFeed, account); Feed feed = FeedMatcher.nextNewsFeedToFeed(nextNewsFeed, account);
// if the Nextcloud feed has a folder, it is already inserted, so we have to get its local id // if the Nextcloud feed has a folder, it is already inserted, so we have to get its local id
if (nextNewsFeed.getFolderId() != 0) { if (nextNewsFeed.getFolderId() != 0) {
int folderId = database.folderDao().getRemoteFolderLocalId(nextNewsFeed.getFolderId(), account.getId()); int folderId = database.folderDao().getRemoteFolderLocalId(nextNewsFeed.getFolderId(), account.getId());
if (folderId != 0) if (folderId != 0)
feed.setFolderId(folderId); feed.setFolderId(folderId);
} } else
feed.setFolderId(null);
newFeeds.add(feed); newFeeds.add(feed);
} }
@ -168,6 +205,8 @@ public class NextNewsRepository extends ARepository {
.doOnNext(feed1 -> database.feedDao().updateColors(feed1.getId(), .doOnNext(feed1 -> database.feedDao().updateColors(feed1.getId(),
feed1.getTextColor(), feed1.getBackgroundColor())) feed1.getTextColor(), feed1.getBackgroundColor()))
.subscribe(); .subscribe();
return insertedFeeds;
} }
private void insertFolders(List<NextNewsFolder> folders, Account account) { private void insertFolders(List<NextNewsFolder> folders, Account account) {

View File

@ -1,12 +1,12 @@
package com.readrops.app.utils; package com.readrops.app.utils;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import com.mikepenz.fastadapter.FastAdapter; import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.items.AbstractItem; import com.mikepenz.fastadapter.items.AbstractItem;
import com.readrops.app.R; import com.readrops.app.R;

View File

@ -3,9 +3,13 @@ package com.readrops.app.viewmodels;
import android.app.Application; import android.app.Application;
import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.AndroidViewModel;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import com.readrops.app.database.Database;
import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Account;
import com.readrops.app.repositories.ARepository;
import com.readrops.app.repositories.LocalFeedRepository; import com.readrops.app.repositories.LocalFeedRepository;
import com.readrops.app.repositories.NextNewsRepository;
import com.readrops.app.utils.FeedInsertionResult; import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.HtmlParser; import com.readrops.app.utils.HtmlParser;
import com.readrops.app.utils.ParsingResult; import com.readrops.app.utils.ParsingResult;
@ -18,15 +22,25 @@ import io.reactivex.Single;
public class AddFeedsViewModel extends AndroidViewModel { public class AddFeedsViewModel extends AndroidViewModel {
private LocalFeedRepository repository; private ARepository repository;
private Database database;
public AddFeedsViewModel(@NonNull Application application) { public AddFeedsViewModel(@NonNull Application application) {
super(application); super(application);
repository = new LocalFeedRepository(application); database = Database.getInstance(application);
} }
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account) { public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account) {
switch (account.getAccountType()) {
case LOCAL:
repository = new LocalFeedRepository(getApplication());
break;
case NEXTCLOUD_NEWS:
repository = new NextNewsRepository(getApplication());
break;
}
return repository.addFeeds(results, account); return repository.addFeeds(results, account);
} }
@ -45,4 +59,8 @@ public class AddFeedsViewModel extends AndroidViewModel {
emitter.onSuccess(results); emitter.onSuccess(results);
}); });
} }
public LiveData<List<Account>> getAccounts() {
return database.accountDao().selectAll();
}
} }

View File

@ -0,0 +1,54 @@
package com.readrops.app.views;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.readrops.app.R;
import com.readrops.app.database.entities.Account;
import java.util.List;
public class AccountArrayAdapter extends ArrayAdapter<Account> {
public AccountArrayAdapter(@NonNull Context context, @NonNull List<Account> objects) {
super(context, 0, objects);
}
@Override
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
return createItemView(position, convertView, parent);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
return createItemView(position, convertView, parent);
}
private View createItemView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.account_type_item, parent, false);
}
Account account = getItem(position);
ImageView accountIcon = convertView.findViewById(R.id.account_type_logo);
TextView accountName = convertView.findViewById(R.id.account_type_name);
accountIcon.setImageResource(account.getAccountType().getIconRes());
accountName.setText(account.getAccountType().getName());
return convertView;
}
}

View File

@ -33,8 +33,8 @@
android:id="@+id/add_feed_text_input" android:id="@+id/add_feed_text_input"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/feed_url" android:drawableEnd="@drawable/ic_cancel_grey"
android:drawableEnd="@drawable/ic_cancel_grey"/> android:hint="@string/feed_url" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -83,17 +83,26 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<Spinner
android:id="@+id/add_feed_account_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_main_layout" />
<Button <Button
android:id="@+id/add_feed_ok" android:id="@+id/add_feed_ok"
style="@style/GenericButton" style="@style/GenericButton"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:enabled="true" android:enabled="true"
android:text="@string/validate" android:text="@string/validate"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.6"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_main_layout" /> app:layout_constraintTop_toBottomOf="@id/add_feed_account_spinner" />
<ProgressBar <ProgressBar
android:id="@+id/add_feed_insert_progressbar" android:id="@+id/add_feed_insert_progressbar"

View File

@ -10,6 +10,7 @@ import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.http.Body; import retrofit2.http.Body;
import retrofit2.http.GET; import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.PUT; import retrofit2.http.PUT;
import retrofit2.http.Path; import retrofit2.http.Path;
import retrofit2.http.Query; import retrofit2.http.Query;
@ -35,4 +36,7 @@ public interface NextNewsService {
@PUT("items/{stateType}/multiple") @PUT("items/{stateType}/multiple")
Call<ResponseBody> setArticlesState(@Path("stateType") String stateType, @Body NextNewsItemIds items); Call<ResponseBody> setArticlesState(@Path("stateType") String stateType, @Body NextNewsItemIds items);
@POST("feeds")
Call<NextNewsFeeds> createFeed(@Query("url") String url, @Query("folderId") int folderId);
} }

View File

@ -10,6 +10,8 @@ import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItemIds;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItems; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItems;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsUser; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsUser;
import com.readrops.readropslibrary.utils.HttpManager; import com.readrops.readropslibrary.utils.HttpManager;
import com.readrops.readropslibrary.utils.LibUtils;
import com.readrops.readropslibrary.utils.UnknownFormatException;
import java.io.IOException; import java.io.IOException;
@ -35,11 +37,15 @@ public class NextNewsAPI {
.build(); .build();
} }
public NextNewsUser login(Credentials credentials) throws IOException { private NextNewsService createAPI(@NonNull Credentials credentials) {
HttpManager httpManager = new HttpManager(credentials); HttpManager httpManager = new HttpManager(credentials);
Retrofit retrofit = getConfiguredRetrofitInstance(httpManager); Retrofit retrofit = getConfiguredRetrofitInstance(httpManager);
api = retrofit.create(NextNewsService.class); return retrofit.create(NextNewsService.class);
}
public NextNewsUser login(Credentials credentials) throws IOException {
api = createAPI(credentials);
Response<NextNewsUser> response = api.getUser().execute(); Response<NextNewsUser> response = api.getUser().execute();
@ -49,11 +55,24 @@ public class NextNewsAPI {
return response.body(); return response.body();
} }
public SyncResult sync(@NonNull Credentials credentials, @NonNull SyncType syncType, @Nullable SyncData data) throws IOException { public @Nullable NextNewsFeeds createFeed(Credentials credentials, String url, int folderId)
HttpManager httpManager = new HttpManager(credentials); throws IOException, UnknownFormatException {
Retrofit retrofit = getConfiguredRetrofitInstance(httpManager); api = createAPI(credentials);
api = retrofit.create(NextNewsService.class); Response<NextNewsFeeds> response = api.createFeed(url, folderId).execute();
if (!response.isSuccessful()) {
if (response.code() == LibUtils.UNPROCESSABLE_CODE)
throw new UnknownFormatException();
else
return null;
}
return response.body();
}
public SyncResult sync(@NonNull Credentials credentials, @NonNull SyncType syncType, @Nullable SyncData data) throws IOException {
api = createAPI(credentials);
SyncResult syncResult = new SyncResult(); SyncResult syncResult = new SyncResult();
switch (syncType) { switch (syncType) {

View File

@ -18,6 +18,8 @@ public final class LibUtils {
public static final String LAST_MODIFIED_HEADER = "Last-Modified"; public static final String LAST_MODIFIED_HEADER = "Last-Modified";
public static final String IF_MODIFIED_HEADER = "If-Modified-Since"; public static final String IF_MODIFIED_HEADER = "If-Modified-Since";
public static final int UNPROCESSABLE_CODE = 422;
public static String inputStreamToString(InputStream input) { public static String inputStreamToString(InputStream input) {
Scanner scanner = new Scanner(input).useDelimiter("\\A"); Scanner scanner = new Scanner(input).useDelimiter("\\A");
return scanner.hasNext() ? scanner.next() : ""; return scanner.hasNext() ? scanner.next() : "";