Automated download of LANDSAT data from USGS website

Overview

LANDSAT-Download

It seems USGS has changed the structure of its data, and so far, I have not been able to find the direct links to the products? Help welcome !

you might also be interested by the S2-download tool to download Sentinel-2 data https://github.com/olivierhagolle/Sentinel-download/blob/master/README.md

The routine provided below enables to automatically download LANDSAT data, using the current (April 2014) version of EarthExplorer system. This new version (2014-08-19) does not need to provide the exact overpass date anymore, I have reused here an idea of my colleague Michel Le Page at CESBIO (Thanks Michel !), though implemented differently.

It works for LANDSAT 8 and LANDSAT 5&7, but needs that the data be already online. It was true for LANDSAT 8 until September 2014, but after that date, to avoid increasing the on-line data volume indefinitely, USGS started to clean out older data to replace them by the new ones. It is also the case for the older LANDSAT satellites. Depending on the products you need, it may be necessary to first order for the production of L1T products, on the EarthExplorer site http://earthexplorer.usgs.gov. And of course, you will need to have an account and password on the EarthExplorer website, and you will have to store it on the usgs.txt file. If you have an access through a proxy, you might try the -p option. It works through CNES proxy at least but was only tested there.

In 2016, USGS introduced a CRSF token for the authentification. @mkmitchell found a solution, which was later enhanced by @dswanepoel.

Examples :

This routine may be used in three ways :

  • iterative search, by providing the WRS-2 coordinates of the LANDSAT scene, for instance, (198,030) for Toulouse (-s option), , the start date (-d option), and the end date (-f option). If the end date is not provided, it is replaced by today's date by default. Example:

download_landsat_scene.py -o scene -b LC8 -d 20130127 -s 198030 -u usgs.txt -p proxy.txt --output /mnt/data/LANDSAT8/N0/

  • catalog search, by providing the WRS-2 coordinates of the LANDSAT scene, for instance, (198,030) for Toulouse (-s option), , the start date (-d option), and the end date (-f option). If the end date is not provided, it is replaced by today's date by default. Example:

download_landsat_scene.py -o catalog -b LC8 -d 20130127 -s 198030 -u usgs.txt -p proxy.txt --output /mnt/data/LANDSAT8/N0/

  • by providing a list of products to download, as in the example below:

python download_landsat_scene.py -o liste -l list2_landsat8.txt -u usgs.txt --output /mnt/data/LANDSAT8/N0/

with a file list2_landsat8.txt as provided below (the LANDSAT references must exist in the EarthExplorer catalog) :

Tunisie LC81910352013160LGN00

Tunisie LC81910362013160LGN00

The usgs.txt must contain your username and password on the same line separated by a blank.

If you do not use the --output option, the files will be downloaded to /tmp/Landsat (provided it exists)

Set a cloud limit to get only images with cloud cover below that limit. In the catalogue search mode, the program will get the best image below that limit. For example, if you set a limit of 20% and it finds 3 images it will download the one will less cloud cover.

To see all the options : download_landsat_scene.py -h

The nice progress bar was provided by Jake Brinkmann ( Thanks Jake !)

Vascobnunes made large improvements, in terms of performance (connection to EarthExplorer was included in the download loop !) and added options to automatically unzip data, and configuration for LANDSAT 5 and 7. (Thanks Vascobnunes !)

Troubleshooting

There is a difficulty with this code which is the necessity to know in advance the station where the product is received, the directory where it is stored, and the version of the product. If this is not known, there is a need to try the various possibilities, which takes some time. It is also not excluded that USGS might change these values from time to time. They ghanged it for instance when introducing Landsat Coolelctions

Here is what we found so far :

| Satellite name | directory | Stations | Versions |

| LT5 | 12266 | GLC,ASA,KIR,MOR,KHC,PAC,KIS,CHM,LGS,MGR,COA,MPS,JSA | 0-1 |

| LE7 | 12267 |'EDC','SGS','AGS','ASN' | 0-1 |

| LT8 | 12864 | 'LGN' | 0-5 |

If the configuration we provide by default does not work, you may provide the directory and station on the command line, using options --dir and --station . If you use thess options, it might speed a little the download as the tool will not need to search for all possible stations.

To find the station, you can try to download a preoduct from the user interface (https://earthexplorer.usgs.gov), annd check with the web console which dir and station the product belongs to. Here is for instance a screen copy provided by

Comments
  • 403 Forbidden

    403 Forbidden

    Is anyone else experiencing 'USGS not currently responding to requests'?

    When catching the error it is giving me a 403 Forbidden.

    My user name and password are working in Earth Explorer web interface when I try download the exact file using the link LANDSAT-Download generates.

    I have logged out of Earth Explorer before using this script as well.

    opened by benboughton1 17
  • urllib2.HTTPError: HTTP Error 503: Service Unavailable

    urllib2.HTTPError: HTTP Error 503: Service Unavailable

    Good evening Olivier,

    Thank you very much for sharing this script! I'm a first-time user, and I've been running into an HTTP Error 503. At the moment, I'm just testing things out by using your README example, with no proxy and my own usgs.txt file:

    download_landsat_scene.py -o scene -b LC8 -d 20130127 -s 043034 -u usgs.txt --output /home/miriam/Documents/test/

    The full error is:

    None None Traceback (most recent call last): File "download_landsat_scene.py", line 594, in main() File "download_landsat_scene.py", line 412, in main connect_earthexplorer_no_proxy(usgs) File "download_landsat_scene.py", line 79, in connect_earthexplorer_no_proxy f = urllib2.urlopen(request) File "/usr/lib/python2.7/urllib2.py", line 127, in urlopen return _opener.open(url, data, timeout) File "/usr/lib/python2.7/urllib2.py", line 410, in open response = meth(req, response) File "/usr/lib/python2.7/urllib2.py", line 523, in http_response 'http', request, response, code, msg, hdrs) File "/usr/lib/python2.7/urllib2.py", line 442, in error result = self._call_chain(*args) File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain result = func(*args) File "/usr/lib/python2.7/urllib2.py", line 629, in http_error_302 return self.parent.open(new, timeout=req.timeout) File "/usr/lib/python2.7/urllib2.py", line 410, in open response = meth(req, response) File "/usr/lib/python2.7/urllib2.py", line 523, in http_response 'http', request, response, code, msg, hdrs) File "/usr/lib/python2.7/urllib2.py", line 448, in error return self._call_chain(*args) File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain result = func(*args) File "/usr/lib/python2.7/urllib2.py", line 531, in http_error_default raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) urllib2.HTTPError: HTTP Error 503: Service Unavailable

    Generally, I think a 503 error would signal some issue with the webpage itself, but I can sign in just fine using a browser, and a quick check with curl (curl -I "https://ers.cr.usgs.gov/login") says "HTTP/1.1 200 OK."

    Do you know what the source of this issue may be? Many thanks, in advance. I really appreciate your help.

    opened by mrjohnston 10
  • Added handling for csrftoken

    Added handling for csrftoken

    First pull request!

    For some reason there was an extra space in some of the code so I removed those in the area I was working in. I'm not sure if this works for proxy but it worked fine for no_proxy.

    opened by mkmitchell 10
  • After USGS site maintenance, code no longer works

    After USGS site maintenance, code no longer works

    Brad-Batess-MacBook-Pro:Landsat_Data bradbates$ python download_landsat_scene.py -o scene -b LC8 -d 20150526 -f 20150601 -s 029033 -u usgs.txt --output /Users/bradbates/Desktop/Landsat_Data/Landsat_8 None None Establishing connection to Earthexplorer... Traceback (most recent call last): File "download_landsat_scene.py", line 564, in main() File "download_landsat_scene.py", line 384, in main connect_earthexplorer_no_proxy(usgs)
    File "download_landsat_scene.py", line 58, in connect_earthexplorer_no_proxy f = opener.open("https://earthexplorer.usgs.gov/login/", params) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 410, in open response = meth(req, response) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 523, in http_response 'http', request, response, code, msg, hdrs) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 448, in error return self._call_chain(_args) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 382, in _call_chain result = func(_args) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 531, in http_error_default raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) urllib2.HTTPError: HTTP Error 404: Not Found

    opened by blbates 9
  • Addition of unzip (for windows), bird and cloud options. LT5 and LT7 download capability

    Addition of unzip (for windows), bird and cloud options. LT5 and LT7 download capability

    I added the following options:

    • z - to unzip downloaded tgz files. Uses the tartool (https://tartool.codeplex.com/)
    • b - which lets you select the product you're looking for (LT5, LE7 or LC8)
    • c - which lets you define a cloud cover limit for the downloaded images. If an image is found with clouds below the limit the script stops looking for more images within the time interval. If not, it doesn't keep the image and tries to find another.

    Landsat 5 and Landsat 7 download wasn't working (at least for me). I fixed that.

    The connection to earthexplorer was established within the while loop, so it was repeating it for each iteration. I moved that block to before the while loop, making the process much faster.

    opened by vascobnunes 7
  • Proxying not working

    Proxying not working

    something changed in the USGS interface, not allowing the proxying "urllib2.URLError: <urlopen error Tunnel connection failed: 403 Forbidden>" Any idea on why this occurs?

    opened by vascobnunes 6
  • Error downloading LC8 images

    Error downloading LC8 images

    Hi there,

    I am getting an error and don't know the actual issue? The query I run is as follows: "E:\xx_2_Python_Automation_Scripts\TEMP\Automated_Download_LANDSAT\LANDSAT-Download-master>download_landsat_scene.py -o scene -b LC8 -d 20161001 -s 170073 -u E:\xx_2_Python_Automation_Scripts\TEMP\Automated_Download_LANDSAT\LANDSAT-Download-master\usgs.txt --output E:\xx_2_Python_Automation_Scripts\TEMP\Automated_Download_LANDSAT\TEST_OUTPUTS"

    And the error that comes up is the following: "Searching for images on (julian date): 2016278... http://earthexplorer.usgs.gov/download/4923/LC81700732016278LGN00/STANDARD/EE error : file is in html and not an expected binary file result saved in ./error_output.html product LC81700732016278LGN00 not found http://earthexplorer.usgs.gov/download/4923/LC81700732016278LGN01/STANDARD/EE http://earthexplorer.usgs.gov/download/4923/LC81700732016278LGN02/STANDARD/EE Searching for images on (julian date): 2016294... http://earthexplorer.usgs.gov/download/4923/LC81700732016294LGN00/STANDARD/EE error : file is in html and not an expected binary file result saved in ./error_output.html product LC81700732016294LGN00 not found http://earthexplorer.usgs.gov/download/4923/LC81700732016294LGN01/STANDARD/EE http://earthexplorer.usgs.gov/download/4923/LC81700732016294LGN02/STANDARD/EE"

    Not too sure why it is failing to find the results.

    Thanks!

    opened by jens2121 5
  • Download very slow for Windows

    Download very slow for Windows

    Hi Olivier,

    after some testing everything works fine for me on Windows as well as on Linux. There remains just one issue regarding the download speed on Windows. Compared to Linux it is much slower (factor 10 ~200KB/s to 2MB/s), even though the Linux OS is implemented on a Virtual Machine on the same Desktop as Windows(so both are connected to the same Network). I am not a python expert, so do you have any clue what this might cause? Thanks,

    Fabian

    opened by FabianVista 5
  • What is necessary to get Landsat 5 and 7?

    What is necessary to get Landsat 5 and 7?

    First of all, congratulations on your script. It will certainly be of much help to me. I was able to download LC8 images, but could get images with dates previous to Landsat 8 being operational. Also, suggestion for future improvement: automatically unpack the tgz files... Maybe I can even try to help you with that if you're interested. Thanks

    opened by vascobnunes 5
  • urllib2 Error

    urllib2 Error

    Hi,

    I am trying to run the code to download some landsat scenes but get this errors:

    Establishing connection to Earthexplorer with proxy...
    Traceback (most recent call last):
      File "download_landsat_scene.py", line 592, in <module>
        main()
      File "download_landsat_scene.py", line 410, in main
        connect_earthexplorer_proxy(proxy,usgs)
      File "download_landsat_scene.py", line 37, in connect_earthexplorer_proxy
        data=urllib2.urlopen("https://earthexplorer.usgs.gov/").read()
      File "/root/anaconda3/envs/py2/lib/python2.7/urllib2.py", line 154, in urlopen
        return opener.open(url, data, timeout)
      File "/root/anaconda3/envs/py2/lib/python2.7/urllib2.py", line 429, in open
        response = self._open(req, data)
      File "/root/anaconda3/envs/py2/lib/python2.7/urllib2.py", line 447, in _open
        '_open', req)
      File "/root/anaconda3/envs/py2/lib/python2.7/urllib2.py", line 407, in _call_chain
        result = func(*args)
      File "/root/anaconda3/envs/py2/lib/python2.7/urllib2.py", line 1241, in https_open
        context=self._context)
      File "/root/anaconda3/envs/py2/lib/python2.7/urllib2.py", line 1198, in do_open
        raise URLError(err)
    urllib2.URLError: <urlopen error [Errno -2] Name or service not known>
    

    I have hanged from http://ers.cr.usgs.gov/ to http://earthexplorer.usgs.gov/ like you said in the post, but always get the same error. Appreciate your help.

    Best regards

    opened by Digdgeo 4
  • Not able to download data

    Not able to download data

    Thanks for the code! I am first time user but failed to use the script, here is my script and error: python ./download_landsat_scene.py -o scene -s 100062 -b LC8 --dir 12864 --station 'LGN' -d 20180321 -u usgs.txt

    and the error: LGN 12864 Searching for images on (julian date): 2018081... https://earthexplorer.usgs.gov/download/12864/LC81000622018081LGN00/STANDARD/EE URL Error: [Errno 8] _ssl.c:480: EOF occurred in violation of protocol https://earthexplorer.usgs.gov/download/12864/LC81000622018081LGN00/STANDARD/EE

    in the output file only one log.txt with [] inside.

    I tried one of the links in browser (for example:https://earthexplorer.usgs.gov/download/12864/LC81000622018081LGN00/STANDARD/EE) and it works perfect, and the download started after I input my credential. Not sure what I am doing wrong. Any help is great appreciated!!!

    opened by llin-csiss 4
  • scenes found, but

    scenes found, but "EarthExplorerError: Download is not available" error comes while downloading

    import json from landsatxplore.api import API from landsatxplore.earthexplorer import EarthExplorer

    Initialize a new API instance and get an access key

    usgs_username = "******" usgs_password = "******"

    api = API(usgs_username, usgs_password)

    Search for Landsat TM scenes

    scenes = api.search( dataset='landsat_ot_c2_l1', latitude=30.9, longitude=75.85, #bbox= (70, 28, 80, 32), #(xmin, ymin, xmax, ymax), start_date='2017-01-01', end_date='2017-04-01', max_cloud_cover=10 )

    print(f"{len(scenes)} scenes found.")

    Process the result

    for scene in scenes: print(scene['acquisition_date'].strftime('%Y-%m-%d')) # Write scene footprints to disk fname = f"{scene['landsat_product_id']}.geojson" with open(fname, "w") as f: json.dump(scene['spatial_coverage'].geo_interface, f) print(f)

    api.logout()

    output

    3 scenes found. 2017-03-19 <_io.TextIOWrapper name='LC08_L1TP_148038_20170319_20200904_02_T1.geojson' mode='w' encoding='cp1252'> 2017-03-19 <_io.TextIOWrapper name='LC08_L1TP_148039_20170319_20200904_02_T1.geojson' mode='w' encoding='cp1252'> 2017-02-15 <_io.TextIOWrapper name='LC08_L1TP_148039_20170215_20200905_02_T1.geojson' mode='w' encoding='cp1252'>

    Downloading Scenes

    ee = EarthExplorer(usgs_username, usgs_password)

    ee.download('LC08_L1TP_148038_20170319_20200904_02_T1', output_dir=r'D:\RF_Paper\JAM\MODIS')

    ee.logout()

    error


    EarthExplorerError Traceback (most recent call last) in 2 ee = EarthExplorer(usgs_username, usgs_password) 3 ----> 4 ee.download('LC08_L1TP_148038_20170319_20200904_02_T1', output_dir=r'D:\RF_Paper\JAM\MODIS') 5 6 ee.logout()

    ~\Anaconda3\lib\site-packages\landsatxplore\earthexplorer.py in download(self, identifier, output_dir, dataset, timeout, skip) 148 data_product_id=DATA_PRODUCTS[dataset], entity_id=entity_id 149 ) --> 150 filename = self._download(url, output_dir, timeout=timeout, skip=skip) 151 return filename

    ~\Anaconda3\lib\site-packages\landsatxplore\earthexplorer.py in _download(self, url, output_dir, timeout, chunk_size, skip) 90 error_msg = r.json().get("errorMessage") 91 if error_msg: ---> 92 raise EarthExplorerError(error_msg) 93 download_url = r.json().get("url") 94

    EarthExplorerError: Download is not available

    opened by abhilashsinghimd 0
  • Error : CSRF_Token not found

    Error : CSRF_Token not found

    Hi,

    I used this code without problems earlier this year. Now I keep getting the error "Error : CSRF_Token not found”. If I change line 68:
    m = re.search(r'<input .?name="csrf_token".?value="(.?)"', data) to m = re.search(r'<input .?name="csrf".?value="(.?)"', data) I don't get the error. But the download still doesn't work.

    opened by karinahansen 1
  • Webscraping Help

    Webscraping Help

    Yo yo, I'm trying to webscrape the shitttttt out of Yahoo finance and they blocked me with a 503 error, which I'm given to understand means my IP doesn't work? ANYWAY, this is a thing I want to be able to make into an exe and put online someday and I don't wanna be limited by the silly webscraping rules. Is there an IP randomiser module? Would a VPN module work? Or should I try Tor? Help me out please guys, much appreciated! Or perhaps is there a better way for me to get on demand/live data on stocks etc?

    opened by WillHenryGates 0
  • No image was found in the catalog with the given specifications! Exiting...

    No image was found in the catalog with the given specifications! Exiting...

    After I run this code in Linux Mint 18.3....

    python download_landsat_scene.py -o catalog -b LE7 -d 20170401 -f 20171101 -s 191028 -u usgs.txt --output /home/alen/LANDSAT-Download-master/Landsat_download ... I get this output:

    None None Verifying catalog metadata files... Searching for images in catalog... No image was found in the catalog with the given specifications! Exiting...

    The same output is after using the manual example: python download_landsat_scene.py -o catalog -b LC8 -d 20130127 -s 198030 -u usgs.txt --output /home/alen/LANDSAT-Download-master/Landsat_download

    opened by mazingaro 1
  • Landsat 5 not downloading

    Landsat 5 not downloading

    This script is super cool beacuse it saves time in downloading data and has selective attributes put into consideration. however, I am trying to download Landsat5 data and it is just iterating through the archive with no result. Below is the command

    python download_landsat_scene.py -o scene -b LT5 -d 20000101 -f 20001231 -c 50 -s 169060 -u usgs.txt --output ~/Documents/GIS/

    opened by jkariukidev 3
Releases(v1.0.0)
  • v1.0.0(Jan 11, 2015)

    Automatically downloads Landsat images from (http://earthexplorer.usgs.gov/)

    Several options are provided, as the possibility of downloading all the scenes of a given scene defined by its Path-Row coordinates, of providing a list of files to download. it is also possible to only download files with less than XX% of clouds, or to unzip the files directly.

    This little software was developped by Olivier Hagolle and received contributions by Vasco Nunes and Jake Brinkmann

    Source code(tar.gz)
    Source code(zip)
Owner
Olivier Hagolle
Researcher at CESBIO - optical time series of rem. sens. images w/ high resolution. - atmospheric correction and cloud detection. - python and linux amateur
Olivier Hagolle
Client library for interfacing with USGS datasets

USGS API USGS is a python module for interfacing with the US Geological Survey's API. It provides submodules to interact with various endpoints, and c

Amit Kapadia 104 Dec 30, 2022
Get Landsat surface reflectance time-series from google earth engine

geextract Google Earth Engine data extraction tool. Quickly obtain Landsat multispectral time-series for exploratory analysis and algorithm testing On

Loïc Dutrieux 50 Dec 15, 2022
A simple python script that, given a location and a date, uses the Nasa Earth API to show a photo taken by the Landsat 8 satellite. The script must be executed on the command-line.

What does it do? Given a location and a date, it uses the Nasa Earth API to show a photo taken by the Landsat 8 satellite. The script must be executed

Caio 42 Nov 26, 2022
Script that allows to download data with satellite's orbit height and create CSV with their change in time.

Satellite orbit height ◾ Requirements Python >= 3.8 Packages listen in reuirements.txt (run pip install -r requirements.txt) Account on Space Track ◾

Alicja Musiał 2 Jan 17, 2022
A NASA MEaSUREs project to provide automated, low latency, global glacier flow and elevation change datasets

Notebooks A NASA MEaSUREs project to provide automated, low latency, global glacier flow and elevation change datasets This repository provides tools

NASA Jet Propulsion Laboratory 27 Oct 25, 2022
Search and download Copernicus Sentinel satellite images

sentinelsat Sentinelsat makes searching, downloading and retrieving the metadata of Sentinel satellite images from the Copernicus Open Access Hub easy

null 837 Dec 28, 2022
Download and process satellite imagery in Python using Sentinel Hub services.

Description The sentinelhub Python package allows users to make OGC (WMS and WCS) web requests to download and process satellite images within your Py

Sentinel Hub 659 Dec 23, 2022
Open Data Cube analyses continental scale Earth Observation data through time

Open Data Cube Core Overview The Open Data Cube Core provides an integrated gridded data analysis environment for decades of analysis ready earth obse

Open Data Cube 410 Dec 13, 2022
A public data repository for datasets created from TransLink GTFS data.

TransLink Spatial Data What: TransLink is the statutory public transit authority for the Metro Vancouver region. This GitHub repository is a collectio

Henry Tang 3 Jan 14, 2022
Using Global fishing watch's data to build a machine learning model that can identify illegal fishing and poaching activities through satellite and geo-location data.

Using Global fishing watch's data to build a machine learning model that can identify illegal fishing and poaching activities through satellite and geo-location data.

Ayush Mishra 3 May 6, 2022
Python Data. Leaflet.js Maps.

folium Python Data, Leaflet.js Maps folium builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js

null 6k Jan 2, 2023
Python tools for geographic data

GeoPandas Python tools for geographic data Introduction GeoPandas is a project to add support for geographic data to pandas objects. It currently impl

GeoPandas 3.5k Jan 3, 2023
Fiona reads and writes geographic data files

Fiona Fiona reads and writes geographic data files and thereby helps Python programmers integrate geographic information systems with other computer s

null 987 Jan 4, 2023
A package built to support working with spatial data using open source python

EarthPy EarthPy makes it easier to plot and manipulate spatial data in Python. Why EarthPy? Python is a generic programming language designed to suppo

Earth Lab 414 Dec 23, 2022
Python package for earth-observing satellite data processing

Satpy The Satpy package is a python library for reading and manipulating meteorological remote sensing data and writing it to various image and data f

PyTroll 882 Dec 27, 2022
Use Mapbox GL JS to visualize data in a Python Jupyter notebook

Location Data Visualization library for Jupyter Notebooks Library documentation at https://mapbox-mapboxgl-jupyter.readthedocs-hosted.com/en/latest/.

Mapbox 620 Dec 15, 2022
python toolbox for visualizing geographical data and making maps

geoplotlib is a python toolbox for visualizing geographical data and making maps data = read_csv('data/bus.csv') geoplotlib.dot(data) geoplotlib.show(

Andrea Cuttone 976 Dec 11, 2022
OSMnx: Python for street networks. Retrieve, model, analyze, and visualize street networks and other spatial data from OpenStreetMap.

OSMnx OSMnx is a Python package that lets you download geospatial data from OpenStreetMap and model, project, visualize, and analyze real-world street

Geoff Boeing 4k Jan 8, 2023
Tool to suck data from ArcGIS Server and spit it into PostgreSQL

chupaESRI About ChupaESRI is a Python module/command line tool to extract features from ArcGIS Server map services. Name? Think "chupacabra" or "Chupa

John Reiser 34 Dec 4, 2022