diff options
Diffstat (limited to 'libs/wpcomrest')
45 files changed, 1862 insertions, 0 deletions
diff --git a/libs/wpcomrest/.gitignore b/libs/wpcomrest/.gitignore new file mode 100644 index 000000000..8babf679a --- /dev/null +++ b/libs/wpcomrest/.gitignore @@ -0,0 +1,25 @@ +# generated files +build/ + +# Local configuration file (sdk path, etc) +local.properties +tools/deploy-mvn-artifact.conf + +# Intellij project files +*.iml +*.ipr +*.iws +.idea/ + +# Gradle +.gradle/ +gradle.properties + +# Idea +.idea/workspace.xml +*.iml + +# OS X +.DS_Store + +# dependencies diff --git a/libs/wpcomrest/LICENSE-GPL b/libs/wpcomrest/LICENSE-GPL new file mode 100644 index 000000000..356777934 --- /dev/null +++ b/libs/wpcomrest/LICENSE-GPL @@ -0,0 +1,279 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/libs/wpcomrest/LICENSE-MIT b/libs/wpcomrest/LICENSE-MIT new file mode 100644 index 000000000..63ecc8b97 --- /dev/null +++ b/libs/wpcomrest/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Automattic Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.
\ No newline at end of file diff --git a/libs/wpcomrest/README.md b/libs/wpcomrest/README.md new file mode 100644 index 000000000..23db4c914 --- /dev/null +++ b/libs/wpcomrest/README.md @@ -0,0 +1,26 @@ +# WordPress REST Client for Android + +## Build + +To build the library, invoke the following `gradle` command in the project root directory: + + $ ./gradlew build + +This will create an `aar` package at this location: `WordPressComRest/build/outputs/aar/WordPressComRest.aar`. Feel free to use it directly or put it in a maven repository. + +## Usage + +If you don't want to compile and host it. The easiest way to use it in your Android project is to add it as a library in your build.gradle file, don't forget to add the wordpress-mobile maven repository. For instance: + + repositories { + maven { url 'http://wordpress-mobile.github.io/WordPress-Android' } + } + + dependencies { + // use the latest 1.x version + compile 'com.automattic:wordpresscom-rest:1.+' + } + +## LICENSE + +This library is dual licensed unded MIT and GPL v2. diff --git a/libs/wpcomrest/WordPressComRest/build.gradle b/libs/wpcomrest/WordPressComRest/build.gradle new file mode 100644 index 000000000..8fa117bcf --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/build.gradle @@ -0,0 +1,31 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { classpath 'com.android.tools.build:gradle:0.12.+' } +} + +apply plugin: 'com.android.library' + +repositories { + mavenCentral() +} + +android { + defaultPublishConfig 'debug' + + compileSdkVersion 20 + buildToolsVersion "19.1.0" + + defaultConfig { + applicationId "com.wordpress.rest" + versionName "1.0.0" + versionCode 1 + minSdkVersion 14 + targetSdkVersion 20 + } +} + +dependencies { + compile 'com.mcxiaoke.volley:library:1.0.+' +} diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/AndroidManifest.xml b/libs/wpcomrest/WordPressComRest/src/androidTest/AndroidManifest.xml new file mode 100644 index 000000000..bb23b43d9 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/AndroidManifest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.wordpress.notereader.tests" + android:versionCode="1" + android:versionName="1.0"> + <!-- We add an application tag here just so that we can indicate that + this package needs to link against the android.test library, + which is needed when building test cases. --> + <application> + <uses-library android:name="android.test.runner" /> + </application> + <uses-permission android:name="android.permission.INTERNET" /> + <!-- + This declares that this application uses the instrumentation test runner targeting + the package of com.wordpress.notereader. To run the tests use the command: + "adb shell am instrument -w com.wordpress.notereader.tests/android.test.InstrumentationTestRunner" + --> + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.wordpress.notereader" + android:label="Tests for com.wordpress.notereader"/> +</manifest> diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/LoginActivity.java b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/LoginActivity.java new file mode 100644 index 000000000..07a0058e3 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/LoginActivity.java @@ -0,0 +1,91 @@ +package com.wordpress.notereader; + +import android.app.Activity; +import android.os.Bundle; +import android.content.Intent; + +import android.widget.Button; +import android.widget.EditText; + +import android.util.Log; +import android.view.View; + +import com.wordpress.rest.Oauth; +import com.wordpress.rest.OauthToken; +import com.wordpress.rest.OauthTokenResponseHandler; + +import java.util.Properties; +import java.io.InputStream; + +import org.json.JSONObject; + +public class LoginActivity extends Activity { + + private static final String OAUTH_ID_NAME="oauth.appid"; + private static final String OAUTH_SECRET_NAME="oauth.appsecret"; + private static final String OAUTH_REDIRECT_URI="oauth.redirect_uri"; + public static final String OAUTH_TOKEN_EXTRA="oauth-access-token"; + private static final String TAG="NotesLogin"; + private Properties mConfig; + + @Override + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + getConfigProperties(); + + setContentView(R.layout.login); + + final Oauth oauth = new Oauth( + mConfig.getProperty(OAUTH_ID_NAME), + mConfig.getProperty(OAUTH_SECRET_NAME), + mConfig.getProperty(OAUTH_REDIRECT_URI) + ); + + Button button = (Button) findViewById(R.id.signin_button); + final EditText usernameField = (EditText) findViewById(R.id.username); + final EditText passwordField = (EditText) findViewById(R.id.password); + + button.setOnClickListener( new View.OnClickListener(){ + public void onClick(View v){ + oauth.requestAccessToken( + usernameField.getText().toString(), + passwordField.getText().toString(), + new OauthTokenResponseHandler(){ + @Override + public void onSuccess(final OauthToken token){ + runOnUiThread(new Runnable(){ + @Override + public void run(){ + Intent result = new Intent(); + result.putExtra(OAUTH_TOKEN_EXTRA, token.toString()); + setResult(Activity.RESULT_OK, result); + finish(); + } + }); + } + @Override + public void onFailure(Throwable e, JSONObject response){ + Log.d(TAG, String.format("Failed %s", response)); + } + } + ); + } + }); + + } + + protected Properties getConfigProperties(){ + if (mConfig == null) { + mConfig = new Properties(); + InputStream stream = getResources().openRawResource(R.raw.oauth); + try { + mConfig.load(stream); + } catch(java.io.IOException e){ + mConfig = null; + Log.e(TAG, "Could not load config", e); + } + } + return mConfig; + } + +}
\ No newline at end of file diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/LoginActivityTest.java b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/LoginActivityTest.java new file mode 100644 index 000000000..8401a3b56 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/LoginActivityTest.java @@ -0,0 +1,44 @@ +package com.wordpress.notereader; + +// import com.wordpress.notereader.R; + +import android.test.ActivityInstrumentationTestCase2; +import android.test.UiThreadTest; + +import android.widget.EditText; +import android.widget.Button; + +public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> { + + private LoginActivity mActivity; + + public LoginActivityTest(){ + super("com.wordpress.notereader", LoginActivity.class); + } + + public void setUp(){ + setActivityInitialTouchMode(false); + mActivity = getActivity(); + } + + public void testInitialViewState(){ + EditText usernameField = (EditText) mActivity.findViewById(R.id.username); + Button signInButton = (Button) mActivity.findViewById(R.id.signin_button); + + assertEquals("", usernameField.getText().toString()); + assertEquals("Sign In", signInButton.getText().toString()); + } + + @UiThreadTest + public void testLogin(){ + EditText usernameField = (EditText) mActivity.findViewById(R.id.username); + EditText passwordField = (EditText) mActivity.findViewById(R.id.password); + Button signInButton = (Button) mActivity.findViewById(R.id.signin_button); + + usernameField.setText("mobiletestuser"); + passwordField.setText("password"); + + signInButton.performClick(); + + } +}
\ No newline at end of file diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/NotesActivity.java b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/NotesActivity.java new file mode 100644 index 000000000..450df9227 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/NotesActivity.java @@ -0,0 +1,183 @@ +package com.wordpress.notereader; + +import static com.wordpress.notereader.WPClient.*; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import com.loopj.android.http.JsonHttpResponseHandler; + +import android.content.SharedPreferences; +import android.app.ListActivity; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; + +import android.text.Html; + +public class NotesActivity extends ListActivity +{ + private static final int LOGIN_REQUEST_CODE=0xCC; + private static final String PREFERENCES_NAME="account-prefs"; + private static final String OAUTH_TOKEN_PREFERENCE="oauth-access-token"; + public static final String TAG="WPNotes"; + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + loadAccessTokenFromPreferences(); + setContentView(R.layout.main); + setListAdapter(new NotesAdapter(this)); + } + + @Override + public void onStart(){ + super.onStart(); + if (!isAuthenticated()) { + startLoginActivity(); + } else { + refreshNotifications(); + } + } + + public void startLoginActivity(){ + Intent intent = new Intent(this, LoginActivity.class); + startActivityForResult(intent, LOGIN_REQUEST_CODE); + } + + private void refreshNotifications(){ + get("notifications", new NotesResponseHandler()); + } + + private NotesAdapter getNotesAdapter(){ + return (NotesAdapter) getListAdapter(); + } + + private class NotesAdapter extends ArrayAdapter<Note> { + private static final int LAYOUT_ID=R.layout.note; + private static final int VIEW_ID=R.id.note_label; + public NotesAdapter(Context context){ + super(context, LAYOUT_ID, VIEW_ID); + } + + public void bindView(int position, View view){ + Log.d(TAG, String.format("Bind view for %d", position)); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent){ + View view = super.getView(position, convertView, parent); + + return view; + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data){ + Log.d(TAG, String.format("Activity finished %d with result %d", requestCode, resultCode)); + switch (requestCode) { + case LOGIN_REQUEST_CODE: + Log.d(TAG, String.format("Was result (%d) ok? %d", resultCode, Activity.RESULT_OK)); + if (resultCode == RESULT_OK) { + String accessToken = data.getStringExtra(LoginActivity.OAUTH_TOKEN_EXTRA); + setAccessToken(accessToken); + saveAccessTokenToPreferences(accessToken); + refreshNotifications(); + } + break; + + } + } + + private void loadAccessTokenFromPreferences(){ + SharedPreferences prefs = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE); + String token = prefs.getString(OAUTH_TOKEN_PREFERENCE, null); + Log.d(TAG, String.format("Retrieved access token: %s", token)); + setAccessToken(token); + } + + private void saveAccessTokenToPreferences(String token){ + Log.d(TAG, String.format("Saving access token %s", token)); + SharedPreferences.Editor prefs = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE).edit(); + prefs.putString(OAUTH_TOKEN_PREFERENCE, token); + prefs.commit(); + } + + private class NotesResponseHandler extends JsonHttpResponseHandler { + private static final String NOTES_KEY="notes"; + + @Override + public void onStart(){ + Log.d(TAG, "Fetching notes"); + } + @Override + public void onFinish(){ + Log.d(TAG, "Finished notes request"); + } + @Override + public void onFailure(Throwable error, JSONObject response){ + Log.e(TAG, String.format("Failed to retrieve notes: %s"), error); + } + + @Override + public void onFailure(Throwable error, String response){ + Log.e(TAG, String.format("Failed: %s", response), error); + } + + @Override + public void onSuccess(int statuScode, JSONObject notes){ + try { + final JSONArray notesArray = notes.getJSONArray(NOTES_KEY); + getNotesAdapter().clear(); + for (int i=0;i<notesArray.length();i++) { + JSONObject noteJson = notesArray.getJSONObject(i); + getNotesAdapter().add(new Note(noteJson)); + } + + runOnUiThread( new Runnable(){ + @Override + public void run(){ + getNotesAdapter().notifyDataSetChanged(); + } + }); + + } catch (JSONException e) { + Log.e(TAG, "Couldn't retrieve notes", e); + } + } + + } + + private class Note { + + private static final String SUBJECT_KEY="subject"; + private static final String SUBJECT_TEXT_KEY="text"; + private static final String UNKNOWN_SUBJECT="no subject"; + + private JSONObject mNoteData; + + public Note(JSONObject noteData){ + mNoteData = noteData; + } + + public String toString(){ + // try to get the subject.text property + try { + JSONObject subject = mNoteData.getJSONObject(SUBJECT_KEY); + String subjectText = subject.getString(SUBJECT_TEXT_KEY); + return Html.fromHtml(subjectText.trim()).toString(); + } catch (JSONException error) { + return UNKNOWN_SUBJECT; + } + } + + } + +} diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/WPClient.java b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/WPClient.java new file mode 100644 index 000000000..a1274f213 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/notereader/WPClient.java @@ -0,0 +1,35 @@ +package com.wordpress.notereader; + +import com.wordpress.rest.RestClient; +import com.loopj.android.http.AsyncHttpResponseHandler; +import com.loopj.android.http.RequestParams; + +public class WPClient { + + public static RestClient restClient = new RestClient(); + + public static void setAccessToken(String token){ + restClient.setAccessToken(token); + } + + public static boolean isAuthenticated(){ + return restClient.isAuthenticated(); + } + + public static void get(String path, AsyncHttpResponseHandler handler){ + restClient.get(path, handler); + } + + public static void get(String path, RequestParams params, AsyncHttpResponseHandler handler){ + restClient.get(path, params, handler); + } + + public static void notifications(AsyncHttpResponseHandler handler){ + notifications(null, handler); + } + + public static void notifications(RequestParams params, AsyncHttpResponseHandler handler){ + get("notifications", params, handler); + } + +}
\ No newline at end of file diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/rest/OauthTest.java b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/rest/OauthTest.java new file mode 100644 index 000000000..2958b8934 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/rest/OauthTest.java @@ -0,0 +1,32 @@ +package com.wordpress.rest; + +import android.test.AndroidTestCase; +import com.wordpress.rest.Oauth; + +import com.wordpress.util.TestExecutorService; + +import android.util.Log; + +public class OauthTest extends AndroidTestCase { + + public final String TAG="WordPressTest"; + + private String mAppId; + private String mAppSecret; + private String mAppRedirectURI; + private Oauth mClient; + + @Override + public void setUp(){ + mClient = new Oauth(mAppId, mAppSecret, mAppRedirectURI); + } + + public void testRequestAuthorizationURL(){ + String url = mClient.getAuthorizationURL(); + + String expected = String.format("https://public-api.wordpress.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code", mClient.getAppID(), mClient.getAppSecret(), mClient.getAppRedirectURI()); + assertEquals(expected, url); + } + + +}
\ No newline at end of file diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/rest/RestClientTest.java b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/rest/RestClientTest.java new file mode 100644 index 000000000..7fa2053f1 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/rest/RestClientTest.java @@ -0,0 +1,26 @@ +package com.wordpress.rest; + +import android.test.AndroidTestCase; + +public class RestClientTest extends AndroidTestCase { + + public void testGetAbsoluteURLWithPath(){ + String path = "me"; + String url = RestClient.getAbsoluteURL(path); + String expected = String.format("%s%s", RestClient.REST_API_ENDPOINT_URL, path); + assertEquals(expected, url); + } + + public void testGetAbsoluteURLWithLeadingSlash(){ + String path = "/sites/mobileprojects.wordpress.com/posts"; + String url = RestClient.getAbsoluteURL(path); + String expected = String.format("https://public-api.wordpress.com/rest/v1%s", path); + assertEquals(expected, url); + } + + public void testGetAbsoluteURLWithFullURL(){ + String expected = String.format("%s%s", RestClient.REST_API_ENDPOINT_URL, "notes"); + assertEquals(expected, RestClient.getAbsoluteURL(expected)); + } + +}
\ No newline at end of file diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/util/TestExecutorService.java b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/util/TestExecutorService.java new file mode 100644 index 000000000..0ff3189e3 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/java/src/com/wordpress/util/TestExecutorService.java @@ -0,0 +1,20 @@ +package com.wordpress.util; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.FutureTask; +import java.util.concurrent.Future; +import java.util.concurrent.BlockingQueue; + +public class TestExecutorService extends ThreadPoolExecutor { + public TestExecutorService(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); + } + + @Override + public Future<?> submit(Runnable runnable) { + FutureTask futureTask = new FutureTask(runnable, null); + futureTask.run(); // or queue this future to be run when you want it to be run + return futureTask; + } +} diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-hdpi/ic_launcher.png b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..96a442e5b --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-hdpi/ic_launcher.png diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-ldpi/ic_launcher.png b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-ldpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..99238729d --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-ldpi/ic_launcher.png diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-mdpi/ic_launcher.png b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..359047dfa --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-mdpi/ic_launcher.png diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-xhdpi/ic_launcher.png b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..71c6d760f --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/drawable-xhdpi/ic_launcher.png diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/login.xml b/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/login.xml new file mode 100644 index 000000000..d38f3cc88 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/login.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:padding="10dp" + > + <EditText android:id="@+id/username" + android:hint="@string/username_hint" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + <EditText android:id="@+id/password" + android:hint="@string/password_hint" + android:password="true" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="10dp" /> + <Button android:id="@+id/signin_button" + android:text="@string/signin_label" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> +</LinearLayout> + diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/main.xml b/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/main.xml new file mode 100644 index 000000000..6bf742217 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/main.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + > + <ListView android:id="@android:id/list" + android:layout_width="fill_parent" + android:layout_height="fill_parent" /> + <TextView + android:id="@android:id/empty" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/no_notifications" /> +</LinearLayout> + diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/note.xml b/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/note.xml new file mode 100644 index 000000000..4fab73b9f --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/layout/note.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:padding="8sp" + > + <LinearLayout + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + <ImageView + android:id="@+id/note_image" + android:layout_width="48sp" + android:layout_height="48sp" + android:scaleType="fitCenter" /> + <TextView + android:id="@+id/note_label" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:textSize="16sp" + android:gravity="fill" /> + </LinearLayout> +</LinearLayout> + diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/raw/oauth.properties b/libs/wpcomrest/WordPressComRest/src/androidTest/res/raw/oauth.properties new file mode 100644 index 000000000..fa5b5d7b2 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/raw/oauth.properties @@ -0,0 +1,3 @@ +oauth.appid=11 +oauth.appsecret=zf66wMPjz0BNohvOLsfYGyM2YbxwgVEVyiXXQDcVwzK73JDOPPuhrvCuoln0Ul9o +oauth.redirect_uri=https://wordpress.com/
\ No newline at end of file diff --git a/libs/wpcomrest/WordPressComRest/src/androidTest/res/values/strings.xml b/libs/wpcomrest/WordPressComRest/src/androidTest/res/values/strings.xml new file mode 100644 index 000000000..f8f6bccd9 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/androidTest/res/values/strings.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Notes</string> + <string name="signin_label">Sign In</string> + <string name="username_hint">Username</string> + <string name="password_hint">Password</string> + <string name="no_notifications">No notifications</string> +</resources> diff --git a/libs/wpcomrest/WordPressComRest/src/main/AndroidManifest.xml b/libs/wpcomrest/WordPressComRest/src/main/AndroidManifest.xml new file mode 100644 index 000000000..95a7bbddc --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/main/AndroidManifest.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.wordpress.rest" + android:versionCode="1" + android:versionName="1.0"> + <uses-sdk android:minSdkVersion="3" /> + <uses-permission android:name="android.permission.INTERNET" /> +</manifest> diff --git a/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/Oauth.java b/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/Oauth.java new file mode 100644 index 000000000..250921772 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/Oauth.java @@ -0,0 +1,168 @@ +package com.wordpress.rest; + +import com.android.volley.NetworkResponse; +import com.android.volley.ParseError; +import com.android.volley.Response; +import com.android.volley.toolbox.HttpHeaderParser; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +public class Oauth { + public static final String TAG = "WordPressREST"; + + public static final String AUTHORIZE_ENDPOINT = "https://public-api.wordpress.com/oauth2/authorize"; + private static final String AUTHORIZED_ENDPOINT_FORMAT = "%s?client_id=%s&redirect_uri=%s&response_type=code"; + + public static final String TOKEN_ENDPOINT = "https://public-api.wordpress.com/oauth2/token"; + + public static final String CLIENT_ID_PARAM_NAME = "client_id"; + public static final String REDIRECT_URI_PARAM_NAME = "redirect_uri"; + public static final String CLIENT_SECRET_PARAM_NAME = "client_secret"; + public static final String CODE_PARAM_NAME = "code"; + public static final String GRANT_TYPE_PARAM_NAME = "grant_type"; + public static final String USERNAME_PARAM_NAME = "username"; + public static final String PASSWORD_PARAM_NAME = "password"; + + public static final String PASSWORD_GRANT_TYPE = "password"; + public static final String BEARER_GRANT_TYPE = "bearer"; + public static final String AUTHORIZATION_CODE_GRANT_TYPE = "authorization_code"; + + private String mAppId; + private String mAppSecret; + private String mAppRedirectURI; + + public interface Listener extends Response.Listener<Token> { + } + public interface ErrorListener extends Response.ErrorListener { + } + + public Oauth(String appId, String appSecret, String redirectURI) { + mAppId = appId; + mAppSecret = appSecret; + mAppRedirectURI = redirectURI; + } + + public String getAppID() { + return mAppId; + } + + public String getAppSecret() { + return mAppSecret; + } + + public String getAppRedirectURI() { + return mAppRedirectURI; + } + + public String getAuthorizationURL() { + return String.format(AUTHORIZED_ENDPOINT_FORMAT, AUTHORIZE_ENDPOINT, getAppID(), getAppRedirectURI()); + } + + public Request makeRequest(String username, String password, Listener listener, ErrorListener errorListener) { + return new PasswordRequest(getAppID(), getAppSecret(), getAppRedirectURI(), username, password, listener, + errorListener); + } + + public Request makeRequest(String code, Listener listener, ErrorListener errorListener) { + return new BearerRequest(getAppID(), getAppSecret(), getAppRedirectURI(), code, listener, errorListener); + } + + private static class Request extends com.android.volley.Request<Token> { + private final Listener mListener; + protected Map<String, String> mParams = new HashMap<String, String>(); + + Request(String appId, String appSecret, String redirectUri, Listener listener, ErrorListener errorListener) { + super(Method.POST, TOKEN_ENDPOINT, errorListener); + mListener = listener; + mParams.put(CLIENT_ID_PARAM_NAME, appId); + mParams.put(CLIENT_SECRET_PARAM_NAME, appSecret); + mParams.put(REDIRECT_URI_PARAM_NAME, redirectUri); + } + + @Override + public Map<String, String> getParams() { + return mParams; + } + + @Override + public void deliverResponse(Token token) { + mListener.onResponse(token); + } + + @Override + protected Response<Token> parseNetworkResponse(NetworkResponse response) { + try { + String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); + JSONObject tokenData = new JSONObject(jsonString); + return Response.success(Token.fromJSONObject(tokenData), HttpHeaderParser.parseCacheHeaders(response)); + } catch (UnsupportedEncodingException e) { + return Response.error(new ParseError(e)); + } catch (JSONException je) { + return Response.error(new ParseError(je)); + } + } + } + + public static class PasswordRequest extends Request { + + public PasswordRequest(String appId, String appSecret, String redirectUri, String username, String password, + Listener listener, ErrorListener errorListener) { + super(appId, appSecret, redirectUri, listener, errorListener); + mParams.put(USERNAME_PARAM_NAME, username); + mParams.put(PASSWORD_PARAM_NAME, password); + mParams.put(GRANT_TYPE_PARAM_NAME, PASSWORD_GRANT_TYPE); + } + } + + public static class BearerRequest extends Request { + + public BearerRequest(String appId, String appSecret, String redirectUri, String code, Listener listener, + ErrorListener errorListener) { + super(appId, appSecret, redirectUri, listener, errorListener); + mParams.put(CODE_PARAM_NAME, code); + mParams.put(GRANT_TYPE_PARAM_NAME, BEARER_GRANT_TYPE); + } + } + + public static class Token { + + private static final String TOKEN_TYPE_FIELD_NAME = "token_type"; + private static final String ACCESS_TOKEN_FIELD_NAME = "access_token"; + private static final String BLOG_URL_FIELD_NAME = "blog_url"; + private static final String SCOPE_FIELD_NAME = "scope"; + private static final String BLOG_ID_FIELD_NAME = "blog_id"; + + private String mTokenType; + private String mScope; + private String mAccessToken; + private String mBlogUrl; + private String mBlogId; + + public Token(String accessToken, String blogUrl, String blogId, String scope, String tokenType) { + mAccessToken = accessToken; + mBlogUrl = blogUrl; + mBlogId = blogId; + mScope = scope; + mTokenType = tokenType; + } + + public String getAccessToken() { + return mAccessToken; + } + + public String toString() { + return getAccessToken(); + } + + public static Token fromJSONObject(JSONObject tokenJSON) throws JSONException { + return new Token(tokenJSON.getString(ACCESS_TOKEN_FIELD_NAME), tokenJSON.getString(BLOG_URL_FIELD_NAME), + tokenJSON.getString(BLOG_ID_FIELD_NAME), tokenJSON.getString(SCOPE_FIELD_NAME), tokenJSON.getString( + TOKEN_TYPE_FIELD_NAME)); + } + } +}
\ No newline at end of file diff --git a/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/RestClient.java b/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/RestClient.java new file mode 100644 index 000000000..5320f679c --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/RestClient.java @@ -0,0 +1,101 @@ +package com.wordpress.rest; + +import com.android.volley.Request.Method; +import com.android.volley.RequestQueue; +import com.android.volley.Response.ErrorListener; +import com.android.volley.Response.Listener; + +import org.json.JSONObject; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; + +public class RestClient { + public static final String TAG = "WordPressREST"; + public static final String REST_API_ENDPOINT_URL = "https://public-api.wordpress.com/rest/v1/"; + public static final String PARAMS_ENCODING = "UTF-8"; + + private RequestQueue mQueue; + private String mAccessToken; + private String mUserAgent; + + public RestClient(RequestQueue queue) { + mQueue = queue; + } + + public RestClient(RequestQueue queue, String token) { + this(queue); + mAccessToken = token; + } + + public RestRequest get(String path, Listener<JSONObject> listener, ErrorListener errorListener) { + return makeRequest(Method.GET, getAbsoluteURL(path), null, listener, errorListener); + } + + public RestRequest post(String path, Map<String, String> body, Listener<JSONObject> listener, + ErrorListener errorListener) { + return makeRequest(Method.POST, getAbsoluteURL(path), body, listener, errorListener); + } + + public RestRequest makeRequest(int method, String url, Map<String, String> params, Listener<JSONObject> listener, + ErrorListener errorListener) { + RestRequest request = new RestRequest(method, url, params, listener, errorListener); + request.setUserAgent(mUserAgent); + request.setAccessToken(mAccessToken); + return request; + } + + public RestRequest send(RestRequest request) { + // Volley send the request + mQueue.add(request); + return request; + } + + public static String getAbsoluteURL(String url) { + // if it already starts with our endpoint, let it pass through + if (url.indexOf(REST_API_ENDPOINT_URL) == 0) { + return url; + } + // if it has a leading slash, remove it + if (url.indexOf("/") == 0) { + url = url.substring(1); + } + // prepend the endpoint + return String.format("%s%s", REST_API_ENDPOINT_URL, url); + } + + public static String getAbsoluteURL(String path, Map<String, String> params) { + String url = getAbsoluteURL(path); + if (params != null) { + // build a query string + StringBuilder query = new StringBuilder(); + try { + for (Map.Entry<String, String> entry : params.entrySet()) { + query.append(URLEncoder.encode(entry.getKey(), PARAMS_ENCODING)); + query.append("="); + query.append(URLEncoder.encode(entry.getValue(), PARAMS_ENCODING)); + query.append("&"); + } + } catch (UnsupportedEncodingException uee) { + throw new RuntimeException("Encoding not supported: " + PARAMS_ENCODING, uee); + } + url = String.format("%s?%s", url, query); + } + return url; + } + + //Sets the User-Agent header to be sent with each future request. + public void setUserAgent(String userAgent) { + mUserAgent = userAgent; + } + + // Sets the auth token to be used in the request header + public void setAccessToken(String token) { + mAccessToken = token; + } + + public boolean isAuthenticated() { + return mAccessToken != null; + } +} diff --git a/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/RestRequest.java b/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/RestRequest.java new file mode 100644 index 000000000..8ad4653d5 --- /dev/null +++ b/libs/wpcomrest/WordPressComRest/src/main/java/com/wordpress/rest/RestRequest.java @@ -0,0 +1,83 @@ +package com.wordpress.rest; + +import com.android.volley.NetworkResponse; +import com.android.volley.ParseError; +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.toolbox.HttpHeaderParser; + +import org.json.JSONObject; +import org.json.JSONException; + +import java.util.Map; +import java.util.HashMap; + +import java.io.UnsupportedEncodingException; + +public class RestRequest extends Request<JSONObject> { + public static final String USER_AGENT_HEADER = "User-Agent"; + public static final String REST_AUTHORIZATION_HEADER = "Authorization"; + public static final String REST_AUTHORIZATION_FORMAT = "Bearer %s"; + + public interface Listener extends Response.Listener<JSONObject> { + } //This is just a shortcut for Response.Listener<JSONObject> + public interface ErrorListener extends Response.ErrorListener { + } //This is just a shortcut for Response.ErrorListener + + private final com.android.volley.Response.Listener<JSONObject> mListener; + private final Map<String, String> mParams; + private final Map<String, String> mHeaders = new HashMap<String, String>(2); + + public RestRequest(int method, String url, Map<String, String> params, + com.android.volley.Response.Listener<JSONObject> listener, + com.android.volley.Response.ErrorListener errorListener) { + super(method, url, errorListener); + mParams = params; + mListener = listener; + } + + public void removeAccessToken() { + setAccessToken(null); + } + + public void setAccessToken(String token) { + if (token == null) { + mHeaders.remove(REST_AUTHORIZATION_HEADER); + } else { + mHeaders.put(REST_AUTHORIZATION_HEADER, String.format(REST_AUTHORIZATION_FORMAT, token)); + } + } + + public void setUserAgent(String userAgent) { + mHeaders.put(USER_AGENT_HEADER, userAgent); + } + + @Override + public Map<String, String> getHeaders() { + return mHeaders; + } + + @Override + protected void deliverResponse(JSONObject response) { + if (mListener != null) { + mListener.onResponse(response); + } + } + + @Override + protected Map<String, String> getParams() { + return mParams; + } + + @Override + protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { + try { + String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); + return Response.success(new JSONObject(jsonString), HttpHeaderParser.parseCacheHeaders(response)); + } catch (UnsupportedEncodingException e) { + return Response.error(new ParseError(e)); + } catch (JSONException je) { + return Response.error(new ParseError(je)); + } + } +} diff --git a/libs/wpcomrest/build.gradle b/libs/wpcomrest/build.gradle new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/libs/wpcomrest/build.gradle diff --git a/libs/wpcomrest/gradle/wrapper/gradle-wrapper.jar b/libs/wpcomrest/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 000000000..0087cd3b1 --- /dev/null +++ b/libs/wpcomrest/gradle/wrapper/gradle-wrapper.jar diff --git a/libs/wpcomrest/gradle/wrapper/gradle-wrapper.properties b/libs/wpcomrest/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..55431dfe6 --- /dev/null +++ b/libs/wpcomrest/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Jul 10 14:47:28 CEST 2014 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip diff --git a/libs/wpcomrest/gradlew b/libs/wpcomrest/gradlew new file mode 100755 index 000000000..91a7e269e --- /dev/null +++ b/libs/wpcomrest/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/libs/wpcomrest/gradlew.bat b/libs/wpcomrest/gradlew.bat new file mode 100644 index 000000000..8a0b282aa --- /dev/null +++ b/libs/wpcomrest/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/libs/wpcomrest/settings.gradle b/libs/wpcomrest/settings.gradle new file mode 100644 index 000000000..473ceab34 --- /dev/null +++ b/libs/wpcomrest/settings.gradle @@ -0,0 +1 @@ +include ':WordPressComRest' diff --git a/libs/wpcomrest/test/.gitignore b/libs/wpcomrest/test/.gitignore new file mode 100644 index 000000000..81e9c938d --- /dev/null +++ b/libs/wpcomrest/test/.gitignore @@ -0,0 +1,3 @@ +bin/* +local.properties +gen/*
\ No newline at end of file diff --git a/libs/wpcomrest/test/ant.properties b/libs/wpcomrest/test/ant.properties new file mode 100644 index 000000000..02634db80 --- /dev/null +++ b/libs/wpcomrest/test/ant.properties @@ -0,0 +1,18 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + +tested.project.dir=./app diff --git a/libs/wpcomrest/test/app/.gitignore b/libs/wpcomrest/test/app/.gitignore new file mode 100644 index 000000000..81e9c938d --- /dev/null +++ b/libs/wpcomrest/test/app/.gitignore @@ -0,0 +1,3 @@ +bin/* +local.properties +gen/*
\ No newline at end of file diff --git a/libs/wpcomrest/test/app/AndroidManifest.xml b/libs/wpcomrest/test/app/AndroidManifest.xml new file mode 100644 index 000000000..a1ea8b431 --- /dev/null +++ b/libs/wpcomrest/test/app/AndroidManifest.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.wordpress.notereader" + android:versionCode="1" + android:versionName="1.0"> + <application android:label="@string/app_name" android:icon="@drawable/ic_launcher"> + <activity android:name="NotesActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name=".LoginActivity" /> + </application> + <uses-permission android:name="android.permission.INTERNET" /> +</manifest> diff --git a/libs/wpcomrest/test/app/ant.properties b/libs/wpcomrest/test/app/ant.properties new file mode 100644 index 000000000..b0971e891 --- /dev/null +++ b/libs/wpcomrest/test/app/ant.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/libs/wpcomrest/test/app/build.xml b/libs/wpcomrest/test/app/build.xml new file mode 100644 index 000000000..b05b8e9e5 --- /dev/null +++ b/libs/wpcomrest/test/app/build.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="NotesActivity" default="help"> + + <!-- The local.properties file is created and updated by the 'android' tool. + It contains the path to the SDK. It should *NOT* be checked into + Version Control Systems. --> + <property file="local.properties" /> + + <!-- The ant.properties file can be created by you. It is only edited by the + 'android' tool to add properties to it. + This is the place to change some Ant specific build properties. + Here are some properties you may want to change/update: + + source.dir + The name of the source directory. Default is 'src'. + out.dir + The name of the output directory. Default is 'bin'. + + For other overridable properties, look at the beginning of the rules + files in the SDK, at tools/ant/build.xml + + Properties related to the SDK location or the project target should + be updated using the 'android' tool with the 'update' action. + + This file is an integral part of the build system for your + application and should be checked into Version Control Systems. + + --> + <property file="ant.properties" /> + + <!-- if sdk.dir was not set from one of the property file, then + get it from the ANDROID_HOME env var. + This must be done before we load project.properties since + the proguard config can use sdk.dir --> + <property environment="env" /> + <condition property="sdk.dir" value="${env.ANDROID_HOME}"> + <isset property="env.ANDROID_HOME" /> + </condition> + + <!-- The project.properties file is created and updated by the 'android' + tool, as well as ADT. + + This contains project specific properties such as project target, and library + dependencies. Lower level build properties are stored in ant.properties + (or in .classpath for Eclipse projects). + + This file is an integral part of the build system for your + application and should be checked into Version Control Systems. --> + <loadproperties srcFile="project.properties" /> + + <!-- quick check on sdk.dir --> + <fail + message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." + unless="sdk.dir" + /> + + <!-- + Import per project custom build rules if present at the root of the project. + This is the place to put custom intermediary targets such as: + -pre-build + -pre-compile + -post-compile (This is typically used for code obfuscation. + Compiled code location: ${out.classes.absolute.dir} + If this is not done in place, override ${out.dex.input.absolute.dir}) + -post-package + -post-build + -pre-clean + --> + <import file="custom_rules.xml" optional="true" /> + + <!-- Import the actual build file. + + To customize existing targets, there are two options: + - Customize only one target: + - copy/paste the target into this file, *before* the + <import> task. + - customize it to your needs. + - Customize the whole content of build.xml + - copy/paste the content of the rules files (minus the top node) + into this file, replacing the <import> task. + - customize to your needs. + + *********************** + ****** IMPORTANT ****** + *********************** + In all cases you must update the value of version-tag below to read 'custom' instead of an integer, + in order to avoid having your file be overridden by tools such as "android update project" + --> + <!-- version-tag: 1 --> + <import file="${sdk.dir}/tools/ant/build.xml" /> + +</project> diff --git a/libs/wpcomrest/test/app/proguard-project.txt b/libs/wpcomrest/test/app/proguard-project.txt new file mode 100644 index 000000000..f2fe1559a --- /dev/null +++ b/libs/wpcomrest/test/app/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/libs/wpcomrest/test/app/project.properties b/libs/wpcomrest/test/app/project.properties new file mode 100644 index 000000000..fe8b84557 --- /dev/null +++ b/libs/wpcomrest/test/app/project.properties @@ -0,0 +1,15 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-16 +android.library.reference.1=../../ diff --git a/libs/wpcomrest/test/build.xml b/libs/wpcomrest/test/build.xml new file mode 100644 index 000000000..7f26967c7 --- /dev/null +++ b/libs/wpcomrest/test/build.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="NoteReaderTest" default="help"> + + <!-- The local.properties file is created and updated by the 'android' tool. + It contains the path to the SDK. It should *NOT* be checked into + Version Control Systems. --> + <property file="local.properties" /> + + <!-- The ant.properties file can be created by you. It is only edited by the + 'android' tool to add properties to it. + This is the place to change some Ant specific build properties. + Here are some properties you may want to change/update: + + source.dir + The name of the source directory. Default is 'src'. + out.dir + The name of the output directory. Default is 'bin'. + + For other overridable properties, look at the beginning of the rules + files in the SDK, at tools/ant/build.xml + + Properties related to the SDK location or the project target should + be updated using the 'android' tool with the 'update' action. + + This file is an integral part of the build system for your + application and should be checked into Version Control Systems. + + --> + <property file="ant.properties" /> + + <!-- if sdk.dir was not set from one of the property file, then + get it from the ANDROID_HOME env var. + This must be done before we load project.properties since + the proguard config can use sdk.dir --> + <property environment="env" /> + <condition property="sdk.dir" value="${env.ANDROID_HOME}"> + <isset property="env.ANDROID_HOME" /> + </condition> + + <!-- The project.properties file is created and updated by the 'android' + tool, as well as ADT. + + This contains project specific properties such as project target, and library + dependencies. Lower level build properties are stored in ant.properties + (or in .classpath for Eclipse projects). + + This file is an integral part of the build system for your + application and should be checked into Version Control Systems. --> + <loadproperties srcFile="project.properties" /> + + <!-- quick check on sdk.dir --> + <fail + message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." + unless="sdk.dir" + /> + + <!-- + Import per project custom build rules if present at the root of the project. + This is the place to put custom intermediary targets such as: + -pre-build + -pre-compile + -post-compile (This is typically used for code obfuscation. + Compiled code location: ${out.classes.absolute.dir} + If this is not done in place, override ${out.dex.input.absolute.dir}) + -post-package + -post-build + -pre-clean + --> + <import file="custom_rules.xml" optional="true" /> + + <!-- Import the actual build file. + + To customize existing targets, there are two options: + - Customize only one target: + - copy/paste the target into this file, *before* the + <import> task. + - customize it to your needs. + - Customize the whole content of build.xml + - copy/paste the content of the rules files (minus the top node) + into this file, replacing the <import> task. + - customize to your needs. + + *********************** + ****** IMPORTANT ****** + *********************** + In all cases you must update the value of version-tag below to read 'custom' instead of an integer, + in order to avoid having your file be overridden by tools such as "android update project" + --> + <!-- version-tag: 1 --> + <import file="${sdk.dir}/tools/ant/build.xml" /> + +</project> diff --git a/libs/wpcomrest/test/proguard-project.txt b/libs/wpcomrest/test/proguard-project.txt new file mode 100644 index 000000000..f2fe1559a --- /dev/null +++ b/libs/wpcomrest/test/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/libs/wpcomrest/test/project.properties b/libs/wpcomrest/test/project.properties new file mode 100644 index 000000000..9b84a6b4b --- /dev/null +++ b/libs/wpcomrest/test/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-16 diff --git a/libs/wpcomrest/tools/deploy-mvn-artifact.conf-example b/libs/wpcomrest/tools/deploy-mvn-artifact.conf-example new file mode 100644 index 000000000..5aaf644ad --- /dev/null +++ b/libs/wpcomrest/tools/deploy-mvn-artifact.conf-example @@ -0,0 +1 @@ +LOCAL_GH_PAGES=file:///Users/max/work/automattic/WordPress-Android-gh-pages/ diff --git a/libs/wpcomrest/tools/deploy-mvn-artifact.sh b/libs/wpcomrest/tools/deploy-mvn-artifact.sh new file mode 100755 index 000000000..e76998f93 --- /dev/null +++ b/libs/wpcomrest/tools/deploy-mvn-artifact.sh @@ -0,0 +1,19 @@ +#!/bin/sh +v + +. tools/deploy-mvn-artifact.conf +PROJECT=WordPressComRest +VERSION=`grep -E 'versionName' $PROJECT/build.gradle \ + | sed s/versionName// \ + | grep -Eo "[a-zA-Z0-9.-]+"` +GROUPID=com.automattic +ARTIFACTID=wordpresscom-rest +AARFILE=$PROJECT/build/outputs/aar/WordPressComRest.aar + +# Deploy release build +mvn deploy:deploy-file -Dfile=$AARFILE \ + -Durl=$LOCAL_GH_PAGES -DgroupId=$GROUPID \ + -DartifactId=$ARTIFACTID -Dversion=$VERSION + +echo ======================================== +echo +echo \"$GROUPID:$ARTIFACTID:$VERSION\" deployed
\ No newline at end of file |