req) {
61 | req.setTag(TAG);
62 | getRequestQueue().add(req);
63 | }
64 |
65 | public void cancelPendingRequests(Object tag) {
66 | if (mRequestQueue != null) {
67 | mRequestQueue.cancelAll(tag);
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/technikh/onedrupal/network/ReceivedCookiesInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.technikh.onedrupal.network;
2 |
3 | /*
4 | * Copyright (c) 2019. Nikhil Dubbaka from TechNikh.com under GNU AFFERO GENERAL PUBLIC LICENSE
5 | * Copyright and license notices must be preserved.
6 | * When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.
7 | */
8 |
9 | import android.content.Context;
10 | import android.content.SharedPreferences;
11 | import android.util.Log;
12 |
13 | import com.technikh.onedrupal.app.MyApplication;
14 |
15 | import java.io.IOException;
16 | import java.util.HashSet;
17 |
18 | import okhttp3.Interceptor;
19 | import okhttp3.Request;
20 | import okhttp3.Response;
21 |
22 | /**
23 | * This Interceptor add all received Cookies to the app DefaultPreferences.
24 | * Your implementation on how to save the Cookies on the Preferences MAY VARY.
25 | *
26 | * Created by tsuharesu on 4/1/15.
27 | */
28 | public class ReceivedCookiesInterceptor implements Interceptor {
29 | private Context context;
30 | public static final String APP_PREFERENCES = "mysettings";
31 | private SharedPreferences mSettings;
32 | private String TAG = "ReceivedCookiesInterceptor";
33 | @Override
34 | public Response intercept(Chain chain) throws IOException {
35 | context = MyApplication.getAppContext();
36 | Response originalResponse = chain.proceed(chain.request());
37 | mSettings = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
38 |
39 | if (!originalResponse.headers("Set-Cookie").isEmpty()) {
40 | HashSet cookies = (HashSet) mSettings.getStringSet("PREF_COOKIES", new HashSet());
41 |
42 | for (String header : originalResponse.headers("Set-Cookie")) {
43 | cookies.add(header);
44 | }
45 | Log.d(TAG, "intercept: "+cookies.toString());
46 |
47 | SharedPreferences.Editor memes = mSettings.edit();
48 | memes.putStringSet("PREF_COOKIES", cookies).apply();
49 | memes.commit();
50 | }
51 |
52 | return originalResponse;
53 | }
54 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
18 |
19 |
25 |
28 |
31 |
32 |
33 |
34 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/technikh/onedrupal/util/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.technikh.onedrupal.util;
2 |
3 | /*
4 | * Copyright (c) 2019. Nikhil Dubbaka from TechNikh.com under GNU AFFERO GENERAL PUBLIC LICENSE
5 | * Copyright and license notices must be preserved.
6 | * When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.
7 | */
8 |
9 | import java.util.ArrayList;
10 | import java.util.Collections;
11 | import java.util.HashMap;
12 | import java.util.Iterator;
13 | import java.util.LinkedHashMap;
14 | import java.util.List;
15 |
16 | public class StringUtils {
17 |
18 | private static String TAG = "ApiUtils";
19 |
20 | public static String implode(String separator, List data) {
21 | StringBuilder sb = new StringBuilder();
22 | for (int i = 0; i < data.size() - 1; i++) {
23 | //data.length - 1 => to not add separator at the end
24 | if (!data.get(i).matches(" *")) {//empty string are ""; " "; " "; and so on
25 | sb.append(data.get(i));
26 | sb.append(separator);
27 | }
28 | }
29 | sb.append(data.get(data.size() - 1).trim());
30 | return sb.toString();
31 | }
32 |
33 | public static LinkedHashMap sortHashMapByValues(
34 | HashMap passedMap) {
35 | List mapKeys = new ArrayList<>(passedMap.keySet());
36 | List mapValues = new ArrayList<>(passedMap.values());
37 | Collections.sort(mapValues);
38 | Collections.sort(mapKeys);
39 |
40 | LinkedHashMap sortedMap =
41 | new LinkedHashMap<>();
42 |
43 | Iterator valueIt = mapValues.iterator();
44 | while (valueIt.hasNext()) {
45 | String val = valueIt.next();
46 | Iterator keyIt = mapKeys.iterator();
47 |
48 | while (keyIt.hasNext()) {
49 | Integer key = keyIt.next();
50 | String comp1 = passedMap.get(key);
51 | String comp2 = val;
52 |
53 | if (comp1.equals(comp2)) {
54 | keyIt.remove();
55 | sortedMap.put(key, val);
56 | break;
57 | }
58 | }
59 | }
60 | return sortedMap;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
18 |
19 |
25 |
28 |
31 |
32 |
33 |
34 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
21 |
22 |
26 |
27 |
32 |
33 |
36 |
37 |
40 |
41 |
42 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/technikh/onedrupal/network/OnSettingsApiGetTaskCompleted.java:
--------------------------------------------------------------------------------
1 | package com.technikh.onedrupal.network;
2 |
3 | /*
4 | * Copyright (c) 2019. Nikhil Dubbaka from TechNikh.com under GNU AFFERO GENERAL PUBLIC LICENSE
5 | * Copyright and license notices must be preserved.
6 | * When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.
7 | */
8 |
9 | import android.content.Intent;
10 | import android.util.Log;
11 |
12 | import com.technikh.onedrupal.activities.ActivityDashboard;
13 | import com.technikh.onedrupal.activities.SiteContentTabsActivity;
14 | import com.technikh.onedrupal.app.MyApplication;
15 | import com.technikh.onedrupal.models.ModelNodeType;
16 | import com.technikh.onedrupal.models.SettingsType;
17 |
18 | import org.json.JSONArray;
19 | import org.json.JSONException;
20 | import org.json.JSONObject;
21 |
22 | public class OnSettingsApiGetTaskCompleted implements OnApiGetTaskCompleted{
23 | private String TAG = "OnSettingsApiGetTaskCompleted";
24 | @Override
25 | public void onTaskCompleted(String responseStr) {
26 | // do something with result here!
27 | //Log.d(TAG, "onTaskCompleted: "+responseStr);
28 | Log.d(TAG, "fetchSettingsAPI: responseStr "+responseStr);
29 | if(responseStr == null){
30 | return;
31 | }
32 | try {
33 | JSONObject responseBodyObj = new JSONObject(responseStr);
34 | if (responseBodyObj.has("types")) {
35 | Log.d(TAG, "fetchSettingsAPI: in types");
36 | JSONArray ja = responseBodyObj.getJSONArray("types");
37 | MyApplication.gblNodeTypeSettings.clear();
38 | for (int j = 0; j < ja.length(); j++) {
39 | Log.d(TAG, "fetchSettingsAPI: in for");
40 | JSONObject jo = (JSONObject) ja.get(j);
41 | //SettingsType modelNodeType = new SettingsType(jo);
42 | //MyApplication.gblNodeTypeSettings.add(modelNodeType);
43 | }
44 | Intent intent1 = new Intent(MyApplication.getAppContext(), SiteContentTabsActivity.class);
45 | intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
46 | MyApplication.getAppContext().startActivity(intent1);
47 | }
48 | } catch (JSONException e) {
49 | e.printStackTrace();
50 | } catch (Exception e) {
51 | e.printStackTrace();
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/technikh/onedrupal/authenticator/AuthPreferences.java:
--------------------------------------------------------------------------------
1 | package com.technikh.onedrupal.authenticator;
2 |
3 | /*
4 | * Copyright (c) 2019. Nikhil Dubbaka from TechNikh.com under GNU AFFERO GENERAL PUBLIC LICENSE
5 | * Copyright and license notices must be preserved.
6 | * When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.
7 | */
8 |
9 | import android.content.Context;
10 | import android.content.SharedPreferences;
11 | import android.content.SharedPreferences.Editor;
12 | import android.util.Log;
13 |
14 | public class AuthPreferences {
15 |
16 | private static final String PREFS_NAME = "auth";
17 | private static final String KEY_ACCOUNT_NAME = "account_name";
18 | private static final String KEY_AUTH_TOKEN = "auth_token";
19 | private static final String KEY_PRI_SITE_URL = "primary_site_url";
20 | private static final String KEY_PRI_SITE_PROTOCOL = "primary_site_protocol";
21 | private String TAG = "AuthPreferences";
22 |
23 | private SharedPreferences preferences;
24 |
25 | public AuthPreferences(Context context) {
26 | preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
27 | }
28 |
29 | public String getAccountName() {
30 | return preferences.getString(KEY_ACCOUNT_NAME, null);
31 | }
32 |
33 | public String getPrimarySiteUrl() {
34 | Log.d(TAG, "getPrimarySiteUrl: "+preferences.getString(KEY_PRI_SITE_URL, null));
35 | return preferences.getString(KEY_PRI_SITE_URL, null);
36 | }
37 | public String getPrimarySiteProtocol() {
38 | return preferences.getString(KEY_PRI_SITE_PROTOCOL, null);
39 | }
40 |
41 | public String getAuthToken() {
42 | return preferences.getString(KEY_AUTH_TOKEN, null);
43 | }
44 |
45 | public void setUsername(String accountName) {
46 | final Editor editor = preferences.edit();
47 | editor.putString(KEY_ACCOUNT_NAME, accountName);
48 | editor.commit();
49 | }
50 |
51 | public void setPrimarySiteUrl(String accountName) {
52 | final Editor editor = preferences.edit();
53 | editor.putString(KEY_PRI_SITE_URL, accountName);
54 | editor.commit();
55 | }
56 | public void setPrimarySiteProtocol(String accountName) {
57 | final Editor editor = preferences.edit();
58 | editor.putString(KEY_PRI_SITE_PROTOCOL, accountName);
59 | editor.commit();
60 | }
61 |
62 | public void setAuthToken(String authToken) {
63 | final Editor editor = preferences.edit();
64 | editor.putString(KEY_AUTH_TOKEN, authToken);
65 | editor.commit();
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/technikh/onedrupal/adapter/BreadcumAdapter.java:
--------------------------------------------------------------------------------
1 | package com.technikh.onedrupal.adapter;
2 |
3 |
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 | import com.technikh.onedrupal.R;
9 | import com.technikh.onedrupal.models.BreadcumModel;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | import androidx.recyclerview.widget.RecyclerView;
15 |
16 |
17 | public class BreadcumAdapter extends RecyclerView.Adapter {
18 |
19 | private buttonEventListenr buttonEventListenr;
20 | private List itemList;
21 |
22 |
23 | public interface buttonEventListenr {
24 |
25 | void buttonEvent(int position,String SiteTitle,String titleid,String vocabularyid);
26 |
27 | }
28 |
29 | public BreadcumAdapter(ListitemList , buttonEventListenr listner) {
30 | this.itemList = itemList;
31 | this.buttonEventListenr = listner;
32 | }
33 |
34 | @Override
35 | public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
36 |
37 | View itemView = LayoutInflater.from(parent.getContext())
38 | .inflate(R.layout.breadcum_list, parent, false);
39 |
40 | return new MyViewHolder(itemView);
41 | }
42 |
43 | @Override
44 | public void onBindViewHolder(MyViewHolder holder, int position) {
45 |
46 | if (itemList.get(position).getXYZ() == null){
47 |
48 | holder.title.setText(itemList.get(position).getVocabId());
49 |
50 | }else{
51 |
52 | holder.title.setText(itemList.get(position).getXYZ());
53 | }
54 |
55 |
56 | holder.title.setOnClickListener(new View.OnClickListener() {
57 | public void onClick(View v) {
58 |
59 | buttonEventListenr.buttonEvent(position,itemList.get(position).getXYZ(), itemList.get(position).getTitleId(),itemList.get(position).getVocabId());
60 |
61 | }
62 | });
63 |
64 | }
65 |
66 | public class MyViewHolder extends RecyclerView.ViewHolder {
67 |
68 | public TextView title;
69 |
70 | public MyViewHolder(View view) {
71 | super(view);
72 | title = (TextView) view.findViewById(R.id.item);
73 | }
74 | }
75 |
76 | @Override
77 | public int getItemCount() {
78 | return itemList.size();
79 | }
80 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/technikh/onedrupal/network/ApiCall.java:
--------------------------------------------------------------------------------
1 | package com.technikh.onedrupal.network;
2 |
3 | /*
4 | * Copyright (c) 2019. Nikhil Dubbaka from TechNikh.com under GNU AFFERO GENERAL PUBLIC LICENSE
5 | * Copyright and license notices must be preserved.
6 | * When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.
7 | */
8 |
9 | import android.content.Context;
10 | import android.util.Log;
11 |
12 | import com.android.volley.Request;
13 | import com.android.volley.RequestQueue;
14 | import com.android.volley.Response;
15 | import com.android.volley.toolbox.StringRequest;
16 | import com.android.volley.toolbox.Volley;
17 | import com.technikh.onedrupal.authenticator.AuthPreferences;
18 |
19 | /**
20 | * Created by MG on 04-03-2018.
21 | */
22 |
23 | public class ApiCall {
24 | private static ApiCall mInstance;
25 | private RequestQueue mRequestQueue;
26 | private static Context mCtx;
27 |
28 | public ApiCall(Context ctx) {
29 | mCtx = ctx;
30 | mRequestQueue = getRequestQueue();
31 | }
32 |
33 | public static synchronized ApiCall getInstance(Context context) {
34 | if (mInstance == null) {
35 | mInstance = new ApiCall(context);
36 | }
37 | return mInstance;
38 | }
39 |
40 | public RequestQueue getRequestQueue() {
41 | if (mRequestQueue == null) {
42 | mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
43 | }
44 | return mRequestQueue;
45 | }
46 |
47 | public void addToRequestQueue(Request req) {
48 | getRequestQueue().add(req);
49 | }
50 |
51 | public static void make(Context ctx, String vid, String query, Response.Listener
52 | listener, Response.ErrorListener errorListener) {
53 | //String url = "https://itunes.apple.com/search?term=" + query + "&country=US";
54 | AuthPreferences mAuthPreferences = new AuthPreferences(ctx);
55 | // http://nikhil.dubbaka.com/onedrupal/api/v1/vocabulary-titles/categories?name=Or
56 | String url = mAuthPreferences.getPrimarySiteProtocol() + mAuthPreferences.getPrimarySiteUrl()+"/onedrupal/api/v1/vocabulary-titles/"+vid+"?name="+query;
57 | Log.d("ApiCall", "make: query "+query);
58 | Log.d("ApiCall", "make: url "+url);
59 | StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
60 | listener, errorListener);
61 | ApiCall.getInstance(ctx).addToRequestQueue(stringRequest);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # One Drupal – Content Builder - Android
2 |
3 |
4 | To manage your Drupal site through this app, You need to install https://www.drupal.org/project/one_api module in your Drupal 8 Site
5 |
6 | ## Features
7 | * Login,
8 | * Create & edit nodes,
9 | * Upload images,
10 | * Publish, Unpublish,
11 | * Promote to front page, remove from front page(Demote),
12 | * API paging - lazy load - scroll up to pull new content - scroll down to pull more content....
13 |
14 |
15 | ## Fields
16 | * Node title
17 | * Text (formatted, long)
18 | * Image
19 | * Link
20 | * Video Embed
21 |
22 |
23 | ## Contribution
24 | * GNU AFFERO GENERAL PUBLIC LICENSE
25 | * Copyright and license notices must be preserved.
26 | * When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.
27 |
28 | ## Building
29 | create a file in the root directory with below data
30 |
31 | `google_auth_client_id="0000000.apps.googleusercontent.com"`
32 |
33 | `demo_site_url="one-drupal-demo.technikh.com"`
34 |
35 | `demo_site_username="000"`
36 |
37 | `demo_site_password="000"`
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/technikh/onedrupal/models/ModelNodeType.java:
--------------------------------------------------------------------------------
1 | package com.technikh.onedrupal.models;
2 |
3 | /*
4 | * Copyright (c) 2019. Nikhil Dubbaka from TechNikh.com under GNU AFFERO GENERAL PUBLIC LICENSE
5 | * Copyright and license notices must be preserved.
6 | * When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.
7 | */
8 |
9 | import android.util.Log;
10 |
11 | import com.google.gson.annotations.SerializedName;
12 |
13 | import org.json.JSONException;
14 | import org.json.JSONObject;
15 |
16 | import java.util.ArrayList;
17 |
18 | public class ModelNodeType {
19 |
20 | @SerializedName("type")
21 | public ArrayList nodeType;
22 | @SerializedName("status")
23 | private ArrayList isPublished;
24 | @SerializedName("promote")
25 | private ArrayList isPromoted;
26 | @SerializedName("nid")
27 | public ArrayList nid;
28 | @SerializedName("title")
29 | public ArrayList title;
30 |
31 | //InvalidArgumentException: Field TAG is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (line 586 of /opt/bitnami/apps/drupal/htdocs/core/lib/Drupal/Core/Entity/ContentEntityBase.php).
32 | //private String TAG = "ModelNodeType";
33 |
34 | public boolean isPublished() {
35 | return isPublished.get(0).getValue();
36 | }
37 |
38 | public int getInt(ArrayList int_i) {
39 | return int_i.get(0).getValue();
40 | }
41 | public String getString(ArrayList i) {
42 | return i.get(0).getValue();
43 | }
44 | public String getTargetId(ArrayList i) {
45 | return i.get(0).getValue();
46 | }
47 |
48 | public boolean isPromoted() {
49 | return isPromoted.get(0).getValue();
50 | }
51 |
52 | public void setPublished(boolean status) {
53 | fieldBooleanValue fbValue = new fieldBooleanValue();
54 | fbValue.setValue(status);
55 | isPublished = new ArrayList();
56 | isPublished.add(fbValue);
57 | }
58 |
59 | public void setPromoted(boolean status) {
60 | fieldBooleanValue fbValue = new fieldBooleanValue();
61 | fbValue.setValue(status);
62 | isPromoted = new ArrayList();
63 | isPromoted.add(fbValue);
64 | }
65 |
66 | public void setNodeType(String type) {
67 | fieldTargetIdValue fbValue = new fieldTargetIdValue();
68 | fbValue.setValue(type);
69 | nodeType = new ArrayList();
70 | nodeType.add(fbValue);
71 | }
72 |
73 |
74 | }
--------------------------------------------------------------------------------