Commit c283d97e authored by Alan McNatty's avatar Alan McNatty
Browse files

This is another major phase of work in getting the upload API working for Journals.

A lot of additonal internal fiddling - we're getting closer to the desired end result but there is still some refactoring to do.
TODO:
1) our Artefact object will become an Upload object (name only really).
2) the files / attachments should be visable on the upload/post settings UI
3) on the back-end upload API sie - check for a Journal post with the same title and description. If one exists - attach the additional file and move on. Saves creating lots of duplicate (looking) journal posts
4) add the Journal name to the main UI (consider also adding an icon for file or compose so the type can be easily seen)
5) review the add / delete philosophy of the sync adapter - may be an easy solution - check for existing, etc and add and remove those not seen.
6) testing - especially the sync of saved posts but also from startup - if auth success trigger a sync etc.
7) review useof notifications - seem very noisey if lots of uploads are done.
parent 30d82bdf
......@@ -101,8 +101,8 @@
</application>
<!-- API Level 4 aka 1.6 required for multi-send support -->
<!-- API Level 5 aka 2.0 required for Account & Sync support -->
<!-- API Level 7 aka 2.2 required for (filtered) Account & Sync Intent support -->
<uses-sdk android:minSdkVersion="7" />
<!-- API Level 8 aka 2.2 required for (filtered) Account & Sync Intent support -->
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
......
......@@ -82,7 +82,7 @@ $activity_arr = get_records_sql_array('select n.id, n.subject, n.message
where n.type=a.id and n.read=0 and '
. db_format_tsfield('n.ctime', '') . ' >= ? and n.usr= ? ',
array($lastsync + 0, $USER->id));
if ( count($activity_arr) )
if ( trim($activity_arr) != '' )
$json['activity'] = $activity_arr;
// OK - let's add tags
......
......@@ -27,12 +27,17 @@
define('INTERNAL', 1);
define('PUBLIC', 1);
define('SECTION_PLUGINTYPE', 'artefact');
define('SECTION_PLUGINNAME', 'blog');
$json = array();
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'file');
safe_require('artefact', 'blog');
if (!get_config('allowmobileuploads')) {
JSONResponse('fail', 'Mobile uploads disabled');
jsonreply( array('fail' => 'Mobile uploads disabled') );
}
$token = '';
......@@ -43,7 +48,7 @@ try {
catch (ParameterException $e) { }
if ($token == '') {
JSONResponse('fail', 'Auth token cannot be blank');
jsonreply( array('fail' => 'Auth token cannot be blank') );
}
$username = '';
......@@ -53,7 +58,7 @@ try {
catch (ParameterException $e) { }
if ($username == '') {
JSONResponse('fail', 'Username cannot be blank');
jsonreply( array('fail' => 'Username cannot be blank') );
}
$data = new StdClass;
......@@ -63,7 +68,7 @@ try {
$USER->find_by_mobileuploadtoken($token, $username);
}
catch (AuthUnknownUserException $e) {
JSONResponse('fail', 'Invalid user token');
jsonreply( array('fail' => 'Invalid user token') );
}
$data->owner = $USER->get('id'); // id of owner
......@@ -106,40 +111,102 @@ $title = '';
try {
$title = param_variable('title');
}
catch (ParameterException $e) {
// Default of the name given with the post
$title = $_FILES['userfile']['name'];
}
$title = $title ? basename($title) : get_string('file', 'artefact.file');
$data->title = ArtefactTypeFileBase::get_new_file_title($title, $data->parent, $data->owner);
catch (ParameterException $e) { }
// Set description
$description = '';
try {
$data->description = param_variable('description');
$description = param_variable('description');
}
catch (ParameterException $e) { }
// Set tags
$tags = '';
try {
$tags = explode(" ", param_variable('tags'));
}
catch (ParameterException $e) { }
$artefact_id = '';
if ( $_FILES ) {
if ( ! $title ) {
basename($_FILES['userfile']['name']);
}
try {
$data->title = ArtefactTypeFileBase::get_new_file_title($title, $data->parent, $data->owner);
$data->description = $description;
$data->tags = $tags;
$artefact_id = ArtefactTypeFile::save_uploaded_file('userfile', $data);
if ( $artefact_id ) {
$json['id'] = $artefact_id;
}
}
catch (QuotaExceededException $e) {
jsonreply( array('fail' => 'Quota exceeded' ) );
}
catch (UploadException $e) {
jsonreply( array('fail' => 'Failed to save file') );
}
}
// Check for Journal ID to add a post to
$blog = ''; $blogpost = ''; $draft = 0; $allowcomments = 1;
try {
$data->tags = explode(" ", param_variable('tags'));
$blog = param_integer('blog');
}
catch (ParameterException $e) { }
try {
$newid = ArtefactTypeFile::save_uploaded_file('userfile', $data);
$blogpost = param_integer('blogpost');
}
catch (QuotaExceededException $e) {
JSONResponse('fail', 'Quota exceeded');
catch (ParameterException $e) { }
try {
$draft = param_variable('draft');
}
catch (UploadException $e) {
JSONResponse('fail', 'Failed to save file');
catch (ParameterException $e) { }
try {
$allowcomments = param_variable('allowcomments');
}
// Here we need to create a new hash - update our own store of it and return it too the handset
JSONResponse ( "success", $USER->refresh_mobileuploadtoken($token) );
catch (ParameterException $e) { }
// Check to see if we're creating a journal entry
if ( $blog && $title && $description ) {
if (!get_record('artefact', 'id', $blog, 'owner', $USER->get('id'))) {
// Blog security is also checked closer to when blogs are added, this
// check ensures that malicious users do not even see the screen for
// adding a post to a blog that is not theirs
throw new AccessDeniedException(get_string('youarenottheownerofthisblog', 'artefact.blog'));
}
$postobj = new ArtefactTypeBlogPost($blogpost, null);
$postobj->set('title', $title);
$postobj->set('description', $description);
$postobj->set('tags', $tags);
$postobj->set('published', !$draft);
$postobj->set('allowcomments', (int) $allowcomments);
$postobj->set('parent', $blog);
$postobj->set('owner', $USER->id);
$postobj->commit();
// If we created an artefact - attach it.
if ( $artefact_id ) {
$postobj->attach($artefact_id);
}
}
// Here we need to create a new hash - update our own store of it and return it to the handset
jsonreply( array('success' => $USER->refresh_mobileuploadtoken($token) ) );
function JSONResponse ( $key, $value ) {
function jsonreply( $arr ) {
global $json;
if ( $json )
$arr['sync'] = $json;
header('Content-Type: application/json');
echo json_encode(array($key => $value));
echo json_encode($arr);
exit;
}
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/button_pressed" />
<item android:drawable="@drawable/button" />
</selector>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="true"
android:drawable="@drawable/button" />
android:drawable="@drawable/button_enabled" />
<item
android:state_enabled="false"
android:drawable="@drawable/button_disabled" />
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom_heading"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/headerBackground"
android:layout_below="@+id/middle"
>
<ImageView
android:id="@+id/saved"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/saved"
android:layout_gravity="left"
android:layout_marginLeft="10dp"
/>
<TextView android:id="@+id/saved_artefacts_header"
android:text="@string/options_menu_viewsaved"
android:layout_width="fill_parent"
android:singleLine="true"
android:layout_height="wrap_content"
style="@style/headerText"
android:layout_below="@+id/banner_text2"
android:layout_marginLeft="10dp"
android:gravity="left|bottom"
android:layout_toRightOf="@id/saved"
android:layout_centerInParent="true"
/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/bottom_heading"
android:layout_margin="5dp"
>
<ExpandableListView android:id="@+id/listView"
android:scrollbars="none"
android:choiceMode="multipleChoice"
android:fastScrollEnabled="true"
android:layout_below="@+id/saved_artefacts_header"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:headerDividersEnabled="true"
android:footerDividersEnabled="true"
android:groupIndicator="@drawable/expander_group"
/>
<TextView android:id="@+id/no_saved_artefacts"
android:text="@string/artefacts_no_saved_artefacts"
android:layout_margin="0dp"
android:layout_width="fill_parent"
android:singleLine="true"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Small"
android:layout_below="@+id/listView"
android:visibility="gone"
/>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/middle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="0dp"
>
<TextView android:id="@+id/banner_text"
android:text="@string/artefacts_banner_text"
android:layout_width="wrap_content"
android:singleLine="false"
android:layout_height="wrap_content"
android:textStyle="bold"
style="@android:style/TextAppearance.Large"
android:layout_below="@+id/banner"
/>
<TextView android:id="@+id/banner_text2"
android:text="@string/artefacts_banner_text2"
android:layout_width="fill_parent"
android:singleLine="false"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Small"
android:layout_below="@+id/banner_text"
/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom_heading"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/headerBackground"
android:layout_below="@+id/middle"
>
<ImageView
android:id="@+id/saved"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/saved"
android:layout_gravity="left"
android:layout_marginLeft="10dp"
/>
<TextView android:id="@+id/saved_artefacts_header"
android:text="@string/options_menu_viewsaved"
android:layout_width="fill_parent"
android:singleLine="true"
android:layout_height="wrap_content"
style="@style/headerText"
android:layout_below="@+id/banner_text2"
android:layout_marginLeft="10dp"
android:gravity="left|bottom"
android:layout_toRightOf="@id/saved"
android:layout_centerInParent="true"
/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/bottom_heading"
android:layout_margin="5dp"
>
<ExpandableListView android:id="@+id/listView"
android:scrollbars="none"
android:choiceMode="multipleChoice"
android:fastScrollEnabled="true"
android:layout_below="@+id/saved_artefacts_header"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:headerDividersEnabled="true"
android:footerDividersEnabled="true"
android:groupIndicator="@drawable/expander_group"
/>
<TextView android:id="@+id/no_saved_artefacts"
android:text="@string/artefacts_no_saved_artefacts"
android:layout_margin="0dp"
android:layout_width="fill_parent"
android:singleLine="true"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Small"
android:layout_below="@+id/listView"
android:visibility="gone"
/>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
......@@ -2,7 +2,8 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:gravity="right" >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
......@@ -55,7 +56,7 @@
/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom_heading"
android:id="@+id/body_heading"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/headerBackground"
......@@ -84,10 +85,10 @@
/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom"
android:id="@+id/body"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/bottom_heading"
android:layout_below="@+id/body_heading"
android:layout_margin="5dp"
>
<ExpandableListView android:id="@+id/listView"
......
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ArtifactSettingsLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"
android:orientation="vertical">
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/top"
android:padding="10dp"
android:orientation="vertical"
>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/JournalLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:text="@string/upload_journal_label"
android:layout_width="60dip"
android:layout_height="wrap_content"
android:padding="2dip"
android:layout_margin="5dip"
style="@android:style/TextAppearance.Small">
</TextView>
<Spinner
android:id="@+id/upload_journal_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ArtifactConfirmLayout"
......@@ -21,9 +43,9 @@
<CheckBox android:text="@string/upload_confirm_label"
style="@android:style/TextAppearance.Small"
android:id="@+id/chkUpload"
android:layout_width="wrap_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:layout_margin="5dip"
/>
<TextView android:text="@string/upload_confirm_text"
......@@ -31,8 +53,8 @@
android:layout_width="wrap_content"
android:singleLine="false"
android:layout_height="wrap_content"
android:padding="2dip"
android:layout_margin="10dip"
android:padding="5dip"
android:layout_margin="5dip"
style="@android:style/TextAppearance.Small">
</TextView>
</LinearLayout>
......@@ -47,15 +69,15 @@
android:id="@+id/ArtifactTitleLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView android:text="@string/upload_title_label"
android:layout_width="50dip"
android:layout_width="60dip"
android:singleLine="false"
android:layout_height="wrap_content"
android:padding="2dip"
android:layout_margin="10dip"
android:layout_margin="5dip"
style="@android:style/TextAppearance.Small">
</TextView>
......@@ -72,15 +94,15 @@
android:id="@+id/ArtifactDescriptionLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView android:text="@string/upload_description_label"
android:layout_width="50dip"
android:layout_width="60dip"
android:singleLine="false"
android:layout_height="wrap_content"
android:padding="2dip"
android:layout_margin="10dip"
android:layout_margin="5dip"
style="@android:style/TextAppearance.Small">
</TextView>
<EditText android:text=""
......@@ -95,18 +117,18 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView android:text="@string/upload_tags_label"
android:layout_width="50dip"
android:layout_width="60dip"
android:singleLine="false"
android:layout_height="wrap_content"
android:padding="2dip"
android:layout_margin="10dip"
android:layout_margin="5dip"
style="@android:style/TextAppearance.Small">
</TextView>
<EditText android:text=""
android:id="@+id/txtArtifactTags"
android:singleLine="true"
......@@ -114,12 +136,34 @@
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView android:text=""
android:layout_width="60dip"
android:singleLine="false"
android:layout_height="wrap_content"
android:padding="2dip"
android:layout_margin="5dip"
style="@android:style/TextAppearance.Small">
</TextView>
<Spinner
android:id="@+id/upload_tags_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ArtifactSettingsButtonLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_margin="5dp"
android:gravity="center_horizontal"
android:orientation="horizontal">
......@@ -158,5 +202,6 @@
android:layout_height="wrap_content"
android:visibility="invisible">
</EditText>
</LinearLayout>
</LinearLayout>
</ScrollView>
\ No newline at end of file
......@@ -3,19 +3,25 @@
<item android:id="@+id/option_camera"
android:icon= "@android:drawable/ic_menu_camera"
android:title="@string/options_menu_camera" />
<item android:id="@+id/option_account"
android:icon="@drawable/ic_menu_login"
android:title="@string/options_menu_account" />
<item android:id="@+id/about"
android:icon="@android:drawable/ic_menu_info_details"
android:title="@string/pref_menu_about" />
<item android:id="@+id/option_gallery"
android:icon= "@android:drawable/ic_menu_gallery"
android:title="@string/options_menu_gallery" />
<item android:id="@+id/option_compose"
android:icon= "@drawable/ic_menu_compose"
android:title="@string/options_menu_compose" />
<item android:id="@+id/option_pref"
android:icon= "@android:drawable/ic_menu_preferences"
android:title="@string/options_menu_prefs" />
<item android:id="@+id/option_account"
android:icon="@drawable/ic_menu_login"
android:title="@string/options_menu_account" />
<item android:id="@+id/option_upload"
android:icon="@android:drawable/ic_menu_upload"
android:title="@string/options_menu_uploadall" />
<item android:id="@+id/option_delete"
android:icon="@android:drawable/ic_delete"
android:title="@string/options_menu_deleteall" />
<item android:id="@+id/about"
android:icon="@android:drawable/ic_menu_info_details"