def __init__(self): super().__init__('tweet_epic') self.parser.add_argument('--now', action='store_true', help="Tweet the next image now") self.epic = EPIC() self.geocoder = GeoNamesGeocoder() self.state = { 'image_queue': {}, 'last_posted_image': datetime(2015, 9, 1), 'last_post_time': datetime(2015, 9, 1) } self.post_interval = timedelta(minutes=60) self.post_interval_fast = timedelta(minutes=45)
def make_animation(): e = EPIC() ENDPOINT = 'http://epic.gsfc.nasa.gov' # get recent images day_before_yesterday = datetime.today() + timedelta(days=-3) recent_images = e.get_recent_images(since=day_before_yesterday) latest_image = recent_images[0]['image'] # only get up to 10 images if len(recent_images) > 10: recent_images = recent_images[:10] # download each image to a temp directory for i, image in enumerate(recent_images): n = str(i).rjust(2, '0') with tempfile.NamedTemporaryFile(dir='tmp/', prefix=f'tmp{n}_', suffix=f'.png', delete=False) as downloadfile: e.download_image(image, downloadfile) # Add annotation to image, resize, rotate annotation = image['image'] os.system(f"convert -resize 800x800 -rotate 180 -fill white -gravity South -pointsize 20 -annotate +0+10 {annotation} {downloadfile.name} {downloadfile.name}") # list of image magick options we want to use for convert to gif animation options = [#'-channel', 'B', '-gamma', '0.90', #'-channel', 'R', '-gamma', '1.03', '-channel', 'RGB', #'-sigmoidal-contrast', '4x5%', '-modulate', '100,130,100', #'-resize', '1000x1000', #'-unsharp', '0x1', #'-rotate', '180', '-delay', '50', '-loop', '0', '-dispose', 'previous'] # put all options into string options_str= '' for element in options: options_str += str(element) + ' ' # combine individual frames into an animated gif os.system(f'convert {options_str} tmp/*.png animation.gif') # remove temporary image frames tmp_files = glob.glob('tmp/*') for f in tmp_files: os.remove(f) return latest_image
def __init__(self): self.log = logging.getLogger(__name__) self.config = ConfigParser.ConfigParser() self.config.read('epictweet.conf') auth = tweepy.OAuthHandler(self.config.get('twitter', 'api_key'), self.config.get('twitter', 'api_secret')) auth.set_access_token(self.config.get('twitter', 'access_key'), self.config.get('twitter', 'access_secret')) self.twitter = tweepy.API(auth) self.epic = EPIC() self.geocoder = GeoNamesGeocoder() self.state = { 'image_queue': {}, 'last_posted_image': datetime(2015, 9, 1), 'last_post_time': datetime(2015, 9, 1) } self.post_interval = timedelta(minutes=80)
def __init__(self): self.log = logging.getLogger(__name__) self.config = ConfigParser.ConfigParser() self.config.read('epictweet.conf') auth = tweepy.OAuthHandler(self.config.get('twitter', 'api_key'), self.config.get('twitter', 'api_secret')) auth.set_access_token(self.config.get('twitter', 'access_key'), self.config.get('twitter', 'access_secret')) self.twitter = tweepy.API(auth) self.epic = EPIC() self.geocoder = GeoNamesGeocoder() self.state = {'image_queue': {}, 'last_posted_image': datetime(2015, 9, 1), 'last_post_time': datetime(2015, 9, 1)} self.post_interval = timedelta(minutes=60)
class TweetEPIC(object): def __init__(self): self.log = logging.getLogger(__name__) self.config = ConfigParser.ConfigParser() self.config.read('epictweet.conf') auth = tweepy.OAuthHandler(self.config.get('twitter', 'api_key'), self.config.get('twitter', 'api_secret')) auth.set_access_token(self.config.get('twitter', 'access_key'), self.config.get('twitter', 'access_secret')) self.twitter = tweepy.API(auth) self.epic = EPIC() self.geocoder = GeoNamesGeocoder() self.state = {'image_queue': {}, 'last_posted_image': datetime(2015, 9, 1), 'last_post_time': datetime(2015, 9, 1)} self.post_interval = timedelta(minutes=60) def poll(self): try: most_recent = sorted(self.state['image_queue'].keys())[-1] except IndexError: most_recent = self.state['last_posted_image'] try: images = self.epic.get_recent_images(most_recent, 20) except (ConnectionError, ValueError): self.log.exception("Unable to fetch images") images = [] added = 0 for image in images: if (image['date'] not in self.state['image_queue'] and image['date'] > self.state['last_posted_image']): self.state['image_queue'][image['date']] = image added += 1 if added > 0: self.log.info("Added %s images to queue", added) if self.state['last_post_time'] < (datetime.now() - self.post_interval) \ and len(self.state['image_queue']) > 0: try: self.do_tweet() except ConnectionError: self.log.exception("Unable to fetch image file") self.save_state() def do_tweet(self): image_date = sorted(self.state['image_queue'].keys())[0] image = self.state['image_queue'][image_date] self.log.info("Tweeting an image") with tempfile.NamedTemporaryFile(suffix='.png') as imagefile: self.fetch_image(image, imagefile) self.post_tweet(image, imagefile) del self.state['image_queue'][image_date] self.state['last_posted_image'] = image_date self.state['last_post_time'] = datetime.now() self.log.info("One image tweeted, %s left in queue", len(self.state['image_queue'])) def post_tweet(self, image, imagefile): lat = image['coords']['centroid_coordinates']['lat'] lon = image['coords']['centroid_coordinates']['lon'] self.log.info("Geocoding %s, %s", lat, lon) geocoded = self.geocoder.geocode(lat, lon) if geocoded[0] is not None: place = " ".join(geocoded) datestring = "%s %s%s" % (image['date'].strftime("%H:%M on %A %B"), image['date'].day, suffix(image['date'].day)) if geocoded[0] is not None: text = "%s, %s" % (datestring, place) else: text = datestring self.twitter.update_with_media(imagefile.name, file=imagefile, status=text, lat=lat, long=lon) def fetch_image(self, image, destfile): with tempfile.NamedTemporaryFile(suffix='.png') as downloadfile: self.epic.download_image(image['image'], downloadfile) process_image(downloadfile.name, destfile.name) def run(self): logging.basicConfig(level=logging.INFO) try: with open("./state.pickle", "r") as f: self.state = pickle.load(f) except IOError: self.log.exception("Failure loading state file, resetting") self.log.info("Running") try: while True: self.poll() sleep(120) finally: self.save_state() self.log.info("Shut down.") def save_state(self): self.log.info("Saving state...") with open("./state.pickle", "w") as f: pickle.dump(self.state, f, pickle.HIGHEST_PROTOCOL)
class TweetEPIC(Bot): def __init__(self): super().__init__('tweet_epic') self.parser.add_argument('--now', action='store_true', help="Tweet the next image now") self.epic = EPIC() self.geocoder = GeoNamesGeocoder() self.state = { 'image_queue': {}, 'last_posted_image': datetime(2015, 9, 1), 'last_post_time': datetime(2015, 9, 1) } self.post_interval = timedelta(minutes=60) self.post_interval_fast = timedelta(minutes=45) def poll(self): try: most_recent = sorted(self.state['image_queue'].keys())[-1] except IndexError: most_recent = self.state['last_posted_image'] try: images = self.epic.get_recent_images(most_recent, 20) except (ConnectionError, ValueError): self.log.exception("Unable to fetch images") images = [] added = 0 for image in images: if (image['date'] not in self.state['image_queue'] and image['date'] > self.state['last_posted_image']): self.state['image_queue'][image['date']] = image added += 1 if added > 0: self.log.info("Added %s images to queue", added) if len(self.state['image_queue']) > 20: to_drop = len(self.state['image_queue']) - 20 self.log.info("Dropping %s images from queue", to_drop) for key in sorted(self.state['image_queue'])[0:to_drop]: del self.state['image_queue'][key] if len(self.state['image_queue']) > 12: interval = self.post_interval_fast else: interval = self.post_interval if self.state['last_post_time'] < (datetime.now() - interval) \ and len(self.state['image_queue']) > 0: try: self.do_tweet() except ConnectionError: self.log.exception("Unable to fetch image file") self.save_state() def do_tweet(self): image_date = sorted(self.state['image_queue'].keys())[0] image = self.state['image_queue'][image_date] self.log.info("Tweeting an image") with tempfile.NamedTemporaryFile(suffix='.png') as imagefile: self.fetch_image(image, imagefile) self.post_tweet(image, imagefile) del self.state['image_queue'][image_date] self.state['last_posted_image'] = image_date self.state['last_post_time'] = datetime.now() self.log.info("One image tweeted, %s left in queue", len(self.state['image_queue'])) def post_tweet(self, image, imagefile): lat = image['centroid_coordinates']['lat'] lon = image['centroid_coordinates']['lon'] self.log.info("Geocoding %s, %s", lat, lon) geocoded = self.geocoder.geocode(lat, lon) if geocoded[0] is not None: place = " ".join(geocoded) datestring = "%s %s%s" % (image['date'].strftime("%H:%M on %A %B"), image['date'].day, suffix(image['date'].day)) if geocoded[0] is not None: text = "%s, %s" % (datestring, place) else: text = datestring self.post(text, imagefile=imagefile, lat=lat, lon=lon) def fetch_image(self, image, destfile): with tempfile.NamedTemporaryFile(suffix='.png') as downloadfile: self.epic.download_image(image, downloadfile) process_image(downloadfile.name, destfile.name) def main(self): if self.args.now: self.state['last_post_time'] = datetime(2015, 9, 1) while True: self.poll() sleep(120)
class TweetEPIC(object): def __init__(self): self.log = logging.getLogger(__name__) self.config = ConfigParser.ConfigParser() self.config.read('epictweet.conf') auth = tweepy.OAuthHandler(self.config.get('twitter', 'api_key'), self.config.get('twitter', 'api_secret')) auth.set_access_token(self.config.get('twitter', 'access_key'), self.config.get('twitter', 'access_secret')) self.twitter = tweepy.API(auth) self.epic = EPIC() self.geocoder = GeoNamesGeocoder() self.state = { 'image_queue': {}, 'last_posted_image': datetime(2015, 9, 1), 'last_post_time': datetime(2015, 9, 1) } self.post_interval = timedelta(minutes=80) def poll(self): try: most_recent = sorted(self.state['image_queue'].keys())[-1] except IndexError: most_recent = self.state['last_posted_image'] try: images = self.epic.get_recent_images(most_recent, 20) except (ConnectionError, ValueError): self.log.exception("Unable to fetch images") images = [] added = 0 for image in images: if (image['date'] not in self.state['image_queue'] and image['date'] > self.state['last_posted_image']): self.state['image_queue'][image['date']] = image added += 1 if added > 0: self.log.info("Added %s images to queue", added) if self.state['last_post_time'] < (datetime.now() - self.post_interval) \ and len(self.state['image_queue']) > 0: try: self.do_tweet() except ConnectionError: self.log.exception("Unable to fetch image file") self.save_state() def do_tweet(self): image_date = sorted(self.state['image_queue'].keys())[0] image = self.state['image_queue'][image_date] self.log.info("Tweeting an image") with tempfile.NamedTemporaryFile(suffix='.png') as imagefile: self.fetch_image(image, imagefile) self.post_tweet(image, imagefile) del self.state['image_queue'][image_date] self.state['last_posted_image'] = image_date self.state['last_post_time'] = datetime.now() self.log.info("One image tweeted, %s left in queue", len(self.state['image_queue'])) def post_tweet(self, image, imagefile): lat = image['coords']['centroid_coordinates']['lat'] lon = image['coords']['centroid_coordinates']['lon'] self.log.info("Geocoding %s, %s", lat, lon) geocoded = self.geocoder.geocode(lat, lon) if geocoded[0] is not None: place = " ".join(geocoded) datestring = "%s %s%s" % (image['date'].strftime("%H:%M on %B"), image['date'].day, suffix(image['date'].day)) if geocoded[0] is not None: text = "%s, %s" % (datestring, place) else: text = datestring self.twitter.update_with_media(imagefile.name, file=imagefile, status=text, lat=lat, long=lon) def fetch_image(self, image, destfile): with tempfile.NamedTemporaryFile(suffix='.png') as downloadfile: self.epic.download_image(image['image'], downloadfile) process_image(downloadfile.name, destfile.name) def run(self): logging.basicConfig(level=logging.INFO) try: with open("./state.pickle", "r") as f: self.state = pickle.load(f) except IOError: self.log.exception("Failure loading state file, resetting") self.log.info("Running") try: while True: self.poll() sleep(120) finally: self.save_state() self.log.info("Shut down.") def save_state(self): self.log.info("Saving state...") with open("./state.pickle", "w") as f: pickle.dump(self.state, f, pickle.HIGHEST_PROTOCOL)
# coding=utf-8 from __future__ import division, absolute_import, print_function, unicode_literals import tempfile from datetime import date from epic import EPIC from processing import process_image e = EPIC() i = 0 for image in e.get_image_range(date(2015, 10, 13), date(2015, 10, 21)): with tempfile.NamedTemporaryFile(suffix='.png') as downloadfile: e.download_image(image['image'], downloadfile) process_image(downloadfile.name, "./out/img%03d.png" % i) i += 1 # avconv -f image2 -r 30 -i ./img%03d.png -s 1024x1024 ./output.mp4