GCal Coupling: Management Site - decoupled Email from profile
This commit is contained in:
parent
6431764858
commit
290db91956
|
@ -1 +1 @@
|
||||||
{"_module": "oauth2client.client", "token_expiry": "2014-04-26T10:33:34Z", "access_token": "ya29.1.AADtN_WzqSiT0Ir0jy8f_InaX_NAUAs98E5YwU_uHYMMCvhfc90boeQSVPQpJQTWHw", "token_uri": "https://accounts.google.com/o/oauth2/token", "invalid": false, "token_response": {"access_token": "ya29.1.AADtN_WzqSiT0Ir0jy8f_InaX_NAUAs98E5YwU_uHYMMCvhfc90boeQSVPQpJQTWHw", "token_type": "Bearer", "expires_in": 3600}, "client_id": "34462582242-4kpdvvbi27ajt4u22uitqurpve9o8ipj.apps.googleusercontent.com", "id_token": null, "client_secret": "y4t9XBrJdCODPTO5UvtONWWn", "revoke_uri": "https://accounts.google.com/o/oauth2/revoke", "_class": "OAuth2Credentials", "refresh_token": "1/7-6-m_lLAKX8IeD7OuGtkcIiprty_nZUSxhMunSC5b0", "user_agent": null}
|
{"_module": "oauth2client.client", "token_expiry": "2014-06-20T09:36:07Z", "access_token": "ya29.LgA4Q4jhQqjEoBwAAABv_luKCAgrb2C-s1IcYmGZ8nZViS_QHvHKT-IkSo31RQ", "token_uri": "https://accounts.google.com/o/oauth2/token", "invalid": false, "token_response": {"access_token": "ya29.LgA4Q4jhQqjEoBwAAABv_luKCAgrb2C-s1IcYmGZ8nZViS_QHvHKT-IkSo31RQ", "token_type": "Bearer", "expires_in": 3600}, "client_id": "34462582242-4kpdvvbi27ajt4u22uitqurpve9o8ipj.apps.googleusercontent.com", "id_token": null, "client_secret": "y4t9XBrJdCODPTO5UvtONWWn", "revoke_uri": "https://accounts.google.com/o/oauth2/revoke", "_class": "OAuth2Credentials", "refresh_token": "1/7-6-m_lLAKX8IeD7OuGtkcIiprty_nZUSxhMunSC5b0", "user_agent": null}
|
|
@ -12,8 +12,7 @@ class ParticipationSerializer(serializers.ModelSerializer):
|
||||||
def get_identity(self, data):
|
def get_identity(self, data):
|
||||||
""" This hook is required for bulk update. """
|
""" This hook is required for bulk update. """
|
||||||
try:
|
try:
|
||||||
print "get_identity event:" + str( data.get('event', None) ) + " user " + str( data.get('user') )
|
return data.get('event', None), data.get('user')
|
||||||
return ( data.get('event', None), data.get('user') )
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,12 @@ import datetime
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from eventplanner.models import Event, EventParticipation
|
from eventplanner.models import Event, EventParticipation
|
||||||
from eventplanner_gcal.models import GCalMapping, GCalPushChannel
|
from eventplanner_gcal.models import GCalMapping, GCalPushChannel,UserGCalCoupling
|
||||||
from apiclient.http import BatchHttpRequest
|
from apiclient.http import BatchHttpRequest
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -54,21 +55,22 @@ def buildGCalAttendeesObj( event ):
|
||||||
"""Builds a attendees object that is inserted into the GCal event.
|
"""Builds a attendees object that is inserted into the GCal event.
|
||||||
Attendees are all users that have a google mail address. """
|
Attendees are all users that have a google mail address. """
|
||||||
result = []
|
result = []
|
||||||
for u in User.objects.all():
|
|
||||||
if u.email.endswith( "@gmail.com") or u.email.endswith("@googlemail.com"):
|
|
||||||
participation = EventParticipation.get_or_create( u, event )
|
|
||||||
status = "tentative"
|
|
||||||
if participation.status == 'Yes': status = "accepted"
|
|
||||||
if participation.status == 'No' : status = "declined"
|
|
||||||
|
|
||||||
o = {
|
for userMapping in UserGCalCoupling.objects.all():
|
||||||
'id': u.email,
|
u = userMapping.user
|
||||||
'email': u.email,
|
participation = EventParticipation.get_or_create( u, event )
|
||||||
'displayName': u.username,
|
status = "tentative"
|
||||||
'comment': participation.comment,
|
if participation.status == 'Yes': status = "accepted"
|
||||||
'responseStatus': status,
|
if participation.status == 'No' : status = "declined"
|
||||||
}
|
|
||||||
result.append( o )
|
o = {
|
||||||
|
'id': userMapping.email,
|
||||||
|
'email': u.email,
|
||||||
|
'displayName': u.username,
|
||||||
|
'comment': participation.comment,
|
||||||
|
'responseStatus': status,
|
||||||
|
}
|
||||||
|
result.append( o )
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -222,6 +224,9 @@ def syncFromLocalToGoogle( service = None ):
|
||||||
eventDjangoID = int( gcalEv['extendedProperties']['private']['blechreizID'] )
|
eventDjangoID = int( gcalEv['extendedProperties']['private']['blechreizID'] )
|
||||||
try:
|
try:
|
||||||
djangoEv = Event.objects.get( pk=eventDjangoID )
|
djangoEv = Event.objects.get( pk=eventDjangoID )
|
||||||
|
if 'attendees' not in gcalEv:
|
||||||
|
gcalEv['attendees'] = []
|
||||||
|
|
||||||
if gcalEv['attendees'] != buildGCalAttendeesObj( djangoEv ):
|
if gcalEv['attendees'] != buildGCalAttendeesObj( djangoEv ):
|
||||||
batch.add( updateGCalEvent( service, djangoEv ) )
|
batch.add( updateGCalEvent( service, djangoEv ) )
|
||||||
batchIsEmpty = False
|
batchIsEmpty = False
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
from eventplanner.models import Event
|
from eventplanner.models import Event
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
from apiclient.channel import Channel
|
from apiclient.channel import Channel
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -9,6 +11,12 @@ from django.db import models
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class UserGCalCoupling( models.Model ):
|
||||||
|
# For every user in this table the gcal coupling is activated
|
||||||
|
user = models.OneToOneField( User )
|
||||||
|
email = models.CharField( max_length=1024 )
|
||||||
|
|
||||||
|
|
||||||
class GCalMapping( models.Model ):
|
class GCalMapping( models.Model ):
|
||||||
"""Mapping between event id at google and local event id"""
|
"""Mapping between event id at google and local event id"""
|
||||||
gcal_id = models.CharField( max_length=64 )
|
gcal_id = models.CharField( max_length=64 )
|
||||||
|
|
|
@ -9,10 +9,10 @@ import logging
|
||||||
logger = logging.getLogger( __name__ )
|
logger = logging.getLogger( __name__ )
|
||||||
|
|
||||||
|
|
||||||
@receiver( post_save, sender=User )
|
#@receiver( post_save, sender=User )
|
||||||
def user_changed( **kwargs ):
|
#def user_changed( **kwargs ):
|
||||||
logger.info("Synchronizing with google - user information changed")
|
# logger.info("Synchronizing with google - user information changed")
|
||||||
syncFromLocalToGoogle( getServiceObject() )
|
# syncFromLocalToGoogle( getServiceObject() )
|
||||||
|
|
||||||
|
|
||||||
@receiver( post_save,sender= Event)
|
@receiver( post_save,sender= Event)
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
/* ========================================================================
|
||||||
|
* bootstrap-switch - v2.0.1
|
||||||
|
* http://www.bootstrap-switch.org
|
||||||
|
* ========================================================================
|
||||||
|
* Copyright 2012-2013 Mattia Larentis
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.has-switch {
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: #cccccc;
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 8px;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
-o-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
vertical-align: middle;
|
||||||
|
min-width: 100px;
|
||||||
|
-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||||
|
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||||
|
}
|
||||||
|
.has-switch:focus {
|
||||||
|
border-color: #66afe9;
|
||||||
|
outline: 0;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
|
||||||
|
}
|
||||||
|
.has-switch.switch-mini {
|
||||||
|
min-width: 72px;
|
||||||
|
}
|
||||||
|
.has-switch.switch-mini span,
|
||||||
|
.has-switch.switch-mini label {
|
||||||
|
padding-bottom: 4px;
|
||||||
|
padding-top: 4px;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 9px;
|
||||||
|
}
|
||||||
|
.has-switch.switch-mini i.switch-mini-icons {
|
||||||
|
height: 1.20em;
|
||||||
|
line-height: 9px;
|
||||||
|
vertical-align: text-top;
|
||||||
|
text-align: center;
|
||||||
|
transform: scale(0.6);
|
||||||
|
margin-top: -1px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
.has-switch.switch-small {
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
.has-switch.switch-small span,
|
||||||
|
.has-switch.switch-small label {
|
||||||
|
padding-bottom: 3px;
|
||||||
|
padding-top: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
.has-switch.switch-large {
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
.has-switch.switch-large span,
|
||||||
|
.has-switch.switch-large label {
|
||||||
|
padding-bottom: 9px;
|
||||||
|
padding-top: 9px;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
.has-switch.switch-animate > div {
|
||||||
|
-webkit-transition: left 0.5s;
|
||||||
|
transition: left 0.5s;
|
||||||
|
}
|
||||||
|
.has-switch.switch-off > div {
|
||||||
|
left: -50%;
|
||||||
|
}
|
||||||
|
.has-switch.switch-on > div {
|
||||||
|
left: 0%;
|
||||||
|
}
|
||||||
|
.has-switch.disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
filter: alpha(opacity=50);
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
.has-switch.disabled span,
|
||||||
|
.has-switch.disabled label {
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
.has-switch > div {
|
||||||
|
display: inline-block;
|
||||||
|
width: 150%;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
.has-switch input[type=radio],
|
||||||
|
.has-switch input[type=checkbox] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.has-switch span,
|
||||||
|
.has-switch label {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block !important;
|
||||||
|
height: 100%;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
padding-top: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
.has-switch label {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: -1px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
z-index: 100;
|
||||||
|
width: 33.333333333%;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
.has-switch label i {
|
||||||
|
color: #000;
|
||||||
|
text-shadow: 0 1px 0 #fff;
|
||||||
|
line-height: 18px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.has-switch span {
|
||||||
|
text-align: center;
|
||||||
|
z-index: 1;
|
||||||
|
width: 33.333333333%;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-left {
|
||||||
|
color: #f00;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-right {
|
||||||
|
color: #000;
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-primary,
|
||||||
|
.has-switch span.switch-left {
|
||||||
|
color: #fff;
|
||||||
|
background: #428bca;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-info {
|
||||||
|
color: #fff;
|
||||||
|
background: #5bc0de;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-success {
|
||||||
|
color: #fff;
|
||||||
|
background: #5cb85c;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-warning {
|
||||||
|
background: #f0ad4e;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-danger {
|
||||||
|
color: #fff;
|
||||||
|
background: #d9534f;
|
||||||
|
}
|
||||||
|
.has-switch span.switch-default {
|
||||||
|
color: #000;
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,110 @@
|
||||||
|
{% extends "website/base.html" %}
|
||||||
|
{% load sekizai_tags staticfiles %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% addtoblock "css" strip %}
|
||||||
|
<link rel="stylesheet" href="{{STATIC_URL}}/css/bootstrap-switch.min.css" type="text/css" media="screen" />
|
||||||
|
{% endaddtoblock %}
|
||||||
|
|
||||||
|
{% addtoblock "css" %}
|
||||||
|
<style>
|
||||||
|
h5 {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
#errorlabel {
|
||||||
|
color: red;
|
||||||
|
margin: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
#activate {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{% endaddtoblock %}
|
||||||
|
|
||||||
|
{% addtoblock "js" strip %}
|
||||||
|
<script src="{{STATIC_URL}}/js/bootstrap-switch.min.js"></script>
|
||||||
|
{% endaddtoblock %}
|
||||||
|
|
||||||
|
{% addtoblock "js" %}
|
||||||
|
<script>
|
||||||
|
$("[name='my-checkbox']").bootstrapSwitch();
|
||||||
|
|
||||||
|
function endsWith(str, suffix) {
|
||||||
|
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||||
|
}
|
||||||
|
validateEmail = function() {
|
||||||
|
if ( endsWith( $("#id_email").val(), "@gmail.com") ||
|
||||||
|
endsWith( $("#id_email").val(), "@googlemail.com") ) {
|
||||||
|
// Activate submit button
|
||||||
|
$("#activate").prop("disabled", false);
|
||||||
|
$("#errorlabel").html("");
|
||||||
|
} else {
|
||||||
|
$("#activate").prop("disabled", true);
|
||||||
|
$("#errorlabel").html("Erlaubte Endung: <em>@gmail.com</em> oder<em>@googlemail.com</em>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#id_email").change( validateEmail );
|
||||||
|
validateEmail();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endaddtoblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="span12">
|
||||||
|
<h2>Google Kalender Anbindung</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="span6">
|
||||||
|
<p>
|
||||||
|
<h5>NEU</h5>
|
||||||
|
Die Blechreiz Termine können jetzt automatisch in den eigenen Google Kalender übernommen werden.
|
||||||
|
Auch vom Google Kalender aus kann man sich dann für Termine eintragen, direkt vom Handy oder Tablet aus.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<h5>SO GEHTS:</h5>
|
||||||
|
Einfach die eigene Google Mail Adresse angeben und die Kopplung aktivieren.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h5>KOPPLUNG:</h5>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<form method="POST" >
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{% if enabled %}
|
||||||
|
Kopplung aktiviert für <em>{{ mail }}</em>.
|
||||||
|
<input type="hidden" name="activate" value="0" >
|
||||||
|
<br><br>
|
||||||
|
<input class="btn btn-primary" value="Deaktivieren" type="submit">
|
||||||
|
{% else %}
|
||||||
|
<input type="hidden" name="activate" value="1" >
|
||||||
|
<label for="id_email">Email:</label>
|
||||||
|
<input id="id_email" type="text" placeholder="GMail Adresse" name="email">
|
||||||
|
<br>
|
||||||
|
<span id="errorlabel"></span>
|
||||||
|
<br>
|
||||||
|
<input id="activate" class="btn btn-primary" value="Aktivieren" type="submit">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="span3 offset1">
|
||||||
|
<img src="{{STATIC_URL}}/img/google_cal.png">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -1,9 +1,10 @@
|
||||||
from django.conf.urls import patterns, url
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
from views import runSync, gcalApiCallback
|
from views import runSync, gcalApiCallback, manage
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^runSync$', runSync ),
|
url(r'^runSync$', runSync ),
|
||||||
url(r'^gcalApiCallback$', gcalApiCallback ),
|
url(r'^gcalApiCallback$', gcalApiCallback ),
|
||||||
|
url(r'^manage$', manage ),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ from django.http import HttpResponse
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from eventplanner_gcal.google_sync import checkIfGoogleCallbackIsValid
|
from eventplanner_gcal.google_sync import checkIfGoogleCallbackIsValid
|
||||||
|
from eventplanner_gcal.models import UserGCalCoupling
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -14,6 +16,29 @@ def runSync( request ):
|
||||||
syncFromLocalToGoogle()
|
syncFromLocalToGoogle()
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|
||||||
|
|
||||||
|
def manage( request ):
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
if request.POST['activate'] == "1":
|
||||||
|
UserGCalCoupling.objects.filter( user=request.user ).delete()
|
||||||
|
c = UserGCalCoupling( user=request.user, email = request.POST['email'] )
|
||||||
|
c.save()
|
||||||
|
syncFromLocalToGoogle()
|
||||||
|
else:
|
||||||
|
UserGCalCoupling.objects.filter( user=request.user ).delete()
|
||||||
|
syncFromLocalToGoogle()
|
||||||
|
|
||||||
|
context = {}
|
||||||
|
userCoupling = UserGCalCoupling.objects.filter( user = request.user )
|
||||||
|
context['enabled'] = len(userCoupling)
|
||||||
|
assert( len(userCoupling) < 2 )
|
||||||
|
if len(userCoupling) == 1:
|
||||||
|
context['mail'] = userCoupling[0].email
|
||||||
|
|
||||||
|
return render( request, 'eventplanner_gcal/management.html', context )
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
def gcalApiCallback( request ):
|
def gcalApiCallback( request ):
|
||||||
# TODO check channel info here
|
# TODO check channel info here
|
||||||
|
|
|
@ -43,7 +43,12 @@
|
||||||
if ( data['redirect']) {
|
if ( data['redirect']) {
|
||||||
window.location.href = data['redirect'];
|
window.location.href = data['redirect'];
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
error: function( jqXHR, text1, text2 ) {
|
||||||
|
console.log( jqXHR );
|
||||||
|
console.log( text1 );
|
||||||
|
console.log( text2 );
|
||||||
|
}
|
||||||
});
|
});
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 MiB |
|
@ -48,6 +48,7 @@
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="/musicians/profile">Eigenes Profil</a></li>
|
<li><a href="/musicians/profile">Eigenes Profil</a></li>
|
||||||
|
<li><a href="/eventplanner_gcal/manage">Google Kalender</a></li>
|
||||||
<li><a href="/musicians/changePassword">Passwort ändern</a> </li>
|
<li><a href="/musicians/changePassword">Passwort ändern</a> </li>
|
||||||
<li><a href="/musicians/logout"> Logout</a></li>
|
<li><a href="/musicians/logout"> Logout</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -76,13 +76,12 @@
|
||||||
|
|
||||||
<section id="feature_slider" class="">
|
<section id="feature_slider" class="">
|
||||||
|
|
||||||
<article class="slide" id="slide_news"
|
<article class="slide" id="slide_news" style="background: url('{{STATIC_URL}}/img/slides/aqua.jpg') repeat-x top center;">
|
||||||
style="background: url('{{STATIC_URL}}/img/slides/osterhase.png') repeat-x top center;">
|
|
||||||
|
|
||||||
<img class="asset left-30 sp600 t150 z1" src="{{STATIC_URL}}/img/googleCalNew.png" />
|
<img class="asset left-30 sp600 t150 z1" src="{{STATIC_URL}}/img/google_cal.png" />
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<a href="/musicians/profile">GoogleCalendar</a>
|
<a href="/eventplanner_gcal/manage">GoogleCalendar</a>
|
||||||
<div class="subtitle subtitlebg">Jetzt auch auf dem Handy im GoogleCalendar Termine planen: Einfach im Profil eine Google Email Adresse eintragen...</div>
|
<div class="subtitle subtitlebg">Jetzt auch auf dem Handy im Google Kalender Termine planen</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|
Loading…
Reference in New Issue