Task

Given the name of a language on Rosetta Code, find all tasks which are not implemented in that language.



Note: Implementations should allow for fetching more data than can be returned in one request to Rosetta Code.

You'll need to use the Media Wiki API, which you can find out about locally, here, or in Media Wiki's API documentation at, API:Query

-- demo\rosetta\Find_unimplemented_tasks.exw
without js -- (libcurl, file i/o, peek, progress..)
constant language = "Phix",
--       language = "Go",
--       language = "Julia",
--       language = "Python",
--       language = "Wren",
         base_query = "http://rosettacode.org/mw/api.php?action=query"&
                      "&format=xml&list=categorymembers&cmlimit=100"

include builtins\libcurl.e
atom curl = NULL
atom pErrorBuffer
include builtins\xml.e

function req(string url, integer rid)
    if curl=NULL then
        curl_global_init()
        curl = curl_easy_init()
        pErrorBuffer = allocate(CURL_ERROR_SIZE)
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, pErrorBuffer)
    end if
    curl_easy_setopt(curl, CURLOPT_URL, url)
    object res = curl_easy_perform_ex(curl)
    if integer(res) then
        string error = sprintf("%d [%s]",{res,peek_string(pErrorBuffer)})
        crash("Download error: %s\n",{error})
    end if
    if not string(res) then ?9/0 end if
    object xml = xml_parse(res)[XML_CONTENTS]
    res = xml_get_nodes(xml,"continue")
    res = iff(res=={}?"":xml_get_attribute(res[1],"cmcontinue"))
    xml = xml_get_nodes(xml,"query")[1]
    xml = xml_get_nodes(xml,"categorymembers")[1]
    xml = xml_get_nodes(xml,"cm")
    for i=1 to length(xml) do
        call_proc(rid,{xml_get_attribute(xml[i],"title")})
    end for
    return res
end function

function html_clean(string ri)
    ri = substitute(ri,`"`,`"`)
    ri = substitute(ri,`'`,`'`)
    ri = substitute(ri,"\xE2\x80\x99","'")
    ri = substitute(ri,"\xC3\xB6","o")
    ri = substitute(ri,"%3A",":")
    ri = substitute(ri,"%E2%80%93","-")
    ri = substitute(ri,"%E2%80%99","'")
    ri = substitute(ri,"%27","'")
    ri = substitute(ri,"%2B","+")
    ri = substitute(ri,"%C3%A8","e")
    ri = substitute(ri,"%C3%A9","e")
    ri = substitute(ri,"%C3%B6","o")
    ri = substitute(ri,"%C5%91","o")
    ri = substitute(ri,"%22",`"`)
    ri = substitute(ri,"%2A","*")
    return ri
end function

sequence titles = {}
procedure store_title(string title)
    titles = append(titles,title)
end procedure

integer unimplemented_count = 0,
        task_count = 0
procedure print_unimplemented(string title)
    if not find(title,titles) then
        title = html_clean(title)
        printf(1,"%s\n",{title})
        unimplemented_count += 1
    end if
    task_count += 1
end procedure

procedure main()
    printf(1,"Loading implemented tasks list...\n")
    -- get and store task itles
    string lang_query := base_query & "&cmtitle=Category:" & language,
           continue_at := req(lang_query, store_title)
    while continue_at!="" do
        continue_at = req(lang_query&"&cmcontinue="&continue_at, store_title)
    end while
 
    -- a quick check to avoid long output
    if length(titles)==0 then
        printf(1,"no tasks implemented for %s\n", {language})
        return
    end if
 
    -- get tasks, print as we go along
    printf(1,"Tasks:\n")
    string task_query := base_query & "&cmtitle=Category:Programming_Tasks"
    continue_at = req(task_query, print_unimplemented)
    while continue_at!="" do
        continue_at = req(task_query&"&cmcontinue="&continue_at, print_unimplemented)
    end while
    printf(1,"%d unimplemented tasks found for %s.\n",{unimplemented_count,language})

    integer full_tasks = unimplemented_count
    printf(1,"Draft tasks:\n")
    task_query := base_query & "&cmtitle=Category:Draft_Programming_Tasks"
    continue_at = req(task_query, print_unimplemented)
    while continue_at!="" do
        continue_at = req(task_query&"&cmcontinue="&continue_at, print_unimplemented)
    end while
    integer draft_tasks = unimplemented_count-full_tasks
    printf(1,"%d unimplemented draft tasks found for %s.\n",{draft_tasks,language})

    printf(1,"%d unimplemented tasks in total found for %s (out of %d).\n",{unimplemented_count,language,task_count})

end procedure
main()
