Esempio n. 1
0
def by_csv():
    """
    nota 1
        El csv debe estar en la carpeta Artwork
    nota 2
        El csv debe ser:#
           caracteres: unicode(UTF-8)
           Idioma: Espanol mexico
           separado: coma
           delimitador de texto: '
    """
    artwork = Artwork()
    backgrounds = os.listdir(os.path.join(artwork.BASE_DIR, 'backgrounds'))
    csv_name = raw_input("Nombre del csv: ")
    file_path = os.path.join(artwork.BASE_DIR, csv_name)

    with open(file_path, 'rb') as csvfile:
        spamreader = csv.reader(csvfile, delimiter=',', quotechar='|')
        for item in spamreader:
            name = item[0].decode('utf-8')
            message = item[1].decode('utf-8')

            artwork.save_picture({
                'background': random.choice(backgrounds),
                'message':message,
                'name': name,
                'color_text': (37, 51, 109),
                'name_output': name
            })
def add_artwork():
    artw_1 = Artwork(1, 1, 'The Beach', 100, available = True)
    artw_2 = Artwork(2, 2, 'Water Lily Pond', 500, available = True)
    artw_3 = Artwork(3, 3, 'Almond Blossom', 500, available = True)
    insert_art(artw_1)
    insert_art(artw_2)
    insert_art(artw_3)
Esempio n. 3
0
 def test_get_all_available_art(self):
     aw1 = Artwork('Baanksy', 'Rats1', 138831, True)
     aw2 = Artwork('Baanksy', 'Rats21', 138831, False)
     aw3 = Artwork('Baanksy', 'Rats31', 138831, True)
     artwork_db.add_artwork(aw1)
     artwork_db.add_artwork(aw2)
     artwork_db.add_artwork(aw3)
     total_arts = artwork_db.get_available_artwork_from_one_artist(
         'Baanksy')
     self.assertEquals(2, len(total_arts))
Esempio n. 4
0
    def test_get_all_work_sold_and_unsold(self):

        aw1 = Artwork('Banksy', 'Rats', 138831, True)
        aw2 = Artwork('Banksy', 'Rats2', 138831, False)
        aw3 = Artwork('Banksy', 'Rats3', 138831, True)
        artwork_db.add_artwork(aw1)
        artwork_db.add_artwork(aw2)
        artwork_db.add_artwork(aw3)
        total_arts = artwork_db.get_all_artwork_from_one_artist('Banksy')
        self.assertEquals(3, len(total_arts))
Esempio n. 5
0
def save_initial_images(liked_images_dir, disliked_images_dir, database,
                        database_txt, all_liked_artworks_dir):
    '''Saves an initial set of liked and disliked images to database and exports the database.
    Also renames and copies all liked artworks to all_liked_artworks.
    '''
    print('Adding initial artworks to database...')
    database.clear_all()
    folders = [liked_images_dir, disliked_images_dir]
    for folder in folders:
        for artwork in os.listdir(folder):
            # Create the new artwork
            new_work = Artwork()
            new_work.ID = database.number_of_artworks + 1
            new_work.like = 0
            if folder == liked_images_dir:
                new_work.like = 1
            new_work.artist = artwork
            new_work.added = str(
                datetime.datetime.now().strftime("%m/%d/%Y %H:%M:%S"))
            new_work.original_name = artwork
            new_work.vector = convert(folder + artwork)

            # Add the new artwork to the database
            database.add_artwork(new_work)

            # If it's a liked artwork, rename it to its ID and copy it to the permanent
            # folder for liked artworks
            if new_work.like == 1:
                shutil.copy(liked_images_dir + new_work.original_name,
                            all_liked_artworks_dir + str(new_work.ID))

    print('Added initial artworks to database')

    # Export the full database
    database.export_full(database_txt)
Esempio n. 6
0
def get_all_artwork_from_one_artist(given_artist):
    """this will return all works by a given artist regardless of availability"""
    con = sqlite3.connect(db_path)
    artwork_cursor = con.execute('SELECT * FROM artwork WHERE artist_name LIKE ? COLLATE NOCASE', (given_artist,))
    artwork = [Artwork(*row) for row in artwork_cursor.fetchall()]
    con.close()
    return artwork
Esempio n. 7
0
def get_all_artwork():
    """this will return all artwork in db for use in data validation"""
    con = sqlite3.connect(db_path)
    artwork_cursor = con.execute('SELECT * FROM artwork')
    artwork = [Artwork(*row) for row in artwork_cursor.fetchall()]
    con.close()
    return artwork
Esempio n. 8
0
    def get_picture(self):
        ret = Artwork.get_cover(self.get_path())

        if ret:
            return ret

        return False
Esempio n. 9
0
 def test_add_new_artwork(self):
     old_results = len(artwork_db.get_all_artwork())
     aw1 = Artwork('Banksy', 'Mcdonald\'s is stealing your children', 138,
                   True)
     artwork_db.add_artwork(aw1)
     results = len(artwork_db.get_all_artwork())
     self.assertEquals(old_results + 1, results)
Esempio n. 10
0
 def test_delete_artwork_in_db(self):
     a1 = Artwork('sven', 'sven nude', 8311, True)
     artwork_db.add_artwork(a1)
     old_results = artwork_db.get_all_artwork()
     artwork_db.delete_artwork(a1.artwork_name)
     results = artwork_db.get_all_artists()
     self.assertEquals(len(old_results) - 1, len(results))
Esempio n. 11
0
def get_available_artwork_from_one_artist(given_artist):
    """this will return all artwork from a given artist that is available"""
    con = sqlite3.connect(db_path)
    artwork_cursor = con.execute('SELECT * FROM artwork WHERE (artist_name LIKE ? COLLATE NOCASE'
                                 ' AND available = true )', (given_artist,))
    artwork = [Artwork(*row) for row in artwork_cursor.fetchall()]
    con.close()
    return artwork
Esempio n. 12
0
def get_art_work_content(
        new_artist):  # retrieve artwork information from new artist
    art_name = input('Enter art name: ')  # get art name from user
    price = float(
        input('Enter art price: ')
    )  # ask user for art's price and convert price string to float data type
    available = input('Is artwork available?  Y/N')
    return Artwork(new_artist, art_name, price, available)
Esempio n. 13
0
 def __init__(self, geocoder):
     self.local_time = LocalTime(geocoder)
     self.sun = Sun(geocoder)
     self.artwork = Artwork()
     self.city = City(geocoder)
     self.commute = Commute(geocoder)
     self.calendar = GoogleCalendar(geocoder)
     self.everyone = Everyone(geocoder)
Esempio n. 14
0
def get_art_work_content(
        new_artist):  # retrieve artwork information from new artist
    art_name = input('Enter art name: ')  # get art name from user
    price = float(
        input('Enter art price: ')
    )  # ask user for art's price and convert price string to float data type
    return Artwork(
        new_artist, art_name, price,
        True)  # you don't need the keyword arguments. Is is a reasonable
Esempio n. 15
0
def facebook():
    artwork = Artwork()
    backgrounds = os.listdir(os.path.join(artwork.BASE_DIR, 'backgrounds'))
    url = raw_input("Ingresa la url para optener los mensajes: ")

    request = urllib2.urlopen(url)
    raw_data = request.read()
    json_comments = json.loads(raw_data)
    messages = json_comments['data']
    for item in messages:
        artwork.save_picture({
            'background': random.choice(backgrounds),
            'message': item['message'],
            'name': item['from']['name'],
            'color_text': (37, 51, 109),
            'name_output': item['id']
        })
    print "Finish"
Esempio n. 16
0
def genamh(filename):
    template = get_template()
    records = get_records(filename)
    locations = get_locations()

    for record in records:
        artwork = Artwork(record, locations)

        if not artwork.is_valid():
            continue

        artwork.process()
        data = artwork.get_data()

        if "nodata" not in sys.argv:
            data["jsondata"] = json.dumps(data)
            data["xmldata"] = escape(etree.tostring(record))

        html = template.render(data).strip().encode('utf-8')
        yield (html, data)
Esempio n. 17
0
def add_new_artwork():
    """checks if artist name is already registered and if not, registers them before adding new artwork"""
    artist_name = get_artist_name()
    if not controls_utils.artist_already_in_db(artist_name):
        print('Artist not registered, creating new registration. ')
        email = get_artist_email()
        new_artist = Artist(artist_name, email)
        artwork_db.add_artist(new_artist)
    artwork_name = get_new_artwork_name()
    price = get_price()
    available = True
    new_artwork = Artwork(artist_name, artwork_name, price, available)
    artwork_db.add_artwork(new_artwork)
Esempio n. 18
0
    def __init__(self, geocoder):
        """Schedule constructor.

        Args:
            geocoder (geocoder.Geocoder): Used to localize user specified locations
        """
        self._local_time = LocalTime(geocoder)
        self._sun = Sun(geocoder)
        self._artwork = Artwork()
        self._city = City(geocoder)
        self._commute = Commute(geocoder)
        self._calendar = GoogleCalendar(geocoder)
        self._everyone = Everyone(geocoder)
Esempio n. 19
0
def change_availability():
    artist_name = ui.get_artist_name()
    artist_id = artwork_store._get_artist_id(artist_name)
    artworks_list = Artwork.get_all_artist_artwork(artist_id)
    if artworks_list:  # If artwork ID found in db
        artwork_name = ui.get_artwork_name()
        artwork_to_change = Artwork.get_artwork_by_name(artwork_name)
        availability_status = ui.get_artwork_availability()
        # if else statement to determine if for sale or not
        if not availability_status:
            sale_status = '"Sold"'
        else:
            sale_status = '"For Sale"'
        artwork_to_change.for_sale = availability_status
        artwork_to_change.update_artwork()
        print('Artwork status has changed to', sale_status)
    else:  # If artwork ID not found in db
        print('That artist has no artworks.')
        option = input(
            'Return to main menu? Y for main menu or Enter to quit. ').upper()
        if option == 'Y':
            print()
        else:
            quit_program()
    def test_add_artwork_with_same_name_returns_false_and_raises_integrity_error(
            self):
        artwork_example = Artwork('Lunar Flesh', 65.99, 6, True)
        artwork_store._add_artwork(artwork_example)

        artwork_same_name_example = Artwork('Lunar Flesh', 35.55, 7, False)
        same_name_artwork_added = artwork_store._add_artwork(
            artwork_same_name_example)

        self.assertFalse(same_name_artwork_added)
        self.assertRaises(
            sqlite3.IntegrityError
        )  # should raise IntegrityError with artwork of same name regardless of other parameter values

        artwork_example2 = Artwork('Cream Skies', 1200, 8, False)
        artwork_store._add_artwork(artwork_example2)

        expected_rows = [
            ('Lunar Flesh', 65.99, 6, True), ('Cream Skies', 1200, 8, False)
        ]  # only artworks with unique names should be found in db
        actual_rows = self.get_artwork_data()

        # assertCountEqual will compare two iterables, e.g. a list of tuples returned from DB
        self.assertCountEqual(expected_rows, actual_rows)
def create_artwork():
    artist, name, price_string = get_user_input_with_three('Please insert artwork information.', 'Artist: ', 'Name: ', 'Price: ')
    price = float(price_string)
    while True:
        try:
            price = price - .1
            price = price + .1
            break
        except:
            price_string = input('Invalid price. Please enter a number. ')
            price = float(price_string)
    exists = database_control.search_artist(artist)
    if exists:
        artwork = Artwork(artist, name, price)
        database_control.create_artwork(artwork)
    else:
        print('No artist with that name.')
Esempio n. 22
0
def load_json():
    global artwork_list, materials, artists, types

    with open('data/artwork.json', 'r') as datafile:
        for record in json.load(datafile):
            record = Artwork(record)

            if not record.images:
                continue

            artwork_list[record.id] = record

            materials.update(record.material.split(', '))
            artists.update(record.artist.split(', '))
            types.update(record.type.split(', '))

    materials = map_slugs(materials)
    artists = map_slugs(artists)
    types = map_slugs(types)

    del materials['']
    del artists['']
    del types['']
Esempio n. 23
0
def genamh(filename):
    template = get_template()
    records = get_records(filename)
    locations = get_locations()

    for record in records:
        artwork = Artwork(record, locations)

        if not artwork.is_valid():
            continue

        artwork.process()
        data = artwork.get_data()

        if "nodata" not in sys.argv:
            data["jsondata"] = json.dumps(data)
            data["xmldata"] = escape(etree.tostring(record))

        html = template.render(data).strip().encode('utf-8')
        yield (html, data)
Esempio n. 24
0
 def test_delete_artwork_not_in_db(self):
     a1 = Artwork('Captain NoFun', 'the cap', 1138, True)
     with self.assertRaises(artwork_db.ArtDbError):
         artwork_db.delete_artwork(a1.artwork_name)
Esempio n. 25
0
import json
from artwork import Artwork
import requests

GEOCODE_URL = 'https://maps.googleapis.com/maps/api/geocode/json?key=AIzaSyBWyV1hr17E7QnvQ-837US6nVHZWKs5tSw&region=AU'

with open('artwork.json', 'r') as json_file:
    records = json.load(json_file)

for i, record in enumerate(records):
    artwork = Artwork(record)

    if artwork.precise_address:
        continue

    response = None

    if artwork.lat and artwork.long:
        response = requests.get(GEOCODE_URL + '&latlng=' +
                                requests.utils.quote(artwork.lat + ',' +
                                                     artwork.long))
    elif artwork.address:
        response = requests.get(GEOCODE_URL + '&address=' +
                                requests.utils.quote(artwork.address))

    if response:
        response = json.loads(response.text)

        if response['status'] == 'OK':
            result = response['results'][0]
            print(result)
Esempio n. 26
0
def new_artwork(name, artwork, price):
    new_artwork = Artwork(name, artwork, price)
    new_artwork.add_artwork()
Esempio n. 27
0
 def test_get_all_artwork_one_artwork_in_db(self):
     aw1 = Artwork('Art Dood', 'Overpriced still life', 1138, True)
     artwork_db.add_artwork(aw1)
     result = artwork_db.get_all_artwork()
     self.assertEquals(1, len(result))
Esempio n. 28
0
    def test_all_artwork_associated_with_artist_id_is_returned(self):
        # List of artists with unique IDs
        example_artist_list = [
            Artist('John', '*****@*****.**', 1),
            Artist('Gary', '*****@*****.**', 3)
        ]

        # add each to db
        for artist in example_artist_list:
            artwork_store._add_artist(artist)

        # list of artworks assigned to artist IDs
        example_artwork_list = [
            Artwork('Pigeon Scape', 150, 1, True),
            Artwork('Tarnished Hallow', 75, 1, False),
            Artwork('Bog Keeper', 140, 1, True),
            Artwork('Dance Rush', 20, 1, True),
            Artwork('Patchwork Sammy', 85, 5, True),
            Artwork('Basked Valley', 560, 3, False),
            Artwork('Patchwork Sammy', 85, 4, True),
            Artwork('Baked Patty', 1600, 3, False)
        ]

        # add each artwork to db
        for art in example_artwork_list:
            artwork_store._add_artwork(art)

        # what is actually found in db based on artist ID foreign key
        actual_john_artwork_list = artwork.get_all_artist_artwork(1)
        actual_gary_artwork_list = artwork.get_all_artist_artwork(3)

        # what's expected from db when ran from John and Gary (artists)
        expected_john_artwork = [
            Artwork('Pigeon Scape', 150, 1, True),
            Artwork('Tarnished Hallow', 75, 1, False),
            Artwork('Bog Keeper', 140, 1, True),
            Artwork('Dance Rush', 20, 1, True)
        ]

        expected_gary_artwork = [
            Artwork('Basked Valley', 560, 3, False),
            Artwork('Baked Patty', 1600, 3, False)
        ]

        # Checks that list of tuples are equivalent to each other
        self.assertListEqual(expected_john_artwork, actual_john_artwork_list)
        self.assertListEqual(expected_gary_artwork, actual_gary_artwork_list)
Esempio n. 29
0
    def test_only_artworks_searched_by_given_id_are_returned(self):
        # List of artists with unique IDs
        example_artist_list = [
            Artist('John', '*****@*****.**', 1),
            Artist('Gary', '*****@*****.**', 3),
            Artist('Paula', '*****@*****.**', 5)
        ]

        # add each to db
        for artist in example_artist_list:
            artwork_store._add_artist(artist)

        # list of artworks assigned to artist IDs
        example_artwork_list = [
            Artwork('Pigeon Scape', 150, 1, True),
            Artwork('Tarnished Hallow', 75, 1, False),
            Artwork('Bog Keeper', 140, 1, True),
            Artwork('Dance Rush', 20, 1, True),
            Artwork('Patchwork Sammy', 85, 5, True),
            Artwork('Basked Valley', 560, 3, False),
            Artwork('Patchwork Sammy', 85, 4, True),
            Artwork('Baked Patty', 1600, 3, False)
        ]

        # add each artwork to db
        for art in example_artwork_list:
            artwork_store._add_artwork(art)

        # what is actually found in db based on artwork ID foreign key of Artist ID
        actual_artwork_id_1_list = artwork.get_artwork_by_id(1)
        actual_artwork_id_3_list = artwork.get_artwork_by_id(3)
        actual_artwork_id_5_list = artwork.get_artwork_by_id(5)

        # what is expected from db when ran based on provided Artwork IDs
        expected_artwork_id_1_list = [
            Artwork('Pigeon Scape', 150, 1, True),
            Artwork('Tarnished Hallow', 75, 1, False),
            Artwork('Bog Keeper', 140, 1, True),
            Artwork('Dance Rush', 20, 1, True)
        ]

        expected_artwork_id_3_list = [
            Artwork('Basked Valley', 560, 3, False),
            Artwork('Baked Patty', 1600, 3, False)
        ]

        expected_artwork_id_5_list = [Artwork('Patchwork Sammy', 85, 5, True)]

        # Checks that list of tuples are equivalent to each other
        self.assertListEqual(expected_artwork_id_1_list,
                             actual_artwork_id_1_list)
        self.assertListEqual(expected_artwork_id_3_list,
                             actual_artwork_id_3_list)
        self.assertEqual(expected_artwork_id_5_list, actual_artwork_id_5_list)
Esempio n. 30
0
    def test_only_available_artist_artworks_are_returned(self):
        # List of artists with unique IDs
        example_artist_list = [
            Artist('John', '*****@*****.**', 1),
            Artist('Gary', '*****@*****.**', 3),
            Artist('Paula', '*****@*****.**', 5)
        ]

        # add each to db
        for artist in example_artist_list:
            artwork_store._add_artist(artist)

        # list of artworks with availability statuses of True or False
        example_artwork_list = [
            Artwork('Pigeon Scape', 150, 1, True),
            Artwork('Tarnished Hallow', 75, 1, False),
            Artwork('Bog Keeper', 140, 1, True),
            Artwork('Dance Rush', 20, 1, True),
            Artwork('Patchwork Sammy', 85, 5, True),
            Artwork('Basked Valley', 560, 3, False),
            Artwork('Patchwork Sammy', 85, 4, True),
            Artwork('Baked Patty', 1600, 3, False)
        ]

        # add each artwork to db
        for art in example_artwork_list:
            artwork_store._add_artwork(art)

        # returned artworks with True status of availability based on given Artowrk ID foreign key to Artist ID primary key
        actual_available_artwork_id_1_list = artwork.get_all_artist_available_artwork(
            1)
        actual_available_artwork_id_3_list = artwork.get_all_artist_available_artwork(
            3)
        actual_available_artwork_id_5_list = artwork.get_all_artist_available_artwork(
            5)

        # what is expected from db when ran based on provided Artwork IDs
        expected_available_artwork_id_1_list = [
            Artwork('Pigeon Scape', 150, 1, True),
            Artwork('Bog Keeper', 140, 1, True),
            Artwork('Dance Rush', 20, 1, True)
        ]

        expected_available_artwork_id_3_list = []

        expected_available_artwork_id_5_list = [
            Artwork('Patchwork Sammy', 85, 5, True)
        ]

        # Checks that list of tuples are equivalent to each other
        self.assertListEqual(expected_available_artwork_id_1_list,
                             actual_available_artwork_id_1_list)
        self.assertListEqual(expected_available_artwork_id_3_list,
                             actual_available_artwork_id_3_list)
        self.assertEqual(expected_available_artwork_id_5_list,
                         actual_available_artwork_id_5_list)
Esempio n. 31
0
import sqlite3
import unittest
from unittest import TestCase

import database_config

test_artwork_db_path = 'database/test_artist_artwork.db'
database_config.db_path = test_artwork_db_path

from artist import Artist
from artwork_store import ArtworkStore
from errors import ArtworkError
from artwork import Artwork

artwork = Artwork(artwork='', price=float, artist_id=int, for_sale=True)
artwork_store = ArtworkStore()


class TestArtistArtworksDB(TestCase):
    def setUp(self):
        # ensure tables exist and clear DB so it's empty before tests start

        ArtworkStore()

        with sqlite3.connect(test_artwork_db_path) as conn:
            conn.execute('DELETE FROM artists')
            conn.execute('DELETE FROM artworks')
        conn.close()

    def test_all_artwork_associated_with_artist_id_is_returned(self):
        # List of artists with unique IDs
Esempio n. 32
0
def predict_and_move(scraped_art_dir, scraped_info_txt, models_txt, database,
                     database_txt, predicted_disliked_txt):
    '''For each freshly scraped artwork, predicts if the viewer will like it. If it will be liked,
    the image becomes an Artwork and is added to the Database. If it will be disliked, the .jpg/.png
    is deleted and some of the artwork's info is stored in predicted_disliked.txt.
    '''
    print('Predicting which artworks will be liked...')

    name_and_liked = {}

    # Get the predicted liked-values for each artwork and store them with their file names
    for artwork in os.listdir(scraped_art_dir):
        # Predict if the artwork will be liked given the latest model in models.txt
        value = mt.predict_if_liked(scraped_art_dir + artwork,
                                    mt.get_theta(models_txt))

        # Add the name of the artwork and its predicted liked value to the dictionary
        name_and_liked[artwork] = value

    # Go through the info for each freshly scraped artwork in scraped_info.txt
    new_artworks = []
    scraped_txt = open(scraped_info_txt, 'r')
    reader = csv.reader(scraped_txt, delimiter=',')
    for work in reader:
        if work[0] != 'artist' and work[0] != '':
            # Get the original name of the .jpg, stored in scraped_info.txt
            original_name = work[4]
            i1 = original_name.find('full/')
            i2 = original_name.find("', 'checksum'")
            original_name = original_name[i1 + 5:i2]

            # Only convert the work into an Artwork if the viewer is expected to like it
            if name_and_liked.get(original_name) == 1:
                this_work = Artwork()
                this_work.ID = database.number_of_artworks + 1

                # Set the like for this work to 2, indicating that the viewer has not yet
                # rated it
                this_work.like = 2

                this_work.artist = work[0]
                this_work.info = work[1]
                this_work.nga_id = int(work[2])
                this_work.nga_page = int(work[5])
                this_work.title = work[6]
                this_work.nga_link = work[7]
                this_work.added = str(
                    datetime.datetime.now().strftime("%m/%d/%Y %H:%M:%S"))
                this_work.original_name = original_name
                this_work.vector = convert(scraped_art_dir + original_name)

                new_artworks.append(this_work)

                # Add the work to the Database
                database.add_artwork(this_work)

            # If the viewer is expected to dislike the artwork, save some info about it to
            # predicted_disliked.txt and delete the .jpg/.png.
            elif name_and_liked.get(original_name) == 0:
                # Save the artist, info, title, viewing link, and time added
                disliked = work[0] + '~' + work[1] + '~' + work[
                    6] + '~' + work[7] + '~' + str(
                        datetime.datetime.now().strftime("%m/%d/%Y %H:%M:%S"))

                file = open(predicted_disliked_txt, 'a')
                file.write(disliked)
                file.write('\n')
                file.close()

                # Delete the .jpg/.png file
                os.remove(scraped_art_dir + original_name)

    # Export the new (predicted liked) Artworks to the database
    database.export_new(database_txt, new_artworks)

    print('Predicted that %s out of %s artworks will be liked' %
          (len(new_artworks), len(name_and_liked)))
Esempio n. 33
0
def show_artist_available_artwork():
    artist_name = ui.get_artist_name()
    artist_id = artwork_store._get_artist_id(artist_name)
    artworks = Artwork.get_all_artist_available_artwork(artist_id)
    ui.show_artworks_by_artist(artworks)
Esempio n. 34
0
SETUP_URL = 'https://medium.com/@maxbraun/setting-up-accent-b71a07c33ca9'

# The URL of the GitHub page with Accent's source code.
CODE_URL = 'https://github.com/maxbbraun/accent'

# The URL of the Accent Twitter profile.
SOCIAL_URL = 'https://twitter.com/AccentInk'

# The template for editing user data.
HELLO_TEMPLATE = 'hello.html'

# A geocoder instance with a shared cache.
geocoder = Geocoder()

# Helper library instances.
artwork = Artwork()
calendar = GoogleCalendar(geocoder)
city = City(geocoder)
commute = Commute(geocoder)
everyone = Everyone(geocoder)
schedule = Schedule(geocoder)

# The Flask app handling requests.
app = Flask(__name__)


@app.route('/artwork')
@user_auth(image_response=gif_response)
def artwork_gif(key=None, user=None):
    """Responds with a GIF version of the artwork image."""