Changes on server
- bugfixes in gcal callback - requirements txt
This commit is contained in:
parent
aac687c0c7
commit
46b4078fac
|
@ -1 +1 @@
|
||||||
{"_module": "oauth2client.client", "token_expiry": "2014-04-19T18:37:13Z", "access_token": "ya29.1.AADtN_UNi3N8wJ5AiTZ3ced1ho7-ZOhe9cV0TqJ7lByEy_h5SHGm0EuZBSWVOQ3q3g", "token_uri": "https://accounts.google.com/o/oauth2/token", "invalid": false, "token_response": {"access_token": "ya29.1.AADtN_UNi3N8wJ5AiTZ3ced1ho7-ZOhe9cV0TqJ7lByEy_h5SHGm0EuZBSWVOQ3q3g", "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-04-20T19:09:26Z", "access_token": "ya29.1.AADtN_VE0fTw3cu2E9SR0XoblR3gXjnON1u2Qy__EB7E6HyEpaDky0LA-SmZVyok6A", "token_uri": "https://accounts.google.com/o/oauth2/token", "invalid": false, "token_response": {"access_token": "ya29.1.AADtN_VE0fTw3cu2E9SR0XoblR3gXjnON1u2Qy__EB7E6HyEpaDky0LA-SmZVyok6A", "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}
|
|
@ -79,7 +79,7 @@ STATIC_ROOT = PROJECT_PATH + '/static_collection'
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
LOGIN_URL="/musicians/login"
|
LOGIN_URL="/musicians/login"
|
||||||
PUBLIC_URLS=( "^musicians/login/?$", "^musicians/login/usernames/?$")
|
PUBLIC_URLS=( "^musicians/login/?$", "^musicians/login/usernames/?$", "^eventplanner_gcal/gcalApiCallback*")
|
||||||
|
|
||||||
# Additional locations of static files
|
# Additional locations of static files
|
||||||
STATICFILES_DIRS = (
|
STATICFILES_DIRS = (
|
||||||
|
@ -195,49 +195,29 @@ CRISPY_TEMPLATE_PACK = 'bootstrap'
|
||||||
# the site admins on every HTTP 500 error when DEBUG=False.
|
# the site admins on every HTTP 500 error when DEBUG=False.
|
||||||
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
||||||
# more details on how to customize your logging configuration.
|
# more details on how to customize your logging configuration.
|
||||||
|
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
'version': 1,
|
||||||
'disable_existing_loggers': True,
|
'disable_existing_loggers': False,
|
||||||
'formatters': {
|
|
||||||
'standard': {
|
|
||||||
'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
|
|
||||||
'datefmt' : "%d/%b/%Y %H:%M:%S"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'handlers': {
|
'handlers': {
|
||||||
'null': {
|
'file': {
|
||||||
'level':'DEBUG',
|
'level': 'DEBUG',
|
||||||
'class':'django.utils.log.NullHandler',
|
'class': 'logging.FileHandler',
|
||||||
},
|
'filename': '/srv/test/eventplanner.log',
|
||||||
'logfile': {
|
|
||||||
'level':'DEBUG',
|
|
||||||
'class':'logging.handlers.RotatingFileHandler',
|
|
||||||
'filename': PROJECT_PATH + "/logfile",
|
|
||||||
'maxBytes': 50000,
|
|
||||||
'backupCount': 2,
|
|
||||||
'formatter': 'standard',
|
|
||||||
},
|
|
||||||
'console':{
|
|
||||||
'level':'INFO',
|
|
||||||
'class':'logging.StreamHandler',
|
|
||||||
'formatter': 'standard'
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'loggers': {
|
'loggers': {
|
||||||
'django': {
|
'eventplanner_gcal': {
|
||||||
'handlers':['console'],
|
'handlers': ['file'],
|
||||||
|
'level': 'DEBUG',
|
||||||
'propagate': True,
|
'propagate': True,
|
||||||
'level':'WARN',
|
|
||||||
},
|
},
|
||||||
'django.db.backends': {
|
'eventplanner': {
|
||||||
'handlers': ['console'],
|
'handler': ['file'],
|
||||||
'level': 'DEBUG',
|
'level': 'DEBUG',
|
||||||
'propagate': False,
|
'propagate': True,
|
||||||
},
|
}
|
||||||
'musicians': {
|
},
|
||||||
'handlers': ['console', 'logfile'],
|
|
||||||
'level': 'DEBUG',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,13 @@ framework.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import site
|
||||||
|
import sys
|
||||||
|
site.addsitedir('/srv/test/env/lib/python2.7/site-packages')
|
||||||
|
sys.path.append('/srv/test')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
||||||
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
||||||
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
||||||
|
|
|
@ -132,6 +132,12 @@ class EventParticipation( models.Model ):
|
||||||
def get_username(self):
|
def get_username(self):
|
||||||
return self.user.username
|
return self.user.username
|
||||||
|
|
||||||
|
def save( self, *args, **kwargs ):
|
||||||
|
prev = EventParticipation.objects.get( event = self.event, user = self.user )
|
||||||
|
if prev.status != self.status or prev.comment != self.comment:
|
||||||
|
super(EventParticipation,self).save( *args,**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def hasUserSetParticipationForAllEvents( user ):
|
def hasUserSetParticipationForAllEvents( user ):
|
||||||
if not EventParticipation.isMember(user):
|
if not EventParticipation.isMember(user):
|
||||||
|
@ -177,4 +183,4 @@ class EventParticipation( models.Model ):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -282,10 +282,10 @@ def checkGCalSubscription():
|
||||||
global service
|
global service
|
||||||
callbackUrl = settings.GCAL_COUPLING['push_url']
|
callbackUrl = settings.GCAL_COUPLING['push_url']
|
||||||
|
|
||||||
#timeToLive = 14*24*3600 # how long the channel should be active
|
timeToLive = 14*24*3600 # how long the channel should be active
|
||||||
#renewBeforeExpiry = 2*24*3600 # duration before expiry when channel is renewed
|
renewBeforeExpiry = 2*24*3600 # duration before expiry when channel is renewed
|
||||||
timeToLive = 60*5
|
#timeToLive = 60*5
|
||||||
renewBeforeExpiry = 60*3
|
#renewBeforeExpiry = 60*3
|
||||||
|
|
||||||
# Test if a channel already exists for this callbackURL
|
# Test if a channel already exists for this callbackURL
|
||||||
try:
|
try:
|
||||||
|
@ -318,4 +318,4 @@ def checkGCalSubscription():
|
||||||
def stopAllGCalSubscriptions():
|
def stopAllGCalSubscriptions():
|
||||||
for dbChannel in GCalPushChannel.objects.all():
|
for dbChannel in GCalPushChannel.objects.all():
|
||||||
print("Stopping %s expiry at %d " % ( dbChannel.id, dbChannel.expiration ) )
|
print("Stopping %s expiry at %d " % ( dbChannel.id, dbChannel.expiration ) )
|
||||||
GCalPushChannel.stop( service, dbChannel.toGChannel() )
|
GCalPushChannel.stop( service, dbChannel.toGChannel() )
|
||||||
|
|
|
@ -2,9 +2,11 @@ from django.db.models.signals import post_save,pre_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from eventplanner.models import Event, EventParticipation
|
from eventplanner.models import Event, EventParticipation
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
import eventplanner_gcal.models
|
import eventplanner_gcal.models
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger( __name__ )
|
||||||
|
|
||||||
|
|
||||||
class SignalLock:
|
class SignalLock:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -25,10 +27,21 @@ class SignalLock:
|
||||||
|
|
||||||
signalLock = SignalLock()
|
signalLock = SignalLock()
|
||||||
|
|
||||||
@receiver( post_save, sender=User )
|
|
||||||
def user_changed( **kwargs ):
|
def onGoogleCallback():
|
||||||
if not signalLock.isLocked():
|
if not signalLock.isLocked():
|
||||||
with signalLock:
|
with signalLock:
|
||||||
|
logger.info( "Sync back from google" )
|
||||||
|
eventplanner_gcal.models.syncParticipationFromGoogleToLocal()
|
||||||
|
|
||||||
|
|
||||||
|
@receiver( post_save, sender=User )
|
||||||
|
def user_changed( **kwargs ):
|
||||||
|
logger.info("User info changed")
|
||||||
|
if not signalLock.isLocked():
|
||||||
|
with signalLock:
|
||||||
|
logger.info("Synchronizing with google - user information changed")
|
||||||
|
eventplanner_gcal.models.deleteAllGCalEvents()
|
||||||
eventplanner_gcal.models.syncGCalEvents()
|
eventplanner_gcal.models.syncGCalEvents()
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,10 +52,10 @@ def event_post_save_handler( **kwargs):
|
||||||
event = kwargs['instance']
|
event = kwargs['instance']
|
||||||
created = kwargs['created']
|
created = kwargs['created']
|
||||||
if created:
|
if created:
|
||||||
print("Creating Gcal event")
|
logger.info("Creating Gcal event")
|
||||||
eventplanner_gcal.models.createGCalEvent( event ).execute()
|
eventplanner_gcal.models.createGCalEvent( event ).execute()
|
||||||
else:
|
else:
|
||||||
print( "Updating Gcal event")
|
logger.info( "Updating Gcal event")
|
||||||
eventplanner_gcal.models.updateGCalEvent( event ).execute()
|
eventplanner_gcal.models.updateGCalEvent( event ).execute()
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +65,7 @@ def event_pre_delete_handler( **kwargs):
|
||||||
if not signalLock.isLocked():
|
if not signalLock.isLocked():
|
||||||
with signalLock:
|
with signalLock:
|
||||||
event = kwargs['instance']
|
event = kwargs['instance']
|
||||||
print ("Deleting GCAL event")
|
logger.info ("Deleting GCAL event")
|
||||||
eventplanner_gcal.models.deleteGCalEvent( event ).execute()
|
eventplanner_gcal.models.deleteGCalEvent( event ).execute()
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +74,7 @@ def participation_post_save_handler( **kwargs):
|
||||||
if not signalLock.isLocked():
|
if not signalLock.isLocked():
|
||||||
with signalLock:
|
with signalLock:
|
||||||
participation = kwargs['instance']
|
participation = kwargs['instance']
|
||||||
print("Participation post save -> update gcal")
|
logger.info("Participation post save -> update gcal")
|
||||||
eventplanner_gcal.models.updateGCalEvent( participation.event ).execute()
|
eventplanner_gcal.models.updateGCalEvent( participation.event ).execute()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from eventplanner_gcal.models import syncGCalEvents, syncParticipationFromGoogleToLocal
|
from eventplanner_gcal.models import syncGCalEvents, syncParticipationFromGoogleToLocal
|
||||||
|
from eventplanner_gcal.signals import onGoogleCallback
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger( __name__ )
|
||||||
|
|
||||||
|
|
||||||
def runSync( request ):
|
def runSync( request ):
|
||||||
syncGCalEvents()
|
syncGCalEvents()
|
||||||
|
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
def gcalApiCallback( request ):
|
def gcalApiCallback( request ):
|
||||||
syncParticipationFromGoogleToLocal()
|
onGoogleCallback()
|
||||||
print ( "gcalApiCallback called" )
|
logger.info("Received callback from GCal - updating event participations... ")
|
||||||
return redirect("/")
|
return HttpResponse('<h1>Callback successful</h1>')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
Django==1.5.5
|
||||||
|
PIL==1.1.7
|
||||||
|
South==0.8.2
|
||||||
|
django-classy-tags==0.4
|
||||||
|
django-crispy-forms==1.4.0
|
||||||
|
django-sekizai==0.7
|
||||||
|
django-tagging==0.3.1
|
||||||
|
djangorestframework==2.3.8
|
||||||
|
google-api-python-client==1.2
|
||||||
|
httplib2==0.9
|
||||||
|
reportlab==3.0
|
||||||
|
sorl-thumbnail==11.12
|
||||||
|
tagging==0.2.1
|
||||||
|
wsgiref==0.1.2
|
|
@ -82,7 +82,7 @@
|
||||||
<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/googleCalNew.png" />
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<a href="/musicians/profile">GoogleCalendar</a>
|
<a href="/musicians/profile">GoogleCalendar</a>
|
||||||
<div class="subtitle subtitlebg">Geht ganz einfach: Im Profil eine Google Mail Adresse eintragen</div>
|
<div class="subtitle subtitlebg">Jetzt auch auf dem Handy im GoogleCalendar Termine planen: Einfach im Profil eine Google Email Adresse eintragen...</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|
Loading…
Reference in New Issue