Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download all items for given track #718

Open
Jarvvski opened this issue Aug 25, 2018 · 16 comments
Open

Download all items for given track #718

Jarvvski opened this issue Aug 25, 2018 · 16 comments

Comments

@Jarvvski
Copy link

Did some quick searching and I see that the ability to download all items for a given track isn't currently in the CLI.

I'd really find this item useful, as it's great to have access to items to work on during a long flight etc.

In the mean time (because I've been searching for it in the issues here) I made a tiny script to be able to download all items for a given track: https://github.com/Jarvvski/exercism-downloader

@kytrinyx
Copy link
Member

I think this would be a nice addition.

A few notes:

  • It would have to be "all unlocked", not "all"
  • In "independent mode", "all unlocked" would be equivalent to "all"

We would need some design/implementation on the backend API in https://github.com/exercism/website before we can start addressing this

@raymondchen625
Copy link

Before this task is completed, we can use this shell command to pull the list of go:
curl -LS https://exercism.io/tracks/go/exercises | grep "/tracks/go/exercises/" | awk '{print $3}' | cut -d/ -f5 | cut -d\" -f1

@Jarvvski
Copy link
Author

@raymondchen625 awesome 1 liner!

@tsoernes
Copy link

tsoernes commented Feb 12, 2019

curl -LS https://exercism.io/tracks/rust/exercises | grep "/tracks/rust/exercises/" | awk '{print $3}' | cut -d/ -f5 | cut -d\" -f1 > exercises.txt
while read in; do exercism download --exercise="$in" --track=rust; done < exercises.txt

Change track as needed

@cocoonkid
Copy link

cocoonkid commented Apr 1, 2019

I also would massively appreciate a way to download full tracks.
EDIT: I just realized I have to have exercises unlocked. @tsoernes script works beautifully though.

@agentofuser
Copy link

If you're doing multiple tracks in parallel this might be helpful:

# "exercism download all" for specific tracks

function eda() {
  for trackname in "$@"; do
    echo https://exercism.io/tracks/$trackname/exercises
    curl -LS https://exercism.io/tracks/$trackname/exercises | grep "/tracks/$trackname/exercises/" | awk '{print $3}' | cut -d/ -f5 | cut -d\" -f1 > exercises.txt
    while read in; do exercism download --exercise="$in" --track=$trackname; done < exercises.txt
    rm exercises.txt
  done
}

# example usage:
# ❯ eda typescript reasonml ocaml racket nim

Thank you @tsoernes for doing the hard part. This is just a for loop around his code.

@farv
Copy link

farv commented Apr 18, 2020

I'm having issues using that @tsoernes code from a computer using WSL2 and redid some part of it:

TRACK=<TRACK-TO-BE-DOWNLOADED> && curl -LS https://exercism.io/tracks/$TRACK/exercises | grep "/tracks/$TRACK/exercises/" | awk '{print $3}' | cut -d/ -f5 | cut -d\" -f1 > exercises.txt
for word in `sed '/^$/d' exercises.txt`; do exercism download --exercise="$word" --track=$TRACK; done

Be careful when your home excercism workspace path has spaces.

Hope you all enjoy it! ;)

@lcharles123
Copy link

If you're doing multiple tracks in parallel this might be helpful:

# "exercism download all" for specific tracks

function eda() {
  for trackname in "$@"; do
    echo https://exercism.io/tracks/$trackname/exercises
    curl -LS https://exercism.io/tracks/$trackname/exercises | grep "/tracks/$trackname/exercises/" | awk '{print $3}' | cut -d/ -f5 | cut -d\" -f1 > exercises.txt
    while read in; do exercism download --exercise="$in" --track=$trackname; done < exercises.txt
    rm exercises.txt
  done
}

# example usage:
# ❯ eda typescript reasonml ocaml racket nim

Thank you @tsoernes for doing the hard part. This is just a for loop around his code.

Note that it will overwrite all already downloaded folders

@she3o
Copy link

she3o commented Sep 20, 2021

The previous scripts don't work on the new website anymore.

This works for me:

#!/usr/bin/env bash 

# You have to have `pup` and `jq` in your $PATH.
# Does `mkfifo` work on MacOS?
# example usage:
# ❯ eda typescript reasonml ocaml racket nim

arrow="\e[31;1m=>\e[0m"
pipe="/tmp/pipe-$$"

for trackname in "$@"; do
	mkfifo "$pipe"
	echo -e "$arrow Downloading ${trackname^} track..."
	curl -LSs https://exercism.org/tracks/"$trackname"/exercises |
		pup -p 'section[class=exercises] div attr{data-react-data}' |
		jq -r '.request.options.initial_data.exercises | .[].slug' >"$pipe" &
	while read in; do
		exercism download --exercise="$in" --track="$trackname"
	done <"$pipe"
	rm "$pipe"
done

@robertpkoenig
Copy link

This is a python script I just used.

import requests
import re
import os

# Replace this with your language
LANGUAGE = "java"

# Get the html from the exercism page
pageURL = 'https://exercism.org/tracks/' + LANGUAGE + '/exercises'
request = requests.get(pageURL)
pageHTML = request.content.decode('utf-8')

# Each exercise is in the form "/tracks/java/"exerciseName&
regexString = r'tracks/' + LANGUAGE + '/exercises/(.*?)&'
allMatches = re.findall(regexString, pageHTML)
numDownloads = 0
for exercise in allMatches:
    downloadCommand = 'exercism download --exercise=' + exercise + ' --track=' + LANGUAGE
    os.system(downloadCommand)
    numDownloads += 1

print("Total downloads: ", numDownloads)

@gustafc
Copy link

gustafc commented Nov 16, 2022

To add to this pageant of download scripts, here's a bash version of @robertpkoenig's Python script that doesn't need anything you don't already have (the exercism CLI, curl, and pretty standard *NIX/Posix stuff). Just change TRACK to whatever floats your boat.

(TRACK=rust; set -euo pipefail; trackdir="$(exercism workspace)/$TRACK"; mkdir -p "$trackdir"; curl --silent --fail "https://exercism.org/tracks/$TRACK/exercises" | grep -Eo 'tracks/'"$TRACK"'/exercises/[^&]+' | cut -d/ -f4 | tee "$trackdir/exercise-order.txt" | while read ex; do if test -d "$trackdir/$ex" ; then echo "$ex already downloaded"; else (set -x && exercism download --track "$TRACK" --exercise "$ex"); fi; done)

Works On My Machine™️

Edit: Now also works on other machines (Mac/bash and Alpine/ash at least)

@AmjadHD
Copy link

AmjadHD commented Mar 18, 2023

Here's a python script that asynchronously downloads a track from it's config.json:

import asyncio
import json
import requests


async def download_exercise(exercise: str, track: str, overwrite):
    cmd = f"exercism download --exercise={exercise} --track={track}"
    if overwrite:
        cmd += " --force"
    proc = await asyncio.create_subprocess_shell(
        cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)

    stdout, stderr = await proc.communicate()

    print(f'[{cmd!r} exited with {proc.returncode}]')
    if stdout:
        print(f'[stdout]\n{stdout.decode()}')
    if stderr:
        print(f'[stderr]\n{stderr.decode()}')

async def download_track(track: str, overwrite=false):
    url = f"https://github.com/exercism/{track}/raw/main/config.json"
    content = json.loads(requests.get(url).content)

    await asyncio.gather(*(download_exercise(exercise['slug'], track, overwrite) for exercise in content["exercises"]["practice"]))

asyncio.run(download_track("dart"))

@nihilismus
Copy link

Another Bash script, but using Exercism's API:

#!/usr/bin/env bash

set -e
set -u

export track="$1"

curl \
  --silent --fail \
  "https://exercism.org/api/v2/tracks/$track/exercises" \
  | sed 's/"slug":"/\n/g' \
  | sed 's/",.*$//' \
  | grep -v '"exercises":' \
  | while read -r slug; do
      exercism download --track="$track" --exercise="$slug"
    done

@baduker
Copy link
Contributor

baduker commented Sep 19, 2023

So, my PR got automatically closed because of the pause of community contributions, which I wasn't aware of, but that doesn't mean you can't use the feature I've developed to list, filter, and download exercises. Just read the PR, it has all the examples. Until the pause gets lifted, happy coding!

PR - #1113

@jonnylangefeld
Copy link

A shorter command than what I have seen here before. Uses jq as dependency which is pretty common.

  • downloads only exercises you don't already have (doesn't overwrite. But still can if you add --force)
  • only downloads unlocked exercises
track=go; curl "https://exercism.org/api/v2/tracks/$track/exercises" | \
  jq -r '.exercises[].slug' | \
  xargs -I {} -n1 sh -c "exercism download --track=$track --exercise {} || true"

@Giveback007
Copy link

Giveback007 commented Jul 23, 2024

In case somone wants an out of the box solution: exer-h

screen-1

It's a small wrapper for the official exercism cli. Hope it helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.