1 # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 # vim: tabstop=4:shiftwidth=4:softtabstop=4:expandtab
4 # Copyright (C) 2010-2014 GRNET S.A.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 from gevent.pool import Pool
26 from django.shortcuts import render_to_response
27 from django.template.loader import render_to_string
28 from django.http import HttpResponse
29 from gevent.event import Event
30 from django.conf import settings
31 #from django.views.decorators.csrf import csrf_exempt
32 from django.http import HttpResponseRedirect
33 from django.core.urlresolvers import reverse
34 from django.conf import settings
41 LOG_FILENAME = os.path.join(settings.LOG_FILE_LOCATION, 'poller.log')
42 formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
43 logger = logging.getLogger(__name__)
44 logger.setLevel(logging.DEBUG)
45 handler = logging.FileHandler(LOG_FILENAME)
46 handler.setFormatter(formatter)
47 logger.addHandler(handler)
49 def create_message(message, user, time):
50 data = {'id': str(uuid.uuid4()), 'body': message, 'user':user, 'time':time}
51 data['html'] = render_to_string('poll_message.html', dictionary={'message': data})
55 def json_response(value, **kwargs):
56 kwargs.setdefault('content_type', 'text/javascript; charset=UTF-8')
57 return HttpResponse(json.dumps(value), **kwargs)
63 def __new__(cls, *args, **kwargs):
65 cls._instance = super(Msgs, cls).__new__(cls, *args, **kwargs)
69 logger.info("initializing")
74 self.new_message_event = None
75 self.new_message_user_event = {}
77 def main(self, request):
79 request.session['cursor'] = self.user_cache[-1]['id']
80 return render_to_response('poll.html', {'messages': self.user_cache})
82 def message_existing(self, request):
85 user = request.user.get_profile().peer.peer_tag
90 assert(self.new_message_user_event[user])
92 self.new_message_user_event[user] = Event()
94 if self.user_cache[user]:
95 self.user_cursor[user] = self.user_cache[user][-1]['id']
97 self.user_cache[user] = []
98 self.user_cursor[user] = ''
99 return json_response({'messages': self.user_cache[user]})
100 return HttpResponseRedirect(reverse('group-routes'))
102 def message_new(self, mesg=None):
104 message = mesg['message']
105 user = mesg['username']
106 logger.info("from %s" %user)
107 now = datetime.datetime.now()
108 msg = create_message(message, user, now.strftime("%Y-%m-%d %H:%M:%S"))
110 isinstance(self.user_cache[user], list)
112 self.user_cache[user] = []
113 self.user_cache[user].append(msg)
114 if self.user_cache[user][-1] == self.user_cache[user][0]:
115 self.user_cursor[user] = self.user_cache[user][-1]['id']
117 self.user_cursor[user] = self.user_cache[user][-2]['id']
118 if len(self.user_cache[user]) > self.cache_size:
119 self.user_cache[user] = self.user_cache[user][-self.cache_size:]
121 assert(self.new_message_user_event[user])
123 self.new_message_user_event[user] = Event()
124 self.new_message_user_event[user].set()
125 self.new_message_user_event[user].clear()
126 return json_response(msg)
128 def message_updates(self, request):
129 if request.is_ajax():
132 user = request.user.get_profile().peer.peer_tag
137 cursor[user] = self.user_cursor[user]
139 return HttpResponse(content='', mimetype=None, status=400)
142 if not isinstance(self.user_cache[user], list):
143 self.user_cache[user] = []
145 self.user_cache[user] = []
146 if not self.user_cache[user] or cursor[user] == self.user_cache[user][-1]['id']:
147 self.new_message_user_event[user].wait(settings.POLL_SESSION_UPDATE)
149 for index, m in enumerate(self.user_cache[user]):
150 if m['id'] == cursor[user]:
151 return json_response({'messages': self.user_cache[user][index + 1:]})
152 return json_response({'messages': self.user_cache[user]})
154 if self.user_cache[user]:
155 self.user_cursor[user] = self.user_cache[user][-1]['id']
156 return HttpResponseRedirect(reverse('group-routes'))
158 def monitor_polls(self):
159 b = beanstalkc.Connection()
160 b.watch(settings.POLLS_TUBE)
163 msg = json.loads(job.body)
165 logger.info("Got New message")
166 self.message_new(msg)
169 def start_polling(self):
170 logger.info("Start Polling")
171 gevent.spawn(self.monitor_polls)
177 message_updates = msgs.message_updates
178 message_existing = msgs.message_existing
181 poll = msgs.start_polling