project clean-up

This commit is contained in:
Andrew Bryant 2023-12-24 14:48:52 -05:00
parent 36273d7151
commit 4fca9b53d3
60 changed files with 33 additions and 1817 deletions

5
.gitignore vendored
View File

@ -1,3 +1,8 @@
all_paw_care/invoice_ninja
all_paw_care/templates/markdown_content
__pycache__
*.py[cod]
.env*
!.env.project
!.env.vault

View File

@ -1,3 +1,7 @@
# Scripts directory variable
SCRIPTS_DIR = "scripts"
# Bootstrap variables
BOOTSTRAP_MODULE = "bootstrap-custom/boostrap/scss"
CUSTOM_SCSS = "bootstrap-custom/custom.scss"
PUBLIC_CSS = "all_paw_care/static/css/custom.css"
@ -13,5 +17,5 @@ build-custom-bootstrap:
.PHONY: process-images
process-images:
./process-images.sh
./$(SCRIPTS_DIR)/process-images.sh

10
TODO.md
View File

@ -1,3 +1,13 @@
# Code clean-up
## scripts dir
move process-images.sh here
# Services/<service>
Route to service documentation page.

View File

@ -1,57 +0,0 @@
from config import Config
from datetime import datetime
# TODO replace self.smtp_url and self.email_user with Config values
class MeetGreetNotification(object):
def __init__(self, config: str):
self.smtp_url =
self.email_user =
def __get_smtp_client(self):
from smtplib import SMTP_SSL
smtp_client = SMTP_SSL(host=self.smtp_url)
smtp_client.login(self.email_user,self.c['fastmail-smtp']['pass'])
return smtp_client
def send(self, name: str, address: str, greet_time: datetime, notes: str = None):
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
subject = "Meet & greet request: {}".format(name)
email = MIMEMultipart()
email['Subject'] = subject
email['From'] = self.email_user
email['To'] = self.email_user
content = '''
<table>
<tr>
<th>Name</th>
<td>{}</td>
</tr>
<tr>
<th>Address</th>
<td>{}</td>
</tr>
<tr>
<th>Datetime</th>
<td>{}</td>
</tr>
<tr>
<th>Notes</th>
<td>{}</td>
</tr>
</table>
'''.format(name,address,greet_time,notes)
email_content = MIMEMultipart('alternative')
email_content.attach(MIMEText(content, 'html'))
email.attach(email_content)
with self.__get_smtp_client() as c:
c.sendmail(self.email_user,self.email_user,email.as_string())

View File

@ -1,49 +0,0 @@
{% extends "jinja/types/page.html" %}
{% set title %}Contact me{% endset %}
{% block content %}
<div class="row">
<h4>If you have any questions, the
<a href="../faq.html">FAQ</a>
page may have an answer. Contacting me directly by
<a href="mailto: bryant.caregiving@fastmail.com">email</a> or
<a href="tel:+14102799125">text</a> message is welcome.
</h4>
</div>
<div class="row mt-2">
<div class="col-6">
<h3 class="text-center text-primary">
Contact me directly!
</h3>
<a href="tel::+14102799125" class="mr-8">
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="currentColor" class="bi bi-telephone-fill" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.885.511a1.745 1.745 0 0 1 2.61.163L6.29 2.98c.329.423.445.974.315 1.494l-.547 2.19a.678.678 0 0 0 .178.643l2.457 2.457a.678.678 0 0 0 .644.178l2.189-.547a1.745 1.745 0 0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 1.034c-.74.74-1.846 1.065-2.877.702a18.634 18.634 0 0 1-7.01-4.42 18.634 18.634 0 0 1-4.42-7.009c-.362-1.03-.037-2.137.703-2.877L1.885.511z"/>
</svg>
</a>
<a href="mailto: bryant.caregiving@fastmail.com">
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="currentColor" class="bi bi-envelope-fill" viewBox="0 0 16 16">
<path d="M.05 3.555A2 2 0 0 1 2 2h12a2 2 0 0 1 1.95 1.555L8 8.414.05 3.555ZM0 4.697v7.104l5.803-3.558L0 4.697ZM6.761 8.83l-6.57 4.027A2 2 0 0 0 2 14h12a2 2 0 0 0 1.808-1.144l-6.57-4.027L8 9.586l-1.239-.757Zm3.436-.586L16 11.801V4.697l-5.803 3.546Z"/>
</svg>
</a>
</div>
</div>
<div class="row">
<div class="col-4">
<h3 class="text-center text-primary">
Follow me!
</h3>
<a href="https://www.instagram.com/awkawb" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="currentColor" class="bi bi-instagram" viewBox="0 0 16 16">
<path d="M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.917 3.917 0 0 0-1.417.923A3.927 3.927 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.916 3.916 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.926 3.926 0 0 0-.923-1.417A3.911 3.911 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0h.003zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599.28.28.453.546.598.92.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.47 2.47 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.478 2.478 0 0 1-.92-.598 2.48 2.48 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233 0-2.136.008-2.388.046-3.231.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92.28-.28.546-.453.92-.598.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045v.002zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92zm-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217zm0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334z"/>
</svg>
</a>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,39 +0,0 @@
{% extends "jinja/types/page.html" %}
{% set title %}FAQ{% endset %}
{% block content %}
<div class="row text-center">
<h2 class="text-primary">Do you accept more than one animal?</h2>
</div>
<div class="row text-center pb-3">
<h5 class="text-secondary">
I do but all services are priced for one animal. For more than
one pet I charge $8 per additional animal for walking and house
sitting services.
</h5>
</div>
<div class="row text-center">
<h2 class="text-primary">What types of payments do you accept?</h2>
</div>
<div class="row text-center pb-3">
<h5 class="text-secondary">
I accept all major credit cards, bank transfers, and Paypal. Invoices are sent after service is rendered.
</h5>
</div>
<div class="row text-center">
<h2 class="text-primary">Can you clean up my yard, my dog has made it a mess?</h2>
</div>
<div class="row text-center">
<h5 class="text-secondary">
I offer poop clean up as an additional add-on service. If you
decide to schedule a walk or house sitting, I will gladly
remove the poop.
</h5>
</div>
{% endblock %}

View File

@ -1,49 +0,0 @@
{% extends "jinja/types/page.html" %}
{% set title %}About me{% endset %}
{% block content %}
<div class="row pb-3">
<div class="col-8 text-center">
Welcome to All Paw Care!
</div>
<div class="col-4">
<img class="img-fluid"
src="/static/img/about_me_1_md.jpg"
srcset="/static/img/about_me_1_sm.jpg 540w, /static/img/about_me_1_md.jpg 720w, /static/img/about_me_1_lg.jpg 960w"
sizes="50vw">
</div>
</div>
<div class="row pb-3">
<div class="col-4">
<img class="img-fluid" src="/static/img/about_me_2_lg.jpg"
srcset="/static/img/about_me_2_sm.jpg 540w, /static/img/about_me_2_md.jpg 720w, /static/img/about_me_2_lg.jpg 960w"
sizes="50vw">
</div>
<div class="col-8 text-center">
<p>
I've been providing professional animal caretaking
services in the Baltimore area for over 4 years. I
provide services for paws of all shapes and sizes.
</p>
</div>
</div>
<div class="row">
<div class="col-8 text-center">
<p>
I specialize in dog and cat care. Animals add so much
to our lives so caring for them is just as important.
</p>
</div>
<div class="col-4">
<img class="img-fluid" src="/static/img/about_me_3_lg.jpg"
srcset="/static/img/about_me_3_sm.jpg 540w, /static/img/about_me_3_md.jpg 720w, /static/img/about_me_3_lg.jpg 960w"
sizes="50vw">
</div>
</div>
{% endblock %}

View File

@ -1,96 +0,0 @@
{% extends "jinja/types/form.html" %}
{% set title %}Request meet and greet{% endset %}
{% block content %}
<form method="POST">
<h1 class="text-success text-center my-4">Meet & greet</h1>
<div class="d-flex flex-row justify-content-center px-4">
<div class="input-group mx-2">
<span class="input-group-text">Pet name(s)</span>
<input class="form-control" type="text"
placeholder="Tabby, Curly" name="client-pets" id="client-pets" required>
</div>
<div class="input-group mx-2">
<span class="input-group-text">Name</span>
<input class="form-control" type="text"
placeholder="Kasey" name="client-name" id="client-name" required>
</div>
</div>
<div class="d-flex flex-row justify-content-center input-group m-2">
<span class="input-group-text">Visit type</span>
<input class="btn-check" type="radio"
name="visit-type" id="visit-type-walk" required>
<label class="btn btn-primary" for="visit-type-walk">
Walk
</label>
<input class="btn-check" type="radio"
name="visit-type" id="visit-type-sitting">
<label class="btn btn-primary" for="visit-type-sitting">
House sitting
</label>
</div>
<div class="d-flex flex-row justify-content-center m-2">
<div class="col-4 pe-1">
<div class="input-group">
<span class="input-group-text">Date</span>
<input type="date" id="date"
name="meet-greet-date" class="form-control"
placeholder="mm/dd/yyyy" value="" required>
</div>
</div>
<div class="col-4 ps-1">
<div class="input-group">
<span class="input-group-text" id="time">Time</span>
<input type="time" id="meet-greet-time"
name="meet-greet-time" class="form-control"
min="09:00" max="16:00" value="09:00" required>
</div>
</div>
</div>
<div class="d-flex flex-row justify-content-center mx-4 mb-2">
<div class="input-group">
<span class="input-group-text">Contact</span>
<input class="btn-check" type="radio"
name="contact-type" id="email" required>
<label class="btn btn-primary" for="email">
Email
</label>
<input class="btn-check" type="radio"
name="contact-type" id="phone">
<label class="btn btn-primary" for="phone">
Phone
</label>
<input type="text" class="form-control" name="contact"
required>
</div>
</div>
<div class="d-flex flex-row justify-content-center mx-4 mb-2">
<span class="input-group-text">Additional notes</span>
<textarea class="form-control" rows="5" for="notes"
id="notes" name="notes">
</textarea>
</div>
<div class="row m-2">
<button class="btn btn-primary" type="submit"
action="{{ url_for('forms.meet_and_greet') }}" method="post">
Book it
</button>
</div>
</form>
{% endblock %}

View File

@ -1,69 +0,0 @@
{% extends "jinja/types/page.html" %}
{% set title %}Services{% endset %}
{% block content %}
<div class="row pt-2 pb-4">
<div class="col">
<div class="card">
<img class="img-fluid" class="card-img-top"
src="../static/img/services_dog_walking_card_lg.png"
srcset="../static/img/services_dog_walking_card_sm.png 540w,
../static/img/services_dog_walking_card_md.png 720w,
../static/img/services_dog_walking_card_lg.png 960w,
../static/img/services_dog_walking_card_xl.png 1140w"
sizes="50vw" alt="Woman walking dog">
<div class="card-body">
<h1 class="card-title text-center text-primary">Walking</h1>
<hr>
<h2 class="text-success text-center">$20+/visit</h2>
<hr class="invisible">
<p class="text-secondary">
Service includes 30 minute walk for your pet. Bags for poop
clean-up are included.
</p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<img class="img-fluid" class="card-img-top"
src="../static/img/services_house_sitting_card_lg.png"
srcset="../static/img/services_house_sitting_card_sm.png 540w,
../static/img/services_house_sitting_card_md.png 720w,
../static/img/services_house_sitting_card_lg.png 960w,
../static/img/services_house_sitting_card_xl.png 1140w"
sizes="50vw" alt="Dog eating from food bowl">
<div class="card-body">
<h1 class="card-title text-center text-primary">
House sitting
</h1>
<hr>
<h2 class="text-success text-center">$38+/night</h2>
<hr class="invisible">
<p class="text-secondary">
Service includes in-home overnight stays and animal care.
</p>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-center">
<a href="{{ url_for('forms.meet_and_greet') }}">
<button class="btn btn-primary text-light">
Request meet & greet
</button>
</a>
</div>
{% endblock %}

View File

@ -1,9 +0,0 @@
[fastmail-smtp]
url = https://smtp.fastmail.com
user = awkawb@awkawb.cloud
pass = xw392bf7shg6wbzb
[fastmail-caldav]
url = https://caldav.fastmail.com/caldav
user = awkawb@awkawb.cloud
pass = xk5fzhfdr2w9h86v

View File

@ -1,41 +0,0 @@
from configparser import ConfigParser
from datetime import date
from email.message import Message
from smtplib import SMTP
from flask import Flask,request
from meetgreetnotification import MeetGreeNotification
app = Flask(__name__)
@app.route('/forms/meetgreetrequest.html', methods=['POST'])
def walk_request():
if request.method == 'POST':
name = request.form['client-name']
pets = request.form['client-pets']
notes = request.form['notes']
requested_date = get_datetime(request.form['meet-greet-date'],
request.form['meet-greet-time'])
#if is_valid_date(requested_date):
# n = MeetGreetNotification('allpawcare.ini')
# n.send(name,address,requested_date,notes)
def get_datetime(raw_date: str, raw_time: str):
date_list = raw_date.rsplit('-')
print(raw_time)
year = int(date_list[0])
month = int(date_list[1])
day = int(date_list[2])
return datetime_request
def is_valid_date(requested_date: date):
if requested_date <= date.today():
return False
else:
return True

View File

@ -1,58 +0,0 @@
from datetime import datetime
class MeetGreetNotification(object):
def __init__(self, config: str):
from configparser import ConfigParser
self.c = ConfigParser()
self.c.read(config)
self.smtp_url = self.c['fastmail-smtp']['url']
self.email_user = self.c['fastmail-smtp']['user']
def __get_smtp_client(self):
from smtplib import SMTP_SSL
smtp_client = SMTP_SSL(host=self.smtp_url)
smtp_client.login(self.email_user,self.c['fastmail-smtp']['pass'])
return smtp_client
def send(self, name: str, address: str, greet_time: datetime, notes: str = None):
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
subject = "Meet & greet request: {}".format(name)
email = MIMEMultipart()
email['Subject'] = subject
email['From'] = self.email_user
email['To'] = self.email_user
content = '''
<table>
<tr>
<th>Name</th>
<td>{}</td>
</tr>
<tr>
<th>Address</th>
<td>{}</td>
</tr>
<tr>
<th>Datetime</th>
<td>{}</td>
</tr>
<tr>
<th>Notes</th>
<td>{}</td>
</tr>
</table>
'''.format(name,address,greet_time,notes)
email_content = MIMEMultipart('alternative')
email_content.attach(MIMEText(content, 'html'))
email.attach(email_content)
with self.__get_smtp_client() as c:
c.sendmail(self.email_user,self.email_user,email.as_string())

126
config.py
View File

@ -1,6 +1,9 @@
import os
class Config(object):
# Enable debugging for development
DEBUG = True
# App base directory
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
@ -25,126 +28,3 @@ class Config(object):
'1400px'
]
# About me page content
ABOUT_ME = [
(
[
'../static/img/about_me/about_me_1_sm.jpg',
'../static/img/about_me/about_me_1_md.jpg',
'../static/img/about_me/about_me_1_lg.jpg',
'../static/img/about_me/about_me_1_xl.jpg',
'../static/img/about_me/about_me_1_xxl.jpg'
],
'''
Before I provided animal caretaking services, I focused
my time on computers. I designed and coded this website!
'''
),
(
[
'../static/img/about_me/about_me_2_sm.jpg',
'../static/img/about_me/about_me_2_md.jpg',
'../static/img/about_me/about_me_2_lg.jpg',
'../static/img/about_me/about_me_2_xl.jpg',
'../static/img/about_me/about_me_2_xxl.jpg'
],
'''
My passion for animals and plants are what I spend
most my time on currently. I love providing quality
animal care.
'''
),
(
[
'../static/img/about_me/about_me_3_sm.jpg',
'../static/img/about_me/about_me_3_md.jpg',
'../static/img/about_me/about_me_3_lg.jpg',
'../static/img/about_me/about_me_3_xl.jpg',
'../static/img/about_me/about_me_3_xxl.jpg'
],
'''
For the past 5 years, my interest in plants and
horticulture have expanded exponentially. As a kid,
my mother always expressed interest in plants. Plants
are something, for me, that took patients and I
had little patients as a child.
'''
)
]
# Service page content
SERVICES = {
'Walking': [
[
'../static/img/services/dog_walking_card_sm.png',
'../static/img/services/dog_walking_card_md.png',
'../static/img/services/dog_walking_card_lg.png',
'../static/img/services/dog_walking_card_xl.png',
'../static/img/services/dog_walking_card_xxl.png'
],
'$20/visit',
'Service includes:',
[
'30 minute walk.',
'Bags for poop clean-up.'
]
],
'Drop-in': [
[
'../static/img/services/drop_in_card_sm.png',
'../static/img/services/drop_in_card_md.png',
'../static/img/services/drop_in_card_lg.png',
'../static/img/services/drop_in_card_xl.png',
'../static/img/services/drop_in_card_xxl.png'
],
'$20/visit',
'Service includes:',
[
'30 minute in home visit.',
'Bags for poop clean-up.'
]
],
'House sitting': [
[
'../static/img/services/house_sitting_card_sm.png',
'../static/img/services/house_sitting_card_md.png',
'../static/img/services/house_sitting_card_lg.png',
'../static/img/services/house_sitting_card_xl.png',
'../static/img/services/house_sitting_card_xxl.png'
],
'$38/visit',
'Service includes:',
[
'Animal care.',
'In-home overnight stays.'
]
]
}
# FAQ page content
FAQS = {
'What kind of animals do you caretake?': (
'animal-types-faq',
'I have experience careing for many types of animals. '
+ 'I provide care for reptiles, mammals, etc.'
),
'Can you care for special needs pets?': (
'special-needs-faq',
'''I have experience care for special needs, including older
animals'''
),
'Can you stay at my house?': (
'house-sitting-faq',
'I offer house sitting services. This includes in home stays.'
),
'Can you take care of my plants?': (
'plant-faq',
'I love plants and have a garden of my own. I\'ll gladly '
+ 'remove the mess for you.'
),
'My yard is a mess, can you clean up the dog poop?': (
'poop-scoop-faq',
'I do offer animal poop clean up add-on yard'
)
}

View File

@ -1,104 +0,0 @@
#!/usr/bin/env python3
class AllPawCare(object):
"""
Builder for www.allpawcare.com
Builds www.allpawcare.com static resources.
"""
def __init__(self):
# Directory variables
self.CGI_DIR = 'cgi-bin'
self.IMG_DIR = 'img'
self.PUBLIC_DIR = 'public'
self.TEMPLATES_DIR = 'templates'
self.CGI_PUBLIC_DIR = self.PUBLIC_DIR + '/' + self.CGI_DIR
self.IMG_PUBLIC_DIR = self.PUBLIC_DIR + '/' + self.IMG_DIR
# Types of templates to render
self.RENDERED_TYPES = ['forms', 'pages']
# Year to copyright the rendered templates
from datetime import datetime
self.CURRENT_YEAR = datetime.today().strftime('%Y')
# Setup Jinja environment
from jinja2 import Environment, FileSystemLoader
self.JINJA_ENV = Environment(loader=FileSystemLoader(self.TEMPLATES_DIR))
def __enter__(self):
return self
def __get_name_map(self):
"""
Map page templates to page titles.
Returns dictionary mapping page templates to page titles.
"""
name_map = dict()
for t in self.JINJA_ENV.list_templates():
t_type = t.partition('/')[0]
t_name = t.partition('/')[2]
# Only consider page templates
if t_type == 'pages':
# TEMPLATE: PAGETITLE
name_map[t_name] = t_name.removesuffix('.html')
return name_map
def copy_static_resources(self):
"""
Copy static assets to public directory.
Copies CGI and image resources to public directory.
"""
import shutil
print('Copying static assets...')
try:
# Copy cgi scripts to public dir
shutil.copytree(self.CGI_DIR, self.CGI_PUBLIC_DIR)
# Copy images to public dir
shutil.copytree(self.IMG_DIR, self.IMG_PUBLIC_DIR)
except:
print("Error copying static files. Does the public directory exist?")
def render_site(self):
"""
Render site template to static HTML
Render www.AllPawCare.com static site from jinja
template.
"""
name_map = self.__get_name_map()
for t in self.JINJA_ENV.list_templates():
t_type = t.partition('/')[0]
if t_type in self.RENDERED_TYPES:
print('Rendering {}'.format(t))
output_file = '{}/{}'.format(self.PUBLIC_DIR, t)
with open(output_file, 'w+') as file:
template = self.JINJA_ENV.get_template(t)
t = template.render(pages=name_map,
current_year=self.CURRENT_YEAR)
file.write(t)
builder = AllPawCare()
builder.copy_static_resources()
builder.render_site()

View File

@ -1,17 +0,0 @@
#!/usr/bin/env bash
IMG_ORIGINALS="img_original"
IMG_PUBLIC="all_paw_care/static/img"
IMG_SIZES_NAME=("sm" "md" "lg" "xl" "xxl")
IMG_SIZES=("576" "768" "992" "1200" "1400")
for img in $(find $IMG_ORIGINALS -type f)
do
for ((i=0;i<${#IMG_SIZES_NAME[@]};i++))
do
new_img_path=$(echo "$img" | sed -e "s,img_original\(.*\),$IMG_PUBLIC\1,g" \
-e "s,\.,_${IMG_SIZES_NAME[i]}\.,g")
magick "$img" -filter spline -resize ${IMG_SIZES[i]} "$new_img_path"
done
done

View File

@ -1,9 +0,0 @@
[fastmail-smtp]
url = https://smtp.fastmail.com
user = awkawb@awkawb.cloud
pass = xw392bf7shg6wbzb
[fastmail-caldav]
url = https://caldav.fastmail.com/caldav
user = awkawb@awkawb.cloud
pass = xk5fzhfdr2w9h86v

View File

@ -1,41 +0,0 @@
from configparser import ConfigParser
from datetime import date
from email.message import Message
from smtplib import SMTP
from flask import Flask,request
from meetgreetnotification import MeetGreeNotification
app = Flask(__name__)
@app.route('/forms/meetgreetrequest.html', methods=['POST'])
def walk_request():
if request.method == 'POST':
name = request.form['client-name']
pets = request.form['client-pets']
notes = request.form['notes']
requested_date = get_datetime(request.form['meet-greet-date'],
request.form['meet-greet-time'])
#if is_valid_date(requested_date):
# n = MeetGreetNotification('allpawcare.ini')
# n.send(name,address,requested_date,notes)
def get_datetime(raw_date: str, raw_time: str):
date_list = raw_date.rsplit('-')
print(raw_time)
year = int(date_list[0])
month = int(date_list[1])
day = int(date_list[2])
return datetime_request
def is_valid_date(requested_date: date):
if requested_date <= date.today():
return False
else:
return True

View File

@ -1,58 +0,0 @@
from datetime import datetime
class MeetGreetNotification(object):
def __init__(self, config: str):
from configparser import ConfigParser
self.c = ConfigParser()
self.c.read(config)
self.smtp_url = self.c['fastmail-smtp']['url']
self.email_user = self.c['fastmail-smtp']['user']
def __get_smtp_client(self):
from smtplib import SMTP_SSL
smtp_client = SMTP_SSL(host=self.smtp_url)
smtp_client.login(self.email_user,self.c['fastmail-smtp']['pass'])
return smtp_client
def send(self, name: str, address: str, greet_time: datetime, notes: str = None):
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
subject = "Meet & greet request: {}".format(name)
email = MIMEMultipart()
email['Subject'] = subject
email['From'] = self.email_user
email['To'] = self.email_user
content = '''
<table>
<tr>
<th>Name</th>
<td>{}</td>
</tr>
<tr>
<th>Address</th>
<td>{}</td>
</tr>
<tr>
<th>Datetime</th>
<td>{}</td>
</tr>
<tr>
<th>Notes</th>
<td>{}</td>
</tr>
</table>
'''.format(name,address,greet_time,notes)
email_content = MIMEMultipart('alternative')
email_content.attach(MIMEText(content, 'html'))
email.attach(email_content)
with self.__get_smtp_client() as c:
c.sendmail(self.email_user,self.email_user,email.as_string())

View File

@ -1,238 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
</head>
<body>
<header>
<div class="px-3 py-2 bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<main>
<div class="container pt-5">
<div class="rounded border b-5">
<form>
<h1 class="text-success text-center my-4">Meet & greet</h1>
<div class="d-flex flex-row justify-content-center px-4">
<div class="input-group mx-2">
<span class="input-group-text">Pet name(s)</span>
<input class="form-control" type="text"
placeholder="Tabby, Curly" name="client-pets" id="client-pets" required>
</div>
<div class="input-group mx-2">
<span class="input-group-text">Name</span>
<input class="form-control" type="text"
placeholder="Kasey" name="client-name" id="client-name" required>
</div>
</div>
<div class="d-flex flex-row justify-content-center input-group m-2">
<span class="input-group-text">Visit type</span>
<input class="btn-check" type="radio"
name="visit-type" id="visit-type-walk" required>
<label class="btn btn-primary" for="visit-type-walk">
Walk
</label>
<input class="btn-check" type="radio"
name="visit-type" id="visit-type-dropin">
<label class="btn btn-primary" for="visit-type-dropin">
Drop-in
</label>
<input class="btn-check" type="radio"
name="visit-type" id="visit-type-sitting">
<label class="btn btn-primary" for="visit-type-sitting">
House sitting
</label>
</div>
<div class="d-flex flex-row justify-content-center m-2">
<div class="col-4 pe-1">
<div class="input-group">
<span class="input-group-text">Date</span>
<input type="date" id="date"
name="meet-greet-date" class="form-control"
placeholder="mm/dd/yyyy" value="" required>
</div>
</div>
<div class="col-4 ps-1">
<div class="input-group">
<span class="input-group-text" id="time">Time</span>
<input type="time" id="meet-greet-time" class="form-control"
min="09:00" max="16:00" value="09:00" required>
</div>
</div>
</div>
<div class="d-flex flex-row justify-content-center mx-4 mb-2">
<div class="input-group">
<span class="input-group-text">Contact</span>
<input class="btn-check" type="radio"
name="contact-type" id="email" required>
<label class="btn btn-primary" for="email">
Email
</label>
<input class="btn-check" type="radio"
name="contact-type" id="phone">
<label class="btn btn-primary" for="phone">
Phone
</label>
<input type="text" class="form-control" required>
</div>
</div>
<div class="d-flex flex-row justify-content-center mx-4 mb-2">
<span class="input-group-text">Additional notes</span>
<textarea class="form-control" rows="5" for="notes" id="notes">
</textarea>
</div>
<div class="row m-2">
<button class="btn btn-primary" type="submit"
action="http://allpawcare.com/" method="post">
Book it
</button>
</div>
</form>
</div>
</div>
</main>
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<p class="col-md-4 mb-0 text-muted">
© 2023 Andrew Bryant
</p>
<a href="/" class="col-md-4 d-flex align-items-center justify-content-center mb-3 mb-md-0 me-md-auto link-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32">
<use xlink:href="#bootstrap"></use>
</svg>
</a>
<ul class="nav col-md-4 justify-content-end">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@ -1,179 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>FAQ</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
</head>
<body>
<header>
<div class="px-3 py-2 bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="FAQ.html" class="nav-link text-secondary">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<main>
<div class="container pt-5">
<div>
<h1 class="text-primary">Do you accept more than one animal?</h1>
</div>
<div>
<h5 class="text-secondary">
I do but all services are priced for one animal. For more than one pet I
charge $8 per additional animal for walking and drop-in services. For
house sitting services, more than one pet I charge $10 per additional animal.
</h5>
</div>
<hr>
<div>
<h1 class="text-primary">What types of payments do you accept?</h1>
</div>
<div>
<h5 class="text-secondary">
I accept all major credit cards, bank transfers, and Paypal. Invoices are sent after service is rendered.
</h5>
</div>
<hr>
<div>
<h1 class="text-primary">When is payment due?</h1>
</div>
<div>
<h5 class="text-secondary">
Invoices are sent via email that have a link to the invoice. Clients are able to pay directly from the invoice.
</h5>
</div>
<hr>
<hr>
</div>
</main>
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<p class="col-md-4 mb-0 text-muted">
© 2023 Andrew Bryant
</p>
<a href="/" class="col-md-4 d-flex align-items-center justify-content-center mb-3 mb-md-0 me-md-auto link-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32">
<use xlink:href="#bootstrap"></use>
</svg>
</a>
<ul class="nav col-md-4 justify-content-end">
<li>
<a href="FAQ.html" class="nav-link text-secondary">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -1,161 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>About me</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
</head>
<body>
<header>
<div class="px-3 py-2 bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<main>
<div class="container pt-5">
<div class="row">
<div class="col-8">
Laboriosam voluptatem pariatur consequatur. Corrupti corrupti et aut commodi vero nesciunt totam. Deleniti et labore reiciendis quia tempore voluptas occaecati. Debitis necessitatibus velit ut unde aliquam id quod. Laborum quas non itaque et ut veniam voluptate. Voluptates numquam non non id natus voluptatibus. Nobis eius dicta suscipit in at voluptas numquam molestiae. Qui non magni velit qui autem veniam quia. Dolore velit doloremque dolores doloremque eveniet. Libero rerum est debitis sint velit. Id sapiente magnam voluptas at corporis. Error quia laudantium et veniam adipisci ipsum.
</div>
<div class="col-4">
<img class="img-fluid" src="../img/about_me_1_md.jpg" srcset="../img/about_me_1_sm.jpg 540w, ../img/about_me_1_md.jpg 720w, ../img/about_me_1_lg.jpg 960w" sizes="50vw">
</div>
<div class="col-4">
<img class="img-fluid" src="../img/about_me_2_lg.jpg" srcset="../img/about_me_2_sm.jpg 540w, ../img/about_me_2_md.jpg 720w, ../img/about_me_2_lg.jpg 960w" sizes="50vw">
</div>
<div class="col-8">
Suscipit est voluptatum possimus aut. Culpa laboriosam id explicabo. Aut qui ad repellat doloremque. Quis quo sunt sed ab optio voluptate reprehenderit. Autem aut ea odit sed. Laboriosam minus eos qui dicta qui molestias. Labore quis quae aliquam quod quia cum ut laboriosam. Incidunt aut aut libero voluptates velit ut saepe. Qui deserunt tempore doloremque qui veniam aliquid. Vel est eligendi ipsum ullam corrupti explicabo saepe. Eligendi cum soluta numquam nihil doloribus praesentium. Doloribus blanditiis incidunt itaque veniam.
</div>
<div class="col-8">
Debitis nulla impedit consectetur cum laboriosam autem qui minus. Soluta placeat est inventore facere. Inventore voluptates vero assumenda inventore illum eos eveniet. Itaque corrupti aliquid aut officiis. Quia voluptatem voluptas aut placeat. Dolor quis eos magnam cum. Vel vel magni ea at. Earum molestiae id illum eius sit officiis. Corporis non eveniet deleniti quaerat eos. Corrupti ad repellendus facere quisquam aut. Hic neque aut ea incidunt inventore fugiat doloribus ullam. Eius quo veritatis exercitationem suscipit. Laudantium sed aut doloremque. Molestias unde ipsa eum quos deserunt aut voluptate atque. Deserunt omnis excepturi ipsum recusandae beatae. Voluptas repellat accusantium omnis animi ut accusantium dolorum commodi. Qui natus delectus a. Qui sequi pariatur aut et voluptatum atque vero. Iusto ea cupiditate sed qui quae. Aliquid a illum repellat pariatur aut repudiandae.
</div>
<div class="col-4">
<img class="img-fluid" src="../img/about_me_3_lg.jpg" srcset="../img/about_me_3_sm.jpg 540w, ../img/about_me_3_md.jpg 720w, ../img/about_me_3_lg.jpg 960w" sizes="50vw">
</div>
</div>
</div>
</main>
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<p class="col-md-4 mb-0 text-muted">
© 2023 Andrew Bryant
</p>
<a href="/" class="col-md-4 d-flex align-items-center justify-content-center mb-3 mb-md-0 me-md-auto link-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32">
<use xlink:href="#bootstrap"></use>
</svg>
</a>
<ul class="nav col-md-4 justify-content-end">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -1,184 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Contact me</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
</head>
<body>
<header>
<div class="px-3 py-2 bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<main>
<div class="container pt-5">
<div class="row">
<h4>If you have any questions, the
<a href="../faq.html">FAQ</a>
page may have an answer. Contacting me directly by
<a href="mailto: bryant.caregiving@fastmail.com">email</a> or
<a href="tel:+14102799125">text</a> message is welcome.
</h4>
</div>
<div class="row mt-2">
<div class="col-6">
<h3 class="text-center text-primary">
Contact me directly!
</h3>
<a href="tel::+14102799125" class="mr-8">
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="currentColor" class="bi bi-telephone-fill" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.885.511a1.745 1.745 0 0 1 2.61.163L6.29 2.98c.329.423.445.974.315 1.494l-.547 2.19a.678.678 0 0 0 .178.643l2.457 2.457a.678.678 0 0 0 .644.178l2.189-.547a1.745 1.745 0 0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 1.034c-.74.74-1.846 1.065-2.877.702a18.634 18.634 0 0 1-7.01-4.42 18.634 18.634 0 0 1-4.42-7.009c-.362-1.03-.037-2.137.703-2.877L1.885.511z"/>
</svg>
</a>
<a href="mailto: bryant.caregiving@fastmail.com">
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="currentColor" class="bi bi-envelope-fill" viewBox="0 0 16 16">
<path d="M.05 3.555A2 2 0 0 1 2 2h12a2 2 0 0 1 1.95 1.555L8 8.414.05 3.555ZM0 4.697v7.104l5.803-3.558L0 4.697ZM6.761 8.83l-6.57 4.027A2 2 0 0 0 2 14h12a2 2 0 0 0 1.808-1.144l-6.57-4.027L8 9.586l-1.239-.757Zm3.436-.586L16 11.801V4.697l-5.803 3.546Z"/>
</svg>
</a>
</div>
</div>
<div class="row">
<div class="col-4">
<h3 class="text-center text-primary">
Follow me!
</h3>
<a href="https://www.instagram.com/awkawb" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="currentColor" class="bi bi-instagram" viewBox="0 0 16 16">
<path d="M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.917 3.917 0 0 0-1.417.923A3.927 3.927 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.916 3.916 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.926 3.926 0 0 0-.923-1.417A3.911 3.911 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0h.003zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599.28.28.453.546.598.92.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.47 2.47 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.478 2.478 0 0 1-.92-.598 2.48 2.48 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233 0-2.136.008-2.388.046-3.231.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92.28-.28.546-.453.92-.598.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045v.002zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92zm-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217zm0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334z"/>
</svg>
</a>
</div>
</div>
</div>
</div>
</main>
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<p class="col-md-4 mb-0 text-muted">
© 2023 Andrew Bryant
</p>
<a href="/" class="col-md-4 d-flex align-items-center justify-content-center mb-3 mb-md-0 me-md-auto link-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32">
<use xlink:href="#bootstrap"></use>
</svg>
</a>
<ul class="nav col-md-4 justify-content-end">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -1,231 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Services</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
</head>
<body>
<header>
<div class="px-3 py-2 bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<main>
<div class="container pt-5">
<div class="row pt-2 pb-4">
<div class="col">
<div class="card">
<img class="img-fluid" class="card-img-top"
src="../img/services_dog_walking_card_lg.png"
srcset="../img/services_dog_walking_card_sm.png 540w,
../img/services_dog_walking_card_md.png 720w,
../img/services_dog_walking_card_lg.png 960w,
../img/services_dog_walking_card_xl.png 1140w"
sizes="50vw" alt="Woman walking dog">
<div class="card-body">
<h1 class="card-title text-center text-primary">Walking</h1>
<hr>
<h2 class="text-success text-center">$20+/visit</h2>
<hr class="invisible">
<p class="text-secondary">
Service includes 30 minute walk for your pet. Bags for poop
clean-up are included.
</p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<img class="img-fluid" class="card-img-top"
src="../img/services_drop_in_card_lg.png"
srcset="../img/services_drop_in_card_sm.png 540w,
../img/services_drop_in_card_md.png 720w,
../img/services_drop_in_card_lg.png 960w,
../img/services_drop_in_card_xl.png 1140w"
sizes="50vw" alt="Woman petting dog">
<div class="card-body">
<h1 class="card-title text-center text-primary">
Drop-in visits
</h1>
<hr>
<h2 class="text-success text-center">$18+/visit</h2>
<hr class="invisible">
<p class="text-secondary">
Service includes 30 minutes of in-home play and/or care for
your pet.
</p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<img class="img-fluid" class="card-img-top"
src="../img/services_house_sitting_card_lg.png"
srcset="../img/services_house_sitting_card_sm.png 540w,
../img/services_house_sitting_card_md.png 720w,
../img/services_house_sitting_card_lg.png 960w,
../img/services_house_sitting_card_xl.png 1140w"
sizes="50vw" alt="Dog eating from food bowl">
<div class="card-body">
<h1 class="card-title text-center text-primary">
House sitting
</h1>
<hr>
<h2 class="text-success text-center">$45+/night</h2>
<hr class="invisible">
<p class="text-secondary">
Service includes in-home overnight stays and animal care.
</p>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-center">
<a href="../forms/meetgreetrequest.html">
<button class="btn btn-primary text-light">
Request meet & greet
</button>
</a>
</div>
</div>
</main>
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<p class="col-md-4 mb-0 text-muted">
© 2023 Andrew Bryant
</p>
<a href="/" class="col-md-4 d-flex align-items-center justify-content-center mb-3 mb-md-0 me-md-auto link-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32">
<use xlink:href="#bootstrap"></use>
</svg>
</a>
<ul class="nav col-md-4 justify-content-end">
<li>
<a href="FAQ.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
FAQ
</a>
</li>
<li>
<a href="about_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
about me
</a>
</li>
<li>
<a href="contact_me.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
contact me
</a>
</li>
<li>
<a href="services.html" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home"></use>
</svg>
services
</a>
</li>
</ul>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -10,6 +10,7 @@ pkgs.mkShell {
flask
markdown
python-dateutil
python-dotenv
python-frontmatter
requests
six
@ -17,19 +18,24 @@ pkgs.mkShell {
urllib3
]))
# Custom Bootstrap
dart-sass
imagemagick
nodejs_20
sqlite
unzip
# DB testing
sqlite
# Static image processing
imagemagick
# Design tools
graphviz
];
shellHook = ''
export FLASK_APP=all_paw_care
export FLASK_DEBUG=1
'';
}