i wanted to make a small script that download "maps" automatically when the user open the ingame link.
Once the link Open in chrome, the extension get the current URL and send it to python(this is where i'm stuck right now) and then close the tab if successful (since it will fail if the python script isn't running?).
once in python i then proceed to download the map in question and add it to the Songs folder where the only thing he will to do is push F5
right now, i have these pieces of code:
Manifest.json:
{
"name": "Osu!AltDownload",
"version": "1.0",
"description": "A requirement to make osu!AltDownload work",
"permissions": ["tabs","http://localhost:5000/"],
"background": {
"scripts": ["Osu!AltDownload.js"],
"persistant": false
},
"manifest_version": 2
}
Osu!AltDownload.js
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
let url = tabs[0].url;
});
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:5000/",true);
xhr.send(url);
}
})
The script that receive the links and download the "maps":
import browser_cookie3
import requests
from bs4 import BeautifulSoup as BS
import re
import os
def maplink(osupath):
link = link #obtain link from POST ?
if link.split("/",4[:4]) == ['https:', '', 'osu.ppy.sh', 'beatmapsets']:
Download_map(osupath, link.split("#osu")[0])
def Download_map(osupath, link):
cj = browser_cookie3.load()
print("Downloading", link)
headers = {"referer": link}
with requests.get(link) as r:
t = BS(r.text, 'html.parser').title.text.split("ยท")[0]
with requests.get(link+"/download", stream=True, cookies=cj, headers=headers) as r:
if r.status_code == 200:
try:
id = re.sub("[^0-9]", "", link)
with open(os.path.abspath(osupath+"/Songs/"+id+" "+t+".osz"), "wb") as otp:
otp.write(r.content)
except:
print("You either aren't connected on osu!'s website or you're limited by the API, in which case you now have to wait 1h and then try again.")
i would like to add in that i used these lines of codes in my extension:
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:5000/",true);
xhr.send(url);
they come from one of my google searches but i don't really understand how i can handle POST request in python with that and i don't even know if i going the right way.
Some may say i haven't done much research at this subject but out of about 50 chrome tabs, i haven't really found anything that would really give me an idea of the right approach for this subject.
You have to run web server to get http requests
You can use Flask for this.
from flask import Flask, request
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
#print(request.form)
print(request.data)
return "OK"
if __name__ == '__main__':
app.run(port=5000)
If you want to send only url then you can use even GET instead of POST and send as
http://localhost:5000/?data=your_url
where your_url is what you get with tab[0].url.
xhr.open("GET", "http://localhost:5000/?data=" + url, true);
xhr.send(); // or maybe xhr.send(null);
And then you can get it with
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def index():
print(request.args.get('data'))
return "OK"
if __name__ == '__main__':
app.run(port=5000)
EDIT:
Example which tests Flask using directly JavaScript when you visit http://localhost:5000/test
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def index():
print(request.args.get('data'))
return "OK"
#app.route('/test/')
def test():
return """
<script>
var url = "https://stackoverflow.com/questions/65867136/need-help-about-sending-variable-from-chrome-extension-to-python/";
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:5000/?data=" + url, true);
xhr.send();
</script>
"""
if __name__ == '__main__':
app.run(port=5000)
Eventually I can test it with bookmarklet
javascript:{window.location='http://localhost:5000/?data='+encodeURIComponent(window.location.href)}
which I put as url in bookmark in favorites - but this reload page
or using modern fetch() (instead of old XMLHttpRequest()) and it doesn't reload page.
javascript:{fetch('http://localhost:5000/?data='+encodeURIComponent(window.location.href))}
Related
I am making a web app to help disabled people to navigate the internet. It is taking voice command through a JavaScript and sending the command to the Python app.py Flask app. However, weirdly enough it is not redirecting in any way and giving me 500 internal server error.
This is the JavaScript function which sends command -
// This function sends command to python
function sendCommand(command){
let userCommand = {
"command": command
}
$.ajax({
type: "POST",
url: "/command",
data: JSON.stringify(userCommand),
contentType: "application/JSON",
dataType: 'json',
success: function(){
window.location.href = "temp.html";
}
})
}
And this is the python flask app -
# Importing required libraries and functions
from flask import Flask, render_template, request, redirect
import speech_recognition as sr
import sys
# Initiating Flask
app = Flask(__name__)
# Command Global variable
COMMAND = ""
# Route to Command (Index) page
#app.route("/", methods=["GET", "POST"])
def index():
return render_template("index.html")
# Processing Command
#app.route('/command', methods=["POST"])
def get_javascript_data():
if request.method == "POST":
JSONdict = request.get_json()
COMMAND = JSONdict["command"]
print(f'{COMMAND}', file=sys.stdout)
if "search" in COMMAND:
print("TODOSearch")
elif ("music" and "play") in COMMAND:
print("TODO")
else:
print("TODO")
return redirect("/redirect")
#app.route("/redirect")
def redirect():
return render_template("redirect.html")
What is my fault over here?
You won't be able to redirect from flask on a POST request. Instead use return 200
Then the success function in your Ajax request should trigger.
If you need more flexibility, you can also return json data to the "success" or "error" function.
return json.dumps({'success' : True}), 200, {'ContentType' : 'application/json'}
I am following this tutorial to communicate between python and javascript. I am a beginner to this so I dont understand what exactly I am doing wrong.
Following is my code in index.html which sends a POST request to the python server side when the button is clicked:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript">
// setup some JSON to use
var cars = [
{ "make":"Porsche", "model":"911S" },
{ "make":"Mercedes-Benz", "model":"220SE" },
{ "make":"Jaguar","model": "Mark VII" }
];
window.onload = function() {
// setup the button click
document.getElementById("theButton").onclick = function() {
doWork()
};
}
function doWork() {
console.log("posting data")
// ajax the JSON to the server
$.post("receiver", cars, function(){
});
// stop link reloading the page
event.preventDefault();
}
</script>
This will send data using AJAX to Python:<br /><br />
<button type="button" id="theButton">Click Me!</button>
And this is my code on the python side:
import sys
from flask import Flask, render_template, request, redirect, Response
import random, json
app = Flask(__name__)
#app.route('/')
def output():
# serve index template
return render_template('index.html', name='Joe')
#app.route('/receiver', methods = ['GET', 'POST'])
def worker():
print("got some data")
# read json + reply
data = request.get_json()
result = ''
for item in data:
# loop over every row
result += str(item['make']) + ''
return result
if __name__ == '__main__':
app.run()
So, when I press the button in the index.html file, the tutorial says that I will be able to see a server response in the web browser. But even though my server is running, this is what I see in the network tab of developer tools for index.html in the Firefox web browser:
I don't understand what I am doing wrong and how I am supposed to see the communication between the client and server. Any help would be appreciated
Your request is not sending JSON, you have to stringify the cars object to send it as JSON.
function doWork() {
console.log("posting data")
// ajax the JSON to the server
$.post("receiver", JSON.stringify(cars), function(){
}, 'application/json');
// stop link reloading the page
event.preventDefault();
}
I also set the content type to application/json as this is required by request.get_json().
For your network tab issue, you have JS selected so you would not see ajax requests only javascript files. You have to have XHR selected or All.
I have setup a simple flask server using the following code:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
#app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
if __name__ == '__main__':
app.run(host = '0.0.0.0', port='5000')
From js I am making a request to the address using the follwing code
const theUrl="<myip>:5000/";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false);
xmlHttp.send();
console.log(xmlHttp.response);
The console shows
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>404 Not Found</title> <h1>Not Found</h1> <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
When I try to access the same url from the browser, it returns
Hello, cross-origin-world!
Is there something wrong I am doing with the server? I have tried the js code on a dummy address and I am able to get the contents of that website. There is something wrong with the Flask server.
Just wrote something for file uploads.
Hope this helps.
$('.custom-file-input').change(function () {
console.log($(this)[0].files[0].name);
$('.custom-file-label').text($(this)[0].files[0].name);
var formData = new FormData();
formData.append('file', $(this)[0].files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/', true);
xhr.send(formData)
I don't understand why one would use XHR for get requests, couldn't you just use Ajax instead?
The last parameter is whether the connection is asynchronous. Perhaps that's what wrong?
Also, don't use Flask built-in webserver for production environment, it just isn't made to cope with more than one user testing for example.
Furthermore, perhaps someone can tell me why not, however, I think you would be better off simply having url as the section of the url after the port declaration, in my example, notice that I only tell jquery or js to post data to / and this is because that means local server, or is interpreted to mean itself, so by default is prepended with your server IP and in this case the port 5000 aswell
I have a website that should send a name to a python script (on a third-party website) when a button is pressed. This python script will then make the name uppercase and return it back to the website.
Right now an XMLHttpRequest is correctly being sent when the button is pressed, but I'm unsure how I correctly send the data with the XMLHttpRequest, and then how this data is accessed in the python script.
XMLHttpRequest:
document.getElementById("myButton").addEventListener("click",
function() {
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://example.com/');
myRequest.onreadystatechange = function () {
if (myRequest.readyState === 4) {
alert(myRequest.responseText);
}
}
myRequest.send("Bob"});
}
);
Python script:
from flask import Flask, jsonify
from flask_cors import CORS
from requests import request
app = Flask(__name__)
CORS(app)
#app.route("/", methods=["GET"])
def hello_world():
return jsonify(name = (name_sent_by_XMLHttpRequest).upper()) # Should return "BOB"
if __name__ == '__main__':
app.run()
I know nothing about javascripts' XMLHTTPRequest but at some point, you need to send the name to the python server, right? HOW to do that is up to you, but a GET based option:
GET request with args: https://example.com/?name=your_name_goes_here
in your flask app, the function listening on route "/" will now have access to that arg, something like
name = request.args.get('name', '')
then you can uppercase() it, and return it in some format - probably XML ?
return Response(my_xml, mimetype='text/xml')
Update based on your comment: usually in a flask function, you would use the flask request object to get your URL parameters. In your example, you're importing the requests module as request, not using it, but clobbering the flask.request namesspace. Change your imports to something like this, and it should work normally:
from flask import Flask, jsonify, request
from flask_cors import CORS
import requests
So I tried javascript below
$(document).ready(function () {
$("#mtime").bind("click", function (e) {
$.getJSON('/test', function(data){
if(data.result==15){
alert("success!");
}else{
alert("fail....");
}
});
});
});
And made route using flask like this
#app.route('/test',methods=[GET,POST])
def test():
return jsonify(result=15)
But when I clicked the 'mtime' , alert method did not work.
And got this message from cmd window
"GET /test HTTP/1.1" 404 -"
How can i make it work?
As PJ Santoro wrote there are the quotation marks missing around GET and POST. However you don't need to add the methods explicitly as you only make a GET request which is the default.
from flask import Flask, render_template, jsonify
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/test')
def test():
return jsonify(result=15)
if __name__ == '__main__':
app.run(host='localhost', port=5000, debug=True)
Also it's better practice if you use url_for in your HTML file to generate the url for your endpoint. This way you can be sure the url changes when you decide to change your subdomain or use a Blueprint.
$(document).ready(function () {
$("#mtime").bind("click", function (e) {
$.getJSON({{ url_for('test') }}, function(data){
if(data.result==15){
alert("success!");
}else{
alert("fail....");
}
});
});
});