Commit c83ac5ef authored by Jordi Masip's avatar Jordi Masip
Browse files

Primera versió d'AteneaCal per un 'environment' diferent de AppEngine

parents
Qiwei Ni
Jordi Masip
\ No newline at end of file
This diff is collapsed.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import qiwi, re, logging
from flask import Flask, render_template, make_response, request
from werkzeug.routing import BaseConverter
from urllib import unquote
app = Flask(__name__)
app.debug = True
DOMAIN_NAME = "atena-cal.jmr.cat"
class RegexConverter(BaseConverter):
def __init__(self, url_map, *items):
super(RegexConverter, self).__init__(url_map)
self.regex = items[0]
app.url_map.converters['regex'] = RegexConverter
@app.route('/')
def main():
if "Safari" in request.headers.get('User-Agent'):
return render_template("index.html", button_name="SUBSCRIURE'S", open_cal="YES", domain=DOMAIN_NAME)
else:
return render_template("index.html", button_name="OBTENIR URL", open_cal="NO", domain=DOMAIN_NAME)
@app.route('/calendar/<regex("\d+"):uid>/<regex("[\d\w]+"):token><regex("(\/\d*)?"):hours>')
def calendar(uid, token, hours):
# Hores on es configura l'alarma
hours = 0 if hours == "" or hours == "/" else int(hours[1:])
#logging.debug("uid %s: %d hours" % (uid, hours))
url = "http://atenea.upc.edu/moodle/calendar/export_execute.php?userid=%s&authtoken=%s&preset_what=all&preset_time=custom" % (uid, token)
calendar = qiwi.contingut(url, hours, uid)
if isinstance(calendar, Exception):
return render_template("error.html", error_msg=calendar.value)
r = make_response(calendar)
r.headers["Content-Type"] = "text/calendar; charset=utf-8"
r.headers["Content-Disposition"] = 'attachment; filename="calendar.ics"'
return r
@app.route('/getCalendar/<regex(".*"):url>')
def getCalendar(url):
url = unquote(url)
pttrn = r"^http\:\/\/atenea\.upc\.edu\/moodle\/calendar\/.*?(?:userid=(\d+)&.*?token=(\w+)&).*$"
r = re.findall(pttrn, url)
if len(r) == 0:
return render_template("error.html", error_msg="la url no és vàlida")
return calendar(r[0][0], r[0][1], "")
if __name__ == "__main__":
DOMAIN_NAME = "127.0.0.1:5000"
app.run()
#Q1
330214:INF
330213:F
330215:ISD
330216:FMT
330217:ME
#Q2
330217:EST
330218:TC1
330219:TECPRO
330220:SD
330221:TCIR
#Q3
330222:MAE
330223:TC2
330224:DP
330225:EMP
330226:CSL
#Q4
330227:SA
330228:PBN
330229:AC
330230:CSR
330231:SS
#Q5
330232:PCTR
330233:GOP
330234:SO
330235:XCOM
330236:PDS
#Q6
330237:SE
330238:ES
330239:ASI
330240:SEC
330241:
#Q7
330242:
330243:
330244:
330245:
330246:
330247:BD
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re, datetime, time, json, requests
class Calendar(object):
def __init__(self, text, hores, db = None):
self.text = text.encode('utf-8')
self.info = ''
self.llista = self.event()
self.t = hores
self.db = db
def event(self):
llista = []
self.info = self.text[:self.text.find("BEGIN:VEVENT")].replace('\r\n', '\n').rstrip() \
+ "\nNAME:Calendari TIC\nX-WR-CALNAME:Calendari TIC\n"
result = re.findall("(BEGIN\:VEVENT.*?END\:VEVENT)", self.text, re.MULTILINE|re.DOTALL)
for e in result:
l = e.replace('\r\n\t ', '').split('\r\n')
d = {}
for a in l[1:-1]:
i = a.find(':')
d[a[0:i]] = a[i+1:]
llista.append(d)
return llista
def __str__(self):
s = self.info
for d in self.llista:
l = [k+':'+v for k, v in d.iteritems()]
s += "BEGIN:VEVENT\n" + "\n".join(l)
nom_tasca = d["SUMMARY"]
if len(s) > 20:
nom_tasca = nom_tasca[0:20].strip() + "..."
if self.t: # S'ha definit una alarma:
s += "\nBEGIN:VALARM\n" \
"TRIGGER:-PT%dH\n" \
"ACTION:DISPLAY\n" \
"DESCRIPTION:La tasca de \"%s\" finalitza d'aquí %dh\n" \
"END:VALARM" % (self.t, nom_tasca, self.t)
s += "\nEND:VEVENT\n"
s += "END:VCALENDAR"
return s.replace('\n', '\r\n')
def ISOStringToDate(fromString):
return datetime.datetime(*time.strptime(fromString,"%Y%m%dT%H%M%S")[0:6])
def get_assignatures():
d = {}
with open("noms.txt", 'r') as f:
for e in f.readlines():
if e[0] != '#':
d[e[0:6]] = e[7:].strip()
return d
def get_calendari(url, hores, uid="-1"):
r = requests.get(url)
if r.status_code != 200:
return render_template("error.html", error_msg="Hi ha hagut un error en obtenir el calendari des d'Atenea. Error %d\n\n" % r.status_code)
c = Calendar(r.text, hores)
d = get_assignatures()
uid = int(uid)
# es completa el nom de cada event i d'altres claus:
for e in c.llista:
if d.has_key(e["CATEGORIES"][17:23]):
e["SUMMARY"] += " - " + d[e["CATEGORIES"][17:23]]
if e.has_key("DESCRIPTION"):
e["DESCRIPTION"] = e["DESCRIPTION"].strip()
e["DTEND"] = e["DTSTART"]
e["DTSTART"] = time.strftime("%Y%m%dT%H%M%SZ", (ISOStringToDate(e["DTSTART"][:-1]) - datetime.timedelta(hours = 1)).timetuple())
return str(c)
if __name__ == '__main__':
print get_calendari("http://atenea.upc.edu/...", 3)
Flask==0.10.1
requests==2.7.0
\ No newline at end of file
body {
font-family: "Arial", Helvetica, sans-serif;
/*background-color: #EEE;*/
font-size: 16px;
line-height: 22px;
}
h1, h2, h3 {
font-weight: normal;
}
a {
color: #34AADC;
text-decoration: none;
}
#content {
width: 600px;
margin:20px auto 0 auto;
padding: 10px;
}
#url_result {
font-size: 12px;
visibility: hidden;
}
input[type=text] {
padding: 5px;
border:1px solid #BBB;
}
#ical_url {
width: 385px;
margin-right:10px;
}
#hours {
width: 100px;
margin-right:10px;
}
#notice {
font-style: italic;
font-size: 13px;
color: #AAA;
}
input[type=button] {
padding: 10px;
margin:10px 0 10px 0;
color: #FFF;
border: 1px solid rgba(255,255,255,0.5);
background-color: #34AADC;
border-radius: 3px;
}
footer {
margin-top: 20px;
color: #888;
font-size: 13px;
text-align: center;
line-height: 17px;
}
\ No newline at end of file
<html>
<head>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}" media="screen" />
<meta charset='utf-8'>
<title>{% block title %}{% endblock %} - AteneaCalendar</title>
{% block head %}
{% endblock %}
</head>
<body>
<div id="content">
{% block body %}
{% endblock %}
<footer><small>DESENVOLUPAT PER</small> Qiwei Ni<small> I </small>Jordi Masip</br><small>EPSEM, 2014-2016</small></footer>
</div>
</body>
</html>
{% extends "base.html" %}
{% block title %}Error{% endblock %}
{% block body %}
<h1>Error</h1>
<p><strong>Hi ha hagut un error: </strong>{{ error_msg }}</p>
{% endblock %}
{% extends "base.html" %}
{% block head %}
<script>
function showUrl() {
var open_cal = "{{ open_cal }}" == "YES";
var url = document.getElementById("ical_url").value;
var m = url.match(/(userid=(\d+)&|token=(\w+)&)/g);
var err_msg = "La URL introduïda és invàlida";
var url_result = document.getElementById("url_result");
url_result.style.visibility = "visible";
var hours = document.getElementById("hours").value;
// Mostrem el missatge d'erorr per defecte
url_result.innerHTML = err_msg;
if (m != null) {
var result = m.map(function(val){
return val.replace(/((userid|token)=|&)/g,'');
});
if (result.length == 2) {
hours = hours.match(/^[1-9]\d*$/g) ? hours.toString() : "";
url_result.innerHTML = "http://{{ domain }}/calendar/" + result[0] + "/" + result[1] + "/" + hours;
window.location = "webcal://{{ domain }}/calendar/" + result[0] + "/" + result[1] + "/" + hours;
}
}
};
window.onload = function() {
document.getElementById("generateUrl").onclick = showUrl;
};
</script>
{% endblock %}
{% block title %}Principal{% endblock %}
{% block body %}
<h1>Benvingut a AteneaCalendar</h1>
<p>Per subsciure-us a un calendari, vés al <a href="http://atenea.upc.edu/moodle/calendar/">calendari d'Atenea</a> i exporta'l generant una URL. Tot seguit introdueix l'URL a la següent caixa i el número d'hores de l'avís*. Finalment, prem el botó blau:<br></p>
<input type="text" id="hours" value="" placeholder="Hores de l'avís"><input type="text" id="ical_url" value="" placeholder="URL del calendari"><input type="button" name="generateUrl" value="{{ button_name }}" id="generateUrl">
<div id="url_result">-</div>
<div id="notice">* Els avisos no estan disponibles a Google Calendar ni a Outlook</div>
{% endblock %}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment