jsonp attempts
This commit is contained in:
parent
d90f87efe3
commit
3462cd3101
BIN
__pycache__/headers.cpython-311.pyc
Normal file
BIN
__pycache__/headers.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/player_games.cpython-311.pyc
Normal file
BIN
__pycache__/player_games.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/user_agents.cpython-311.pyc
Normal file
BIN
__pycache__/user_agents.cpython-311.pyc
Normal file
Binary file not shown.
16
gpt/index.html
Normal file
16
gpt/index.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Chess Game Downloader</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Chess Game Downloader</h1>
|
||||||
|
<input type="text" id="username" placeholder="Enter username">
|
||||||
|
<button onclick="downloadGames()">Download Games</button>
|
||||||
|
|
||||||
|
<script src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
94
gpt/main.js
Normal file
94
gpt/main.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// main.js
|
||||||
|
|
||||||
|
function jsonp(url, callbackName) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = `${url}&callback=${callbackName}`;
|
||||||
|
document.body.appendChild(script);
|
||||||
|
|
||||||
|
window[callbackName] = (data) => {
|
||||||
|
delete window[callbackName];
|
||||||
|
document.body.removeChild(script);
|
||||||
|
resolve(data);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getGames(username, userAgents) {
|
||||||
|
const gamesUrl = `https://api.chess.com/pub/player/${username}/games/archives`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await jsonp(gamesUrl);
|
||||||
|
// Extracting URLs
|
||||||
|
const gameUrls = response.archives.map(url => `${url}/.pgn`);
|
||||||
|
return gameUrls;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching game URLs:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchGames(url, userAgent) {
|
||||||
|
const callbackName = `jsonp_callback_${Math.round(100000 * Math.random())}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await jsonp(url, callbackName);
|
||||||
|
// Process the JSONP response as needed
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching game from ${url}:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function concatenateGames(gameResults) {
|
||||||
|
// Customize how you want to concatenate the games
|
||||||
|
return gameResults.join('\n\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadGames() {
|
||||||
|
const username = document.getElementById('username').value;
|
||||||
|
|
||||||
|
// Function 1: Get game URLs
|
||||||
|
const allUserAgents = await loadUserAgents();
|
||||||
|
const urls = await getGames(username, allUserAgents);
|
||||||
|
|
||||||
|
// Function 2: Asynchronously fetch games
|
||||||
|
const gamePromises = urls.map(async (url, index) => {
|
||||||
|
const userAgent = allUserAgents[index % allUserAgents.length];
|
||||||
|
return await fetchGames(url, userAgent);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Function 3: Concatenate game results
|
||||||
|
const gameResults = await Promise.all(gamePromises);
|
||||||
|
const concatenatedGames = concatenateGames(gameResults);
|
||||||
|
|
||||||
|
// Function 4: Trigger download
|
||||||
|
download(concatenatedGames, 'chess_games.pgn', 'application/pgn');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching games:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function download(content, fileName, contentType) {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
const file = new Blob([content], { type: contentType });
|
||||||
|
a.href = URL.createObjectURL(file);
|
||||||
|
a.download = fileName;
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadUserAgents() {
|
||||||
|
try {
|
||||||
|
const userAgentsModule = await import('./userAgents.js');
|
||||||
|
return userAgentsModule.default;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading user agents:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
// Your initialization logic here...
|
||||||
|
});
|
14
gpt/userAgents.js
Normal file
14
gpt/userAgents.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
// userAgents.js
|
||||||
|
|
||||||
|
const userAgents = [
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; rv:109.0) Gecko/20100101 Firefox/113.0",
|
||||||
|
"Mozilla/5.0 (Android 12; Mobile; rv:109.0) Gecko/113.0 Firefox/113.0",
|
||||||
|
"mozilla/5.0 (macintosh; intel mac os x 10.15; rv:109.0) gecko/20100101 firefox/113.0",
|
||||||
|
// Add more user agents as needed
|
||||||
|
];
|
||||||
|
|
||||||
|
export default userAgents;
|
29
gpt_prompt.txt
Normal file
29
gpt_prompt.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
I want to write a simple web app that has the following characteristics and functionality:
|
||||||
|
|
||||||
|
1. There is a text box with a submit/download button
|
||||||
|
2. the user inputs a valid username and presses submit/download
|
||||||
|
3. The pressing of this button triggers the downloading of a .pgn file to their local machine
|
||||||
|
|
||||||
|
There are three main files for the app to work:
|
||||||
|
|
||||||
|
1. the .html file
|
||||||
|
2. the main javascript file
|
||||||
|
3. the userAgents.js file which holds a list of user agents that will be called in the main javascript file
|
||||||
|
|
||||||
|
|
||||||
|
The following is a simple outline of how the web app should work:
|
||||||
|
|
||||||
|
There are 4 main functions:
|
||||||
|
|
||||||
|
1. a function that makes a single call one time to one endpoint, `https://api.chess.com/pub/player/${username from the text box}/games/archives`, to retreive a list of urls links used in the following function 2.
|
||||||
|
2. a function that asynchronously makes get requests using that list of download links returned from function 1.
|
||||||
|
3. a function that concatenates the results of the responses (chess games) of those requests (in .pgn format)
|
||||||
|
4. a function that triggers the download to save the concatenated results of function 3. the user's local machine.
|
||||||
|
|
||||||
|
Note that:
|
||||||
|
|
||||||
|
- you can use as many functions as required to accomplish the what the above functions accomplish and fulfill the characteristics and functionality of the web app.
|
||||||
|
- all functions that make get requests implement JSONp
|
||||||
|
- No api key is required at any point
|
||||||
|
- random user agents selected from the userAgents.js file must be applied to each get request
|
||||||
|
- each url in the list of urls returned from the request to the endpoint "https://api.chess.com/pub/player/${username from the text box}/games/archives", must have a "/.pgn" appended to it prior to making subsequent asynchronous requests. For example, if the list of games returned from a get request to "https://api.chess.com/pub/player/${username from the text box}/games/archives" returns a list of urls, ["https://api.chess.com/pub/player/hippodrunkimus/games/2023/03", "https://api.chess.com/pub/player/hippodrunkimus/games/2023/04"], then the url, "https://api.chess.com/pub/player/hippodrunkimus/games/2023/03" should look like "https://api.chess.com/pub/player/hippodrunkimus/games/2023/03/.pgn?callback=myExampleJavascriptFunction".
|
45
javascript_notes.txt
Normal file
45
javascript_notes.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
keywords to research:
|
||||||
|
|
||||||
|
1. async
|
||||||
|
2. await
|
||||||
|
3. fetch
|
||||||
|
4. Promise.all
|
||||||
|
5. resolve()
|
||||||
|
6. Blob() - needed to download files. Creation of a blob is needed to link the data to a download link to trigger a download see
|
||||||
|
the sample javascript below.
|
||||||
|
7. new - I think this is a constructor?
|
||||||
|
8. appendChild
|
||||||
|
9. createElement
|
||||||
|
10. removeChild
|
||||||
|
11. window.URL.createObjectURL
|
||||||
|
12. click
|
||||||
|
13. window
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Create a Blob containing the file data
|
||||||
|
var fileData = "Hello, this is the content of the file!";
|
||||||
|
var blob = new Blob([fileData], { type: "text/plain" });
|
||||||
|
|
||||||
|
// Create an anchor element and set its attributes
|
||||||
|
var a = document.createElement("a");
|
||||||
|
a.href = window.URL.createObjectURL(blob); // Create a URL for the Blob
|
||||||
|
a.download = "example.txt";
|
||||||
|
|
||||||
|
// Append the anchor element to the body
|
||||||
|
document.body.appendChild(a);
|
||||||
|
|
||||||
|
// Programmatically click the anchor to trigger the download
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
// Remove the anchor from the body
|
||||||
|
document.body.removeChild(a);
|
||||||
|
|
||||||
|
|
||||||
|
* may have to concatenate the games with newlines prior to making the blob. DEFINITELY HAVE TO
|
||||||
|
Keep in mind that if the number of games is large, and you're dealing with a substantial amount of data, you might want to consider optimizing the concatenation process to avoid performance issues. Depending on your use case, you could use an array to store the individual games and then use the join method to concatenate them with a separator.
|
||||||
|
|
||||||
|
-- you will have to piece the app together
|
||||||
|
|
||||||
|
UPDATE: since your site is static and your client essentially has to download the entire website to their machine first it means that requests are not coming from a different origin. This means you don't need jsonp or cors. So you can write your application without the necessary complications
|
18
jsonp/arch_dl.html
Normal file
18
jsonp/arch_dl.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Chess.com API Request</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<label for="username">Enter Chess.com Username:</label>
|
||||||
|
<input type="text" id="username" placeholder="Enter username">
|
||||||
|
|
||||||
|
<button onclick="makeRequest()">Fetch Games</button>
|
||||||
|
|
||||||
|
<script src="./main.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
35
jsonp/main.js
Normal file
35
jsonp/main.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
// Define userAgents directly in the script
|
||||||
|
const userAgents = [
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; rv:109.0) Gecko/20100101 Firefox/113.0",
|
||||||
|
"Mozilla/5.0 (Android 12; Mobile; rv:109.0) Gecko/113.0 Firefox/113.0",
|
||||||
|
"mozilla/5.0 (macintosh; intel mac os x 10.15; rv:109.0) gecko/20100101 firefox/113.0",
|
||||||
|
];
|
||||||
|
|
||||||
|
function getRandomUserAgent() {
|
||||||
|
return userAgents[Math.floor(Math.random() * userAgents.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeRequest() {
|
||||||
|
var username = document.getElementById('username').value;
|
||||||
|
var randomUserAgent = getRandomUserAgent();
|
||||||
|
|
||||||
|
var url = `https://api.chess.com/pub/player/hippodrunkimus/games/2023/03?callback=jsonpCallback&user_agent=${encodeURIComponent(randomUserAgent)}`;
|
||||||
|
|
||||||
|
var script = document.createElement('script');
|
||||||
|
script.src = url;
|
||||||
|
|
||||||
|
window.jsonpCallback = function(data) {
|
||||||
|
archive_list = data;
|
||||||
|
console.log(archive_list);
|
||||||
|
document.head.removeChild(script);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.head.appendChild(script);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://api.chess.com/pub/player/hippodrunkimus/games/2023/03 (can't use .pgn)
|
||||||
|
//https://api.chess.com/pub/player/${username}/games/archives?callback=jsonpCallback&user_agent=${encodeURIComponent(randomUserAgent)}`
|
39
jsonp/test.html
Normal file
39
jsonp/test.html
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>File Download App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<button id="downloadButton">Download File</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Function to trigger the download
|
||||||
|
function downloadFile() {
|
||||||
|
// Create a Blob containing the file data
|
||||||
|
var fileData = "Hello, this is the content of the file!"; // this will end up being the concatenated .pgn results returned by the async function
|
||||||
|
var blob = new Blob([fileData], { type: "text/plain" });
|
||||||
|
|
||||||
|
// Create an anchor element and set its attributes
|
||||||
|
var a = document.createElement("a");
|
||||||
|
a.href = window.URL.createObjectURL(blob);
|
||||||
|
a.download = "example.txt";
|
||||||
|
|
||||||
|
// Append the anchor element to the body
|
||||||
|
document.body.appendChild(a);
|
||||||
|
|
||||||
|
// Programmatically click the anchor to trigger the download
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
// Remove the anchor from the body
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the downloadFile function to the button click event
|
||||||
|
document.getElementById("downloadButton").addEventListener("click", downloadFile);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
13
jsonp/userAgents.js
Normal file
13
jsonp/userAgents.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
// userAgents.js
|
||||||
|
|
||||||
|
export const userAgents = [
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; rv:109.0) Gecko/20100101 Firefox/113.0",
|
||||||
|
"Mozilla/5.0 (Android 12; Mobile; rv:109.0) Gecko/113.0 Firefox/113.0",
|
||||||
|
"mozilla/5.0 (macintosh; intel mac os x 10.15; rv:109.0) gecko/20100101 firefox/113.0",
|
||||||
|
// Add more user agents as needed
|
||||||
|
];
|
||||||
|
|
76
non_jsonp/=
Normal file
76
non_jsonp/=
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Chess.com API Request</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<label for="username">Enter Chess.com Username:</label>
|
||||||
|
<input type="text" id="username" placeholder="Enter username">
|
||||||
|
|
||||||
|
<button onclick="makeRequest()">Fetch Games</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const userAgents = [
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
// Add more user agents as needed
|
||||||
|
];
|
||||||
|
|
||||||
|
let jsonData;
|
||||||
|
|
||||||
|
function getRandomUserAgent() {
|
||||||
|
return userAgents[Math.floor(Math.random() * userAgents.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function makeRequest() {
|
||||||
|
try {
|
||||||
|
const username = document.getElementById('username').value;
|
||||||
|
const randomUserAgent = getRandomUserAgent();
|
||||||
|
|
||||||
|
const url = `https://api.chess.com/pub/player/${username}/games/archives`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
'User-Agent': randomUserAgent,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
jsonData = await response.json();
|
||||||
|
|
||||||
|
// Process the URLs in the archives array
|
||||||
|
if (jsonData && jsonData.archives && Array.isArray(jsonData.archives)) {
|
||||||
|
const promises = jsonData.archives.map(function(url) {
|
||||||
|
return makeAsyncRequest(url, randomUserAgent);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Use Promise.all to wait for all requests to complete
|
||||||
|
const results = await Promise.all(promises);
|
||||||
|
console.log("All requests completed:", results);
|
||||||
|
// Perform further processing with the results
|
||||||
|
const concatenatedContent = results.map(data => data.pgn).join('\n');
|
||||||
|
console.log("Concatenated PGN:", concatenatedContent);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in one or more requests:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function makeAsyncRequest(url, userAgent) {
|
||||||
|
try {
|
||||||
|
const asyncUrl = `${url}?user_agent=${encodeURIComponent(userAgent)}`;
|
||||||
|
const response = await fetch(asyncUrl);
|
||||||
|
const data = await response.json();
|
||||||
|
console.log("Async Response:", data);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in async request:", error);
|
||||||
|
throw error; // Rethrow the error to propagate it to the Promise.all catch block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
80
non_jsonp/index.html
Normal file
80
non_jsonp/index.html
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Chess.com API Request</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<label for="username">Enter Chess.com Username:</label>
|
||||||
|
<input type="text" id="username" placeholder="Enter username">
|
||||||
|
|
||||||
|
<button onclick="makeRequest()">Fetch Games</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const userAgents = [
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; rv:109.0) Gecko/20100101 Firefox/113.0",
|
||||||
|
"Mozilla/5.0 (Android 12; Mobile; rv:109.0) Gecko/113.0 Firefox/113.0",
|
||||||
|
"mozilla/5.0 (macintosh; intel mac os x 10.15; rv:109.0) gecko/20100101 firefox/113.0",
|
||||||
|
];
|
||||||
|
|
||||||
|
let jsonData;
|
||||||
|
|
||||||
|
function getRandomUserAgent() {
|
||||||
|
return userAgents[Math.floor(Math.random() * userAgents.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function makeRequest() {
|
||||||
|
try {
|
||||||
|
const username = document.getElementById('username').value;
|
||||||
|
const randomUserAgent = getRandomUserAgent();
|
||||||
|
|
||||||
|
const url = `https://api.chess.com/pub/player/${username}/games/archives`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
'User-Agent': randomUserAgent,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
jsonData = await response.json();
|
||||||
|
|
||||||
|
// Process the URLs in the archives array
|
||||||
|
if (jsonData && jsonData.archives && Array.isArray(jsonData.archives)) {
|
||||||
|
const url = archiveUrl + '/.pgn';
|
||||||
|
const promises = jsonData.archives.map(function(url) {
|
||||||
|
return makeAsyncRequest(url, randomUserAgent);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Use Promise.all to wait for all requests to complete
|
||||||
|
const results = await Promise.all(promises);
|
||||||
|
console.log("All requests completed:", results);
|
||||||
|
// Perform further processing with the results
|
||||||
|
const concatenatedContent = results.map(data => data.pgn).join('\n');
|
||||||
|
console.log("Concatenated PGN:", concatenatedContent);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in one or more requests:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function makeAsyncRequest(url, userAgent) {
|
||||||
|
try {
|
||||||
|
const asyncUrl = `${url}?user_agent=${encodeURIComponent(userAgent)}`;
|
||||||
|
const response = await fetch(asyncUrl);
|
||||||
|
const data = await response.json();
|
||||||
|
console.log("Async Response:", data);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in async request:", error);
|
||||||
|
throw error; // Rethrow the error to propagate it to the Promise.all catch block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -29,12 +29,22 @@ function getRandomUserAgent() {
|
|||||||
return userAgents[Math.floor(Math.random() * userAgents.length)];
|
return userAgents[Math.floor(Math.random() * userAgents.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function playerArchives(username, callback) {
|
function playerArchives(username, callback) {
|
||||||
// Replace 'YOUR_API_KEY' with your Chess.com API key
|
const apiKey = 'YOUR_API_KEY'; // Replace with your Chess.com API key
|
||||||
const url = `https://api.chess.com/pub/player/${username}/games/archives`;
|
const url = `https://api.chess.com/pub/player/${username}/games/archives?apikey=${apiKey}`;
|
||||||
const response = await fetch(url);
|
|
||||||
const data = await response.json();
|
// Choose a random user agent from the userAgents array
|
||||||
window[callback](data.archives);
|
const user_agent = getRandomUserAgent();
|
||||||
|
|
||||||
|
// Create a script element
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.id = 'jsonpScript';
|
||||||
|
script.src = `${url}&callback=${callback}`;
|
||||||
|
|
||||||
|
// Add the User-Agent header to the script element
|
||||||
|
script.setAttribute('User-Agent', user_agent);
|
||||||
|
|
||||||
|
document.head.appendChild(script); // Append the script element to the document head
|
||||||
}
|
}
|
||||||
|
|
||||||
async function playerMonthly(url, callback) {
|
async function playerMonthly(url, callback) {
|
||||||
|
1
python_files/archives/carlosattack_archive.txt
Normal file
1
python_files/archives/carlosattack_archive.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
["https://api.chess.com/pub/player/carlosattack/games/2012/10", "https://api.chess.com/pub/player/carlosattack/games/2013/01", "https://api.chess.com/pub/player/carlosattack/games/2013/02", "https://api.chess.com/pub/player/carlosattack/games/2013/03", "https://api.chess.com/pub/player/carlosattack/games/2013/04", "https://api.chess.com/pub/player/carlosattack/games/2013/07", "https://api.chess.com/pub/player/carlosattack/games/2014/08", "https://api.chess.com/pub/player/carlosattack/games/2015/09", "https://api.chess.com/pub/player/carlosattack/games/2015/10", "https://api.chess.com/pub/player/carlosattack/games/2015/11", "https://api.chess.com/pub/player/carlosattack/games/2015/12", "https://api.chess.com/pub/player/carlosattack/games/2016/01", "https://api.chess.com/pub/player/carlosattack/games/2016/04", "https://api.chess.com/pub/player/carlosattack/games/2016/08", "https://api.chess.com/pub/player/carlosattack/games/2016/10", "https://api.chess.com/pub/player/carlosattack/games/2017/10", "https://api.chess.com/pub/player/carlosattack/games/2018/02", "https://api.chess.com/pub/player/carlosattack/games/2018/03", "https://api.chess.com/pub/player/carlosattack/games/2018/04", "https://api.chess.com/pub/player/carlosattack/games/2019/02", "https://api.chess.com/pub/player/carlosattack/games/2019/06", "https://api.chess.com/pub/player/carlosattack/games/2019/07", "https://api.chess.com/pub/player/carlosattack/games/2019/08", "https://api.chess.com/pub/player/carlosattack/games/2019/09", "https://api.chess.com/pub/player/carlosattack/games/2019/10", "https://api.chess.com/pub/player/carlosattack/games/2019/11", "https://api.chess.com/pub/player/carlosattack/games/2019/12", "https://api.chess.com/pub/player/carlosattack/games/2020/02", "https://api.chess.com/pub/player/carlosattack/games/2020/03", "https://api.chess.com/pub/player/carlosattack/games/2020/04", "https://api.chess.com/pub/player/carlosattack/games/2020/05", "https://api.chess.com/pub/player/carlosattack/games/2020/06", "https://api.chess.com/pub/player/carlosattack/games/2020/07", "https://api.chess.com/pub/player/carlosattack/games/2020/08", "https://api.chess.com/pub/player/carlosattack/games/2020/09", "https://api.chess.com/pub/player/carlosattack/games/2020/10", "https://api.chess.com/pub/player/carlosattack/games/2020/11", "https://api.chess.com/pub/player/carlosattack/games/2020/12", "https://api.chess.com/pub/player/carlosattack/games/2021/01", "https://api.chess.com/pub/player/carlosattack/games/2021/02", "https://api.chess.com/pub/player/carlosattack/games/2021/03", "https://api.chess.com/pub/player/carlosattack/games/2021/04", "https://api.chess.com/pub/player/carlosattack/games/2021/05", "https://api.chess.com/pub/player/carlosattack/games/2021/06", "https://api.chess.com/pub/player/carlosattack/games/2021/07", "https://api.chess.com/pub/player/carlosattack/games/2021/08", "https://api.chess.com/pub/player/carlosattack/games/2021/09", "https://api.chess.com/pub/player/carlosattack/games/2021/10", "https://api.chess.com/pub/player/carlosattack/games/2021/11", "https://api.chess.com/pub/player/carlosattack/games/2021/12", "https://api.chess.com/pub/player/carlosattack/games/2022/01", "https://api.chess.com/pub/player/carlosattack/games/2022/02", "https://api.chess.com/pub/player/carlosattack/games/2022/03", "https://api.chess.com/pub/player/carlosattack/games/2022/04", "https://api.chess.com/pub/player/carlosattack/games/2022/05", "https://api.chess.com/pub/player/carlosattack/games/2022/06", "https://api.chess.com/pub/player/carlosattack/games/2022/07", "https://api.chess.com/pub/player/carlosattack/games/2022/08", "https://api.chess.com/pub/player/carlosattack/games/2022/09", "https://api.chess.com/pub/player/carlosattack/games/2023/01", "https://api.chess.com/pub/player/carlosattack/games/2023/02", "https://api.chess.com/pub/player/carlosattack/games/2023/03", "https://api.chess.com/pub/player/carlosattack/games/2023/04", "https://api.chess.com/pub/player/carlosattack/games/2023/05", "https://api.chess.com/pub/player/carlosattack/games/2023/06", "https://api.chess.com/pub/player/carlosattack/games/2023/07"]
|
1
python_files/archives/hippodrunkimus.txt
Normal file
1
python_files/archives/hippodrunkimus.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
["https://api.chess.com/pub/player/hippodrunkimus/games/2023/03", "https://api.chess.com/pub/player/hippodrunkimus/games/2023/04", "https://api.chess.com/pub/player/hippodrunkimus/games/2023/05", "https://api.chess.com/pub/player/hippodrunkimus/games/2023/06", "https://api.chess.com/pub/player/hippodrunkimus/games/2023/07"]
|
1
python_files/archives/hipposcottimus_archive.txt
Normal file
1
python_files/archives/hipposcottimus_archive.txt
Normal file
File diff suppressed because one or more lines are too long
1
python_files/archives/sebastian-mendoza_archive.txt
Normal file
1
python_files/archives/sebastian-mendoza_archive.txt
Normal file
File diff suppressed because one or more lines are too long
36698
python_files/combined.pgn
Normal file
36698
python_files/combined.pgn
Normal file
File diff suppressed because one or more lines are too long
73
python_files/player_games.py
Normal file
73
python_files/player_games.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import user_agents
|
||||||
|
import random
|
||||||
|
import requests
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import concurrent.futures
|
||||||
|
|
||||||
|
|
||||||
|
def playerArchives(username):
|
||||||
|
# Create archive list. This is a list of pages containing lists of games used for futher downloading
|
||||||
|
|
||||||
|
user_agent = random.choice(user_agents.user_agents) # load up random user agent from list
|
||||||
|
headers = {
|
||||||
|
'User-Agent':user_agent
|
||||||
|
}
|
||||||
|
url = f"https://api.chess.com/pub/player/{username}/games/archives"
|
||||||
|
archive = requests.get(url, headers=headers).json()['archives']
|
||||||
|
|
||||||
|
try:
|
||||||
|
cwd = os.getcwd()
|
||||||
|
path = os.path.join(cwd, 'archives')
|
||||||
|
os.makedirs(path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
file_name = os.path.join(path, username+'_archive.txt')
|
||||||
|
with open(file_name, 'w') as f:
|
||||||
|
json.dump(archive, f)
|
||||||
|
|
||||||
|
return archive
|
||||||
|
|
||||||
|
|
||||||
|
def playerMonthly(url=None):
|
||||||
|
|
||||||
|
user_agent = random.choice(user_agents.user_agents) # load up random user agent from list
|
||||||
|
headers = {
|
||||||
|
'User-Agent':user_agent
|
||||||
|
}
|
||||||
|
|
||||||
|
if url:
|
||||||
|
url=url+'/pgn' # connect to multi-game pgn download endpoint by appending a "pgn" to the url provided by url in archive list
|
||||||
|
else:
|
||||||
|
username=input("username: ")
|
||||||
|
YYYY=input("year in YYYY: ")
|
||||||
|
MM=input("month in MM: ")
|
||||||
|
url = f"https://api.chess.com/pub/player/{username}/games/{YYYY}/{MM}/pgn"
|
||||||
|
|
||||||
|
# get and save games list in .pgn format
|
||||||
|
games = requests.get(url, headers=headers).content.decode("utf-8")
|
||||||
|
|
||||||
|
return games
|
||||||
|
|
||||||
|
# Multithreaded games download
|
||||||
|
def threddGames(username=None, archive=None):
|
||||||
|
|
||||||
|
if archive:
|
||||||
|
with open(archive) as f:
|
||||||
|
archive = json.load(f)
|
||||||
|
else:
|
||||||
|
archive = playerArchives(username)
|
||||||
|
|
||||||
|
# async download games
|
||||||
|
games_list = []
|
||||||
|
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||||
|
for future in executor.map(playerMonthly, archive):
|
||||||
|
games_list.extend(future)
|
||||||
|
pgn_db = "\n\n".join(games_list)
|
||||||
|
with open(username+'.pgn', 'w') as f:
|
||||||
|
f.write(pgn_db)
|
||||||
|
|
||||||
|
return pgn_db
|
||||||
|
|
8
python_files/user_agents.py
Normal file
8
python_files/user_agents.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
user_agents = [
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; rv:109.0) Gecko/20100101 Firefox/113.0",
|
||||||
|
"Mozilla/5.0 (Android 12; Mobile; rv:109.0) Gecko/113.0 Firefox/113.0",
|
||||||
|
"mozilla/5.0 (macintosh; intel mac os x 10.15; rv:109.0) gecko/20100101 firefox/113.0",
|
||||||
|
]
|
@ -11,4 +11,4 @@ const userAgents = [
|
|||||||
// Add more user agents as needed
|
// Add more user agents as needed
|
||||||
];
|
];
|
||||||
|
|
||||||
export default userAgents;
|
module.exports = userAgents;
|
||||||
|
Loading…
Reference in New Issue
Block a user