1
0
mirror of https://github.com/instaloader/instaloader.git synced 2024-08-17 12:19:38 +02:00

Consistently use datetime type for handling dates

This commit is contained in:
Alexander Graf 2017-07-29 11:08:52 +02:00
parent 48d6f0226b
commit 66f69b5c21

View File

@ -2,7 +2,6 @@
"""Download pictures (or videos) along with their captions and other metadata from Instagram."""
import datetime
import getpass
import json
import os
@ -16,6 +15,7 @@ import tempfile
import time
from argparse import ArgumentParser
from base64 import b64decode, b64encode
from datetime import datetime
from io import BytesIO
from typing import Any, Callable, Dict, List, Optional
@ -87,10 +87,6 @@ class ConnectionException(InstaloaderException):
pass
def _epoch_to_string(epoch: float) -> str:
return datetime.datetime.fromtimestamp(epoch).strftime('%Y-%m-%d_%H-%M-%S')
def get_default_session_filename(username: str) -> str:
"""Returns default session filename for given username."""
dirname = tempfile.gettempdir() + "/" + ".instaloader-" + getpass.getuser()
@ -327,7 +323,7 @@ class Instaloader:
break
return comments
def download_pic(self, filename: str, url: str, date_epoch: float,
def download_pic(self, filename: str, url: str, mtime: datetime,
filename_suffix: Optional[str] = None) -> bool:
"""Downloads and saves picture with given url under given directory with given timestamp.
Returns true, if file was actually downloaded, i.e. updated."""
@ -345,7 +341,7 @@ class Instaloader:
with open(filename, 'wb') as file:
resp.raw.decode_content = True
shutil.copyfileobj(resp.raw, file)
os.utime(filename, (datetime.datetime.now().timestamp(), date_epoch))
os.utime(filename, (datetime.now().timestamp(), mtime.timestamp()))
return True
else:
raise ConnectionException("File \'" + url + "\' could not be downloaded.")
@ -373,7 +369,7 @@ class Instaloader:
file.write(json.dumps(unique_comments_list, indent=4))
self._log('comments', end=' ', flush=True)
def save_caption(self, filename: str, date_epoch: float, caption: str) -> None:
def save_caption(self, filename: str, mtime: datetime, caption: str) -> None:
"""Updates picture caption"""
filename += '.txt'
pcaption = caption.replace('\n', ' ').strip()
@ -413,30 +409,34 @@ class Instaloader:
self._log('txt', end=' ', flush=True)
with open(filename, 'wb') as text_file:
shutil.copyfileobj(BytesIO(caption), text_file)
os.utime(filename, (datetime.datetime.now().timestamp(), date_epoch))
os.utime(filename, (datetime.now().timestamp(), mtime.timestamp()))
def save_location(self, filename: str, location_json: Dict[str, str], date_epoch: float) -> None:
def save_location(self, filename: str, location_json: Dict[str, str], mtime: datetime) -> None:
filename += '_location.txt'
location_string = (location_json["name"] + "\n" +
"https://maps.google.com/maps?q={0},{1}&ll={0},{1}\n".format(location_json["lat"],
location_json["lng"]))
with open(filename, 'wb') as text_file:
shutil.copyfileobj(BytesIO(location_string.encode()), text_file)
os.utime(filename, (datetime.datetime.now().timestamp(), date_epoch))
os.utime(filename, (datetime.now().timestamp(), mtime.timestamp()))
self._log('geo', end=' ', flush=True)
def download_profilepic(self, name: str, url: str) -> None:
"""Downloads and saves profile pic with given url."""
date_object = datetime.datetime.strptime(requests.head(url).headers["Last-Modified"],
'%a, %d %b %Y %H:%M:%S GMT')
def _epoch_to_string(epoch: datetime) -> str:
return epoch.strftime('%Y-%m-%d_%H-%M-%S')
date_object = datetime.strptime(requests.head(url).headers["Last-Modified"],
'%a, %d %b %Y %H:%M:%S GMT')
if ((format_string_contains_key(self.dirname_pattern, 'profile') or
format_string_contains_key(self.dirname_pattern, 'target'))):
filename = '{0}/{1}_UTC_profile_pic.{2}'.format(self.dirname_pattern.format(profile=name.lower(),
target=name.lower()),
_epoch_to_string(date_object.timestamp()), url[-3:])
_epoch_to_string(date_object), url[-3:])
else:
filename = '{0}/{1}_{2}_UTC_profile_pic.{3}'.format(self.dirname_pattern.format(), name.lower(),
_epoch_to_string(date_object.timestamp()), url[-3:])
_epoch_to_string(date_object), url[-3:])
if os.path.isfile(filename):
self._log(filename + ' already exists')
return None
@ -452,7 +452,7 @@ class Instaloader:
with open(filename, 'wb') as file:
resp.raw.decode_content = True
shutil.copyfileobj(resp.raw, file)
os.utime(filename, (datetime.datetime.now().timestamp(), date_object.timestamp()))
os.utime(filename, (datetime.now().timestamp(), date_object.timestamp()))
else:
raise ConnectionException("File \'" + url + "\' could not be downloaded.")
@ -573,10 +573,10 @@ class Instaloader:
else:
profilename = None
profilename = profilename.lower() if profilename else None
date = node["date"] if "date" in node else node["taken_at_timestamp"]
date = datetime.fromtimestamp(node["date"] if "date" in node else node["taken_at_timestamp"])
dirname = self.dirname_pattern.format(profile=profilename, target=target.lower())
filename = dirname + '/' + self.filename_pattern.format(profile=profilename, target=target.lower(),
date=datetime.datetime.fromtimestamp(date),
date=date,
shortcode=shortcode)
os.makedirs(os.path.dirname(filename), exist_ok=True)
if '__typename' in node:
@ -591,7 +591,7 @@ class Instaloader:
for edge in media['edge_sidecar_to_children']['edges']:
edge_downloaded = self.download_pic(filename=filename,
url=edge['node']['display_url'],
date_epoch=date,
mtime=date,
filename_suffix=str(edge_number))
downloaded = downloaded and edge_downloaded
edge_number += 1
@ -599,13 +599,13 @@ class Instaloader:
url = node["display_url"] if "display_url" in node else node["display_src"]
downloaded = self.download_pic(filename=filename,
url=url,
date_epoch=date)
mtime=date)
else:
self._log("Warning: Unknown typename discovered:" + node['__typename'])
downloaded = False
else:
# Node is an old image or video.
downloaded = self.download_pic(filename=filename, url=node["display_src"], date_epoch=date)
downloaded = self.download_pic(filename=filename, url=node["display_src"], mtime=date)
if "edge_media_to_caption" in node and node["edge_media_to_caption"]["edges"]:
self.save_caption(filename, date, node["edge_media_to_caption"]["edges"][0]["node"]["text"])
elif "caption" in node:
@ -616,7 +616,7 @@ class Instaloader:
video_data = self.get_json('p/' + shortcode)
self.download_pic(filename=filename,
url=video_data['entry_data']['PostPage'][0]['graphql']['shortcode_media']['video_url'],
date_epoch=date)
mtime=date)
if geotags:
location = self.get_location(shortcode)
if location:
@ -684,24 +684,24 @@ class Instaloader:
self._sleep()
shortcode = item["code"] if "code" in item else "no_code"
date = item["device_timestamp"] if "device_timestamp" in item else item["taken_at"]
date_float = item["device_timestamp"] if "device_timestamp" in item else item["taken_at"]
try:
date_stamp = datetime.datetime.fromtimestamp(date)
date = datetime.fromtimestamp(date_float)
except ValueError:
# device_timestamp seems to sometime be in milliseconds
date /= 1000
date_stamp = datetime.datetime.fromtimestamp(date)
date_float /= 1000
date = datetime.fromtimestamp(date_float)
dirname = self.dirname_pattern.format(profile=name, target=':stories')
filename = dirname + '/' + self.filename_pattern.format(profile=name, target=':stories',
date=date_stamp,
date=date,
shortcode=shortcode)
os.makedirs(os.path.dirname(filename), exist_ok=True)
if "image_versions2" in item:
url = item["image_versions2"]["candidates"][0]["url"]
downloaded = self.download_pic(filename=filename,
url=url,
date_epoch=date)
mtime=date)
else:
self._log("Warning: Unable to find story image.")
downloaded = False
@ -715,7 +715,7 @@ class Instaloader:
if "video_versions" in item and download_videos:
downloaded = self.download_pic(filename=filename,
url=item["video_versions"][0]["url"],
date_epoch=date)
mtime=date)
if "video_duration" in item and self.sleep and downloaded:
time.sleep(item["video_duration"])
if item["story_locations"]: