diff --git a/paris.fr/cpp/README.md b/paris.fr/cpp/README.md index 39e6268..ef8b75b 100644 --- a/paris.fr/cpp/README.md +++ b/paris.fr/cpp/README.md @@ -31,6 +31,12 @@ make ``` ./booking.bin ``` +For the multithreaded version, + +``` +./booking_mt.bin n +``` +where n is an integer representing the number of threads. If not given in argument, the number of threads is determined at runtime. If you want to be able to book several appointments simultaneously, your email provider must support aliases like john+1234@gmail.com. 6. When an availability is posted on the site and waiting for you to book, solve the captcha which appears in the terminal. diff --git a/paris.fr/cpp/booking_mt.cc b/paris.fr/cpp/booking_mt.cc index c176437..ad07c8c 100644 --- a/paris.fr/cpp/booking_mt.cc +++ b/paris.fr/cpp/booking_mt.cc @@ -15,13 +15,15 @@ #include #include #include +#include #include using std::string; -std::mutex output_mutex; +std::mutex output_mutex, hash_table_mutex; std::unordered_map hmap; +std::unordered_set hash_table; // libcurl write callback function static int writer(char *data, size_t size, size_t nmemb, std::string *writerData) @@ -38,6 +40,8 @@ void book(){ CURL *curl = NULL; CURLcode code; + + char errorBuffer[CURL_ERROR_SIZE]; std::string buffer; @@ -59,6 +63,8 @@ void book(){ rdstring.push_back(alphanum[std::rand()/((RAND_MAX + 1u)/62)]); } + while( true ){ + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer); curl_easy_setopt(curl, CURLOPT_URL, "https://teleservices.paris.fr/rdvtitres/jsp/site/Portal.jsp?page=appointmentsearch&view=search&category=titres"); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0L); @@ -111,11 +117,20 @@ void book(){ "Le 3975 n’est pas en mesure de vous proposer des rendez-vous|" "Les 5 500" )); - std::cout << std::endl; + string link, date; RE2::PartialMatch(buffer, R"(<\s*a\s.*href=\"([[:ascii:]]*)\".*id=\".*appointment_first_slot\"\s*>([[:alnum:]\s:]*))",&link, &date); - + { + std::lock_guard g(hash_table_mutex); + auto it = hash_table.find(date); + if ( it != hash_table.end() ) { + continue; + } + else{ + hash_table.insert(date); + } + } buffer.clear(); auto it = link.find("step3"); @@ -227,10 +242,14 @@ void book(){ { std::lock_guard guard(output_mutex); std::system(command); - std::cout << std::this_thread::get_id() << '\t' << date << ' ' << filename << '\n' << '\t' << "Enter Captcha: "; + std::cout << std::this_thread::get_id() << '\t' << date << ' ' << filename << '\n' << '\t' << "Enter Captcha (:q to discard): "; std::cin >> captcha; } + if(captcha == ":q") { + break; + } + multipart = curl_mime_init(curl); part = curl_mime_addpart(multipart); @@ -298,6 +317,8 @@ void book(){ } + } + curl_easy_cleanup(curl); } @@ -327,7 +348,7 @@ int main(int argc, char *argv[]) curl_global_init(CURL_GLOBAL_DEFAULT); - unsigned int nt = argc>1 ? atoi(argv[0]):std::thread::hardware_concurrency(); + unsigned int nt = argc>1 ? std::min((uint)atoi(argv[1]), std::thread::hardware_concurrency()):std::thread::hardware_concurrency(); std::vector threads; for (uint j=0; j