Skip to content

Commit

Permalink
tweaks + caching
Browse files Browse the repository at this point in the history
  • Loading branch information
peterk committed Aug 24, 2018
1 parent 4a1643e commit 0b9d6a1
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,8 @@ venv.bak/

# mypy
.mypy_cache/

env_file
web/app/static/ad/*
docker-compose.override.yml
dbdata/*
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ services:
- ./dbdata:/var/lib/postgresql/data
env_file:
- env_file
memcached:
image: "memcached:1.5.10-alpine"
ports:
- "11211"
env_file:
- env_file
web:
build: ./web
env_file:
Expand All @@ -14,6 +20,7 @@ services:
- ./web/app:/app
depends_on:
- db
- memcached
ports:
- "5432:8080"
command: flask run --host=0.0.0.0 --port=8080
2 changes: 1 addition & 1 deletion web/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7
ENV LISTEN_PORT 8080
EXPOSE 8080
RUN apk add --no-cache git
RUN apk add --no-cache postgresql-dev gcc python3-dev musl-dev postgresql-client
RUN apk add --no-cache postgresql-dev gcc python3-dev musl-dev postgresql-client libmemcached-dev zlib-dev
COPY ./app /app
COPY ./requirements.txt ./requirements.txt
RUN pip install -r ./requirements.txt
Expand Down
26 changes: 23 additions & 3 deletions web/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from models import db, Ad
from sqlalchemy.orm import load_only
import os
from flask_caching import Cache
import time

app = Flask(__name__)
db.init_app(app)
Expand All @@ -16,23 +18,32 @@
}

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://%(user)s:%(pw)s@%(host)s:%(port)s/%(db)s' % POSTGRES
cache = Cache(app, config={'CACHE_TYPE': 'memcached', 'CACHE_MEMCACHED_SERVERS': ('memcached:11211',)})

def view_full_path_key():
return request.full_path


@cache.cached(timeout=120, key_prefix='advertisers')
def get_advertisers():
return [ad.advertiser for ad in Ad.query.options(load_only("advertiser")).order_by(Ad.advertiser).distinct("advertiser").all() if ad.advertiser is not None]


@app.route("/", methods=['GET'])
def index():

advertiser_filter = request.args.get('advertiser', None)

advertisers = [ad.advertiser for ad in Ad.query.options(load_only("advertiser")).order_by(Ad.advertiser).distinct("advertiser").all() if ad.advertiser is not None]

ads = Ad.query.all()
if advertiser_filter:
ads = Ad.query.filter_by(advertiser=advertiser_filter)

return render_template('index.html', ads=ads, advertisers=advertisers, advertiser_filter=advertiser_filter)
return render_template('index.html', ads=ads, advertisers=get_advertisers(), advertiser_filter=advertiser_filter)



@app.route("/ad/<string:fbid>", methods=['GET'])
@cache.cached(timeout=60*60*24)
def ad(fbid):
ad = Ad.query.filter_by(fbid=fbid).first()

Expand All @@ -41,6 +52,15 @@ def ad(fbid):
else:
abort(404)



@app.route("/om-insamlingen", methods=['GET'])
@cache.cached(timeout=60*60*24)
def about():
return render_template('about.html')



if __name__ == "__main__":
# Only for debugging while developing
app.run(host='0.0.0.0', debug=DEBUG, port=80)
8 changes: 2 additions & 6 deletions web/app/static/css/adstyle.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,10 @@
max-width: 308px;
border: 1px solid #dddfe2; }

/* NEWS FEED ADS */
#ads {
display: flex;
flex-wrap: wrap;
justify-content: center; }

.ad {
margin: 0 20px; }
margin: 0 20px;
}

._5pb8._1yz2._8o._8s.lfloat._ohe,
._38vo {
Expand Down
25 changes: 25 additions & 0 deletions web/app/templates/about.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "layout.html" %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-md-8 offset-md-2 text-left mt-5">
<h1>Om politisk annonsering på Facebook</h1>
<p>Annonserna har samlats in med hjälp av frivilliga som installerat en webbläsarplugin från ProPublica. Verktyget plockar ut annonser ur användarens Facebookflöde och skickar in till en databas. Där klassificeras det för att avgöra om det är en politisk annons eller en vanlig. Från databasen hämtas svensk politisk annonsering varje natt till denna webbplats.</p>

<h2>Frågor?</h2>
<h3>Visas alla politiska annonser som läggs upp på Facebook?</h3>
<p>Nej, bara den som frivilliga rapporterat in. Det finns säkerligen ett stort mörkertal i annonser som riktar sig till målgrupper som inte deltar i insamlingsarbetet. <a href="https://projects.propublica.org/political-ad-collector/">Men du kan hjälpa till!</a></p>

<h3>Varför saknas målgruppsinformation på vissa annonser?</h3>
<p>Verktyget har utvecklats löpande för att kunna identifiera annonser i Facebooks webbsidor. Eftersom de ändras ibland kan det under vissa perioder blivit fel i insamlingen.</p>

<h3>Varför står det "SpSonSsrSadS" istället för "Sponsrad"?</h3>
<p>Vi tror att Facebook försöker göra det svårare för annonsblockerare. Därför är deras html-kod ibland strukturerad på ett sätt som skapar annorlunda texter.</p>

<h3>Vad är det för skillnad mot Facebooks egna insynsinitiativ?</h3>
<p>Facebook har, föredömligt, <a href="https://www.facebook.com/politicalcontentads">försökt öka insynen i politisk annonsering på Facebook</a>. Men insynstjänsten går inte att komma åt för den som inte är inloggad på Facebook. Det betyder att arkivinitiativ som t.ex. <a href="https://archive.org/">Internet Archive</a> eller <a href="https://www.kb.se/hitta-och-bestall/hitta-i-samlingarna/kulturarw3.html">Kungliga bibliotekets webbinsamling</a> inte kan komma åt informationen. Utan arkiv blir det svårt för framtida forskare att förstå hur valrörelsen 2018 utspelade sig.</p>

</div>
</div>
</div>
{% endblock %}
5 changes: 2 additions & 3 deletions web/app/templates/ad.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
<div class="ad">
<div class="message">
{% autoescape false %}
{{ad.raw["message"]}}
{{ad.raw["html"]}}
{% endautoescape %}
</div>
<div class="ad-metadata">
<a class="permalink" href="/static/ad/{{ad.fbid}}">Permalink to this ad</a>
<a class="permalink" href="/ad/{{ad.fbid}}">Permalänk till {{ad.fbid}}</a>
<p>Sågs först: <time datetime="{{ad.created_at}}">{{ad.created_at.strftime('%Y-%m-%d')}}</time></p>
</div>
<div class="targeting_info">
<div class="targeting">
<h3>Targeting Information</h3>
<h3>Målgruppsinformation</h3>
{% autoescape false %}
{% if ad.raw["targetings"] %}
{% for targeting in ad.raw["targetings"] %}
Expand Down
27 changes: 14 additions & 13 deletions web/app/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{% extends "layout.html" %}
{% block title %}
Politisk annonsering på Facebook
{% endblock %}
{% block body %}
<section class="jumbotron text-center">
<div class="container">
<h1 class="jumbotron-heading">Politisk annonsering på Facebook</h1>
<p class="lead">Politisk annonsering kan idag vara målgruppsanpassad på detaljnivå. Genom att ta hjälp av frivilliga och verktyg från ProPublica har jag i detta projekt samlat in <a href="#adsection">hundratals politiska annonser</a> från Facebook. Genom att presentera dem här kan vi lära oss mer om hur politisk annonsering går till och vilka budskap som riktas till andra målgrupper än de man själv ingår i.</p>
<p class="lead">Politisk annonsering kan idag vara målgruppsanpassad på detaljnivå. Genom att ta hjälp av frivilliga och verktyg från ProPublica har det samlats in <a href="#adsection">hundratals politiska annonser</a> från Facebook. Genom att presentera dem här kan vi lära oss mer om hur politisk annonsering går till och vilka budskap som riktas till andra målgrupper än de man själv ingår i.</p>
<p class="lead">Vill du hjälpa till att samla in annonser? Installera denna <a href="https://projects.propublica.org/political-ad-collector/">plugin för Chrome och Firefox</a> och hjälp till att rapportera in annonser du med. Insamlingen sparar ingen information om dig som person.</p>
<div class="row" role="main">
<div class="col-md-4 offset-md-4">
Expand All @@ -25,38 +28,36 @@ <h1 class="jumbotron-heading">Politisk annonsering på Facebook</h1>
<div class="container">
<div class="row">
<div class="col-sm-10 offset-sm-1 text-center">
<form action="/" method="get" accept-charset="utf-8" class="form-inline justify-content-center">
<form action="/" method="get" accept-charset="utf-8" class="form-inline justify-content-center">
<label for="advertiser" class="mr-3">Avsändare</label>
<select id="advertiser" name="advertiser" class="form-control mr-3">
<option value="">Alla...</option>
<option value="">Alla...</option>
{% for advertiser in advertisers %}
{% if advertiser_filter == advertiser %}
<option value="{{advertiser}}" selected>{{advertiser}}</option>
<option value="{{advertiser}}" selected>{{advertiser}}</option>
{% else %}
<option value="{{advertiser}}">{{advertiser}}</option>
<option value="{{advertiser}}">{{advertiser}}</option>
{% endif %}
{% endfor %}
</select>
<button type="submit" class="btn btn-primary">Filtrera</button>
</form>
</div>
</div>
</form>
</div>
</div>

<div class="row" id="adsection">
<div class="col-md-12 text-left">
{% if ads %}
<div id="#ads" class="ads mt-2">
<div id="#ads" class="ads mt-2 d-flex flex-wrap">
{% for ad in ads %}

<hr>
<div class="ad">
<div class="ad ml-2">
<div class="message">
{% autoescape false %}
{{ad.raw["html"]}}
{% endautoescape %}
</div>
<div class="ad-metadata">
<a class="permalink" href="/ad/{{ad.fbid}}">Permalänk till annons {{ad.fbid}}</a>
<a class="permalink" href="/ad/{{ad.fbid}}">Permalänk till {{ad.fbid}}</a>
<p>Sågs först: <time datetime="{{ad.created_at}}">{{ad.created_at.strftime('%Y-%m-%d')}}</time></p>
</div>
<div class="targeting_info">
Expand Down
11 changes: 8 additions & 3 deletions web/app/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="sv">
<head>
<meta charset="utf-8">
<title>Politisk annonsering på Facebook</title>
<title>{% block title %}{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta property="og:title" content="Politisk annonsering på Facebook">
<meta property="og:url" content="http://www.politiskannonsering.se/">
Expand All @@ -20,17 +20,22 @@
<body class="text-center">
<nav class="navbar navbar-expand-lg navbar-dark justify-content-between" style="background-color: #3F7FBF;">
<a class="navbar-brand" href="/">Politiska annonser</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Visa/dölj meny">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" href="https://projects.propublica.org/political-ad-collector/#how-it-works">Om insamlingen</a>
<a class="nav-link active" href="/om-insamlingen">Om insamlingen</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="https://www.peterkrantz.se/">Kontakt</a>
</li>
</ul>
</div>
</nav>
{% block body %}{% endblock %}
<p>Ser du inga annonser? Missa inte att stänga av din adblocker.</p>
<p class="mt-5">Ser du inga annonser? Missa inte att stänga av din adblocker.</p>
<script src="{{ url_for('static', filename='js/jquery-3.2.1.slim.min.js') }}" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="{{ url_for('static', filename='js/popper.min.js') }}" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
Expand Down
2 changes: 2 additions & 0 deletions web/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Flask-SQLAlchemy==2.3.2
Flask-Migrate==2.2.1
Flask-Script==2.0.6
requests==2.19.1
Flask-Caching==1.4.0
pylibmc==1.5.2

0 comments on commit 0b9d6a1

Please sign in to comment.