<commit_before>import datetime
import urllib
import urlparse
from utils import log as logging
import oauth2 as oauth
import uuid
from django.contrib.sites.models import Site
from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.contrib.auth import login as login_user
from django.shortcuts import render_to_response
from apps.reader.forms import SignupForm
from apps.reader.models import UserSubscription
from apps.feed_import.models import OAuthToken, OPMLImporter, OPMLExporter, GoogleReaderImporter
from utils import json_functions as json
from utils.user_functions import ajax_login_required, get_user

@ajax_login_required
def opml_upload(request):
    xml_opml = None
    message = "OK"
    code = 1
    payload = {}

    if request.method == 'POST':
        if 'file' in request.FILES:
            logging.user(request, "~FR~SBOPML upload starting...")
            file = request.FILES['file']
            xml_opml = file.read()
            opml_importer = OPMLImporter(xml_opml, request.user)
            folders = opml_importer.process()

            feeds = UserSubscription.objects.filter(user=request.user).values()
            payload = dict(folders=folders, feeds=feeds)
            logging.user(request, "~FR~SBOPML Upload: ~SK%s~SN~SB~FR feeds" % (len(feeds)))

            request.session['import_from_google_reader'] = False
        else:
            message = "Attach an .opml file."
            code = -1

    data = json.encode(dict(message=message, code=code, payload=payload))
    return HttpResponse(data, mimetype='text/plain')

def opml_export(request):
    user     = get_user(request)
    exporter = OPMLExporter(user)
    opml     = exporter.process()
    now      = datetime.datetime.now()

    response = HttpResponse(opml, mimetype='text/xml')
    response['Content-Disposition'] = 'attachment; filename=NewsBlur Subscriptions - %s' % (
        now.strftime('%d %B %Y')
    )

    return response

def reader_authorize(request):
    logging.user(request, "~BB~FW~SBAuthorize Google Reader import - %s" % (
        request.META['REMOTE_ADDR'],
    ))
    oauth_key = settings.OAUTH_KEY
    oauth_secret = settings.OAUTH_SECRET
    scope = "http://www.google.com/reader/api"
    request_token_url = ("https://www.google.com/accounts/OAuthGetRequestToken?"
                         "scope=%s&secure=1&session=1&oauth_callback=http://%s%s") % (
                            urllib.quote_plus(scope),
                            Site.objects.get_current().domain,
                            reverse('google-reader-callback'),
                         )
    authorize_url = 'https://www.google.com/accounts/OAuthAuthorizeToken'

    # Grab request token from Google's OAuth
    consumer = oauth.Consumer(oauth_key, oauth_secret)
    client = oauth.Client(consumer)
    resp, content = client.request(request_token_url, "GET")
    request_token = dict(urlparse.parse_qsl(content))

    # Save request token and delete old tokens
    auth_token_dict = dict(request_token=request_token['oauth_token'],
                           request_token_secret=request_token['oauth_token_secret'])
    if request.user.is_authenticated():
        OAuthToken.objects.filter(user=request.user).delete()
        auth_token_dict['user'] = request.user
    else:
        OAuthToken.objects.filter(session_id=request.session.session_key).delete()
        OAuthToken.objects.filter(remote_ip=request.META['REMOTE_ADDR']).delete()
    auth_token_dict['uuid'] = str(uuid.uuid4())
    auth_token_dict['session_id'] = request.session.session_key
    auth_token_dict['remote_ip'] = request.META['REMOTE_ADDR']
    OAuthToken.objects.create(**auth_token_dict)

    redirect = "%s?oauth_token=%s" % (authorize_url, request_token['oauth_token'])
    response = HttpResponseRedirect(redirect)
    response.set_cookie('newsblur_reader_uuid', auth_token_dict['uuid'])
    return response

def reader_callback(request):
    access_token_url = 'https://www.google.com/accounts/OAuthGetAccessToken'
    consumer = oauth.Consumer(settings.OAUTH_KEY, settings.OAUTH_SECRET)
    user_token = None
    if request.user.is_authenticated():
        user_token = OAuthToken.objects.filter(user=request.user).order_by('-created_date')
    if not user_token:
        user_uuid = request.COOKIES.get('newsblur_reader_uuid')
        if user_uuid:
            user_token = OAuthToken.objects.filter(uuid=user_uuid).order_by('-created_date')
    if not user_token:
        session = request.session
        if session.session_key:
            user_token = OAuthToken.objects.filter(session_id=request.session.session_key).order_by('-created_date')
    if not user_token:
        user_token = OAuthToken.objects.filter(remote_ip=request.META['REMOTE_ADDR']).order_by('-created_date')
        # logging.info("Found ip user_tokens: %s" % user_tokens)

    if user_token:
        user_token = user_token[0]
        user_token.session_id = request.session.session_key
        user_token.save()

    if user_token and request.GET.get('oauth_verifier'):
        # logging.info("Google Reader request.GET: %s" % request.GET)
        # Authenticated in Google, so verify and fetch access tokens
        token = oauth.Token(user_token.request_token, user_token.request_token_secret)
        token.set_verifier(request.GET['oauth_verifier'])
        client = oauth.Client(consumer, token)
        resp, content = client.request(access_token_url, "POST")
        access_token = dict(urlparse.parse_qsl(content))
        user_token.access_token = access_token.get('oauth_token')
        user_token.access_token_secret = access_token.get('oauth_token_secret')
        try:
            user_token.save()
        except IntegrityError:
            logging.info(" ***> [%s] Bad token from Google Reader. Re-authenticating." % (request.user,))
            return HttpResponseRedirect(reverse('google-reader-authorize'))

        # Fetch imported feeds on next page load
        request.session['import_from_google_reader'] = True

        logging.user(request, "~BB~FW~SBFinishing Google Reader import - %s" % (request.META['REMOTE_ADDR'],))

        if request.user.is_authenticated():
            return HttpResponseRedirect(reverse('index'))
    else:
        logging.info(" ***> [%s] Bad token from Google Reader. Re-authenticating." % (request.user,))
        return HttpResponseRedirect(reverse('google-reader-authorize'))

    return HttpResponseRedirect(reverse('import-signup'))

@json.json_view
def import_from_google_reader(request):
    code = 0

    if request.user.is_authenticated():
        reader_importer = GoogleReaderImporter(request.user)
        try:
            reader_importer.import_feeds()
            reader_importer.import_starred_items()
        except AssertionError:
            code = -1
        else:
            code = 1
        if 'import_from_google_reader' in request.session:
            del request.session['import_from_google_reader']

    return dict(code=code)

def import_signup(request):
    if request.method == "POST":
        signup_form = SignupForm(prefix='signup', data=request.POST)
        if signup_form.is_valid():
            new_user = signup_form.save()

            user_token = None
            if not user_token:
                user_uuid = request.COOKIES.get('newsblur_reader_uuid')
                if user_uuid:
                    user_token = OAuthToken.objects.filter(uuid=user_uuid).order_by('-created_date')
            if not user_token:
                if request.session.session_key:
                    user_token = OAuthToken.objects.filter(session_id=request.session.session_key).order_by('-created_date')
            if not user_token:
                user_token = OAuthToken.objects.filter(remote_ip=request.META['REMOTE_ADDR']).order_by('-created_date')

            if user_token:
                user_token = user_token[0]
                user_token.session_id = request.session.session_key
                user_token.user = new_user
                user_token.save()
                login_user(request, new_user)
                return HttpResponseRedirect(reverse('index'))
            else:
                logging.user(request, "~BR~FW ***> Can't find user token during import/signup. Re-authenticating...")
                return HttpResponseRedirect(reverse('google-reader-authorize'))
    else:
        signup_form = SignupForm(prefix='signup')

    return render_to_response('import/signup.xhtml', {
        'signup_form': signup_form,
    }, context_instance=RequestContext(request))<commit_msg>Checking for a signup that is really a login when importing GR.<commit_after>import datetime
import urllib
import urlparse
from utils import log as logging
import oauth2 as oauth
import uuid
from django.contrib.sites.models import Site
from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.contrib.auth import login as login_user
from django.shortcuts import render_to_response
from apps.reader.forms import SignupForm
from apps.reader.models import UserSubscription
from apps.feed_import.models import OAuthToken, OPMLImporter, OPMLExporter, GoogleReaderImporter
from utils import json_functions as json
from utils.user_functions import ajax_login_required, get_user

@ajax_login_required
def opml_upload(request):
    xml_opml = None
    message = "OK"
    code = 1
    payload = {}

    if request.method == 'POST':
        if 'file' in request.FILES:
            logging.user(request, "~FR~SBOPML upload starting...")
            file = request.FILES['file']
            xml_opml = file.read()
            opml_importer = OPMLImporter(xml_opml, request.user)
            folders = opml_importer.process()

            feeds = UserSubscription.objects.filter(user=request.user).values()
            payload = dict(folders=folders, feeds=feeds)
            logging.user(request, "~FR~SBOPML Upload: ~SK%s~SN~SB~FR feeds" % (len(feeds)))

            request.session['import_from_google_reader'] = False
        else:
            message = "Attach an .opml file."
            code = -1

    data = json.encode(dict(message=message, code=code, payload=payload))
    return HttpResponse(data, mimetype='text/plain')

def opml_export(request):
    user     = get_user(request)
    exporter = OPMLExporter(user)
    opml     = exporter.process()
    now      = datetime.datetime.now()

    response = HttpResponse(opml, mimetype='text/xml')
    response['Content-Disposition'] = 'attachment; filename=NewsBlur Subscriptions - %s' % (
        now.strftime('%d %B %Y')
    )

    return response

def reader_authorize(request):
    logging.user(request, "~BB~FW~SBAuthorize Google Reader import - %s" % (
        request.META['REMOTE_ADDR'],
    ))
    oauth_key = settings.OAUTH_KEY
    oauth_secret = settings.OAUTH_SECRET
    scope = "http://www.google.com/reader/api"
    request_token_url = ("https://www.google.com/accounts/OAuthGetRequestToken?"
                         "scope=%s&secure=1&session=1&oauth_callback=http://%s%s") % (
                            urllib.quote_plus(scope),
                            Site.objects.get_current().domain,
                            reverse('google-reader-callback'),
                         )
    authorize_url = 'https://www.google.com/accounts/OAuthAuthorizeToken'

    # Grab request token from Google's OAuth
    consumer = oauth.Consumer(oauth_key, oauth_secret)
    client = oauth.Client(consumer)
    resp, content = client.request(request_token_url, "GET")
    request_token = dict(urlparse.parse_qsl(content))

    # Save request token and delete old tokens
    auth_token_dict = dict(request_token=request_token['oauth_token'],
                           request_token_secret=request_token['oauth_token_secret'])
    if request.user.is_authenticated():
        OAuthToken.objects.filter(user=request.user).delete()
        auth_token_dict['user'] = request.user
    else:
        OAuthToken.objects.filter(session_id=request.session.session_key).delete()
        OAuthToken.objects.filter(remote_ip=request.META['REMOTE_ADDR']).delete()
    auth_token_dict['uuid'] = str(uuid.uuid4())
    auth_token_dict['session_id'] = request.session.session_key
    auth_token_dict['remote_ip'] = request.META['REMOTE_ADDR']
    OAuthToken.objects.create(**auth_token_dict)

    redirect = "%s?oauth_token=%s" % (authorize_url, request_token['oauth_token'])
    response = HttpResponseRedirect(redirect)
    response.set_cookie('newsblur_reader_uuid', auth_token_dict['uuid'])
    return response

def reader_callback(request):
    access_token_url = 'https://www.google.com/accounts/OAuthGetAccessToken'
    consumer = oauth.Consumer(settings.OAUTH_KEY, settings.OAUTH_SECRET)
    user_token = None
    if request.user.is_authenticated():
        user_token = OAuthToken.objects.filter(user=request.user).order_by('-created_date')
    if not user_token:
        user_uuid = request.COOKIES.get('newsblur_reader_uuid')
        if user_uuid:
            user_token = OAuthToken.objects.filter(uuid=user_uuid).order_by('-created_date')
    if not user_token:
        session = request.session
        if session.session_key:
            user_token = OAuthToken.objects.filter(session_id=request.session.session_key).order_by('-created_date')
    if not user_token:
        user_token = OAuthToken.objects.filter(remote_ip=request.META['REMOTE_ADDR']).order_by('-created_date')
        # logging.info("Found ip user_tokens: %s" % user_tokens)

    if user_token:
        user_token = user_token[0]
        user_token.session_id = request.session.session_key
        user_token.save()

    if user_token and request.GET.get('oauth_verifier'):
        # logging.info("Google Reader request.GET: %s" % request.GET)
        # Authenticated in Google, so verify and fetch access tokens
        token = oauth.Token(user_token.request_token, user_token.request_token_secret)
        token.set_verifier(request.GET['oauth_verifier'])
        client = oauth.Client(consumer, token)
        resp, content = client.request(access_token_url, "POST")
        access_token = dict(urlparse.parse_qsl(content))
        user_token.access_token = access_token.get('oauth_token')
        user_token.access_token_secret = access_token.get('oauth_token_secret')
        try:
            user_token.save()
        except IntegrityError:
            logging.info(" ***> [%s] Bad token from Google Reader. Re-authenticating." % (request.user,))
            return HttpResponseRedirect(reverse('google-reader-authorize'))

        # Fetch imported feeds on next page load
        request.session['import_from_google_reader'] = True

        logging.user(request, "~BB~FW~SBFinishing Google Reader import - %s" % (request.META['REMOTE_ADDR'],))

        if request.user.is_authenticated():
            return HttpResponseRedirect(reverse('index'))
    else:
        logging.info(" ***> [%s] Bad token from Google Reader. Re-authenticating." % (request.user,))
        return HttpResponseRedirect(reverse('google-reader-authorize'))

    return HttpResponseRedirect(reverse('import-signup'))

@json.json_view
def import_from_google_reader(request):
    code = 0

    if request.user.is_authenticated():
        reader_importer = GoogleReaderImporter(request.user)
        try:
            reader_importer.import_feeds()
            reader_importer.import_starred_items()
        except AssertionError:
            code = -1
        else:
            code = 1
        if 'import_from_google_reader' in request.session:
            del request.session['import_from_google_reader']

    return dict(code=code)

def import_signup(request):
    if request.method == "POST":
        signup_form = SignupForm(prefix='signup', data=request.POST)
        if signup_form.is_valid():
            new_user = signup_form.save()

            user_token = OAuthToken.objects.filter(user=new_user)
            if not user_token:
                user_uuid = request.COOKIES.get('newsblur_reader_uuid')
                if user_uuid:
                    user_token = OAuthToken.objects.filter(uuid=user_uuid).order_by('-created_date')
            if not user_token:
                if request.session.session_key:
                    user_token = OAuthToken.objects.filter(session_id=request.session.session_key).order_by('-created_date')
            if not user_token:
                user_token = OAuthToken.objects.filter(remote_ip=request.META['REMOTE_ADDR']).order_by('-created_date')

            if user_token:
                user_token = user_token[0]
                user_token.session_id = request.session.session_key
                user_token.user = new_user
                user_token.save()
                login_user(request, new_user)
                return HttpResponseRedirect(reverse('index'))
            else:
                logging.user(request, "~BR~FW ***> Can't find user token during import/signup. Re-authenticating...")
                return HttpResponseRedirect(reverse('google-reader-authorize'))
    else:
        signup_form = SignupForm(prefix='signup')

    return render_to_response('import/signup.xhtml', {
        'signup_form': signup_form,
    }, context_instance=RequestContext(request))<|endoftext|>


<commit_before>import pygame
from operator import truth

ANCHOR_TOPLEFT = 101
ANCHOR_TOPRIGHT = 102
ANCHOR_BOTTOMLEFT = 103
ANCHOR_BOTTOMRIGHT = 104
ANCHOR_CENTER = 105

class Sprite(object):
    """simple base class for visible game objects

    pygame.sprite.Sprite(*groups): return Sprite

    The base class for visible game objects. Derived classes will want to
    override the Sprite.update() method and assign Sprite.image and Sprite.rect
    attributes.  The initializer can accept any number of Group instances that
    the Sprite will become a member of.

    When subclassing the Sprite class, be sure to call the base initializer
    before adding the Sprite to Groups.

    """

    def __init__(self, *groups):
        self.image = None
        self.rect = None

        self.anchor = ANCHOR_TOPLEFT
        self.position = None
        self.offset = (0, 0)

        self.dirty = False

        # visual attributes
        self.scale = 1
        self.rotate = 0
        self.visible = True

        self.__g = {}  # The groups the sprite is in
        if groups:
            self.add(*groups)

    def draw(self, surface):
        if (self.visible):
            return surface.blit(self.image, self.rect)
        else:
            return 0

    # a callback that gets called on any visual change
    def _visual_set(method):
        def wrapper(self, *args, **kwargs):
            result = None

            do_change = True
            if hasattr(self, 'on_visual_set'):
                do_change = self.on_visual_set(method, *args, **kwargs)

            if do_change:
                result = method(self, *args, **kwargs)
                self.dirty = True
            return result
        return wrapper

    def _get_image(self):
        try:
            img = self._image
        except AttributeError:
            img = None

        if img is not None:
            if self.scale != 1 or self.rotate != 0:
                if self.scale != 1:
                    img = pygame.transform.scale(img, self.scaled_size())
                if self.rotate != 0:
                    img = pygame.transform.rotate(img, self.rotate)
                self.rect = img.get_rect()
                self.position = self.position

        return img

    def _set_image(self, img):
        self._image = img

    image = property(_get_image,
                     _visual_set(_set_image),
                     doc="The sprite's image to draw")

    #TODO handle negative values
    #TODO use same constants as Rect's
    def anchor_value(self):
        if type(self.anchor) is tuple:
            return self.anchor
        elif self.anchor == ANCHOR_TOPLEFT:
            return (0, 0)
        elif self.anchor == ANCHOR_TOPRIGHT:
            return (self.rect.width, 0)
        elif self.anchor == ANCHOR_BOTTOMLEFT:
            return (0, self.rect.height)
        elif self.anchor == ANCHOR_BOTTOMRIGHT:
            return (self.rect.width, self.rect.height)
        elif self.anchor == ANCHOR_CENTER:
            return (self.rect.width / 2, self.rect.height / 2)
        else:
            return None  # shouldn't happen :(

    def _get_position(self):
        return self._position

    #TODO handle float values
    def _set_position(self, value):
        self._position = value
        if value:
            (x, y) = value
            (off_x, off_y) = self.offset
            (anchor_x, anchor_y) = self.anchor_value()
            self.rect.topleft = (x + off_x - anchor_x, y + off_y - anchor_y)

    position = property(_get_position,
                        _visual_set(_set_position),
                        doc="The sprite's designated position, \
                        that is, where on the surface its anchor \
                        would be rendered")

    def _get_visible(self):
        return self._visible

    def _set_visible(self, value):
        self._visible = value

    visible = property(_get_visible,
                       _visual_set(_set_visible),
                       doc="Whether to draw the sprite")

    def _get_scale(self):
        return self._scale

    def _set_scale(self, ratio):
        if ratio < 0:
            raise AttributeError("ratio must be a positive float")
        self._scale = ratio

    scale = property(_get_scale,
                     _visual_set(_set_scale),
                     doc="A float representing the ratio between the \
                     original image's size and the size rendered")

    def scaled_size(self):
        (width, height) = self._image.get_size()
        width = (int)(width * self.scale)
        height = (int)(height * self.scale)
        return (width, height)

    def _get_rotate(self):
        try:
            return self._rotate
        except AttributeError:
            return 0

    def _set_rotate(self, degree):
        self._rotate = degree % 360  # TODO magic number?

    rotate = property(_get_rotate,
                      _visual_set(_set_rotate),
                      doc="The degrees by which to rotate the sprite's image")

    def add(self, *groups):
        """add the sprite to groups

        Sprite.add(*groups): return None

        Any number of Group instances can be passed as arguments. The
        Sprite will be added to the Groups it is not already a member of.

        """
        has = self.__g.__contains__
        for group in groups:
            if hasattr(group, '_spritegroup'):
                if not has(group):
                    group.add_internal(self)
                    self.add_internal(group)
            else:
                self.add(*group)

    def remove(self, *groups):
        """remove the sprite from groups

        Sprite.remove(*groups): return None

        Any number of Group instances can be passed as arguments. The Sprite
        will be removed from the Groups it is currently a member of.

        """
        has = self.__g.__contains__
        for group in groups:
            if hasattr(group, '_spritegroup'):
                if has(group):
                    group.remove_internal(self)
                    self.remove_internal(group)
            else:
                self.remove(*group)

    def add_internal(self, group):
        self.__g[group] = 0

    def remove_internal(self, group):
        del self.__g[group]

    def update(self, *args):
        """method to control sprite behavior

        Sprite.update(*args):

        The default implementation of this method does nothing; it's just a
        convenient "hook" that you can override. This method is called by
        Group.update() with whatever arguments you give it.

        There is no need to use this method if not using the convenience
        method by the same name in the Group class.

        """
        pass

    def kill(self):
        """remove the Sprite from all Groups

        Sprite.kill(): return None

        The Sprite is removed from all the Groups that contain it. This won't
        change anything about the state of the Sprite. It is possible to
        continue to use the Sprite after this method has been called, including
        adding it to Groups.

        """
        for c in self.__g:
            c.remove_internal(self)
        self.__g.clear()

    def groups(self):
        """list of Groups that contain this Sprite

        Sprite.groups(): return group_list

        Returns a list of all the Groups that contain this Sprite.

        """
        return list(self.__g)

    def alive(self):
        """does the sprite belong to any groups

        Sprite.alive(): return bool

        Returns True when the Sprite belongs to one or more Groups.
        """
        return truth(self.__g)

    def __repr__(self):
        return "<%s sprite(in %d groups)>" \
                % (self.__class__.__name__, len(self.__g))

class AggregatedSprite(Sprite):
    def _get_sprites(self):
        try:
            return self._sprites
        except AttributeError:
            self._sprites = []
            return self._sprites

    def _set_sprites(self, sprites):
        self._sprites = sprites

    def add_sprite(self, sprite):
        self.sprites.append(sprite)

    sprites = property(_get_sprites,
                       _set_sprites,
                       doc="List of sprites to aggregate")

    def draw(self, surface):
        ret = pygame.Rect(0, 0, 0, 0)
        for spr in self.sprites:
            r = spr.draw(surface)
            if r != 0:
                ret.union_ip(r)
        return ret

    def on_visual_set(self, method, *args, **kwargs):
        if method.__name__ == '_set_position':
            for spr in self.sprites:
                spr.offset = args[0]
        else:
            for spr in self.sprites:
                method(spr, *args, **kwargs)
        return True

class AbstractGroup(object):
    """base class for containers of sprites

    AbstractGroup does everything needed to behave as a normal group. You can
    easily subclass a new group class from this or the other groups below if
    you want to add more features.

    Any AbstractGroup-derived sprite groups act like sequences and support
    iteration, len, and so on.

    """

    # dummy val to identify sprite groups, and avoid infinite recursion
    _spritegroup = True

    def __init__(self):
        self.spritedict = {}
        self.lostsprites = []

    def sprites(self):
        """get a list of sprites in the group

        Group.sprite(): return list

        Returns an object that can be looped over with a 'for' loop. (For now,
        it is always a list, but this could change in a future version of
        pygame.) Alternatively, you can get the same information by iterating
        directly over the sprite group, e.g. 'for sprite in group'.

        """
        return list(self.spritedict)

    def add_internal(self, sprite):
        self.spritedict[sprite] = 0

    def remove_internal(self, sprite):
        r = self.spritedict[sprite]
        if r is not 0:
            self.lostsprites.append(r)
        del self.spritedict[sprite]

    def has_internal(self, sprite):
        return sprite in self.spritedict

    def copy(self):
        """copy a group with all the same sprites

        Group.copy(): return Group

        Returns a copy of the group that is an instance of the same class
        and has the same sprites in it.

        """
        return self.__class__(self.sprites())

    def __iter__(self):
        return iter(self.sprites())

    def __contains__(self, sprite):
        return self.has(sprite)

    def add(self, *sprites):
        """add sprite(s) to group

        Group.add(sprite, list, group, ...): return None

        Adds a sprite or sequence of sprites to a group.

        """
        for sprite in sprites:
            # It's possible that some sprite is also an iterator.
            # If this is the case, we should add the sprite itself,
            # and not the iterator object.
            if isinstance(sprite, Sprite):
                if not self.has_internal(sprite):
                    self.add_internal(sprite)
                    sprite.add_internal(self)
            else:
                try:
                    # See if sprite is an iterator, like a list or sprite
                    # group.
                    self.add(*sprite)
                except (TypeError, AttributeError):
                    # Not iterable. This is probably a sprite that is not an
                    # instance of the Sprite class or is not an instance of a
                    # subclass of the Sprite class. Alternately, it could be an
                    # old-style sprite group.
                    if hasattr(sprite, '_spritegroup'):
                        for spr in sprite.sprites():
                            if not self.has_internal(spr):
                                self.add_internal(spr)
                                spr.add_internal(self)
                    elif not self.has_internal(sprite):
                        self.add_internal(sprite)
                        sprite.add_internal(self)

    def remove(self, *sprites):
        """remove sprite(s) from group

        Group.remove(sprite, list, or group, ...): return None

        Removes a sprite or sequence of sprites from a group.

        """
        # This function behaves essentially the same as Group.add. It first
        # tries to handle each argument as an instance of the Sprite class. If
        # that failes, then it tries to handle the argument as an iterable
        # object. If that failes, then it tries to handle the argument as an
        # old-style sprite group. Lastly, if that fails, it assumes that the
        # normal Sprite methods should be used.
        for sprite in sprites:
            if isinstance(sprite, Sprite):
                if self.has_internal(sprite):
                    self.remove_internal(sprite)
                    sprite.remove_internal(self)
            else:
                try:
                    self.remove(*sprite)
                except (TypeError, AttributeError):
                    if hasattr(sprite, '_spritegroup'):
                        for spr in sprite.sprites():
                            if self.has_internal(spr):
                                self.remove_internal(spr)
                                spr.remove_internal(self)
                    elif self.has_internal(sprite):
                        self.remove_internal(sprite)
                        sprite.remove_internal(self)

    def has(self, *sprites):
        """ask if group has a sprite or sprites

        Group.has(sprite or group, ...): return bool

        Returns True if the given sprite or sprites are contained in the
        group. Alternatively, you can get the same information using the
        'in' operator, e.g. 'sprite in group', 'subgroup in group'.

        """
        return_value = False

        for sprite in sprites:
            if isinstance(sprite, Sprite):
                # Check for Sprite instance's membership in this group
                if self.has_internal(sprite):
                    return_value = True
                else:
                    return False
            else:
                try:
                    if self.has(*sprite):
                        return_value = True
                    else:
                        return False
                except (TypeError, AttributeError):
                    if hasattr(sprite, '_spritegroup'):
                        for spr in sprite.sprites():
                            if self.has_internal(spr):
                                return_value = True
                            else:
                                return False
                    else:
                        if self.has_internal(sprite):
                            return_value = True
                        else:
                            return False

        return return_value

    def update(self, *args):
        """call the update method of every member sprite

        Group.update(*args): return None

        Calls the update method of every member sprite. All arguments that
        were passed to this method are passed to the Sprite update function.

        """
        for s in self.sprites():
            s.update(*args)

    def draw(self, surface):
        """draw all sprites onto the surface

        Group.draw(surface): return None

        Draws all of the member sprites onto the given surface.

        """
        sprites = self.sprites()
        surface_blit = surface.blit
        for spr in sprites:
            if (hasattr(spr, 'draw')):
                self.spritedict[spr] = spr.draw(surface)
            else:
                self.spritedict[spr] = surface_blit(spr.image, spr.rect)
        self.lostsprites = []

    def clear(self, surface, bgd):
        """erase the previous position of all sprites

        Group.clear(surface, bgd): return None

        Clears the area under every drawn sprite in the group. The bgd
        argument should be Surface which is the same dimensions as the
        screen surface. The bgd could also be a function which accepts
        the given surface and the area to be cleared as arguments.

        """
        if callable(bgd):
            for r in self.lostsprites:
                bgd(surface, r)
            for r in self.spritedict.values():
                if r is not 0:
                    bgd(surface, r)
        else:
            surface_blit = surface.blit
            for r in self.lostsprites:
                surface_blit(bgd, r, r)
            for r in self.spritedict.values():
                if r is not 0:
                    surface_blit(bgd, r, r)

    def empty(self):
        """remove all sprites

        Group.empty(): return None

        Removes all the sprites from the group.

        """
        for s in self.sprites():
            self.remove_internal(s)
            s.remove_internal(self)

    def __nonzero__(self):
        return truth(self.sprites())

    def __len__(self):
        """return number of sprites in group

        Group.len(group): return int

        Returns the number of sprites contained in the group.

        """
        return len(self.sprites())

    def __repr__(self):
        return "<%s(%d sprites)>" % (self.__class__.__name__, len(self))

class Group(AbstractGroup):
    """container class for many Sprites

    pygame.sprite.Group(*sprites): return Group

    A simple container for Sprite objects. This class can be subclassed to
    create containers with more specific behaviors. The constructor takes any
    number of Sprite arguments to add to the Group. The group supports the
    following standard Python operations:

        in      test if a Sprite is contained
        len     the number of Sprites contained
        bool    test if any Sprites are contained
        iter    iterate through all the Sprites

    The Sprites in the Group are not ordered, so the Sprites are drawn and
    iterated over in no particular order.

    """
    def __init__(self, *sprites):
        AbstractGroup.__init__(self)
        self.add(*sprites)

RenderPlain = Group
RenderClear = Group
<commit_msg>Initializing AggregatedSprite's position.<commit_after>import pygame
from operator import truth

ANCHOR_TOPLEFT = 101
ANCHOR_TOPRIGHT = 102
ANCHOR_BOTTOMLEFT = 103
ANCHOR_BOTTOMRIGHT = 104
ANCHOR_CENTER = 105

class Sprite(object):
    """simple base class for visible game objects

    pygame.sprite.Sprite(*groups): return Sprite

    The base class for visible game objects. Derived classes will want to
    override the Sprite.update() method and assign Sprite.image and Sprite.rect
    attributes.  The initializer can accept any number of Group instances that
    the Sprite will become a member of.

    When subclassing the Sprite class, be sure to call the base initializer
    before adding the Sprite to Groups.

    """

    def __init__(self, *groups):
        self.image = None
        self.rect = None

        self.anchor = ANCHOR_TOPLEFT
        self.position = None
        self.offset = (0, 0)

        self.dirty = False

        # visual attributes
        self.scale = 1
        self.rotate = 0
        self.visible = True

        self.__g = {}  # The groups the sprite is in
        if groups:
            self.add(*groups)

    def draw(self, surface):
        if (self.visible):
            return surface.blit(self.image, self.rect)
        else:
            return 0

    # a callback that gets called on any visual change
    def _visual_set(method):
        def wrapper(self, *args, **kwargs):
            result = None

            do_change = True
            if hasattr(self, 'on_visual_set'):
                do_change = self.on_visual_set(method, *args, **kwargs)

            if do_change:
                result = method(self, *args, **kwargs)
                self.dirty = True
            return result
        return wrapper

    def _get_image(self):
        try:
            img = self._image
        except AttributeError:
            img = None

        if img is not None:
            if self.scale != 1 or self.rotate != 0:
                if self.scale != 1:
                    img = pygame.transform.scale(img, self.scaled_size())
                if self.rotate != 0:
                    img = pygame.transform.rotate(img, self.rotate)
                self.rect = img.get_rect()
                self.position = self.position

        return img

    def _set_image(self, img):
        self._image = img

    image = property(_get_image,
                     _visual_set(_set_image),
                     doc="The sprite's image to draw")

    #TODO handle negative values
    #TODO use same constants as Rect's
    def anchor_value(self):
        if type(self.anchor) is tuple:
            return self.anchor
        elif self.anchor == ANCHOR_TOPLEFT:
            return (0, 0)
        elif self.anchor == ANCHOR_TOPRIGHT:
            return (self.rect.width, 0)
        elif self.anchor == ANCHOR_BOTTOMLEFT:
            return (0, self.rect.height)
        elif self.anchor == ANCHOR_BOTTOMRIGHT:
            return (self.rect.width, self.rect.height)
        elif self.anchor == ANCHOR_CENTER:
            return (self.rect.width / 2, self.rect.height / 2)
        else:
            return None  # shouldn't happen :(

    def _get_position(self):
        return self._position

    #TODO handle float values
    def _set_position(self, value):
        self._position = value
        if value:
            (x, y) = value
            (off_x, off_y) = self.offset
            (anchor_x, anchor_y) = self.anchor_value()
            self.rect.topleft = (x + off_x - anchor_x, y + off_y - anchor_y)

    position = property(_get_position,
                        _visual_set(_set_position),
                        doc="The sprite's designated position, \
                        that is, where on the surface its anchor \
                        would be rendered")

    def _get_visible(self):
        return self._visible

    def _set_visible(self, value):
        self._visible = value

    visible = property(_get_visible,
                       _visual_set(_set_visible),
                       doc="Whether to draw the sprite")

    def _get_scale(self):
        return self._scale

    def _set_scale(self, ratio):
        if ratio < 0:
            raise AttributeError("ratio must be a positive float")
        self._scale = ratio

    scale = property(_get_scale,
                     _visual_set(_set_scale),
                     doc="A float representing the ratio between the \
                     original image's size and the size rendered")

    def scaled_size(self):
        (width, height) = self._image.get_size()
        width = (int)(width * self.scale)
        height = (int)(height * self.scale)
        return (width, height)

    def _get_rotate(self):
        try:
            return self._rotate
        except AttributeError:
            return 0

    def _set_rotate(self, degree):
        self._rotate = degree % 360  # TODO magic number?

    rotate = property(_get_rotate,
                      _visual_set(_set_rotate),
                      doc="The degrees by which to rotate the sprite's image")

    def add(self, *groups):
        """add the sprite to groups

        Sprite.add(*groups): return None

        Any number of Group instances can be passed as arguments. The
        Sprite will be added to the Groups it is not already a member of.

        """
        has = self.__g.__contains__
        for group in groups:
            if hasattr(group, '_spritegroup'):
                if not has(group):
                    group.add_internal(self)
                    self.add_internal(group)
            else:
                self.add(*group)

    def remove(self, *groups):
        """remove the sprite from groups

        Sprite.remove(*groups): return None

        Any number of Group instances can be passed as arguments. The Sprite
        will be removed from the Groups it is currently a member of.

        """
        has = self.__g.__contains__
        for group in groups:
            if hasattr(group, '_spritegroup'):
                if has(group):
                    group.remove_internal(self)
                    self.remove_internal(group)
            else:
                self.remove(*group)

    def add_internal(self, group):
        self.__g[group] = 0

    def remove_internal(self, group):
        del self.__g[group]

    def update(self, *args):
        """method to control sprite behavior

        Sprite.update(*args):

        The default implementation of this method does nothing; it's just a
        convenient "hook" that you can override. This method is called by
        Group.update() with whatever arguments you give it.

        There is no need to use this method if not using the convenience
        method by the same name in the Group class.

        """
        pass

    def kill(self):
        """remove the Sprite from all Groups

        Sprite.kill(): return None

        The Sprite is removed from all the Groups that contain it. This won't
        change anything about the state of the Sprite. It is possible to
        continue to use the Sprite after this method has been called, including
        adding it to Groups.

        """
        for c in self.__g:
            c.remove_internal(self)
        self.__g.clear()

    def groups(self):
        """list of Groups that contain this Sprite

        Sprite.groups(): return group_list

        Returns a list of all the Groups that contain this Sprite.

        """
        return list(self.__g)

    def alive(self):
        """does the sprite belong to any groups

        Sprite.alive(): return bool

        Returns True when the Sprite belongs to one or more Groups.
        """
        return truth(self.__g)

    def __repr__(self):
        return "<%s sprite(in %d groups)>" \
                % (self.__class__.__name__, len(self.__g))

class AggregatedSprite(Sprite):
    def __init__(self, *groups):
        super(AggregatedSprite, self).__init__(*groups)
        self.rect = pygame.Rect(0, 0, 0, 0)
        self.position = (0, 0)

    def _get_sprites(self):
        try:
            return self._sprites
        except AttributeError:
            self._sprites = []
            return self._sprites

    def _set_sprites(self, sprites):
        self._sprites = sprites

    def add_sprite(self, sprite):
        self.sprites.append(sprite)

    sprites = property(_get_sprites,
                       _set_sprites,
                       doc="List of sprites to aggregate")

    def draw(self, surface):
        ret = pygame.Rect(0, 0, 0, 0)
        for spr in self.sprites:
            r = spr.draw(surface)
            if r != 0:
                ret.union_ip(r)
        return ret

    def on_visual_set(self, method, *args, **kwargs):
        if method.__name__ == '_set_position':
            for spr in self.sprites:
                spr.offset = args[0]
        else:
            for spr in self.sprites:
                method(spr, *args, **kwargs)
        return True

class AbstractGroup(object):
    """base class for containers of sprites

    AbstractGroup does everything needed to behave as a normal group. You can
    easily subclass a new group class from this or the other groups below if
    you want to add more features.

    Any AbstractGroup-derived sprite groups act like sequences and support
    iteration, len, and so on.

    """

    # dummy val to identify sprite groups, and avoid infinite recursion
    _spritegroup = True

    def __init__(self):
        self.spritedict = {}
        self.lostsprites = []

    def sprites(self):
        """get a list of sprites in the group

        Group.sprite(): return list

        Returns an object that can be looped over with a 'for' loop. (For now,
        it is always a list, but this could change in a future version of
        pygame.) Alternatively, you can get the same information by iterating
        directly over the sprite group, e.g. 'for sprite in group'.

        """
        return list(self.spritedict)

    def add_internal(self, sprite):
        self.spritedict[sprite] = 0

    def remove_internal(self, sprite):
        r = self.spritedict[sprite]
        if r is not 0:
            self.lostsprites.append(r)
        del self.spritedict[sprite]

    def has_internal(self, sprite):
        return sprite in self.spritedict

    def copy(self):
        """copy a group with all the same sprites

        Group.copy(): return Group

        Returns a copy of the group that is an instance of the same class
        and has the same sprites in it.

        """
        return self.__class__(self.sprites())

    def __iter__(self):
        return iter(self.sprites())

    def __contains__(self, sprite):
        return self.has(sprite)

    def add(self, *sprites):
        """add sprite(s) to group

        Group.add(sprite, list, group, ...): return None

        Adds a sprite or sequence of sprites to a group.

        """
        for sprite in sprites:
            # It's possible that some sprite is also an iterator.
            # If this is the case, we should add the sprite itself,
            # and not the iterator object.
            if isinstance(sprite, Sprite):
                if not self.has_internal(sprite):
                    self.add_internal(sprite)
                    sprite.add_internal(self)
            else:
                try:
                    # See if sprite is an iterator, like a list or sprite
                    # group.
                    self.add(*sprite)
                except (TypeError, AttributeError):
                    # Not iterable. This is probably a sprite that is not an
                    # instance of the Sprite class or is not an instance of a
                    # subclass of the Sprite class. Alternately, it could be an
                    # old-style sprite group.
                    if hasattr(sprite, '_spritegroup'):
                        for spr in sprite.sprites():
                            if not self.has_internal(spr):
                                self.add_internal(spr)
                                spr.add_internal(self)
                    elif not self.has_internal(sprite):
                        self.add_internal(sprite)
                        sprite.add_internal(self)

    def remove(self, *sprites):
        """remove sprite(s) from group

        Group.remove(sprite, list, or group, ...): return None

        Removes a sprite or sequence of sprites from a group.

        """
        # This function behaves essentially the same as Group.add. It first
        # tries to handle each argument as an instance of the Sprite class. If
        # that failes, then it tries to handle the argument as an iterable
        # object. If that failes, then it tries to handle the argument as an
        # old-style sprite group. Lastly, if that fails, it assumes that the
        # normal Sprite methods should be used.
        for sprite in sprites:
            if isinstance(sprite, Sprite):
                if self.has_internal(sprite):
                    self.remove_internal(sprite)
                    sprite.remove_internal(self)
            else:
                try:
                    self.remove(*sprite)
                except (TypeError, AttributeError):
                    if hasattr(sprite, '_spritegroup'):
                        for spr in sprite.sprites():
                            if self.has_internal(spr):
                                self.remove_internal(spr)
                                spr.remove_internal(self)
                    elif self.has_internal(sprite):
                        self.remove_internal(sprite)
                        sprite.remove_internal(self)

    def has(self, *sprites):
        """ask if group has a sprite or sprites

        Group.has(sprite or group, ...): return bool

        Returns True if the given sprite or sprites are contained in the
        group. Alternatively, you can get the same information using the
        'in' operator, e.g. 'sprite in group', 'subgroup in group'.

        """
        return_value = False

        for sprite in sprites:
            if isinstance(sprite, Sprite):
                # Check for Sprite instance's membership in this group
                if self.has_internal(sprite):
                    return_value = True
                else:
                    return False
            else:
                try:
                    if self.has(*sprite):
                        return_value = True
                    else:
                        return False
                except (TypeError, AttributeError):
                    if hasattr(sprite, '_spritegroup'):
                        for spr in sprite.sprites():
                            if self.has_internal(spr):
                                return_value = True
                            else:
                                return False
                    else:
                        if self.has_internal(sprite):
                            return_value = True
                        else:
                            return False

        return return_value

    def update(self, *args):
        """call the update method of every member sprite

        Group.update(*args): return None

        Calls the update method of every member sprite. All arguments that
        were passed to this method are passed to the Sprite update function.

        """
        for s in self.sprites():
            s.update(*args)

    def draw(self, surface):
        """draw all sprites onto the surface

        Group.draw(surface): return None

        Draws all of the member sprites onto the given surface.

        """
        sprites = self.sprites()
        surface_blit = surface.blit
        for spr in sprites:
            if (hasattr(spr, 'draw')):
                self.spritedict[spr] = spr.draw(surface)
            else:
                self.spritedict[spr] = surface_blit(spr.image, spr.rect)
        self.lostsprites = []

    def clear(self, surface, bgd):
        """erase the previous position of all sprites

        Group.clear(surface, bgd): return None

        Clears the area under every drawn sprite in the group. The bgd
        argument should be Surface which is the same dimensions as the
        screen surface. The bgd could also be a function which accepts
        the given surface and the area to be cleared as arguments.

        """
        if callable(bgd):
            for r in self.lostsprites:
                bgd(surface, r)
            for r in self.spritedict.values():
                if r is not 0:
                    bgd(surface, r)
        else:
            surface_blit = surface.blit
            for r in self.lostsprites:
                surface_blit(bgd, r, r)
            for r in self.spritedict.values():
                if r is not 0:
                    surface_blit(bgd, r, r)

    def empty(self):
        """remove all sprites

        Group.empty(): return None

        Removes all the sprites from the group.

        """
        for s in self.sprites():
            self.remove_internal(s)
            s.remove_internal(self)

    def __nonzero__(self):
        return truth(self.sprites())

    def __len__(self):
        """return number of sprites in group

        Group.len(group): return int

        Returns the number of sprites contained in the group.

        """
        return len(self.sprites())

    def __repr__(self):
        return "<%s(%d sprites)>" % (self.__class__.__name__, len(self))

class Group(AbstractGroup):
    """container class for many Sprites

    pygame.sprite.Group(*sprites): return Group

    A simple container for Sprite objects. This class can be subclassed to
    create containers with more specific behaviors. The constructor takes any
    number of Sprite arguments to add to the Group. The group supports the
    following standard Python operations:

        in      test if a Sprite is contained
        len     the number of Sprites contained
        bool    test if any Sprites are contained
        iter    iterate through all the Sprites

    The Sprites in the Group are not ordered, so the Sprites are drawn and
    iterated over in no particular order.

    """
    def __init__(self, *sprites):
        AbstractGroup.__init__(self)
        self.add(*sprites)

RenderPlain = Group
RenderClear = Group
<|endoftext|>


<commit_before>from django.contrib import admin
from .models import Post, Comment

# Register your models here.

class PostAdmin(admin.ModelAdmin):
    search_fields = ["title"]
    display_fields = ["title", "created"]

class CommentAdmin(admin.ModelAdmin):
    display_fields = ["post", "author", "created"]

admin.site.register(Post, PostAdmin)
admin.site.register(Comment, CommentAdmin)
<commit_msg>Commit of group imports<commit_after>from django.contrib import admin

from .models import Post, Comment

# Register your models here.

class PostAdmin(admin.ModelAdmin):
    search_fields = ["title"]
    display_fields = ["title", "created"]

class CommentAdmin(admin.ModelAdmin):
    display_fields = ["post", "author", "created"]

admin.site.register(Post, PostAdmin)
admin.site.register(Comment, CommentAdmin)
<|endoftext|>


<commit_before>from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import Group
from onadata.apps.viewer.models.parsed_instance import dict_for_mongo, _encode_for_mongo, xform_instances
from django.conf import settings
from onadata.apps.fsforms.models import FInstance, FieldSightParsedInstance
import json
class Command(BaseCommand):
    help = 'Create default groups'
# {27694: 58651, 27695: 58663, 27697: 58664, 27701: 58651, 29877: 23866, 29878: 23866, 29881: 23866, 29831: 23896, 29834: 23896, 29837: 23896, 29839: 23896, 29841: 23896, 29843: 23896, 29845: 23896, 29847: 23896, 29850: 23900, 29851: 23900, 29854: 23900, 29857: 23900, 29858: 23900, 29861: 23900, 29862: 23900, 29863: 23900, 29866: 23866, 29868: 23866, 29870: 23866, 29873: 23866, 29874: 23866, 29363: 26646, 29364: 26646, 29365: 26646, 29366: 26646, 29367: 26646, 29368: 26646, 29369: 26646, 29370: 26646, 29371: 26646, 29372: 26646, 29373: 26640, 29374: 26640, 29375: 26640, 29376: 26640, 29377: 26640, 29378: 26640, 29379: 26640, 29380: 26640, 29381: 26630, 29382: 26630, 29383: 26566, 29384: 26566, 29385: 26566, 29386: 26566, 29387: 26566, 29388: 26566, 29389: 26566, 29390: 26566, 29391: 26566, 28455: 24040, 28457: 24040, 28460: 24040, 28464: 24040, 28468: 24040, 28479: 24040, 28488: 24040, 28489: 24040, 28490: 24040, 28491: 24040, 28524: 23777, 28525: 23777, 28526: 23777, 28527: 23777, 28528: 23777, 28529: 23777, 28530: 23777, 28531: 24043, 28532: 24043, 28533: 24043, 28534: 24043, 28535: 24043, 28537: 24043, 28538: 24043, 28540: 24043, 28545: 23772, 28546: 23772, 28547: 23772, 28548: 23772, 28549: 23771, 28551: 23771, 28552: 23771, 28553: 23771, 28554: 23771, 28555: 23771, 28556: 23771, 28557: 23771, 28558: 24040, 28559: 24040, 28563: 23777, 12262: 9025}

# {27694: 58651, 27695: 58663, 27697: 58664, 27701: 58651, 29877: 23866, 29878: 23866, 29881: 23866, 29831: 23896, 29834: 23896, 29837: 23896, 29839: 23896, 29841: 23896, 29843: 23896, 29845: 23896, 29847: 23896, 29850: 23900, 29851: 23900, 29854: 23900, 29857: 23900, 29858: 23900, 29861: 23900, 29862: 23900, 29863: 23900, 29866: 23866, 29868: 23866, 29870: 23866, 29873: 23866, 29874: 23866, 29363: 26646, 29364: 26646, 29365: 26646, 29366: 26646, 29367: 26646, 29368: 26646, 29369: 26646, 29370: 26646, 29371: 26646, 29372: 26646, 29373: 26640, 29374: 26640, 29375: 26640, 29376: 26640, 29377: 26640, 29378: 26640, 29379: 26640, 29380: 26640, 29381: 26630, 29382: 26630, 29383: 26566, 29384: 26566, 29385: 26566, 29386: 26566, 29387: 26566, 29388: 26566, 29389: 26566, 29390: 26566, 29391: 26566, 28455: 24040, 28457: 24040, 28460: 24040, 28464: 24040, 28468: 24040, 28479: 24040, 28488: 24040, 28489: 24040, 28490: 24040, 28491: 24040, 28524: 23777, 28525: 23777, 28526: 23777, 28527: 23777, 28528: 23777, 28529: 23777, 28530: 23777, 28531: 24043, 28532: 24043, 28533: 24043, 28534: 24043, 28535: 24043, 28537: 24043, 28538: 24043, 28540: 24043, 28545: 23772, 28546: 23772, 28547: 23772, 28548: 23772, 28549: 23771, 28551: 23771, 28552: 23771, 28553: 23771, 28554: 23771, 28555: 23771, 28556: 23771, 28557: 23771, 28558: 24040, 28559: 24040, 28563: 23777, 12262: 9025}

    # def handle(self, *args, **options):
    #     f=FInstance.objects.filter(project_fxf__is_staged=True, site_fxf=None, site=None).values_list('instance', flat=True)
    #     fm =list(settings.MONGO_DB.instances.find({ "_id": { "$in": list(f) } }, {"fs_site":1, "_id":1}))

    #     data_dict = {27694: 58651, 27695: 58663, 27697: 58664, 27701: 58651, 29877: 23866, 29878: 23866, 29881: 23866, 29831: 23896, 29834: 23896, 29837: 23896, 29839: 23896, 29841: 23896, 29843: 23896, 29845: 23896, 29847: 23896, 29850: 23900, 29851: 23900, 29854: 23900, 29857: 23900, 29858: 23900, 29861: 23900, 29862: 23900, 29863: 23900, 29866: 23866, 29868: 23866, 29870: 23866, 29873: 23866, 29874: 23866, 29363: 26646, 29364: 26646, 29365: 26646, 29366: 26646, 29367: 26646, 29368: 26646, 29369: 26646, 29370: 26646, 29371: 26646, 29372: 26646, 29373: 26640, 29374: 26640, 29375: 26640, 29376: 26640, 29377: 26640, 29378: 26640, 29379: 26640, 29380: 26640, 29381: 26630, 29382: 26630, 29383: 26566, 29384: 26566, 29385: 26566, 29386: 26566, 29387: 26566, 29388: 26566, 29389: 26566, 29390: 26566, 29391: 26566, 28455: 24040, 28457: 24040, 28460: 24040, 28464: 24040, 28468: 24040, 28479: 24040, 28488: 24040, 28489: 24040, 28490: 24040, 28491: 24040, 28524: 23777, 28525: 23777, 28526: 23777, 28527: 23777, 28528: 23777, 28529: 23777, 28530: 23777, 28531: 24043, 28532: 24043, 28533: 24043, 28534: 24043, 28535: 24043, 28537: 24043, 28538: 24043, 28540: 24043, 28545: 23772, 28546: 23772, 28547: 23772, 28548: 23772, 28549: 23771, 28551: 23771, 28552: 23771, 28553: 23771, 28554: 23771, 28555: 23771, 28556: 23771, 28557: 23771, 28558: 24040, 28559: 24040, 28563: 23777, 12262: 9025}

    #     for list_data in fm:
    #         data_dict[list_data['_id']] = int(list_data['fs_site'])

    #     finstances=FInstance.objects.filter(project_fxf__is_staged=True, site_fxf=None, site=None)
    #     count = 0
    #     for finstance in finstances:
    #         if finstance.instance_id in data_dict:
    #             count += 1
    #             site_id = data_dict[finstance.instance_id]
    #             site_fxf = finstance.project_fxf.parent.filter(site_id=site_id)[0]

    #             finstance.site_id=site_id
    #             finstance.site_fxf_id = site_fxf
    #             finstance.save()
    #             print str(site_id) + ", " + str(finstance.instance_id)  +", "+ str(site_fxf.id) + "," + finstance.submitted_by.first_name +" "+ finstance.submitted_by.last_name

    #             print count
    #             settings.MONGO_DB.instances.find({ "_id": { "$in": list(f) } }, {"fs_site":1, "_id":1})

    #     import pdb; pdb.set_trace()

    def handle(self, *args, **options):
        f=FInstance.objects.filter(date__range=["2018-4-10","2018-5-10"]).values_list('instance', flat=True)
        fm =list(settings.MONGO_DB.instances.find({ "_id": { "$in": list(f) } }, {"_id":1}))
        data = [id['_id'] for id in fm]

        data2 =[item for item in f if item not in data ]
        fm2 =list(settings.MONGO_DB.instances.find({ "_id": { "$in": list(data2) } }, {"_submission_time":1}))
        nf=FInstance.objects.filter(instance_id__in=data2)
        change_ids ={}
        for fi in nf:
            change_ids[fi.instance_id] = fi.instance_id
            print fi.instance_id

            # if fi.fsxfid is None:
            #     fsxfid = ""

            # if fi.site is None:
            #     site_id = ""
            # else:
            #     site_id =fi.site_id

            # if fi.project_fxf in None:
            #     project_fxf_id = ""
            # else:
            #     project_fxf_id=fi.project_fxf_id

            # if fi.project is None:
            #     project_id = fi.project_id
            # else:
            #     project_id = fi.project_id

            # FieldSightParsedInstance.get_or_create(instance, update_data={'fs_uuid': fxid, 'fs_status': 0,
            #                                                               'fs_site':site_id, 'fs_project':project_id,
            #                                                               'fs_project_uuid':project_fxf_id})
        print change_ids
        # for list_data in fm:
        #     data_dict[list_data['_id']] = int(list_data['fs_site'])

        # finstances=FInstance.objects.filter(project_fxf__is_staged=True, site_fxf=None, site=None)
        # count = 0
        # for k,v in data_dict.items():
        #     fi = FInstance.objects.get(instance_id=k)
        #     print fi.instance_id

        #     print count
        #     settings.MONGO_DB.instances.update({ "_id": k }, { "$set": { "fs_uuid": fi.site_fxf_id } })

        import pdb; pdb.set_trace()<commit_msg>updated formec2<commit_after>from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import Group
from onadata.apps.viewer.models.parsed_instance import dict_for_mongo, _encode_for_mongo, xform_instances
from django.conf import settings
from onadata.apps.fsforms.models import FInstance, FieldSightParsedInstance
import json
class Command(BaseCommand):
    help = 'Create default groups'
# 21265
# 21267
# 21268
# 21269
# 21270
# 21271
# 21272
# 21273
# 21274
# 21275
# 21276
# 21277
# 21278
# 21279
# 21280
# 21282
# 21286
# 21287
# 21288
# 21289
# 21290
# 21291
# 21292
# 21293
# 21294
# 21295
# 21296
# 21297
# 21298
# 21299
# 21300
# 21301
# 21302
# 21303
# 21304
# 21305
# 21306
# 21307
# 21308
# 21309
# 21310
# 21311
# 21312
# 21313
# 21314
# 21316
# 21317
# 21318
# 21319
# 21320
# 21321
# 21322
# 21323
# 21324
# 21325
# 21326
# 21327
# 21328
# 21329
# 21330

    def handle(self, *args, **options):
        f=FInstance.objects.filter(date__range=["2018-4-10","2018-5-10"]).values_list('instance', flat=True)
        fm =list(settings.MONGO_DB.instances.find({ "_id": { "$in": list(f) } }, {"_id":1}))
        data = [id['_id'] for id in fm]

        data2 =[item for item in f if item not in data ]
        fm2 =list(settings.MONGO_DB.instances.find({ "_id": { "$in": list(data2) } }, {"_submission_time":1}))
        nf=FInstance.objects.filter(instance_id__in=data2)
        change_ids ={}
        for fi in nf:
            change_ids[fi.instance_id] = fi.instance_id
            print fi.instance_id

            if fi.site is None:
                site_id = ""
            else:
                site_id =fi.site_id

            if fi.project_fxf is None:
                project_fxf_id = ""
            else:
                project_fxf_id=fi.project_fxf_id

            if fi.project is None:
                project_id = ""
            else:
                project_id = fi.project_id

            if fi.site_fxf is None:
                site_fxf_id = ""
            else:
                site_fxf_id = fi.site_fxf_id

            FieldSightParsedInstance.get_or_create(instance, update_data={'fs_uuid': site_fxf_id, 'fs_status': 0,
                                                                          'fs_site':site_id, 'fs_project':project_id,
                                                                          'fs_project_uuid':project_fxf_id})

        # for list_data in fm:
        #     data_dict[list_data['_id']] = int(list_data['fs_site'])

        # finstances=FInstance.objects.filter(project_fxf__is_staged=True, site_fxf=None, site=None)
        # count = 0
        # for k,v in data_dict.items():
        #     fi = FInstance.objects.get(instance_id=k)
        #     print fi.instance_id

        #     print count
        #     settings.MONGO_DB.instances.update({ "_id": k }, { "$set": { "fs_uuid": fi.site_fxf_id } })

        import pdb; pdb.set_trace()<|endoftext|>


<commit_before>#  -*- coding: utf-8 -*-
#  vim: tabstop=4 shiftwidth=4 softtabstop=4

#  Copyright (c) 2017, GEM Foundation

#  OpenQuake is free software: you can redistribute it and/or modify it
#  under the terms of the GNU Affero General Public License as published
#  by the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.

#  OpenQuake is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Affero General Public License for more details.

#  You should have received a copy of the GNU Affero General Public License
#  along with OpenQuake.  If not, see <http://www.gnu.org/licenses/>.

import time
import unittest
import multiprocessing
from openquake.baselib import config
from openquake.baselib.workerpool import WorkerMaster, streamer
from openquake.baselib.parallel import Starmap
from openquake.baselib.general import _get_free_port
from openquake.baselib.performance import Monitor

def double(x, mon):
    return 2 * x

def unpickle(smap):
    for res, exc, mon in smap:
        yield res.unpickle()

class WorkerPoolTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.z = config.zworkers.copy()
        dic = dict(master_host='127.0.0.1',
                   task_in_port=_get_free_port(),
                   task_out_port=_get_free_port(),
                   receiver_ports=_get_free_port())
        config.zworkers.update(dic)
        ctrl_port = _get_free_port()
        host_cores = '127.0.0.1 4'
        cls.master = WorkerMaster(
            dic['master_host'], dic['task_in_port'], dic['task_out_port'],
            ctrl_port, host_cores)
        cls.proc = multiprocessing.Process(
            target=streamer, args=(dic['master_host'], dic['task_in_port'],
                                   dic['task_out_port']))
        cls.proc.start()
        cls.master.start()

    def test(self):
        mon = Monitor()
        iterargs = ((i, mon) for i in range(10))
        smap = Starmap(double, iterargs, distribute='zmq')
        self.assertEqual(sum(res for res in smap), 90)
        # sum[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

    def test_status(self):
        time.sleep(1)  # wait a bit for the workerpool to start
        self.assertEqual(self.master.status(), [('127.0.0.1', 'running')])

    @classmethod
    def tearDownClass(cls):
        cls.master.stop()
        cls.proc.terminate()
        config.zworkers = cls.z
<commit_msg>Removed dead code [skip CI]<commit_after>#  -*- coding: utf-8 -*-
#  vim: tabstop=4 shiftwidth=4 softtabstop=4

#  Copyright (c) 2017, GEM Foundation

#  OpenQuake is free software: you can redistribute it and/or modify it
#  under the terms of the GNU Affero General Public License as published
#  by the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.

#  OpenQuake is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Affero General Public License for more details.

#  You should have received a copy of the GNU Affero General Public License
#  along with OpenQuake.  If not, see <http://www.gnu.org/licenses/>.

import time
import unittest
import multiprocessing
from openquake.baselib import config
from openquake.baselib.workerpool import WorkerMaster, streamer
from openquake.baselib.parallel import Starmap
from openquake.baselib.general import _get_free_port
from openquake.baselib.performance import Monitor

def double(x, mon):
    return 2 * x

class WorkerPoolTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.z = config.zworkers.copy()
        dic = dict(master_host='127.0.0.1',
                   task_in_port=_get_free_port(),
                   task_out_port=_get_free_port(),
                   receiver_ports=_get_free_port())
        config.zworkers.update(dic)
        ctrl_port = _get_free_port()
        host_cores = '127.0.0.1 4'
        cls.master = WorkerMaster(
            dic['master_host'], dic['task_in_port'], dic['task_out_port'],
            ctrl_port, host_cores)
        cls.proc = multiprocessing.Process(
            target=streamer, args=(dic['master_host'], dic['task_in_port'],
                                   dic['task_out_port']))
        cls.proc.start()
        cls.master.start()

    def test(self):
        mon = Monitor()
        iterargs = ((i, mon) for i in range(10))
        smap = Starmap(double, iterargs, distribute='zmq')
        self.assertEqual(sum(res for res in smap), 90)
        # sum[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

    def test_status(self):
        time.sleep(1)  # wait a bit for the workerpool to start
        self.assertEqual(self.master.status(), [('127.0.0.1', 'running')])

    @classmethod
    def tearDownClass(cls):
        cls.master.stop()
        cls.proc.terminate()
        config.zworkers = cls.z
<|endoftext|>


<commit_before>import os, re
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
pd.options.display.mpl_style = 'default'
import plotly.plotly as py
from plotly.graph_objs import *
from itertools import groupby
from io.utils import nest_dict, RecursiveDict
from config import mp_level01_titles
from utils import Author, get_short_object_id, unflatten_dict

class MPContributionsBuilder():
    """build user contributions from `mpcontribs.contributions`"""
    def __init__(self, db):
        self.mp_id_pattern = re.compile('mp-\d+', re.IGNORECASE)
        self.db = db
        if isinstance(self.db, dict):
            self.mat_coll = RecursiveDict()
            self.comp_coll = RecursiveDict()
        else:
            self.mat_coll = db.materials
            self.comp_coll = db.compositions

    @classmethod
    def from_config(cls, db_yaml='mpcontribs_db.yaml'):
        from monty.serialization import loadfn
        from pymongo import MongoClient
        config = loadfn(os.path.join(os.environ['DB_LOC'], db_yaml))
        client = MongoClient(config['host'], config['port'], j=False)
        db = client[config['db']]
        db.authenticate(config['username'], config['password'])
        return MPContributionsBuilder(db)

    def plot(self, contributor_email, contrib):
        """make all plots for contribution"""
        if not any([
          key.startswith(mp_level01_titles[1]+'_') for key in contrib['content']
        ]): return None
        author = Author.parse_author(contributor_email)
        project = str(author.name).translate(None, '.').replace(' ','_') \
                if 'project' not in contrib else contrib['project']
        cid = str(contrib['_id'])
        subfld = '{}.{}.plotly_urls'.format(project, cid)
        url_list = [] if isinstance(self.db, dict) else list(self.curr_coll.find(
            {subfld: {'$exists': True}}, {subfld: 1}
        ))
        urls = url_list[0][project][cid]['plotly_urls'] if len(url_list) else []
        for nplot,plotopts in enumerate(contrib['content']['plots'].itervalues()):
            filename = '{}_{}_{}'.format(
                ('viewer' if isinstance(self.db, dict) else 'mp'), cid, nplot)
            fig, ax = plt.subplots(1, 1)
            table_name = plotopts.pop('table')
            data = contrib['content'][table_name]
            df = pd.DataFrame.from_dict(data)
            df.plot(ax=ax, **plotopts)
            if len(urls) == len(contrib['content']['plots']):
                pyfig = py.get_figure(urls[nplot])
                for ti,line in enumerate(ax.get_lines()):
                    pyfig['data'][ti]['x'] = list(line.get_xdata())
                    pyfig['data'][ti]['y'] = list(line.get_ydata())
                py.plot(pyfig, filename=filename, auto_open=False)
            else:
                update = dict(layout=dict(
                    annotations=[dict(text=' ')],
                    showlegend=True,
                    legend=Legend(x=1.05, y=1)
                ))
                urls.append(py.plot_mpl(
                    fig, filename=filename, auto_open=False,
                    strip_style=True, update=update, resize=True
                ))
        plotly_urls = RecursiveDict({subfld: urls})
        return None if len(url_list) else plotly_urls

    def delete(self, project, cids):
        for contrib in self.db.contributions.find({'_id': {'$in': cids}}):
            mp_cat_id, cid = contrib['mp_cat_id'], contrib['_id']
            is_mp_id = self.mp_id_pattern.match(mp_cat_id)
            coll = self.mat_coll if is_mp_id else self.comp_coll
            key = '.'.join([project, str(cid)])
            coll.update({}, {'$unset': {key: 1}}, multi=True)
        # remove `project` field when no contributions remaining
        for coll in [self.mat_coll, self.comp_coll]:
            for doc in coll.find({project: {'$exists': 1}}):
                for d in doc.itervalues():
                    if not d:
                        coll.update({'_id': doc['_id']}, {'$unset': {project: 1}})

    def find_contribution(self, cid):
        if isinstance(self.db, dict): return self.db
        else: return self.db.contributions.find_one({'_id': cid})

    def build(self, contributor_email, cid):
        """update materials/compositions collections with contributed data"""
        cid_short, cid_str = get_short_object_id(cid), str(cid)
        contrib = self.find_contribution(cid)
        mp_cat_id = contrib['mp_cat_id']
        is_mp_id = self.mp_id_pattern.match(mp_cat_id)
        self.curr_coll = self.mat_coll if is_mp_id else self.comp_coll
        if contributor_email not in contrib['collaborators']: raise ValueError(
            "Build stopped: building contribution {} not "
            "allowed due to insufficient permissions of {}! Ask "
            "someone of {} to make you a collaborator on {}.".format(
                cid_short, contributor_email, contrib['collaborators'], cid_short))
        author = Author.parse_author(contributor_email)
        project = str(author.name).translate(None, '.').replace(' ','_') \
                if 'project' not in contrib else contrib['project']
        # prepare tree and table data
        all_data = RecursiveDict()
        for key,value in contrib['content'].iteritems():
            if key == 'plots' or key.startswith(mp_level01_titles[1]+'_'): continue
            all_data.rec_update(nest_dict(
                value, ['{}.{}.tree_data'.format(project, cid_str), key]
            ))
        if 'plots' in contrib['content']:
            # TODO also include non-default tables (multiple tables support)
            table_columns, table_rows = None, None
            table_name = contrib['content']['plots']['default']['table']
            raw_data = contrib['content'][table_name]
            if isinstance(raw_data, dict):
                table_columns = [ { 'title': k } for k in raw_data ]
                table_rows = [
                    [ str(raw_data[d['title']][row_index]) for d in table_columns ]
                    for row_index in xrange(len(
                        raw_data[table_columns[0]['title']]
                    ))
                ]
            elif isinstance(raw_data, list):
                table_columns = [ { 'title': k } for k in raw_data[0] ]
                table_rows = [
                    [ str(row[d['title']]) for d in table_columns ]
                    for row in raw_data
                ]
            if table_columns is not None:
                all_data.rec_update({
                    '{}.{}.tables.columns'.format(project, cid_str): table_columns,
                    '{}.{}.tables.rows'.format(project, cid_str): table_rows,
                })
        # update collection with tree and table data
        if isinstance(self.db, dict):
            unflatten_dict(all_data)
            self.curr_coll.rec_update(nest_dict(all_data, [mp_cat_id]))
        else:
            self.curr_coll.update({'_id': mp_cat_id}, {'$set': all_data}, upsert=True)
        # interactive graphs
        plotly_urls = self.plot(contributor_email, contrib)
        if plotly_urls is not None:
            if isinstance(self.db, dict):
                unflatten_dict(plotly_urls)
                self.curr_coll.rec_update(nest_dict(plotly_urls, [mp_cat_id]))
            else:
                self.curr_coll.update({'_id': mp_cat_id}, {'$set': plotly_urls})
        if isinstance(self.db, dict):
            return self.curr_coll
        else:
            return '{}/{}/contributions/{}'.format( # return URL for contribution page
                ('materials' if is_mp_id else 'compositions'),
                mp_cat_id, cid_short) # TODO: implement on frontend, short cid sufficient?
<commit_msg>builders: fix URL for contribution page<commit_after>import os, re
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
pd.options.display.mpl_style = 'default'
import plotly.plotly as py
from plotly.graph_objs import *
from itertools import groupby
from io.utils import nest_dict, RecursiveDict
from config import mp_level01_titles
from utils import Author, get_short_object_id, unflatten_dict

class MPContributionsBuilder():
    """build user contributions from `mpcontribs.contributions`"""
    def __init__(self, db):
        self.mp_id_pattern = re.compile('mp-\d+', re.IGNORECASE)
        self.db = db
        if isinstance(self.db, dict):
            self.mat_coll = RecursiveDict()
            self.comp_coll = RecursiveDict()
        else:
            self.mat_coll = db.materials
            self.comp_coll = db.compositions

    @classmethod
    def from_config(cls, db_yaml='mpcontribs_db.yaml'):
        from monty.serialization import loadfn
        from pymongo import MongoClient
        config = loadfn(os.path.join(os.environ['DB_LOC'], db_yaml))
        client = MongoClient(config['host'], config['port'], j=False)
        db = client[config['db']]
        db.authenticate(config['username'], config['password'])
        return MPContributionsBuilder(db)

    def plot(self, contributor_email, contrib):
        """make all plots for contribution"""
        if not any([
          key.startswith(mp_level01_titles[1]+'_') for key in contrib['content']
        ]): return None
        author = Author.parse_author(contributor_email)
        project = str(author.name).translate(None, '.').replace(' ','_') \
                if 'project' not in contrib else contrib['project']
        cid = str(contrib['_id'])
        subfld = '{}.{}.plotly_urls'.format(project, cid)
        url_list = [] if isinstance(self.db, dict) else list(self.curr_coll.find(
            {subfld: {'$exists': True}}, {subfld: 1}
        ))
        urls = url_list[0][project][cid]['plotly_urls'] if len(url_list) else []
        for nplot,plotopts in enumerate(contrib['content']['plots'].itervalues()):
            filename = '{}_{}_{}'.format(
                ('viewer' if isinstance(self.db, dict) else 'mp'), cid, nplot)
            fig, ax = plt.subplots(1, 1)
            table_name = plotopts.pop('table')
            data = contrib['content'][table_name]
            df = pd.DataFrame.from_dict(data)
            df.plot(ax=ax, **plotopts)
            if len(urls) == len(contrib['content']['plots']):
                pyfig = py.get_figure(urls[nplot])
                for ti,line in enumerate(ax.get_lines()):
                    pyfig['data'][ti]['x'] = list(line.get_xdata())
                    pyfig['data'][ti]['y'] = list(line.get_ydata())
                py.plot(pyfig, filename=filename, auto_open=False)
            else:
                update = dict(layout=dict(
                    annotations=[dict(text=' ')],
                    showlegend=True,
                    legend=Legend(x=1.05, y=1)
                ))
                urls.append(py.plot_mpl(
                    fig, filename=filename, auto_open=False,
                    strip_style=True, update=update, resize=True
                ))
        plotly_urls = RecursiveDict({subfld: urls})
        return None if len(url_list) else plotly_urls

    def delete(self, project, cids):
        for contrib in self.db.contributions.find({'_id': {'$in': cids}}):
            mp_cat_id, cid = contrib['mp_cat_id'], contrib['_id']
            is_mp_id = self.mp_id_pattern.match(mp_cat_id)
            coll = self.mat_coll if is_mp_id else self.comp_coll
            key = '.'.join([project, str(cid)])
            coll.update({}, {'$unset': {key: 1}}, multi=True)
        # remove `project` field when no contributions remaining
        for coll in [self.mat_coll, self.comp_coll]:
            for doc in coll.find({project: {'$exists': 1}}):
                for d in doc.itervalues():
                    if not d:
                        coll.update({'_id': doc['_id']}, {'$unset': {project: 1}})

    def find_contribution(self, cid):
        if isinstance(self.db, dict): return self.db
        else: return self.db.contributions.find_one({'_id': cid})

    def build(self, contributor_email, cid):
        """update materials/compositions collections with contributed data"""
        cid_short, cid_str = get_short_object_id(cid), str(cid)
        contrib = self.find_contribution(cid)
        mp_cat_id = contrib['mp_cat_id']
        is_mp_id = self.mp_id_pattern.match(mp_cat_id)
        self.curr_coll = self.mat_coll if is_mp_id else self.comp_coll
        if contributor_email not in contrib['collaborators']: raise ValueError(
            "Build stopped: building contribution {} not "
            "allowed due to insufficient permissions of {}! Ask "
            "someone of {} to make you a collaborator on {}.".format(
                cid_short, contributor_email, contrib['collaborators'], cid_short))
        author = Author.parse_author(contributor_email)
        project = str(author.name).translate(None, '.').replace(' ','_') \
                if 'project' not in contrib else contrib['project']
        # prepare tree and table data
        all_data = RecursiveDict()
        for key,value in contrib['content'].iteritems():
            if key == 'plots' or key.startswith(mp_level01_titles[1]+'_'): continue
            all_data.rec_update(nest_dict(
                value, ['{}.{}.tree_data'.format(project, cid_str), key]
            ))
        if 'plots' in contrib['content']:
            # TODO also include non-default tables (multiple tables support)
            table_columns, table_rows = None, None
            table_name = contrib['content']['plots']['default']['table']
            raw_data = contrib['content'][table_name]
            if isinstance(raw_data, dict):
                table_columns = [ { 'title': k } for k in raw_data ]
                table_rows = [
                    [ str(raw_data[d['title']][row_index]) for d in table_columns ]
                    for row_index in xrange(len(
                        raw_data[table_columns[0]['title']]
                    ))
                ]
            elif isinstance(raw_data, list):
                table_columns = [ { 'title': k } for k in raw_data[0] ]
                table_rows = [
                    [ str(row[d['title']]) for d in table_columns ]
                    for row in raw_data
                ]
            if table_columns is not None:
                all_data.rec_update({
                    '{}.{}.tables.columns'.format(project, cid_str): table_columns,
                    '{}.{}.tables.rows'.format(project, cid_str): table_rows,
                })
        # update collection with tree and table data
        if isinstance(self.db, dict):
            unflatten_dict(all_data)
            self.curr_coll.rec_update(nest_dict(all_data, [mp_cat_id]))
        else:
            self.curr_coll.update({'_id': mp_cat_id}, {'$set': all_data}, upsert=True)
        # interactive graphs
        plotly_urls = self.plot(contributor_email, contrib)
        if plotly_urls is not None:
            if isinstance(self.db, dict):
                unflatten_dict(plotly_urls)
                self.curr_coll.rec_update(nest_dict(plotly_urls, [mp_cat_id]))
            else:
                self.curr_coll.update({'_id': mp_cat_id}, {'$set': plotly_urls})
        if isinstance(self.db, dict):
            return self.curr_coll
        else:
            return '{}/{}/contributions#{}#{}'.format( # return URL for contribution page
                ('materials' if is_mp_id else 'compositions'),
                mp_cat_id, project, cid_short)
<|endoftext|>