Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VersionUpdate #270

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:18.04
FROM ubuntu:22.04

# Installing python
RUN apt-get update
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ gunicorn
humanize
itsdangerous
jinja2
lxml
lxml_html_clean
markupsafe
maya
names
Expand Down Expand Up @@ -44,4 +44,4 @@ werkzeug
whitenoise
python-dotenv
markdown
flask_common
greenlet>=1.1.2
9 changes: 3 additions & 6 deletions saythanks/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@

from functools import wraps
from flask import Flask, request, session, render_template, url_for
from flask import abort, redirect, Markup, make_response
from flask_common import Common
from flask import abort, redirect, make_response
from markupsafe import Markup
from names import get_full_name
from raven.contrib.flask import Sentry
from flask_qrcode import QRcode
from . import storage
from urllib.parse import quote
from lxml.html.clean import Cleaner
from lxml_html_clean import Cleaner
from markdown import markdown

cleaner = Cleaner()
Expand Down Expand Up @@ -59,9 +59,6 @@ def remove_tags(html):
app.secret_key = os.environ.get('APP_SECRET', 'CHANGEME')
app.debug = True

# Flask-Common.
common = Common(app)

# Sentry for catching application errors in production.
if 'SENTRY_DSN' in os.environ:
sentry = Sentry(app, dsn=os.environ['SENTRY_DSN'])
Expand Down
58 changes: 35 additions & 23 deletions saythanks/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def __repr__(self):
def fetch(cls, uuid):
self = cls()
q = sqlalchemy.text("SELECT * FROM notes WHERE uuid=:uuid")
r = conn.execute(q, uuid=uuid).fetchall()
r = conn.execute(q,{'uuid': uuid}).fetchall()
r=[dict(i._mapping) for i in r]
self.body = r[0]['body']
self.byline = r[0]['byline']
self.uuid = uuid
Expand All @@ -79,19 +80,20 @@ def from_inbox(cls, inbox, body, byline, archived=False, uuid=None, timestamp=No
@classmethod
def does_exist(cls, uuid):
q = sqlalchemy.text('SELECT * from notes where uuid = :uuid')
r = conn.execute(q, uuid=uuid).fetchall()
r = conn.execute(q,{'uuid': uuid}).fetchall()
r=[dict(i._mapping) for i in r]
return bool(len(r))

def store(self):
"""Stores the Note instance to the database."""
q = 'INSERT INTO notes (body, byline, inboxes_auth_id)' + \
'VALUES (:body, :byline, :inbox)'
q = sqlalchemy.text(q)
conn.execute(q, body=self.body, byline=self.byline, inbox=self.inbox.auth_id)
conn.execute(q, {'body': self.body, 'byline': self.byline, 'inbox': self.inbox.auth_id})

def archive(self):
q = sqlalchemy.text("UPDATE notes SET archived = 't' WHERE uuid = :uuid")
conn.execute(q, uuid=self.uuid)
conn.execute(q, {'uuid': self.uuid})

def notify(self, email_address):
myemail.notify(self, email_address)
Expand All @@ -105,38 +107,42 @@ def __init__(self, slug):

@property
def auth_id(self):
q = sqlalchemy.text("SELECT * FROM inboxes WHERE slug=:inbox")
r = conn.execute(q, inbox=self.slug).fetchall()
q = sqlalchemy.text("SELECT * FROM inboxes WHERE slug=:slug")
r = conn.execute(q, {'slug': self.slug}).fetchall()
r=[dict(i._mapping) for i in r]
return r[0]['auth_id']

@classmethod
def is_linked(cls, auth_id):
q = sqlalchemy.text('SELECT * from inboxes where auth_id = :auth_id')
r = conn.execute(q, auth_id=auth_id).fetchall()
r = conn.execute(q, {'auth_id': auth_id}).fetchall()
r=[dict(i._mapping) for i in r]
return bool(len(r))

@classmethod
def store(cls, slug, auth_id, email):
try:
q = sqlalchemy.text('INSERT into inboxes (slug, auth_id,email) VALUES (:slug, :auth_id, :email)')
conn.execute(q, slug=slug, auth_id=auth_id, email=email)
q = sqlalchemy.text('INSERT into inboxes (slug, auth_id, email) VALUES (:slug, :auth_id, :email)')
conn.execute(q, {'slug': slug, 'auth_id': auth_id, 'email': email})

except UniqueViolation:
print('Duplicate record - ID already exist')
logging.error("ID already exist")
print('Duplicate record - ID already exists')
logging.error("ID already exists")
return cls(slug)

@classmethod
def does_exist(cls, slug):
q = sqlalchemy.text('SELECT * from inboxes where slug = :slug')
r = conn.execute(q, slug=slug).fetchall()
r = conn.execute(q, {'slug': slug}).fetchall()
r=[dict(i._mapping) for i in r]
return bool(len(r))

@classmethod
def is_email_enabled(cls, slug):
q = sqlalchemy.text('SELECT email_enabled FROM inboxes where slug = :slug')
try:
r = conn.execute(q, slug=slug).fetchall()
r = conn.execute(q, {'slug': slug}).fetchall()
r=[dict(i._mapping) for i in r]
return bool(r[0]['email_enabled'])
except InFailedSqlTransaction:
print(traceback.print_exc())
Expand All @@ -146,18 +152,19 @@ def is_email_enabled(cls, slug):
@classmethod
def disable_email(cls, slug):
q = sqlalchemy.text('update inboxes set email_enabled = false where slug = :slug')
conn.execute(q, slug=slug)
conn.execute(q, {'slug': slug})

@classmethod
def enable_email(cls, slug):
q = sqlalchemy.text('update inboxes set email_enabled = true where slug = :slug')
conn.execute(q, slug=slug)
conn.execute(q, {'slug': slug})

@classmethod
def is_enabled(cls, slug):
q = sqlalchemy.text('SELECT enabled FROM inboxes where slug = :slug')
try:
r = conn.execute(q, slug=slug).fetchall()
r = conn.execute(q, {'slug': slug}).fetchall()
r=[dict(i._mapping) for i in r]
if not r[0]['enabled']:
return False
return bool(r[0]['enabled'])
Expand All @@ -169,12 +176,12 @@ def is_enabled(cls, slug):
@classmethod
def disable_account(cls, slug):
q = sqlalchemy.text('update inboxes set enabled = false where slug = :slug')
conn.execute(q, slug=slug)
conn.execute(q, {'slug': slug})

@classmethod
def enable_account(cls, slug):
q = sqlalchemy.text('update inboxes set enabled = true where slug = :slug')
conn.execute(q, slug=slug)
conn.execute(q, {'slug': slug})

def submit_note(self, body, byline):
note = Note.from_inbox(self.slug, body, byline)
Expand All @@ -184,7 +191,8 @@ def submit_note(self, body, byline):
@classmethod
def get_email(cls, slug):
q = sqlalchemy.text('SELECT email FROM inboxes where slug = :slug')
r = conn.execute(q, slug=slug).fetchall()
r = conn.execute(q, {'slug': slug}).fetchall()
r=[dict(i._mapping) for i in r]
return r[0]['email']

@property
Expand All @@ -198,7 +206,8 @@ def myemail(self):
def notes(self):
"""Returns a list of notes, ordered reverse-chronologically."""
q = sqlalchemy.text("SELECT * from notes where inboxes_auth_id = :auth_id and archived = 'f'")
r = conn.execute(q, auth_id=self.auth_id).fetchall()
r = conn.execute(q, {'auth_id': self.auth_id}).fetchall()
r=[dict(i._mapping) for i in r]

notes = [
Note.from_inbox(
Expand All @@ -212,7 +221,8 @@ def notes(self):
def search_notes(self, search_str):
"""Returns a list of notes, queried by search string "param" """
q = sqlalchemy.text("""SELECT * from notes where ( body LIKE '%' || :param || '%' or byline LIKE '%' || :param || '%' ) and inboxes_auth_id = :auth_id""")
r = conn.execute(q, param=search_str, auth_id=self.auth_id).fetchall()
r = conn.execute(q, {'param': search_str, 'auth_id': self.auth_id}).fetchall()
r=[dict(i._mapping) for i in r]

notes = [
Note.from_inbox(
Expand All @@ -225,14 +235,16 @@ def search_notes(self, search_str):

def export(self, file_format):
q = sqlalchemy.text("SELECT * from notes where inboxes_auth_id = :auth_id and archived = 'f'")
r = conn.execute(q, auth_id=self.auth_id).fetchall()
r = conn.execute(q, {'auth_id': self.auth_id}).fetchall()
r=[dict(i._mapping) for i in r]
return tablib.Dataset(r).export(file_format)

@property
def archived_notes(self):
"""Returns a list of archived notes, ordered reverse-chronologically."""
q = sqlalchemy.text("SELECT * from notes where inboxes_auth_id = :auth_id and archived = 't'")
r = conn.execute(q, auth_id=self.auth_id).fetchall()
r = conn.execute(q, {'auth_id': self.auth_id}).fetchall()
r=[dict(i._mapping) for i in r]

notes = [Note.from_inbox(
self.slug, n['body'], n['byline'], n['archived'], n['uuid']) for n in r]
Expand Down