...
 
Commits (29)
......@@ -45,3 +45,5 @@ env*
.webassets-cache
.DS_Store
*.sublime-*
*.json
archive/*
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding=latin-1
import sys
import json
import requests
import requests.packages.urllib3
import logging
import urllib
import unicodedata
from fredrika import locationfinder
logger = logging.getLogger(__name__)
# disable urllib3 warnings and log mumbojumbo
requests.packages.urllib3.disable_warnings()
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("requests").setLevel(logging.INFO)
name = 'VMA'
base_url = 'https://vma.sverigesradio.se/api'
verify_ssl = False
def parse_feed(db, Message, topic_id):
def byteify(input):
if isinstance(input, dict):
return {byteify(key): byteify(value)
for key, value in input.iteritems()}
elif isinstance(input, list):
return [byteify(element) for element in input]
elif isinstance(input, unicode):
return input.encode('utf-8')
else:
return input
def parse_feed(db, Message, topic_id, app):
logging.debug('Inside parser')
# setup some defaults from the config
archive_path = app.config['ARCHIVE_PATH']
base_url = app.config['VMA_BASE_URL']
changed = False
# see what we have
# see what we have active
logging.debug('Get active json')
vmas = Message.query.filter(Message.active).all()
# make a list of all active ones
# make a list of all active ones (we might need to disable them if they are inactive)
active_vmas = []
for row in vmas:
active_vmas.append(row.raw['identifier'])
for row in vmas:
identifier = row.raw['identifier']
active_vmas.append(identifier)
# do the query
# do the query, get the index and see if we have any active
url = base_url + '/index.json'
try:
r = requests.get(url, verify=verify_ssl)
# force UTF-8 since VMA's often contain mixed encoding
r.encoding = 'UTF-8'
except Exception as e:
logging.error("Problem trying URL in %s %s" % (name, e))
raise ValueError('Couldnt connect to %s url, bailing' % name)
logging.debug("Problem trying URL in %s %s" % (name, e))
raise ValueError("Couldn't connect to %s url, bailing!" % name)
data = r.json()
alerts = []
logging.debug("Parsing feed")
logging.debug("Parsing index result")
logging.debug("Counting feed: %s" % data['count'])
if data['count'] > 0:
logging.debug("New %s(s): %s" % (name, data['count']))
for alert in data['alert']:
alerts.append(alert['identifier'])
logging.debug('Iterater over alerts')
for alert in alerts:
if alert not in [row.raw['identifier'] for row in vmas]:
# have we seen it before?
if alert in [row.raw['identifier'] for row in vmas]:
logging.debug("This VMA (%s) is already know, returning." % alert)
return False
else:
url = base_url + '/%s.json' % alert
logging.debug("Parsing %s: %s" % (name, url))
r = requests.get(url, verify=verify_ssl)
r.encoding = 'UTF-8' # force UTF-8 response again
try:
data = r.json()
except Exception as e:
# wrong encoding or something
logging.error("%s with id %s failed, exiting!" % (name, alert))
raise ValueError('%s Couldnt parse the %s, bailing' % (name, alert))
# lets download to archive file
archive_file = archive_path + '/%s.json' % alert
with open(archive_file, 'wb') as handle:
r = requests.get(url, verify=verify_ssl,stream=True)
r.encoding = 'UTF-8'
for chunk in r.iter_content(chunk_size=512):
if chunk: # filter out keep-alive new chunks
handle.write(chunk)
# sometimes VMA testing tests takes place, lets ignore those.
desc = data['info'][0]['description']
......@@ -62,18 +99,53 @@ def parse_feed(db, Message, topic_id):
logging.info('%s Test message, skipping %s' % (name, alert))
continue
# and sometimes they test stuff without location
logging.info("Adding new %s with id %s" % (name, alert))
# and sometimes they test stuff without location
if 'area' in data['info'][0]:
locationdata = data['info'][0]['area'][0]['areaDesc']
location = data['info'][0]['area'][0]['areaDesc']
else:
locationdata = 'Sverige, Sverige'
location = False
'''
# Lets pretend that this isn't needed any more (due to r.encoding=UTF-8):
# location is probably in windows encoding
try:
location = location.encode("windows-1252").decode("utf-8")
# convert to base form
location = unidecode(location).encode('utf-8')
# new location base form
logging.debug("Base form: %s" % locationdata)
except Exception as e:
# wrong encoding or something
logging.error("%s loc conversion with id %s failed utf8!" % (name, alert))
location = unicodedata.normalize('NFKD', location).encode('ascii','xmlcharrefreplace')
translations = (
('¶', ''), ('¤', ''), ('¥', ''),
('å', 'a'), ('ä', 'a'), ('ö', 'o'),
('Å', 'A'), ('Ä', 'A'), ('Ö', 'O'),
('Ã', 'a'), ('รถ','o'), ('รค','a'),
)
for from_str, to_str in translations:
location = location.replace(from_str, to_str)
'''
location = locationfinder( locationdata )
# Override misspelled county :/
location = location.replace('Gataland', 'Gotaland')
# current location
logging.info(location)
try:
location = locationfinder( location )
logging.info("The location is probably %s" % location)
except Exception as e:
# wrong encoding or something
logging.error("%s location conversion with id %s failed!" % (name, alert))
msg = Message()
msg.subject = data['info'][0]['event']
msg.subject = u'VMA - Viktigt Meddelande till Allmänheten'
msg.message = data['info'][0]['resource'][0]['derefUri']
msg.active = True
msg.topic_id = topic_id
......@@ -89,9 +161,13 @@ def parse_feed(db, Message, topic_id):
# update non-active alerts to be just that
for vma in vmas:
if vma.raw['identifier'] not in alerts:
vma.active = False
db.session.commit()
logging.info("Deactivating inactive %s with id %s" % (name, vma.raw['identifier']))
# ignore our manually sent tests
if vma.raw['identifier'].startswith('HF-'):
continue
else:
vma.active = False
db.session.commit()
logging.info("Deactivating inactive %s with id %s" % (name, vma.raw['identifier']))
# last thing here
return changed
......
......@@ -8,22 +8,28 @@ import requests
import logging
import logging.handlers
import sys
reload(sys) # Reload does the trick!
sys.setdefaultencoding('UTF8')
logger = logging.getLogger()
logger.setLevel(logging.INFO)
#handler = logging.handlers.SysLogHandler(address = '/dev/log', facility='syslog')
if app.config['DEBUG']:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
handler = logging.handlers.SysLogHandler(address = '/dev/log', facility='syslog')
formatter = logging.Formatter( 'feeder[%(process)d]: %(levelname)s: %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
# disable urllib3 warnings and log mumbojumbo
requests.packages.urllib3.disable_warnings()
logging.getLogger("requests").setLevel(logging.WARNING)
def keepalive():
# if not configured, return
if not app.config['STATUSCAKE_MONITOR_URL']:
return False
# disable urllib3 warnings and log mumbojumbo
requests.packages.urllib3.disable_warnings()
logging.getLogger("requests").setLevel(logging.WARNING)
url = app.config['STATUSCAKE_MONITOR_URL']
try:
r = requests.get(url)
......@@ -36,7 +42,7 @@ if __name__ == "__main__":
topic = Topic.query.filter_by(name='VMA').first()
try:
vma_test = vma.parse_feed(db, Message, topic.id)
vma = vma.parse_feed(db, Message, topic.id, app)
except Exception as e:
logger.error('Could not run VMA check: %s' % e)
raise ValueError('Error with VMA test, bailing')
......@@ -44,5 +50,5 @@ if __name__ == "__main__":
# we didn't break, so send keepalive to statuscake.
keepalive()
if vma_test:
if vma:
notify_admin('New VMA!')
......@@ -11,6 +11,7 @@ from flask.ext.cache import Cache
from celery import Celery
from pyfcm import FCMNotification
import requests
import urllib
import os
# time to config
......@@ -37,12 +38,15 @@ def send_to_topic(topic, subject, message, location, message_id):
'place_id' : location[0]['place_id'],
'message' : message,
'message_id' : message_id,
'message_subject' : subject,
'topic_name' : topic,
}
result = push_service.notify_topic_subscribers(
topic_name = topic.lower(),
message_body = subject,
topic_name = "%s" % topic,
data_message = data_message,
dry_run = app.config['FIREBASE_DRY_RUN'],
content_available = True,
)
if app.config['FIREBASE_DRY_RUN']:
......@@ -50,10 +54,12 @@ def send_to_topic(topic, subject, message, location, message_id):
# TODO: here we should have some potential error handling/logging
# Just remember the call is ansyncronus, so we dont know when it returns
if result['success'] is not 1:
if result['failure'] > 0:
msg = "FCM did not succeed with send %s to %s, notifying admin " % (subject, topic)
notify_admin(msg)
return result['results']
@celery.task
def notify_admin(message):
with app.app_context():
......@@ -72,23 +78,23 @@ def notify_admin(message):
@celery.task
def locationfinder(location):
''' takes a list of location names and tries to find them in openstreetmap '''
base_url = 'http://nominatim.openstreetmap.org/search?format=json&limit=1&countrycodes=se&q='
base_url = 'http://nominatim.openstreetmap.org/search?format=json&limit=1&countrycodes=se&'
with app.app_context():
for place in location:
# probably only for tests:
if 'hela landet' in place:
place = 'Sverige'
url = base_url + place
try:
r = requests.get(url)
except:
return False
if r.json():
return r.json()
# if we don't succeed:
return False
# probably only for tests:
if 'hela landet' in location:
location = 'Sverige'
url = base_url + urllib.urlencode( {"q":location} )
try:
r = requests.get(url)
except:
return False
if r.json():
return r.json()
else:
return False
####################
#### extensions ####
......
......@@ -62,7 +62,7 @@ class MessageForm(Form):
subject = TextField(_('Subject'))
location = TextField(_('Location'))
url = TextField(_('URL'))
topic_id = SelectMultipleField(_('Topic'), coerce=int )
topic_id = SelectField(_('Topic'), coerce=int )
def validate(self):
check_validate = super(MessageForm, self).validate()
......@@ -117,3 +117,16 @@ class VolunteerForm(Form):
return False
return True
class SignupForm(Form):
email = TextField(_("Email"), [Required()])
name = TextField(_("Name") )
def validate(self):
check_validate = super(SignupForm, self).validate()
# if our validators do not pass
if not check_validate:
return False
else:
return True
This diff is collapsed.
......@@ -142,3 +142,10 @@ class Message(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), default=1)
org = db.relationship('Org', backref='Message', lazy="joined" )
user = db.relationship('User', backref='Message', lazy="joined" )
class Signup(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(255), unique=True)
email = db.Column(db.String(255), unique=True)
created = db.Column(db.DateTime(timezone=True), server_default=func.now())
......@@ -6,7 +6,7 @@
<div class="row">
<div class="col-lg-12">
<div class="col-xs-offset-1">
To send a message, enter your text and select the topic, then press send.
{{ gettext ("To send a message, enter your text and select the topic, then press send.") }}
</div>
</div>
</div>
......@@ -17,8 +17,17 @@
<div class="row">
<form role="form" action="" method="post">
{{ form.hidden_tag() }}
<div class="col-md-8">
<div class="form-group">
<div class="form-group", style="width: 25%">
{{ form.topic_id.label }}
{{ form.topic_id(class_="form-control") }}
{% if form.topic_id.errors %}
{% for e in form.topic_id.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
<div class="form-group" style="width: 50%">
{{ form.subject.label }}
{{ form.subject(class_="form-control", value="VMA Viktigt meddelande till allmänheten") }}
{% if form.subject.errors %}
......@@ -27,40 +36,27 @@
{% endfor %}
{% endif %}
</div>
<div class="form-group">
<div class="form-group", style="width: 50%">
{{ form.location.label }}
{{ form.location(class_="form-control", value="Malmö, Skåne Län") }}
{{ form.location(class_="form-control", value="Malmö, Sverige", size=10) }}
{% if form.location.errors %}
{% for e in form.location.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
<div class="form-group">
<div class="form-group" style="width: 50%">
{{ form.message.label }}
{{ form.message(class_="form-control") }}
{{ form.message(class_="form-control", cols="25", rows="10") }}
{% if form.message.errors %}
{% for e in form.message.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="form-group">
{{ form.topic_id.label }}
{{ form.topic_id(class_="form-control") }}
{% if form.topic_id.errors %}
{% for e in form.topic_id.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
</div>
</div> {# end row #}
<button type="submit" class="btn btn-primary">Send</button>
<button type="submit" class="btn btn-primary">{{ gettext("Send") }}</button>
</form>
{% endblock %}
......@@ -8,7 +8,6 @@
<span class="sr-only">Toggle navigation</span>
<span class="icon-menu"></span>
</button>
<a class="navbar-brand" href="/"><span class="icon-compass"></span> Hesa Fredrika AB</a>
</div>
<div class="collapse navbar-collapse" id="navbar-collapse">
......@@ -25,10 +24,10 @@
<ul class="nav navbar-nav">
{% if current_user.is_authenticated() %}
{% if current_user.admin %}
<li><a href="{{ url_for('.logging') }}"><span class="icon-list"></span> Logs </a></li>
<li><a href="{{ url_for('.topics') }}"><span class="icon-list"></span> Topics </a></li>
<li><a href="{{ url_for('.volunteer') }}"><span class="icon-list"></span> Volunteers </a></li>
<li><a href="{{ url_for('.logging') }}"><span class="icon-list"></span> Logs </a></li>
<li><a href="{{ url_for('.signups') }}"><span class="icon-people"></span> Signups</a></li>
{% endif %}
<li><a href="{{ url_for('.users') }}"><span class="icon-people"></span> Users</a></li>
{% if current_user.name %}
......
......@@ -18,9 +18,8 @@
<h1 class="text-center">Hesa Fredrika</h1>
<p class="text-center">Få viktiga meddelanden till allmänheten, vädervarningar och annan samhällskritisk information direkt till din mobiltelefon.</p>
<p class="text-center">Ställ upp som frivillig när hjälporganisationer i din närhet behöver hjälp i en krissituation.</p>
<p class="text-center">{{ gettext('Get important public announces, weather warnings and other important information directly to your phone.') }}</p>
<p class="text-center">{{ gettext('Become an volonteer in times of crisis and assist various public organisations.') }}</p>
<div class="row" style="margin-bottom: 1em;">
<div class="col-xs-12 visible-xs">
<br>
......@@ -34,9 +33,54 @@
</div><!-- .row -->
</div>
<div class="hidden-xs col-sm-5 col-md-4 col-md-offset-1">
<img class="img-responsive" src="{{url_for('static', filename='images/splash.png')}}"></p>
</div>
</div>
{# form stuff #}
<form role="form" action="" method="post"> {{ form.hidden_tag() }}
<div class="row">
<p>{{ gettext('Add your email address to our list and get an email when the app is available!') }}</p>
</div> {# end row #}
<div class="row">
<div class="col-md-2">
{{ form.email.label }}
</div>{# end col #}
<div class="col-md-8">
<div class="form-group">
{{ form.email(size=60) }}
{% if form.email.errors %}
{% for e in form.email.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
* <i>{{ gettext('Mandatory') }}</i>
</div>
</div>{# end col #}
<div class="col-md-2">
</div>
</div> {# end row #}
<div class="row">
<div class="col-md-2">
{{ form.name.label }}
</div>{# end col #}
<div class="col-md-8">
<div class="form-group">
{{ form.name(size=60) }}
{% if form.name.errors %}
{% for e in form.name.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
</div>{# end col #}
<div class="col-md-2">
</div>
</div> {# end row #}
<button type="submit" class="btn btn-primary">{{ gettext('Send') }}</button>
</form>
{% endblock %}
......@@ -4,17 +4,6 @@
{% block body %}
{#
<form class="form-inline" action="" method="post" name="searchform">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.word(class='form-control') }}
<button type="submit" class="btn btn-default">Search</button>
</div>
</form>
#}
<div class="container-fluid">
<div class="row" style="background-color: #ccc;">
<div class="col-sm-2">
......@@ -23,21 +12,26 @@
<div class="col-sm-1">
Topic
</div>
<div class="col-sm-5">
Subject
</div>
<div class="col-sm-1">
URL
Active
</div>
<div class="col-sm-1">
<div class="col-sm-4">
Location
</div>
<div class="col-sm-1">
Delivered
URL
</div>
<div class="col-sm-1">
Delivered
</div>
<div class="col-sm-2" align="center">
Identifier
</div>
{#
<div class="col-sm-1" align=center>
Sender
</div>
#}
</div>
{% for l in data.items %}
<div class="row" style="background-color: #{{ loop.cycle('eee', 'ddd') }};">
......@@ -47,21 +41,34 @@
<div class="col-sm-1">
{{ l.topic.name }}
</div>
<div class="col-sm-5">
{{ l.subject }}
<div class="col-sm-1" align=center>
{% if l.active %}
<a href="{{ url_for('.logging', inactivate=l.id ) }} "> <span class="icon-check"></a>
{% else %}
<a href="{{ url_for('.logging', activate=l.id ) }} "> <span class="icon-plus"></a>
{%endif%}
</div>
<div class="col-sm-1">
<a href="{{ url_for('main.message_public', mid=l.id ) }} ">link</a>
<div class="col-sm-4">
{% if l.location[0] %}
{{ l.location[0]['display_name'] }}
{% else %}
{{ l.location }}
{% endif %}
</div>
<div class="col-sm-1">
{{ l.location[0][0] }}
<a href="{{ url_for('main.message_public', mid=l.id ) }} ">link</a>
</div>
<div class="col-sm-1">
<div class="col-sm-1" align=center>
{% if l.delivered %} <span class="icon-check"> {%endif%}
</div>
<div class="col-sm-1">
<div class="col-sm-2" align=center>
<a href="{{ url_for('main.message_edit', mid=l.id ) }} ">{% if l.raw.identifier %} {{ l.raw.identifier }} {%endif%}</a>
</div>
{#
<div class="col-sm-1" align=center>
{% if l.user.name %} {{ l.user.name }} {%else%} {{ l.user.email }} {%endif%}
</div>
#}
</div>
{% endfor %}
</div> {# end container table #}
......@@ -72,14 +79,14 @@
{% for page in data.iter_pages(left_edge=2, left_current=2, right_current=2, right_edge=2) %}
{% if page %}
{% if page != data.page %}
<a href="{{ url_for('admin.analysis', page=page) }}">{{ page }}</a>
<a href="{{ url_for('main.logging', page=page) }}">{{ page }}</a>
{% else %}
<strong>{{ page }}</strong>
{% endif %}
{% endif %}
{% endfor %}
{% if data.has_next %}
| <a href="{{ url_for('admin.analysis', page=data.next_num) }}">Next page &gt;&gt;</a>
| <a href="{{ url_for('main.logging', page=data.next_num) }}">Next page &gt;&gt;</a>
{% endif %}
</div>
<div>
......
......@@ -8,34 +8,37 @@
<div class="row">
<form role="form" action="" method="post"> {{ form.hidden_tag() }}
<div class="col-sm-12">
<p>Active: {{ form.active() }}
<p>Active: <br/>{{ form.active() }}
{% if form.active.errors %}
{% for e in form.active.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</p>
<p>To: {{ data.topic.name }} </p>
<p>Subject: {{ form.subject(size=80) }}
<p>To:<br/> {{ data.topic.name }} </p>
<p>Subject:<br/> {{ form.subject(size=80) }}
{% if form.subject.errors %}
{% for e in form.subject.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</p>
<p>Message: {{ form.message(size=140) }}
<p>Message:<br/>
<textarea cols="80" id="message" name="message" rows="10">{{ data.message | b64decode }}</textarea>
{% if form.message.errors %}
{% for e in form.subject.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</p>
<p>Location: {{ form.location(size=80) }}
<p>Location:<br/>
<input id="location" name="location" size="70" type="text" value="{% if 'display_name' in data.location[0] %}{{data.location[0].display_name }}{% else %}{{ data.location }}{% endif %}">
{% if form.location.errors %}
{% for e in form.location.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</p>
<p>URL for more information: {{ form.url(size=80) }}
{% if form.url.errors %}
{% for e in form.url.errors %}
......
{% extends "base.html" %}
{% block title %}Signups{% endblock %}
{% block body %}
<div class="container">
<h2>Signups</h2>
{% if data %}
{% for u in data %}
<div class="row" style="background-color: #{{ loop.cycle('eee', 'ddd') }};">
<div class="col-md-5">
{{ u.email }}
</div>
<div class="col-md-3">
{% if u.name != 'false' %} {{ u.name }} {% else %} n/a {% endif %}
</div>
<div class="col-md-3">
{{ u.created.strftime('%Y-%m-%d %H:%M:%S') }}
</div>
<div class="col-md-1">
<a href="{{ url_for('.signups', delete=u.id) }}"> <span class="icon-shield"></a>
</div>
</div>{# end row #}
{% endfor %}
{% endif %}{# end data #}
</div>{# end container #}
{% endblock %}
# Swedish translations for PROJECT.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
# Swedish translations for Hesa Fredrika
# MIT LICENSE - 2017 Hesa Fredrika AB
# This file is distributed under the same license as the Hesa Fredrika Project (MIT license)
# FIRST AUTHOR <f@mekk.com>
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: code@hesafredrika.se\n"
"POT-Creation-Date: 2016-12-09 15:37+0100\n"
"POT-Creation-Date: 2017-07-27 19:09+0200\n"
"PO-Revision-Date: 2015-11-18 22:48+0100\n"
"Last-Translator: Fredrik Lundhag <fredrik@hesafredrika.se>\n"
"Language: sv\n"
......@@ -18,11 +18,12 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: fredrika/forms.py:14 fredrika/forms.py:36
#: fredrika/forms.py:14 fredrika/forms.py:36 fredrika/forms.py:122
msgid "Email"
msgstr "E-post"
#: fredrika/forms.py:15 fredrika/forms.py:96 fredrika/forms.py:109
#: fredrika/forms.py:123
msgid "Name"
msgstr "Namn"
......@@ -42,7 +43,7 @@ msgstr "Lösenord"
msgid "Wrong email or password"
msgstr "Fel email eller lösenord"
#: fredrika/forms.py:60 fredrika/forms.py:82 fredrika/templates/message.html:21
#: fredrika/forms.py:60 fredrika/forms.py:82
msgid "Active"
msgstr "Aktiv"
......@@ -74,23 +75,100 @@ msgstr "Välj ämne"
msgid "Note"
msgstr "Notering"
#: fredrika/main/views.py:357
#: fredrika/main/views.py:34
#, python-format
msgid "Your email has been added to the notification list: %s"
msgstr "Din emailadress har blivit tillagd %s"
#: fredrika/main/views.py:37
msgid "Your email has already been added to the notification list"
msgstr "Din emailadress finns redan på vår lista"
#: fredrika/main/views.py:86
msgid "Location could not be found"
msgstr "Platsen kunde inte hittas"
#: fredrika/main/views.py:95
msgid "Your message was sent added to the send queue"
msgstr "Ditt meddelande är lagt i kön"
#: fredrika/main/views.py:264
#, python-format
msgid "Message %s edited."
msgstr "Meddelande %s ändrades"
#: fredrika/main/views.py:277
msgid "You are logged in"
msgstr "Du är inloggad"
#: fredrika/main/views.py:290
#, python-format
msgid "Deleted user %s"
msgstr "Tog bort user %s"
#: fredrika/main/views.py:299
msgid "You are logged out."
msgstr "Du är utloggad."
#: fredrika/main/views.py:306
msgid "You can only see this if you are logged in!"
msgstr "Du kan bara se detta när du är inloggad!"
#: fredrika/main/views.py:449
#, python-format
msgid "The message with id %s could not be found."
msgstr "Meddelandet med id %s kunde inte hittas."
#: fredrika/templates/dashboard.html:9
msgid "To send a message, enter your text and select the topic, then press send."
msgstr "För att skicka ett meddelande, skriv in text, välj topic och klicka på Skicka"
#: fredrika/templates/index.html:21
msgid ""
"Get important public announces, weather warnings and other important "
"information directly to your phone."
msgstr ""
"Få viktiga meddelanden till allmänheten, vädervarningar och annan "
"samhällskritisk information direkt till din mobiltelefon."
#: fredrika/templates/index.html:22
msgid ""
"Become an volonteer in times of crisis and assist various public "
"organisations."
msgstr ""
"Ställ upp som frivillig när hjälporganisationer i din närhet behöver "
"hjälp i en krissituation"
#: fredrika/templates/index.html:45
msgid ""
"Add your email address to our list and get an email when the app is "
"available!"
msgstr "Lägg till dig på vår epostlista och få ett mail när appen släpps!"
#: fredrika/templates/index.html:60
msgid "Mandatory"
msgstr "Obligatorisk"
#: fredrika/templates/index.html:83
msgid "Send"
msgstr "Skicka"
#: fredrika/templates/message.html:3
msgid "Message log"
msgstr "Meddelanden"
#: fredrika/templates/message.html:19
#: fredrika/templates/message.html:17
msgid "Active warning"
msgstr "Aktiv varning"
#: fredrika/templates/message.html:17
msgid "Inactive warning"
msgstr "Inaktiv varning"
#: fredrika/templates/message.html:20
msgid "Updated"
msgstr "Uppdaterad"
#: fredrika/templates/message.html:21
msgid "Not active"
msgstr ""
#: fredrika/templates/message.html:32
msgid "Permanent link to this message"
msgstr "Permanent länk till detta meddelandet"
......@@ -107,21 +185,3 @@ msgstr "Föregående sida"
msgid "Next page"
msgstr "Nästa sida"
#~ msgid "Username"
#~ msgstr "Användarnamn"
#~ msgid "Region"
#~ msgstr "Region"
#~ msgid "Organisation"
#~ msgstr "Organisation"
#~ msgid "Yes"
#~ msgstr "Ja"
#~ msgid "No"
#~ msgstr "Nej"
#~ msgid "Created at"
#~ msgstr "Skapad"
# Translations template for PROJECT.
# Copyright (C) 2016 ORGANIZATION
# Copyright (C) 2017 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2016-12-09 15:37+0100\n"
"POT-Creation-Date: 2017-07-27 19:09+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -17,11 +17,12 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: fredrika/forms.py:14 fredrika/forms.py:36
#: fredrika/forms.py:14 fredrika/forms.py:36 fredrika/forms.py:122
msgid "Email"
msgstr ""
#: fredrika/forms.py:15 fredrika/forms.py:96 fredrika/forms.py:109
#: fredrika/forms.py:123
msgid "Name"
msgstr ""
......@@ -41,7 +42,7 @@ msgstr ""
msgid "Wrong email or password"
msgstr ""
#: fredrika/forms.py:60 fredrika/forms.py:82 fredrika/templates/message.html:21
#: fredrika/forms.py:60 fredrika/forms.py:82
msgid "Active"
msgstr ""
......@@ -73,21 +74,94 @@ msgstr ""
msgid "Note"
msgstr ""
#: fredrika/main/views.py:357
#: fredrika/main/views.py:34
#, python-format
msgid "Your email has been added to the notification list: %s"
msgstr ""
#: fredrika/main/views.py:37
msgid "Your email has already been added to the notification list"
msgstr ""
#: fredrika/main/views.py:86
msgid "Location could not be found"
msgstr ""
#: fredrika/main/views.py:95
msgid "Your message was sent added to the send queue"
msgstr ""
#: fredrika/main/views.py:264
#, python-format
msgid "Message %s edited."
msgstr ""
#: fredrika/main/views.py:277
msgid "You are logged in"
msgstr ""
#: fredrika/main/views.py:290
#, python-format
msgid "Deleted user %s"
msgstr ""
#: fredrika/main/views.py:299
msgid "You are logged out."
msgstr ""
#: fredrika/main/views.py:306
msgid "You can only see this if you are logged in!"
msgstr ""
#: fredrika/main/views.py:449
#, python-format
msgid "The message with id %s could not be found."
msgstr ""
#: fredrika/templates/dashboard.html:9
msgid "To send a message, enter your text and select the topic, then press send."
msgstr ""
#: fredrika/templates/index.html:21
msgid ""
"Get important public announces, weather warnings and other important "
"information directly to your phone."
msgstr ""
#: fredrika/templates/index.html:22
msgid ""
"Become an volonteer in times of crisis and assist various public "
"organisations."
msgstr ""
#: fredrika/templates/index.html:45
msgid ""
"Add your email address to our list and get an email when the app is "
"available!"
msgstr ""
#: fredrika/templates/index.html:60
msgid "Mandatory"
msgstr ""
#: fredrika/templates/index.html:83
msgid "Send"
msgstr ""
#: fredrika/templates/message.html:3
msgid "Message log"
msgstr ""
#: fredrika/templates/message.html:19
msgid "Updated"
#: fredrika/templates/message.html:17
msgid "Active warning"
msgstr ""
#: fredrika/templates/message.html:21
msgid "Not active"
#: fredrika/templates/message.html:17
msgid "Inactive warning"
msgstr ""
#: fredrika/templates/message.html:20
msgid "Updated"
msgstr ""
#: fredrika/templates/message.html:32
......
alembic==0.8.8
amqp==1.4.9
anyjson==0.3.3
Babel==2.1.1
Babel==2.3.4
backports.shutil-get-terminal-size==1.0.0
bcrypt==3.1.0
billiard==3.3.0.23
......@@ -56,7 +56,7 @@ pytest==2.7.0
pytest-cov==1.8.1
python-editor==1.0.1
python-firebase==1.2
pytz==2016.6.1
pytz==2016.7
redis==2.10.5
requests==2.11.1
simplegeneric==0.8.1
......@@ -64,6 +64,7 @@ six==1.10.0
speaklater==1.3
SQLAlchemy==1.0.15
traitlets==4.3.0
Unidecode==0.4.20
wcwidth==0.1.7
webassets==0.12.0
Werkzeug==0.11.10
......
......@@ -2,4 +2,3 @@
#export APP_SETTINGS="config.DevelopmentConfig"
while true; do python manage.py runserver ; sleep 1 ; done