Importing more than one lesson at a time?

Hi guys,

This is something I deal with fairly often. When I have to import TV shows with 100+ episodes using subtitles from text files there is no way to do so other than manually creating each one. It would be great if there was a way to select multiple files at once and create a lesson for each one under an existing course.

I tried looking for any open APIs that Lingq might have as I can write code but no luck there.

How does everyone else deal with this at the moment?

1 Like

for coding, you can use something like Selenium to automate a user using a web browser. I have a use case of importing videos from YouTube right away (without waiting) and made a script where I just need to paste in the YouTube link and then the script opens a browser and does all the manual steps I usually would do to import a lesson.

See this free extension for uploading your media as courses.

Yeah I saw Selenium being used in this GitHub repo: https://github.com/TheGreenAirplane/LingQBulkImporter/blob/master/LingQBulkUpload.ps1
I gave that a go but it wasn’t working for me due to changes to Lingq’s endpoints, so I thought I would check if there was a solution ready before I went down the rabbit hole ahah.

Would you be able to share a sample code snippet?

That looks like a great solution! Just to confirm, the tool needs each lesson to be in its own folder right?
I normally have all files in one folder but I could just write a script to create a folder for each one

Also I uploaded about 100 lessons at once though they were uploaded in “random” order. Is there a way to force it to follow alphabetical order?

That’s right. Will support further inclusions. e.g pics/description/inline images?

The order of upload is actually determined by the sorting options on your pc.

here is the relevant code

async function processFolder(files) {
    let courseTitle = null;
    let lessons = [];

    for (let file of files) {
        const filePath = file.webkitRelativePath.split("/");
        if (!courseTitle) {
            courseTitle = filePath[0];  // Set the course title using the main folder name
        }

        if (filePath.length === 3) {  // Indicates a file inside a lesson folder
            const lessonFolderName = filePath[1];
            const fileName = filePath[2];
            let lesson = lessons.find(l => l.folderName === lessonFolderName);
            if (!lesson) {
                lesson = { folderName: lessonFolderName, text: null, audio: null, title: null };
                lessons.push(lesson);
            }

            if (fileName.endsWith(".txt")) {
                const content = await file.text();
                lesson.title = content.split("\n")[0];
                lesson.text = content;
            } else if (fileName.endsWith(".mp3")) {
                lesson.audio = file;
            }
        }
    }

    // Now you have the course title and an array of lessons with their title, text, and audio.
    // You can proceed to create the course and its lessons on LingQ.
    createCourseOnLingQ(courseTitle, "Course Description")
        .then(courseResponse => {
            // Using the course response (which should contain the course ID), create each lesson
            for (let lesson of lessons) {
                createLessonOnLingQ(
                    lesson.title,
                    "Lesson Description",
                    lesson.text,
                    courseResponse.id,  // Assuming the course response contains the course ID
                    lesson.audio
                );
            }
        });
}

Interesting, I had both the folders and the files sorted alphabetically on my computer but were uploaded seemingly in a random order on Lingq.

Anyway, your extension is just what I needed so thank you so much!

I actually see the error now.

The lessons aren’t created async (waiting for one to finish before starting the next).

I’ll take care of that, cheers.

That’s awesome thanks!