mikeboers / Flask-Images

On-demand resizing of images for Flask applications.
https://mikeboers.github.io/Flask-Images/
BSD 3-Clause "New" or "Revised" License
81 stars 43 forks source link

URL normalization on Windows #25

Open cassac opened 9 years ago

cassac commented 9 years ago

Running my server from localhost and trying to link to an external file produces a ValueError. Is this type of usage allowed?

src="{{resized_img_src('www.example.com/pics/mypicture.jpg'

it throws an error:

raise ValueError('path is not normalized')

iurisilvio commented 9 years ago

You missed the URL scheme, probably http or https.

src="{{resized_img_src('http://www.example.com/pics/mypicture.jpg') }}
mikeboers commented 9 years ago

@iurisilvio is correct, but it still shouldn't be raising that particular error. =P

cassac commented 9 years ago

I used the photo utilized in the Flask-Images demo: src="{{resized_img_src('https://farm4.staticflickr.com/3540/5753968652_a28184e5fb.jpg') }}"

And the same error is still produced:

ValueError ValueError: path is not normalized

Traceback (most recent call last) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1836, in call return self.wsgi_app(environ, start_response) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1820, in wsgi_app response = self.make_response(self.handle_exception(e)) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1403, in handle_exception reraise(exc_type, exc_value, tb) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\app.py", line 1461, in dispatch_request return self.view_functionsrule.endpoint File "c:\Users\mtts\projects\ci\app.py", line 33, in index return render_template('index.html', contacts=contacts) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\templating.py", line 128, in render_template context, ctx.app) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask\templating.py", line 110, in _render rv = template.render(context) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\jinja2\environment.py", line 969, in render return self.environment.handle_exception(exc_info, True) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\jinja2\environment.py", line 742, in handle_exception reraise(exc_type, exc_value, tb) File "c:\Users\mtts\projects\ci\templates\index.html", line 3, in top-level template code

File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask_images\core.py", line 490, in resized_img_src return self.build_url(path, **kw) File "c:\Users\mtts\projects\ci\venv\lib\site-packages\flask_images\core.py", line 144, in build_url raise ValueError('path is not normalized') ValueError: path is not normalized

Any ideas?

cassac commented 9 years ago

Would you mind sharing the configuration settings you used for the demo? (IMAGES_URL, IMAGES_NAME, IMAGES_PATH, etc.)

Cloning your app I still get the same error. Is there a possibility that my OS (Windows) is the culprit?

iurisilvio commented 9 years ago

Yes! Windows is the problem!

From Python docs (https://docs.python.org/2/library/os.path.html#os.path.normpath):

Normalize a pathname by collapsing redundant separators and up-level references so that A//B, A/B/, A/./B and A/foo/../B all become A/B. This string manipulation may change the meaning of a path that contains symbolic links. On Windows, it converts forward slashes to backward slashes. To normalize case, use normcase().

https://github.com/mikeboers/Flask-Images/blob/master/flask_images/core.py#L142

mikeboers commented 9 years ago

So that appears to be an oversight on my part. I guess I get to re-implement that logic, OR just use the posixpath module (which is what we OS X and Linux users have for os.path).

There is no additional configuration for the deployed demo.

cassac commented 9 years ago

Thanks for the lead. Exactly how would os.parth.normpath be implemented? In the configuration settings like this...?

IMAGES_PATH = os.path.normcase('/static')

mikeboers commented 9 years ago

Check out the "windows" branch I just pushed; I tried fixing the one spot that I think is causing you problems. There may be more (I'm very much not a Windows users).

cassac commented 9 years ago

Thanks for your assistance. I made the appropriate updates, but to no avail.

Just for reference anytime I put the direct local path into the image tag there isn't a problem. Inside IMG tag: src="{{resized_img_src('logo.png', width=50)}}" When the page loads the URL generated for the image is: http://localhost:5000/imgsizer/logo.png?v=VId8fQ&w=50&s=2H_o9VK9qsmeU2dHQa2J03lbkJQ

But when I use a variable for the image src like {{ pic.picpath }} the image doesn't display. The URL for the image when the page loads is:

http://localhost:5000/imgsizer/%7B%7Bpic.picpath%7D%7D?w=50&s=zLAooBQ9_nkRsrEKC7Q3WeXhJBc

It seems as though the variable isn't converting properly.

mikeboers commented 9 years ago

We don't parse strings as templates, so try passing the variable directly:

{{ resized_img_src(pic.picpath, width=50) }}

Cheers,

Mike

cassac commented 9 years ago

Awesome! I changed the syntax and now images stored locally are working. This is my content for the working tag.

src={{ resized_img_src(pic.picpath, width=50) }}

I updated the "posixpath" in core.py, but the external files are still having problems. I have a list of full path image links in a database I'm trying to display ie. 'http://www.example.com/pictures/pic.jpg' and that's when the ValueError is thrown or the image simply doesn't display. I'm assuming this has to do with the IMAGE_PATH? Do I need to specify IMAGE_PATH=['http://www.example.com/pictures/'] or something? Is there a need to set the IMAGE_NAME?

As for "url_for" versus "resized_img_src" does it matter when linking to a file like the path mentioned above?

mikeboers commented 9 years ago

Awesome! I changed the syntax and now images stored locally are working.

Hooray!

I updated the "posixpath" in core.py, but the external files are still having problems.

Is it the same problem as before? If not, can we get a backtrace? Have you tried the "windows" branch?

Do I need to specify IMAGE_PATH=['http://www.example.com/pictures/'] or something?

No. IMAGE_PATH is a list of directories that are searched for local images. It plays no part in remote images.

Is there a need to set the IMAGE_NAME?

No. IMAGE_NAME is the name of the endpoint, and only ever needs changing if you already have something that responds to "/imgsizer/...".

As for "url_for" versus "resized_img_src" does it matter when linking to a file like the path mentioned above?

No. They are functionally the same. The url_for variant is provided for an easy transition from using it to serve static files, e.g. via url_for('static', filename='your_image.jpg').

Thanks for sticking this out; I'd love to know that this works on Windows.

Cheers,

Mike

mikeboers commented 9 years ago

@cassac, did this ever work out for you?

tomcart90 commented 7 years ago

@mikeboers, I had the same issue yesterday. The following changes were needed to get Flask-Images working for me on Windows: https://github.com/tomcart90/Flask-Images/commit/50863882431ab55439bdd2f410f2f99343b22da3