How to dowload files from course

How to dowload files from course

by Oriol Biosca Almendros -
Number of replies: 21

Hi humans smile

I must download all files from a course, the teacher and the student ones. How I can get them? I have already revised the page "http://docs.moodle.org/dev/File_API" but all I get is like the image attached at the topic... can you help a poor soul as mine?

 

Thanks!

Attachment fail_get_info2.png
Average of ratings: -
In reply to Oriol Biosca Almendros

Re: How to dowload files from course

by Andrew Normore -

If it were me, I'd build a local plugin, with a few parameters to choose from (course, ect).

Then a nice foreach() loop!

In reply to Andrew Normore

Re: How to dowload files from course

by Rosario Carcò -

Very VERY good Idea. I always adviced the teachers to put all their files also in a zip-file, so that the students could download everything with one click. Of course this meant uploading and vasting double the space if the files were also linked in individually. So this simple Block could really do the trick. I am not sure if we could use the File-Api Matteo Scaramuccia developed already. If I am not mistaken, it is already a block, so we could simply change the code to loop through the files of the given course to download them.

I am asking Matteo to join in and tell us whether his code could help us.

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Matteo Scaramuccia -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers

Ciao Rosario,
DAVRoot is able to show the Moodle Virtual File System without giving any contraint to the user except the ones coming straight from the Files API as well as the opportunity to download them.

It's not a block and not able to provide facilities like 'Download a folder as a zip' like e.g. GitHub does with its own magic URLs: this could be a nice improvement, spare time permitted I'll explore it. It wil require a temporary archive to be created and then deleted within a time range contraint (weak way to recover the wasted space).

That's being said, here what IMHO is required should be something, already described by Andrew Normore - block or local plugin, quite the same; the second will give a place for users to click on in order to get the archive -, able to provide the direct link to an archive which will be always updated whenever something will change in the course.
The loop described above could cycle for all objects (activties, resources) contained into the course, cycle for all the areas coming from each object (ask, for each object, to lib.php::folder_get_file_areas()) using file_storage::get_area_files() and then create the requested archive using zip_archive. Another way is to cycle with file_browser to collect all the files in the given course which could be a candidate to be included into the archive - at least, backup files must be excluded! - and then zip them.
The second option could be easier for a quick prototype, the first more complex but for sure a really good training experience about the Moodle Files API.

HTH,
Matteo

In reply to Matteo Scaramuccia

Re: How to dowload files from course

by Oriol Biosca Almendros -

Hi people I had a little afk because of the winter holidays, but I've returned and did what you told.

I tried to use get_area_files() and folder_get_file_areas(), but they require parameter like contextid, component and filearea... I don't know how to get that info from the code and if I search it no place explains how to get them or where is the getter (if exist).

How can I get that info?? TT I don't understand anything...

Thx

In reply to Oriol Biosca Almendros

Re: How to dowload files from course

by Matteo Scaramuccia -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers

Hi Oriol,
let's see if I'll be able to have some spare time for coding a proof of concept from now to the end of the first week of January.

Matteo

In reply to Matteo Scaramuccia

Re: How to dowload files from course

by Rosario Carcò -

Great. And let me know if I can jump in and help, even if it is only to encapsulate Matteo's code into a block.

In reply to Matteo Scaramuccia

Re: How to dowload files from course

by Rosario Carcò -

Matteo, thinking it over again, I thought that the code or most of the code is already there: we simply could use the built-in backup-code of Moodle leaving away all the xml-stuff, activities, grades, etc. we do not need and let the code build up the desired zip-file.

As usual I am busy these times, but I will try as soon as possible. Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

I just wanted to come back to this issue, but I am seeing that there is such an option to DOWNLOAD ALL files when you are logged in as Admin and I guess also as Teacher. This is true for the legacyFolder copied along with old courses from Moodle 1.9 and I still guess this is true for the new file-system and file-picker. But you have to put the displayed page into EDIT Mode.

But I can not find such an option for logged in students.

So if the functionality is already built in, core programmers should only make it available for students and admins and teachers without putting the page into Edit Mode, saving another click.

OK, I did a quick research on this, as stated, if you put the page into EDIT mode and you are logged in as Admin, you get the Download All link but only to download all files contained in one folder, no matter if legacyFolder or new file system Folder. But you can not really download all files contained in one course, scattered over several folders and linked in several topics. And no chance at all if you are logged in as student.

So I think this idea has still to be coded.

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

I just started working on it. My strategy:

- try to take the built in code for backup

- modify code to only include published files (as all files in the course are published files, there should be no difference between students and teachers, unless teachers could also hide some files in which case the students are not allowed to download them. I will have to check this.)

- implement the working code into a block

Any suggestions are always welcome. Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

Oh, dear it seems not to be so simple as I thought. I created a mockup block but using the backup-code will include the published files with their cryptic hash-code-names instead of their original plain-text names.

I fear I have to rewrite a big part of the backup code. Let me try with the mentioned code for admins and teachers who can download all files in edit mode. Maybe this could be a faster approach.

Edit: yes this code creates a zip-file with the original file names. So I will try to hack this for our purposes.

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

I finished a first mock-up last week. I can already create a zip-file. Now I will have to find the trick to automatically serve it to the client browser and I will have to clean up my code before I can upload a first beta here.

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

Done. I am cleaning up my code and then uploading a first beta here and in the plugins&modules database.

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

Here it is. Simply unzip and copy all files and folders into your moodle/blocks/download_all_published_files directory. In the Zip-File-Name I leave the Version number 2302 meaning it was tested on Moodle 2.3 and is Version 02 of my code.

Note:

@todo reflect topic and nested folderpaths in zip-file
@todo redirection after send_temp_file is not possible, hence the user can not be alerted that download took place!

Please test on your test-servers, not production servers. Test-Cases:

  1. login as Site-Admin and Teacher -> you should get all files of the course where you add my block
  2. login as Student -> you should only get visible files. No files in hidden topics or folders neither

As the download is executed without user interaction you must check in your Browsers' download-directory.

Let me know if the block is useful, if you have suggestions, if it is worth uploading in the plugins&modules Database etc.

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

Here is my second beta with topic/folderpaths implemented. It works well and is tested until level 4 in nested folders.

I will also upload this version into the modules&plugins database now.

Again, unzip everything locally and copy to your blocks/download_all_published_files server-directory.

Let me know if it works for you too. Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Rosario Carcò -

My third beta is to be found in the Modules&Plugins-Database directly.

- lang fr, it, es, de added

- some corrections as suggested by David Mudrák

- @todo: further security checks to exclude student uploaded files and files in forums, assignments, database, etc. modules and activities

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by Tomasz Muras -
Picture of Core developers Picture of Plugin developers Picture of Plugins guardians Picture of Translators

Hello,

I guess this is under review and not available in Moodle plugins DB just yet.

Do you use some public repository to track your code? I could use such functionality in moosh file-list command, so I could help you a bit with development and use some of your code as shared library - if you're interested in cooperation.

cheers,
Tomek

In reply to Tomasz Muras

Re: How to dowload files from course

by Rosario Carcò -

You are right, it is under review and awaits approval. I can upload the latest beta 23.04 here if you like.

This is the link though:

https://moodle.org/plugins/view.php?plugin=block_download_all_published_files

I am a very very old fashioned hobby-programmer. I have only little spare time and I had some  acquaintance with cvs (code versioning system) and only an account on github but very little experience with it.

For the moment being I must await approval because of security concerns. I.e. no student should be allowed to download course-backup files or any other files, e.g. in assignments, databases, or any other activity.

I think I solved the security issues with a simple line of code, but I need more experienced (core) programmers to decide on that and help me where I need help:

    foreach ($result as $file) {
        list($context, $course, $cm) = get_context_info_array($file->contextid);//Cr: might be too much here, but need the context from contextid as object AND, most important, cm to check visibility of the file/folder
        $fileinfo = $browser->get_file_info($context, $file->component, $file->filearea, $file->itemid, $file->filepath, $file->filename);//works well and includes the hash codes, returns null if user is not allowed to see/grab that file

        if ($fileinfo == null)
        {
            continue;//continue with next file, as user is not allowed to zip/download it
        }

        $f = $fs->get_file($context->id, $file->component, $file->filearea, $file->itemid, $file->filepath, $file->filename);//Cr: otherwise get file from storage and add it to the zip archive

Rosario

In reply to Rosario Carcò

Re: How to dowload files from course

by David Mudrák -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Plugins guardians Picture of Testers Picture of Translators

For the record, the concerns raised during the approval review were due to the fact that the current code basically loads all records directly from the files table related to the given course's context (and its sub-contexts). There were no callbacks executed to perform the access control provided by components that own the given file. So I suggested to the authors to study how the Server files repository is implemented and use similar approach. I haven't get to reviewing the new version yet but I am afraid there was more work needed than just adding couple of lines.

Rosario, it would really help if you manage to get your code available in a public git repository so others here could provide you a feedback more easily.

Thanks in advance, and don't give up! The idea is pretty good and this plugin can eventually make many users quite happy.

In reply to David Mudrák

Re: How to dowload files from course

by Rosario Carcò -

OK, no need to review it, as I still use the files table as grand loop and do a $browser->get_file_info for each file to decide if the user has access permissions.

Could you please have a look here:

https://moodle.org/mod/forum/discuss.php?d=264039

This works pretty well, but does not behave as expected for students.

Anyway if I should not be using the files list I get from the files table for each file of the course. Where should I start?

Do I need to start enumerating all sections, all folders, all activities, etc. of the course? then dive into each and try to get the files in there?

I can not learn more from the $browser->get_file_info API nor when I study this class.

You are now speaking of how the "Server files repository is implemented" - Ok then, let me dive into this code and see what I can learn there.

Rosario (expect me back at the end of next week)

In reply to David Mudrák

Re: How to dowload files from course

by Rosario Carcò -

In the class repository_coursefiles I found the same code used in the file API docs to create a tree of files, I assume of the given course. But in my early tests this did not work. But the function get_listing should return a list of course files I hope.

Let me test this. Rosario

In reply to David Mudrák

Re: How to dowload files from course

by Rosario Carcò -

Not sure if I found the correct way to go now.

The course-page the user is viewing at has got everything from /course/externallib.php->get_course_contents(). So if I could loop over the objects I could also find the files the user is allowed to view/download. If the course-contents has been destroyed when the course was rendered, I could reuse code of the function get_course_contents, as I already do with my loop over the

$modinfo = get_fast_modinfo($course);
$sections = $modinfo->get_section_info_all();

and then let the mods own export functions do the rest like this

//call $modulename_export_contents
//(each module callback take care about checking the capabilities)

require_once($CFG->dirroot . '/mod/' . $cm->modname . '/lib.php');
$getcontentfunction = $cm->modname.'_export_contents';

if (function_exists($getcontentfunction)) {
    if ($contents = $getcontentfunction($cm, $baseurl)) {
        $module['contents'] = $contents;
    }
}

//assign result to $sectioncontents
$sectioncontents[] = $module;
 
}
$sectionvalues['modules'] = $sectioncontents;
  
// assign result to $coursecontents
$coursecontents[] = $sectionvalues;

OK, now I would have a list of allowed course contents, including files I suppose.

Let me have a look at the datastructures returned by the $getcontentfunction and see whether I can

$f = $fs->get_file($context->id, $file->component, $file->filearea, $file->itemid, $file->filepath, $file->filename);//Cr: get file from storage

This would really be phantastic. David what do you think?