Upload assignment on Moodle using REST webservice function - android

I am trying to develop a Moodle Android app. I am using MoodleREST source code for my reference. But rest code to upload assignment is not provided by this library. I want to be able to upload assignment from mobile client with a webservice call. Uploading assignment using a webview is possible but in that case user need to login again to access upload assignment page.
I have found something similar here https://moodle.org/mod/forum/discuss.php?d=207875.
I am new to moodle and still learning it, so my question can be a little naive so please bear with it :)

It is kind of possible to upload a submission with a file to the assignment using Moodle webservices.
First upload a file to draft using core_files_upload
http://my-moodle-url/moodle/webservice/rest/server.php?wstoken=token_value_xyz&moodlewsrestformat=json&wsfunction=core_files_upload&component=user&filearea=draft&itemid=0&filepath=/&filename=test2.txt&filecontent=TWFuIGlzIGRpc3Rpbmd1aXNoZWQ=&contextlevel=user&instanceid=8
where:
itemid=0 - moodle will generate and return an itemid or you set itemid
filecontent - base64 encoded file contents
instanceid - userId whose is webservices token
Sample response:
{
"contextid": 26,
"component": "user",
"filearea": "draft",
"itemid": 293005570,
"filepath": "/",
"filename": "test3.txt",
"url": "http://my-moodle-url/moodle/draftfile.php/26/user/draft/293005570/test3.txt"
}
You can search for an assignment id for the next call with mod_assign_get_assignments
Then use itemid received, here "293005570", in mod_assign_save_submission
http://my-moodle-url/moodle/webservice/rest/server.php?wstoken=token_value_xyz&moodlewsrestformat=json&wsfunction=mod_assign_save_submission&assignmentid=5&plugindata[onlinetext_editor][text]
=some_text_here&plugindata[onlinetext_editor][format]
=1&plugindata[onlinetext_editor][itemid]=521767865&plugindata[files_filemanager]=521767865
This will add an assignment submission with this file.
The problem I could core_files_upload and mod_assign_save_submission only using a webservices token for a particular user, i.e. each user needs a webservices token which might be not practical. With a webservices user token I get on the first call:
{
"exception": "moodle_exception",
"errorcode": "nofile",
"message": "File not specified"
}
Tested with Postman. This might be related: https://tracker.moodle.org/browse/MDL-61276

Doesnt look like there is existing solution for this in moodle web services. Moodle actually encodes files in base64 which creates burden on mobile devices. Mobile devices dont have that much memory to encode big files.
Closet solution published by Moodle HQ (and otherwise) is this : https://github.com/moodlehq/sample-ws-clients/blob/master/PHP-HTTP-filehandling/client.php which saves file as private file and not as assignment. You may have to modify substantially the plugin.

To upload files I'm using this API with a POST method
https://{YOUR_URL}/webservice/upload.php?moodlewsrestformat=json&wstoken={WSTOKEN}
And you must pass the following parameters as FormData
file => File // your file
token => Int // same user's wstoken
filearea => String // draft, private... etc
itemid => Int // set to 0 to create a new file

Related

Android , How to access SharePoint data?

Basically , I wanted the files in my Company Sharepoint after reading documents provide by microsoft. By using Microsoft Graph authentication API I be able to receive authenticationResult.accessToken by following this example https://github.com/AzureAD/microsoft-authentication-library-for-android
After that I request https://graph.microsoft.com/v1.0/sites/{Mycompany}.sharepoint.com/drives/{Drives ID}/list/items
the response is all the items in that drives.
But
I want to get specific file to display in my application by add item ID
https://graph.microsoft.com/v1.0/sites/{Mycompany}.sharepoint.com/drives/{Drives ID}/list/items/{Item ID}
I got this error
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token is empty.",
"innerError": {
"date": "2021-02-03T04:57:08",
"request-id": "65b170a7-b864-470e-a1e5-23be9851dd7a",
"client-request-id": "65b170a7-b864-470e-a1e5-23be9851dd7a"
}
}
}
After reading through some Document to find out what wrong with it I'm start to confused with it. Some Document using https://{{tenantName}}.sharepoint.com/Sites.Read.All without using Graph API
example (https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service?tabs=csom)
but this didn't work out for me. Can you guys guide me how this is all work? and how to receive folder and document in Sharepoint
Note
I'm not an expert in Android and new to this kind of stuff.
thank you
The above error is because there is no access token when you were calling the Graph API call. Make sure you pass the header with the HTTP call having access token in Authorization parameter. As suggested by #Dev you can also check in https://jwt.ms and see the access token claims. You can also try the below HTTP call.
https://graph.microsoft.com/v1.0/sites/{siteid}/lists/{listid}/items/{itemid}
in Graph Explorer and you could find the difference.

Custom SignUpURL in Android Management API

I am trying to implement Android Management API in my project where the first step is to create an enterprise:
Post the Callbackurl and ProjectID to the Following URL
https://androidmanagement.googleapis.com/v1/signupUrls
I get the response name and url:
{
"name": "signupUrls/C265d41bc093bdd97",
"url": "https://play.google.com/work/adminsignup?token=someToken"
}
How can I Change this "url" parameter to my own. Do I require to upload my DPC to playstore?
I am out of guesses. please help
Thanks in advance.
The flow is this:
1) Create a Project in Google developer console, enable Android Management API, create credentials and get the project id. (I think you already done that).
2) Create a SignupUrl with signupUrls.create. (What you have done to get that JSON)
3) Keep the SignupUrl Name and redirect the user (or go) to the returned URL (inside the JSON posted).
3) Follow the procedure to create an enterprise.
This will start the creation of an enterprise to the signed Google Account.
4) At the end of the procedure you will be redirected to the callbackUrl specified inside signupUrls.create. Appended to the callbackUrl, as a GET query parameter, will be a token.
5) You must use the appended token to conclude the flow calling the API enterprises.create with these parameters:
The signup url name
The enterprise token returned as parameter
(optional) a request body with some enterprise parameters (logo, name, etc)
At the end of this coming and going between URLs and API calls, you will end with an Enterprise created on the Google Account and the enterprise ID in the form enterprise/<yourID> to interact with the API.
You can check all the Enterprise infos at the created Google Play for Work (or Managed Google Play) at http://play.google.com/work . Left menu "Administration Settings" at check your enterpriseId.

Can I execute a Google App scripts via Sheets URL?

Can't get OAuth to work, so I settled for a public spreadsheet, able to download data via URL (range/value). Struggling to get upload data via JSON embedded in POST, then I thought I saw some other approach: Is it somehow possible to write an app script that writes a value to cell and embed that data in the URL together with the request to execute the app script ?
Basically, download data via GET and upload data via GET, sounds crazy ?
Sure. You just need a function called doGet and then you can deploy the script as a web app. Here is an example.
function doGet(e) {
return ContentService.createTextOutput(JSON.stringify(e, null, 2));
}
If you then open the web app url with some parameters added to it e.g. https://script.google.com/macros/s/.../exec?a=3&b=4 you should see that those parameters are now contained in e so your script can just read them and add them to your spreadsheet.

Create a middle BackEnd for a Mobile app

I am developing a mobile app on Android.
I download a lot of information from the backend via REST API.
For example for obtain the information about a contract I use the api the following request:
GET /contracts/01212314.json
It return a json with many fields
{
"conto_contrattuale": "01212314",
"intestatario": "Dennis D'Amico",
"utilizzo": "COTTURA + PROD. ACQUA 7 GG",
"codice_settore_merceologico": "E1",
"settore_merceologico": "ELETTRICITA",
"codice_societa_vendita": "Z016",
"societa_vendita": "Estra Energie S.r.l.",
"fornitura_indirizzo": "Via Palermo",
"fornitura_civico": "20",
"fornitura_precisazione": "Rosso",
"fornitura_cap": "59100",
"fornitura_comune": "Prato"
"rid": false,
"fatt_elettronica": true,
"fatt_email": "andrea.bettarini#devise.it",
"fatture_scadute": 1,
}
But I am only interested to the field : "fornitura_indirizzo"
I can't modify the backend and the API.
So I think to create a new middle backend that fetch the info from the actual backend and exposes a call only for the field "fornitura_indirizzo".
How can I do?
Is it possible on google cloud platform? and is it free?
Thank you for your consideration.
You can put a file on your server that fetches the data en then recreates a partial array and echo that in json.
Example:
$contract = Json_decode("/contracts/xxxx.json", true);
$needed_info = $contract["fornitura_indirizzo"];
Echo json_encode($needed_info);
I can't access to the server and modify. I can only send request.
I apologise if I misunderstand your goals here, but why bother with creating this new back end for your app. You could simply call the existing back end and ignore the unneeded information. Either way, that existing back end has to send all that info somewhere for every request your mobile app performs. You're also adding more latency to the request since it has to go through your back end first.
I can see this being worth it though if your goal is to minimize the data downloaded by the mobile app when it does a request.

Unity Android java.io.FileNotFoundException

I made a game with Unity3D which is working on my own android phone fine, but it seems not working on other phones. I don't have access to those phones, but this is what I was told.
More detail: My game is an android app and needs to send data to a server to be stored. The URL is something like this "https://example.com/register". The server is hosted on the google app engine. When a user attempts to send the data he gets an error back which is something like this "java.io.FileNotFoundException https://example.com/register". I checked the logs in my server, there is no record regarding a request from that user. I read somewhere that it's because of htaccess and WWW class and you can't call an URL with htaccess data in it! But there is no htaccess to that page in my server. The page simply receives the data and store them, no authentication needed.
Would be great if anyone has any other idea why some devices get this error and some don't.
string url = "https://my-app-name.appspot.com/register";
WWWForm form = new WWWForm();
form.AddField("playerEmail", playerEmail);
form.AddField("registrationId", registrationId);
form.AddField("playerName", playerName);
form.AddField("playerPass", playerPass);
WWW www = new WWW(url, form);
yield return www;
the server-side then use those provided data and return a simple string.
<?php
$player_name = $_POST['playerName'];
$player_pass = $_POST['playerPass'];
$player_email = $_POST['playerEmail'];
$gcm_registration_id = $_POST['registrationId'];
//store data in the Datastore.
echo "success";
?>
app.yaml
application: my-app-name
version: 1
runtime: php55
api_version: 1
threadsafe: false
handlers:
- url: /register
script: register.php
I also had this problem. The takeaway I had was
Java.io.filenotfound exception is bogus error. It's not anything to do with file io - it's the request failing at the server.
To find the actual error in unity - look at the www requestHeaders - this will give you back the response headers from the request from the server - mine was a 500, but it could be a 400+ type error (especially if you're using authentication).
You can do this by doing a
foreach(var header in request.responseHeaders)
....
If anyone wants I can post my diagnostic code to help out.

Categories

Resources