def debug_redis(request): import sputnik client_id = sputnik.get("sputnik:client_id") sputnikchannels = sputnik.smembers("sputnik:channels") chnl = {} for ch in sputnik.rkeys("sputnik:channel:*:channel"): chnl[ch] = sputnik.smembers(ch) usrs = {} for ch in sputnik.rkeys("sputnik:channel:*:users"): usrs[ch] = sputnik.smembers(ch) # for ch in r.keys('sputnik:*:messages'): # pass allValues = {} import time, decimal _now = time.time() for ses in [k[4:-9] for k in sputnik.rkeys("ses:*:username")]: try: allValues[ses] = { "channels": sputnik.smembers("ses:%s:channels" % ses), "last_access": sputnik.get("ses:%s:last_access" % ses), "access_since": decimal.Decimal("%f" % _now) - sputnik.get("ses:%s:last_access" % ses), "username": sputnik.get("ses:%s:username" % ses) } except: pass locks = {} for ch in sputnik.rkeys("booki:*:locks:*"): locks[ch] = sputnik.get(ch) killlocks = {} for ch in sputnik.rkeys("booki:*:killlocks:*"): killlocks[ch] = sputnik.get(ch) return render_to_response('portal/debug_redis.html', {"request": request, "client_id": client_id, "sputnikchannels": sputnikchannels, "channel": chnl.items(), "users": usrs.items(), "sessions": allValues.items(), "locks": locks.items(), "killlocks": killlocks.items() })
def _delete_notifications(self): # TODO # this is just playground # we must create separate tool to push messages through the sputnik channel from API endpoints # without having clientID in request # message_info channel_name = "/chat/{}/".format(self._book.id) clnts = sputnik.smembers( "sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, "command": "message_info", "from": self.request.user.username, "email": self.request.user.email, "message_id": "user_delete_chapter", "message_args": [self.request.user.username, self._chapter.title] } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # chapter delete channel_name = "/booktype/book/{}/{}/".format( self._book.id, self._book.version.get_version()) clnts = sputnik.smembers( "sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, "command": "chapter_delete", "chapterID": self._chapter.id } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # notificatoin message message = { 'channel': channel_name, 'command': 'notification', 'message': 'notification_chapter_was_deleted', 'username': self.request.user.username, 'message_args': (self._chapter.title, ) } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message))
def add_message_to_channel(request, channel_name, message, myself=False): """ Add message to specific channel. :Args: - request (:class:`django.http.HttpRequest`): Django Request - channel_name (`string`): Channel name - message (:class:`dict`): Sputnik message - myself (:class:`bool`): Should client also recieve that message. """ import sputnik from booki.utils.log import print_stack try: clnts = sputnik.smembers("sputnik:channel:%s:channel" % channel_name) except: print_stack(None) return message["channel"] = channel_name message["clientID"] = request.clientID for c in clnts: if not myself and c == request.sputnikID: continue if c.strip() != '': try: sputnik.push("ses:%s:messages" % c, json.dumps(message)) except: print_stack(None)
def remote_init_profile(request, message, profileid): """ Initializes data. @type request: C{django.http.HttpRequest} @param request: Client Request object @type message: C{dict} @param message: Message object @type profileid: C{string} @param profile: Unique Profile id """ import sputnik ## get online users try: _onlineUsers = sputnik.smembers("sputnik:channel:%s:users" % message["channel"]) except: _onlineUsers = [] if request.user.username not in _onlineUsers: try: sputnik.sadd("sputnik:channel:%s:users" % message["channel"], request.user.username) except: pass return {}
def addMessageToChannel2(clientID, sputnikID, channelName, message, myself=False): import sputnik from booki.utils.log import print_stack try: clnts = sputnik.smembers("sputnik:channel:%s:channel" % channelName) except: print_stack(None) return message["channel"] = channelName message["clientID"] = clientID for c in clnts: if not myself and c == sputnikID: continue if c.strip() != '': try: sputnik.push("ses:%s:messages" % c, json.dumps(message)) except: logger.debug('*ERROR PUSH*')
def book_info(request, bookid, version=None): try: book = models.Book.objects.get(url_title__iexact=bookid) except models.Book.DoesNotExist: return pages.ErrorPage(request, "errors/book_does_not_exist.html", {"book_name": bookid}) book_version = getVersion(book, version) book_history = models.BookHistory.objects.filter(version = book_version).order_by("-modified")[:20] book_collaborators = [e.values()[0] for e in models.BookHistory.objects.filter(version = book_version, kind = 2).values("user__username").distinct()] import sputnik channel_name = "/booki/book/%s/%s/" % (book.id, book_version.getVersion()) online_users = sputnik.smembers("sputnik:channel:%s:users" % channel_name) book_versions = models.BookVersion.objects.filter(book=book).order_by("created") return render_to_response('reader/book_info.html', {"book": book, "book_version": book_version.getVersion(), "book_versions": book_versions, "book_history": book_history, "book_collaborators": book_collaborators, "has_css": _customCSSExists(book.url_title), "online_users": online_users, "request": request})
def remote_mood_set(request, message, profileid): # should check permissions from django.utils.html import strip_tags ## maximum size is 30 characters only ## html tags are removed moodMessage = strip_tags(message.get("value",""))[:30] import booki.account.signals booki.account.signals.account_status_changed.send(sender = request.user, message = message.get('value', '')) # save new permissions profile = request.user.get_profile() profile.mood = moodMessage try: profile.save() except: transaction.rollback() else: transaction.commit() ## propagate to other users ## probably should only send it to /booki/ channel import sputnik for chnl in sputnik.smembers("sputnik:channels"): if sputnik.sismember("sputnik:channel:%s:users" % message['channel'], request.user.username): sputnik.addMessageToChannel(request, chnl, {"command": "user_status_changed", "from": request.user.username, "message": moodMessage}, myself=True) return {}
def add_message_to_channel(request, channel_name, message, myself=False): """ Add message to specific channel. :Args: - request (:class:`django.http.HttpRequest`): Django Request - channel_name (`string`): Channel name - message (:class:`dict`): Sputnik message - myself (:class:`bool`): Should client also recieve that message. """ import sputnik from booki.utils.log import print_stack try: clnts = sputnik.smembers("sputnik:channel:%s:channel" % channel_name) except: print_stack(None) return message["channel"] = channel_name message["clientID"] = request.clientID for c in clnts: if not myself and c == request.sputnikID: continue if c.strip() != '': try: sputnik.push("ses:%s:messages" % c, serializeJson(message)) except: print_stack(None)
def _delete_notifications(self): # TODO # this is just playground # we must create separate tool to push messages through the sputnik channel from API endpoints # without having clientID in request # message_info channel_name = "/chat/{}/".format(self._book.id) clnts = sputnik.smembers("sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, "command": "message_info", "from": self.request.user.username, "email": self.request.user.email, "message_id": "user_delete_chapter", "message_args": [self.request.user.username, self._chapter.title] } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # chapter delete channel_name = "/booktype/book/{}/{}/".format(self._book.id, self._book.version.get_version()) clnts = sputnik.smembers("sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, "command": "chapter_delete", "chapterID": self._chapter.id } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # notificatoin message message = { 'channel': channel_name, 'command': 'notification', 'message': 'notification_chapter_was_deleted', 'username': self.request.user.username, 'message_args': (self._chapter.title,) } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message))
def remote_get_users(request, message, bookid, version): res = {} def vidi(a): if a == request.sputnikID: return "!%s!" % a return a res["users"] = [vidi(m) for m in list(sputnik.smembers("sputnik:channel:%s:channel" % message["channel"]))] return res
def remote_mood_set(request, message, profileid): """ Sets new mood for this profile. Input: - value @type request: C{django.http.HttpRequest} @param request: Client Request object @type message: C{dict} @param message: Message object @type profileid: C{string} @param profile: Unique Profile id """ # should check permissions from django.utils.html import strip_tags ## maximum size is 30 characters only ## html tags are removed moodMessage = strip_tags(message.get("value", ""))[:30] import booki.account.signals booki.account.signals.account_status_changed.send(sender=request.user, message=message.get( 'value', '')) # save new permissions profile = request.user.get_profile() profile.mood = moodMessage try: profile.save() except: transaction.rollback() else: transaction.commit() ## propagate to other users ## probably should only send it to /booki/ channel import sputnik for chnl in sputnik.smembers("sputnik:channels"): if sputnik.sismember( "sputnik:channel:%s:users" % message['channel'], request.user.username): sputnik.addMessageToChannel( request, chnl, { "command": "user_status_changed", "from": request.user.username, "message": moodMessage }, myself=True) return {}
def view_book(request, bookid): from booki.utils import misc try: book = models.Book.objects.get(url_title__iexact=bookid) except models.Book.DoesNotExist: return pages.ErrorPage(request, "errors/book_does_not_exist.html", {"book_name": bookid}) book_version = book.getVersion(None) # this only shows info for latest version book_history = models.BookHistory.objects.filter(version=book_version).order_by("-modified")[:20] book_collaborators = [ e.values()[0] for e in models.BookHistory.objects.filter(version=book_version, kind=2).values("user__username").distinct() ] from booki.utils import security bookSecurity = security.getUserSecurityForBook(request.user, book) isBookAdmin = bookSecurity.isAdmin() import sputnik channel_name = "/booki/book/%s/%s/" % (book.id, book_version.getVersion()) online_users = sputnik.smembers("sputnik:channel:%s:users" % channel_name) book_versions = models.BookVersion.objects.filter(book=book).order_by("created") from django.utils.html import escape bookDescription = escape(book.description) attachmentDirectory = "%s/books/%s" % (settings.DATA_ROOT, book.url_title) attachmentsSize = misc.getDirectorySize(attachmentDirectory) return render_to_response( "booktypecontrol/book.html", { "request": request, "admin_options": ADMIN_OPTIONS, "book": book, "book_version": book_version.getVersion(), "book_versions": book_versions, "book_history": book_history, "book_collaborators": book_collaborators, "is_book_admin": isBookAdmin, "online_users": online_users, "book_description": "<br/>".join(bookDescription.replace("\r", "").split("\n")), "attachments_size": attachmentsSize, }, context_instance=RequestContext(request), )
def remote_init_group(request, message, groupid): import sputnik ## get online users try: _onlineUsers = sputnik.smembers("sputnik:channel:%s:users" % message["channel"]) except: _onlineUsers = [] if request.user.username not in _onlineUsers: try: sputnik.sadd("sputnik:channel:%s:users" % message["channel"], request.user.username) except: pass return {}
def book_info(request, bookid, version=None): """ Django View. Shows single page with all the Book info. @type request: C{django.http.HttpRequest} @param request: Client Request object @type bookid: C{string} @param bookid: Unique Book ID @type version: C{string} @param verson: Book version """ try: book = models.Book.objects.get(url_title__iexact=bookid) except models.Book.DoesNotExist: return pages.ErrorPage(request, "errors/book_does_not_exist.html", {"book_name": bookid}) book_version = getVersion(book, version) book_history = models.BookHistory.objects.filter(version = book_version).order_by("-modified")[:20] book_collaborators = [e.values()[0] for e in models.BookHistory.objects.filter(version = book_version, kind = 2).values("user__username").distinct()] from booki.utils import security bookSecurity = security.getUserSecurityForBook(request.user, book) isBookAdmin = bookSecurity.isAdmin() import sputnik channel_name = "/booki/book/%s/%s/" % (book.id, book_version.getVersion()) online_users = sputnik.smembers("sputnik:channel:%s:users" % channel_name) book_versions = models.BookVersion.objects.filter(book=book).order_by("created") from django.utils.html import escape bookDescription = escape(book.description) return render_to_response('reader/book_info.html', {"book": book, "book_version": book_version.getVersion(), "book_versions": book_versions, "book_history": book_history, "book_collaborators": book_collaborators, "has_css": _customCSSExists(book.url_title), "is_book_admin": isBookAdmin, "online_users": online_users, "book_description": '<br/>'.join(bookDescription.replace('\r','').split('\n')), "request": request})
def removeClient(request, clientName): """ Remove client from Sputnik. @type request: C{django.http.HttpRequest} @param request: Django Request. @type clientName: C{string} @param clientName: Unique Client ID. @todo: Should remove all tracks of user existence on the system. """ import sputnik for chnl in sputnik.smembers("ses:%s:channels" % clientName): removeClientFromChannel(request, chnl, clientName) srem("ses:%s:channels" % clientName, chnl) sputnik.rdelete("ses:%s:username" % clientName) sputnik.rdelete("ses:%s:last_access" % clientName)
def addMessageToChannel2(clientID, sputnikID, channelName, message, myself=False): import sputnik from booki.utils.log import print_stack try: clnts = sputnik.smembers("sputnik:channel:%s:channel" % channelName) except: print_stack(None) return message["channel"] = channelName message["clientID"] = clientID for c in clnts: if not myself and c == sputnikID: continue if c.strip() != '': try: sputnik.push("ses:%s:messages" % c, serializeJson(message)) except: logger.debug('*ERROR PUSH*')
def book_info(request, bookid, version=None): """ Django View. Shows single page with all the Book info. @type request: C{django.http.HttpRequest} @param request: Client Request object @type bookid: C{string} @param bookid: Unique Book ID @type version: C{string} @param verson: Book version """ try: book = models.Book.objects.get(url_title__iexact=bookid) except models.Book.DoesNotExist: return pages.ErrorPage(request, "errors/book_does_not_exist.html", {"book_name": bookid}) book_version = getVersion(book, version) book_history = models.BookHistory.objects.filter(version = book_version).order_by("-modified")[:20] book_collaborators = [e.values()[0] for e in models.BookHistory.objects.filter(version = book_version, kind = 2).values("user__username").distinct()] import sputnik channel_name = "/booki/book/%s/%s/" % (book.id, book_version.getVersion()) online_users = sputnik.smembers("sputnik:channel:%s:users" % channel_name) book_versions = models.BookVersion.objects.filter(book=book).order_by("created") return render_to_response('reader/book_info.html', {"book": book, "book_version": book_version.getVersion(), "book_versions": book_versions, "book_history": book_history, "book_collaborators": book_collaborators, "has_css": _customCSSExists(book.url_title), "online_users": online_users, "request": request})
def get_online_users(self): client_list = sputnik.rkeys("ses:*:username") online_users = {} for us in client_list: clientID = us[4:-9] channel_list = [] for chan in sputnik.smembers('ses:%s:channels' % clientID): if chan.startswith('/booktype/book/'): _s = chan.split('/') if len(_s) > 3: bookID = _s[3] try: b = Book.objects.get(pk=bookID) channel_list.append(b) except Book.DoesNotExist: pass _u = sputnik.get(us) online_users[_u] = channel_list return online_users
def addMessageToChannel(request, channelName, message, myself = False ): """ Add message to specific channel. @type request: C{django.http.HttpRequest} @param request: Django Request. @type channelName: C{string} @param channelName: Channel name. @type message: C{dict} @param message: Sputnik message. @type myself: C{bool} @keyword myself: Should client also recieve that message. """ import sputnik # TODO # not iterable try: clnts = sputnik.smembers("sputnik:channel:%s:channel" % channelName) except: from booki.utils.log import printStack printStack(None) return message["channel"] = channelName message["clientID"] = request.clientID for c in clnts: if not myself and c == request.sputnikID: continue if c.strip() != '': try: sputnik.push( "ses:%s:messages" % c, simplejson.dumps(message)) except: pass
def addMessageToChannel(request, channelName, message, myself=False): """ Add message to specific channel. @type request: C{django.http.HttpRequest} @param request: Django Request. @type channelName: C{string} @param channelName: Channel name. @type message: C{dict} @param message: Sputnik message. @type myself: C{bool} @keyword myself: Should client also recieve that message. """ import sputnik # TODO # not iterable try: clnts = sputnik.smembers("sputnik:channel:%s:channel" % channelName) except: from booki.utils.log import printStack printStack(None) return message["channel"] = channelName message["clientID"] = request.clientID for c in clnts: if not myself and c == request.sputnikID: continue if c.strip() != '': try: sputnik.push("ses:%s:messages" % c, simplejson.dumps(message)) except: pass
def create(self, validated_data): chapter = super(ChapterListCreateSerializer, self).create(validated_data) # create toc book = self.context['view']._book book_version = self.context['view']._book.version weight = len(book_version.get_toc()) + 1 for itm in BookToc.objects.filter(version=book_version, book=book).order_by("-weight"): itm.weight = weight itm.save() weight -= 1 toc_item = BookToc( version=book_version, book=book, name=chapter.title, chapter=chapter, weight=1, typeof=1 ) toc_item.save() # create chapter history history = logChapterHistory( chapter=chapter, content=chapter.content, user=self.context['request'].user, comment="created via api", revision=chapter.revision ) # create book history if history: logBookHistory( book=book, version=book_version, chapter=chapter, chapter_history=history, user=self.context['request'].user, kind='chapter_create' ) # TODO # this is just playground # we must create separate tool to push messages through the sputnik channel from API endpoints # without having clientID in request # message_info channel_name = "/chat/{}/".format(book.id) clnts = sputnik.smembers("sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, "command": "message_info", "from": self.context['request'].user.username, "email": self.context['request'].user.email, "message_id": "user_new_chapter", "message_args": [self.context['request'].user.username, chapter.title] } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # chapter_create channel_name = "/booktype/book/{}/{}/".format(book.id, book_version.get_version()) clnts = sputnik.smembers("sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, "command": "chapter_create", "chapter": (chapter.id, chapter.title, chapter.url_title, 1, chapter.status.id, chapter.lock_type, chapter.lock_username, "root", toc_item.id, "normal", None) } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # notificatoin message message = { 'channel': channel_name, 'command': 'notification', 'message': 'notification_chapter_was_created', 'username': self.context['request'].user.username, 'message_args': (chapter.title,) } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) return chapter
def debug_redis(request): """ Django View. This page shows basic debug information about redis. @todo: This should be removed. New Django Application for debuging and monitoring should be created. @type request: C{django.http.HttpRequest} @param request: Client Request object """ import sputnik client_id = sputnik.get("sputnik:client_id") sputnikchannels = sputnik.smembers("sputnik:channels") chnl = {} for ch in sputnik.rkeys("sputnik:channel:*:channel"): chnl[ch] = sputnik.smembers(ch) usrs = {} for ch in sputnik.rkeys("sputnik:channel:*:users"): usrs[ch] = sputnik.smembers(ch) # for ch in r.keys('sputnik:*:messages'): # pass allValues = {} import time, decimal _now = time.time() for ses in [k[4:-9] for k in sputnik.rkeys("ses:*:username")]: try: allValues[ses] = { "channels": sputnik.smembers("ses:%s:channels" % ses), "last_access": sputnik.get("ses:%s:last_access" % ses), "access_since": decimal.Decimal("%f" % _now) - sputnik.get("ses:%s:last_access" % ses), "username": sputnik.get("ses:%s:username" % ses) } except: pass locks = {} for ch in sputnik.rkeys("booki:*:locks:*"): locks[ch] = sputnik.get(ch) killlocks = {} for ch in sputnik.rkeys("booki:*:killlocks:*"): killlocks[ch] = sputnik.get(ch) return render_to_response('portal/debug_redis.html', {"request": request, "client_id": client_id, "sputnikchannels": sputnikchannels, "channel": chnl.items(), "users": usrs.items(), "sessions": allValues.items(), "locks": locks.items(), "killlocks": killlocks.items() })
def book_info(request, bookid, version=None): """ Django View. Shows single page with all the Book info. @type request: C{django.http.HttpRequest} @param request: Client Request object @type bookid: C{string} @param bookid: Unique Book ID @type version: C{string} @param verson: Book version """ try: book = models.Book.objects.get(url_title__iexact=bookid) except models.Book.DoesNotExist: try: resp = pages.ErrorPage(request, "errors/book_does_not_exist.html", {"book_name": bookid}) except: transaction.rollback() raise else: transaction.commit() return resp book_version = book.getVersion(version) book_history = models.BookHistory.objects.filter(version = book_version).order_by("-modified")[:20] book_collaborators = [e.values()[0] for e in models.BookHistory.objects.filter(version = book_version, kind = 2).values("user__username").distinct()] from booki.utils import security bookSecurity = security.getUserSecurityForBook(request.user, book) isBookAdmin = bookSecurity.isAdmin() import sputnik channel_name = "/booki/book/%s/%s/" % (book.id, book_version.getVersion()) online_users = sputnik.smembers("sputnik:channel:%s:users" % channel_name) book_versions = models.BookVersion.objects.filter(book=book).order_by("created") from django.utils.html import escape bookDescription = escape(book.description) try: resp = render_to_response('reader/book_info.html', {"book": book, "book_version": book_version.getVersion(), "book_versions": book_versions, "book_history": book_history, "book_collaborators": book_collaborators, "has_css": _customCSSExists(book.url_title), "is_book_admin": isBookAdmin, "online_users": online_users, "book_description": '<br/>'.join(bookDescription.replace('\r','').split('\n')), "request": request}) except: transaction.rollback() raise else: transaction.commit() return resp
def post(self, request, *args, **kwargs): # TODO test it and cover with tests book_security = BookSecurity(request.user, self._get_book()) user = request.user can_upload_attachment = book_security.has_perm( 'edit.upload_attachment') if not user.is_superuser and not can_upload_attachment and self._book.owner != user: raise PermissionDenied stat = BookStatus.objects.filter(book=self._book)[0] if 'file' not in request.FILES: raise ValidationError({'file': ['"file" is required.']}) file_data = request.FILES['file'] attname, attext = os.path.splitext(file_data.name) available_extensions = ('jpg', 'png', 'jpeg', 'gif') if attext.rsplit('.', 1)[-1].lower() not in available_extensions: raise ValidationError({ 'file': [ 'Not supported extension. Available extensions: {}'.format( ' '.join(available_extensions)) ] }) with transaction.atomic(): att = Attachment( version=self._book.version, # must remove this reference created=datetime.datetime.now(), book=self._book, status=stat) att.save() att.attachment.save('{}{}'.format(booktype_slugify(attname), attext), file_data, save=False) att.save() # notificatoin message channel_name = "/booktype/book/{}/{}/".format( self._book.id, self._book.version.get_version()) clnts = sputnik.smembers( "sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, 'command': 'notification', 'message': 'notification_new_attachment_uploaded', 'username': self.request.user.username, 'message_args': (att.get_name(), ) } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # response serializer_instance = self.serializer_class(att) return Response(serializer_instance.data, status=status.HTTP_201_CREATED)
def remote_init_editor(request, message, bookid, version): book = models.Book.objects.get(id=bookid) book_version = getVersion(book, version) ## get chapters chapters = getTOCForBook(book_version) holdChapters = getHoldChapters(book_version) ## get users def _getUserName(a): if a == request.sputnikID: return "<b>%s</b>" % a return a try: users = [_getUserName(m) for m in list(sputnik.smembers("sputnik:channel:%s:channel" % message["channel"]))] except: users = [] ## get workflow statuses statuses = [(status.id, status.name) for status in models.BookStatus.objects.filter(book=book).order_by("-weight")] ## get attachments try: attachments = getAttachments(book_version) except: attachments = [] ## get metadata metadata = [{'name': v.name, 'value': v.getValue()} for v in models.Info.objects.filter(book=book)] ## notify others sputnik.addMessageToChannel(request, "/chat/%s/" % bookid, {"command": "user_joined", "user_joined": request.user.username}, myself = False) ## get licenses licenses = [(elem.abbrevation, elem.name) for elem in models.License.objects.all().order_by("name")] ## get online users try: _onlineUsers = sputnik.smembers("sputnik:channel:%s:users" % message["channel"]) except: _onlineUsers = [] if request.user.username not in _onlineUsers: try: sputnik.sadd("sputnik:channel:%s:users" % message["channel"], request.user.username) _onlineUsers.append(request.user.username) except: pass ## get mood message for current user ## send mood as seperate message ## set notifications to other clients profile = request.user.get_profile() if profile: moodMessage = profile.mood; else: moodMessage = '' sputnik.addMessageToChannel(request, "/booki/book/%s/%s/" % (bookid, version), {"command": "user_add", "username": request.user.username, "mood": moodMessage} ) ## get online users and their mood messages from django.contrib.auth.models import User def _getUser(_user): try: _u = User.objects.get(username=_user) return (_user, _u.get_profile().mood) except: return None onlineUsers = [x for x in [_getUser(x) for x in _onlineUsers] if x] # for now, this is one big temp here import time, decimal, re _now = time.time() locks = {} try: for key in sputnik.rkeys("booki:*:locks:*"): lastAccess = sputnik.get(key) if type(lastAccess) in [type(' '), type(u' ')]: try: lastAccess = decimal.Decimal(lastAccess) except: continue if lastAccess and decimal.Decimal("%f" % _now) - lastAccess <= 30: m = re.match("booki:(\d+):locks:(\d+):(\w+)", key) if m: if m.group(1) == bookid: locks[m.group(2)] = m.group(3) except: pass return {"licenses": licenses, "chapters": chapters, "metadata": metadata, "hold": holdChapters, "users": users, "locks": locks, "statuses": statuses, "attachments": attachments, "onlineUsers": list(onlineUsers)}
def frontpage(request): # check all active online users and what are they doing import sputnik clientList = sputnik.rkeys("ses:*:username") onlineUsers = [] for us in clientList: clientID = us[4:-9] channelList = [] for chan in sputnik.smembers("ses:%s:channels" % clientID): if chan.startswith("/booki/book/"): _s = chan.split("/") if len(_s) > 3: bookID = _s[3] b = models.Book.objects.get(pk=bookID) channelList.append(b) _u = sputnik.get(us) onlineUsers.append((_u, channelList)) # Check the attachment size. # This should not be here in the future. It takes way too much time. from booki.utils import misc attachmentDirectory = "%s/books/" % (settings.DATA_ROOT,) attachmentsSize = misc.getDirectorySize(attachmentDirectory) # Number of books and number of groups number_of_books = len(models.Book.objects.all()) number_of_groups = len(models.BookiGroup.objects.all()) # Number of all users on the system. # This should somehow check only the active users from django.contrib.auth.models import User number_of_users = len(User.objects.all()) # check the database size from django.db import connection cursor = connection.cursor() try: # This will not work if user has new style of configuration for the database # This will also only work for PostgreSQL. Should make another method for checking sqlite database size. cursor.execute("SELECT pg_database_size(%s)", [settings.DATABASES["default"]["NAME"]]) databaseSize = cursor.fetchone()[0] except: databaseSize = 0 # Book activity activityHistory = models.BookHistory.objects.filter(kind__in=[1, 10]).order_by("-modified")[:20] # Booktype version import booki booktypeVersion = ".".join([str(num) for num in booki.version]) return render_to_response( "booktypecontrol/frontpage.html", { "request": request, "booktype_version": booktypeVersion, "admin_options": ADMIN_OPTIONS, "online_users": onlineUsers, "attachments_size": attachmentsSize, "number_of_books": number_of_books, "number_of_users": number_of_users, "number_of_groups": number_of_groups, "database_size": databaseSize, "activity_history": activityHistory, }, )
def post(self, request, *args, **kwargs): # TODO test it and cover with tests book_security = BookSecurity(request.user, self._get_book()) user = request.user can_upload_attachment = book_security.has_perm('edit.upload_attachment') if not user.is_superuser and not can_upload_attachment and self._book.owner != user: raise PermissionDenied stat = BookStatus.objects.filter(book=self._book)[0] if 'file' not in request.FILES: raise ValidationError({'file': ['"file" is required.']}) file_data = request.FILES['file'] attname, attext = os.path.splitext(file_data.name) available_extensions = ('jpg', 'png', 'jpeg', 'gif') if attext.rsplit('.', 1)[-1].lower() not in available_extensions: raise ValidationError({'file': [ 'Not supported extension. Available extensions: {}'.format( ' '.join(available_extensions)) ]}) with transaction.atomic(): att = Attachment( version=self._book.version, # must remove this reference created=datetime.datetime.now(), book=self._book, status=stat ) att.save() att.attachment.save( '{}{}'.format(booktype_slugify(attname), attext), file_data, save=False ) att.save() # notificatoin message channel_name = "/booktype/book/{}/{}/".format(self._book.id, self._book.version.get_version()) clnts = sputnik.smembers( "sputnik:channel:{}:channel".format(channel_name)) message = { 'channel': channel_name, 'command': 'notification', 'message': 'notification_new_attachment_uploaded', 'username': self.request.user.username, 'message_args': (att.get_name(),) } for c in clnts: if c.strip() != '': sputnik.push("ses:%s:messages" % c, json.dumps(message)) # response serializer_instance = self.serializer_class(att) return Response(serializer_instance.data, status=status.HTTP_201_CREATED)