示例#1
0
    def test_deck_61mountains(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        tformat = Format.objects.filter(format='Standard_2015-01-23').first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = tformat

        tdeck.save()

        c1 = Card.objects.filter(multiverseid=1004).first()

        dc1 = DeckCard()
        dc1.physicalcard = c1.basecard.physicalcard
        dc1.deck = tdeck
        dc1.cardcount = 61
        dc1.board = dc1.MAIN
        dc1.save()

        self.assertEquals(tdeck.get_card_count(), 61)

        self.assertTrue(tdeck.is_legal())
示例#2
0
    def test_tcbf(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        mountain = BaseCard.objects.filter(name='Mountain').first().physicalcard
        island = BaseCard.objects.filter(name='Island').first().physicalcard
        formats = Format.objects.filter(formatname='Modern').order_by('-start_date')
        myform = formats[0]
        prev_form = formats[1]

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = myform

        tdeck.save()
        tdeck = Deck.objects.get(pk=tdeck.id)

        dc1 = DeckCard()
        dc1.physicalcard = island
        dc1.deck = tdeck
        dc1.cardcount = 60
        dc1.board = DeckCard.MAIN
        dc1.save()

        self.assertEquals(tdeck.get_card_count(), 60)

        tourny = Tournament(name='Test', url='http://foo.dog/', format=myform, start_date=myform.start_date, end_date=myform.start_date)
        tourny.save()

        td = TournamentDeck(tournament=tourny, deck=tdeck, place=1)
        td.save()

        FormatStat.calc_all()
        FormatCardStat.calc_all()

        fstat = FormatStat.objects.filter(format=myform).first()
        mstat = FormatCardStat.objects.filter(format=myform, physicalcard=mountain).first()
        istat = FormatCardStat.objects.filter(format=myform, physicalcard=island).first()

        cc = FormatCardStat.objects.top_cards_by_format(myform)
        self.assertEquals(cc.count(), 5, "5 cards, the basic lands, are all in this format")
        first_cc = cc.first()
        self.assertEquals(first_cc.physicalcard, island, "Top card in this format is Island")
        self.assertEquals(
            first_cc.previous_format_ids, str(
                prev_form.pk), "The previous format ids on the FormatCardStat object should be the previous format id")
        self.assertIsNone(first_cc.percentage_of_all_cards_previous(), 'None previously, so no number is returned')
        self.assertEquals(
            first_cc.percentage_of_all_cards_delta(),
            1.0,
            'There has been a change that is positive {}'.format(
                first_cc.percentage_of_all_cards_delta()))
        self.assertIsNone(first_cc.percentage_of_all_cards_perchange(), 'None previously, so no number is returned')
示例#3
0
def manabaseanalysis(request):
    context = BASE_CONTEXT.copy()

    context['current_formats'] = Format.objects.filter(start_date__lte=timezone.now(),
                                                       end_date__gt=timezone.now()).order_by('format')
    # REVISIT - unsafe index
    context['format'] = context['current_formats'][0]

    card_list = '''1 Pithing Needle
4 Chromatic Star
1 Ancient Grudge
1 Boil
3 Nature's Claim
3 Pyroclasm
4 Expedition Map
3 Oblivion Stone
4 Sylvan Scrying
4 Ancient Stirrings
1 Relic of Progenitus
4 Wurmcoil Engine
3 Thragtusk
4 Chromatic Sphere
4 Karn Liberated
1 Grafdigger's Cage
2 Ugin, the Spirit Dragon
2 Ulamog, the Ceaseless Hunger
2 Warping Wail
1 Kozilek's Return
1 World Breaker'''

    if 'format' in request.POST:
        for ff in context['current_formats']:
            if request.POST['format'] == ff.format:
                context['format'] = ff
                break
    if 'cardlist' in request.POST:
        card_list = request.POST['cardlist']
    deck_cards = Deck.read_cards_from_text(card_list, throw_exception=False)

    if 'errors' in deck_cards:
        context['errors'] = deck_cards['errors']
    context['card_list'] = list()
    for key in deck_cards:
        if key != 'errors' and isinstance(deck_cards[key], dict) and 'physicalcard' in deck_cards[key]:
            context['card_list'].append('{} {}'.format(deck_cards[key]['card_count'], deck_cards[key]['physicalcard'].get_card_name()))

    analyzer = Analyzer(format=context['format'])
    deck_score_tuples, query = analyzer.analyze(deck_cards)
    context['analysis'] = query
    context['analysis_json'] = json.dumps(query, sort_keys=True, indent=2, cls=DjangoJSONEncoder)
    context['deckcards'] = list()
    if len(deck_score_tuples):
        all_deckcards = DeckCard.objects.filter(deck=deck_score_tuples[0][0])
        context['recommendation_score'] = 1000.0 - deck_score_tuples[0][1]
        for dc in all_deckcards:
            if dc.physicalcard.get_face_basecard().is_land():
                context['deckcards'].append(dc)
    return render(request, 'decks/manabase.html', context)
示例#4
0
    def test_tcbf_2b(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        mountain = BaseCard.objects.filter(name='Mountain').first().physicalcard
        island = BaseCard.objects.filter(name='Island').first().physicalcard
        formats = Format.objects.filter(formatname='Modern').order_by('-start_date')
        myform = formats[0]
        prev_form = formats[1]

        for fformat in [myform, prev_form]:
            tdeck = Deck()
            tdeck.name = 'My Deck Name in {}'.format(fformat.format)
            tdeck.url = 'http://card.ninja/{}'.format(fformat.id)
            tdeck.visibility = tdeck.VISIBLE
            tdeck.authorname = 'Test Dude'
            tdeck.format = fformat

            tdeck.save()
            tdeck = Deck.objects.get(pk=tdeck.id)

            dc1 = DeckCard()
            dc1.physicalcard = island
            dc1.deck = tdeck
            dc1.cardcount = 60
            dc1.board = DeckCard.MAIN
            dc1.save()

            tourny = Tournament(
                name='Test {}'.format(
                    fformat.pk),
                url='http://foo.dog/',
                format=fformat,
                start_date=fformat.start_date,
                end_date=fformat.start_date)
            tourny.save()

            td = TournamentDeck(tournament=tourny, deck=tdeck, place=1)
            td.save()

        FormatStat.calc_all()
        FormatCardStat.calc_all()

        fstat = FormatStat.objects.filter(format=myform).first()
        mstat = FormatCardStat.objects.filter(format=myform, physicalcard=mountain).first()
        istat = FormatCardStat.objects.filter(format=myform, physicalcard=island).first()

        first_cc = istat
        self.assertEquals(first_cc.percentage_of_all_cards_previous(), 1.0, 'All previously, so 100% is returned')
        self.assertEquals(first_cc.percentage_of_all_cards_delta(), 0.0, 'Same as last format, so no delta')
        self.assertEquals(first_cc.percentage_of_all_cards_perchange(), 0.0, 'No change... still 100%')

        self.assertEquals(first_cc.percentage_of_all_cards_previous(format_lookback_days=10), 1.0, 'F All previously, so 100% is returned')
        self.assertEquals(first_cc.percentage_of_all_cards_delta(format_lookback_days=10), 0.0, 'F Same as last format, so no delta')
        self.assertEquals(first_cc.percentage_of_all_cards_perchange(format_lookback_days=10), 0.0, 'F No change... still 100%')
示例#5
0
def validate_master_vault_url(value):
    master_vault_id = Deck.get_id_from_master_vault_url(value)
    try:
        master_vault_id = uuid.UUID(master_vault_id)
    except ValueError:
        raise(ValidationError(
            _('Master vault link is invalid'),
            code='invalid'
        ))
示例#6
0
    def get_or_create(cls, puuid, deck_code):

        account = LorAccount.get_or_create(puuid=puuid)
        deck = Deck.get_or_create(deck_code=deck_code)

        account_deck, _ = AccountDeck.objects.get_or_create(account=account,
                                                            deck=deck)

        return account_deck
示例#7
0
    def test_one_deck(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        island = BaseCard.objects.filter(name='Island').first().physicalcard
        myform = Format.objects.filter(formatname='Modern').order_by('-start_date').first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = myform

        tdeck.save()
        tdeck = Deck.objects.get(pk=tdeck.id)

        dc1 = DeckCard()
        dc1.physicalcard = island
        dc1.deck = tdeck
        dc1.cardcount = 60
        dc1.board = DeckCard.MAIN
        dc1.save()

        self.assertEquals(tdeck.get_card_count(), 60)

        tourny = Tournament(name='Test', url='http://foo.dog/', format=myform, start_date=myform.start_date, end_date=myform.start_date)
        tourny.save()
        #tourny = Tournament.objects.all().first()

        td = TournamentDeck(tournament=tourny, deck=tdeck, place=1)
        td.save()
        #td = TournamentDeck.objects.filter(tournament=tourny, deck=tdeck, place=1).first()

        FormatStat.calc_all()
        FormatCardStat.calc_all()

        fstat = FormatStat.objects.filter(format=myform).first()
        mstat = FormatCardStat.objects.filter(format=myform, physicalcard=island).first()
        dcount = mstat.deck_count
        self.assertEquals(dcount, 1)
        tdcount = fstat.tournamentdeck_count
        self.assertEquals(tdcount, 1)

        tdccount = fstat.tournamentdeckcard_count
        self.assertEquals(tdccount, 60)

        self.assertEquals(mstat.in_decks_percentage(), 100.0)
示例#8
0
    def test_deck_inst(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        tformat = Format.objects.all().first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = tformat

        tdeck.save()

        self.assertEquals(tdeck.format.id, tformat.id)

        c1 = Card.objects.filter(multiverseid=1002).first()
        self.assertEquals(c1.basecard.name, 'Island')

        dc1 = DeckCard()
        dc1.physicalcard = c1.basecard.physicalcard
        dc1.deck = tdeck
        dc1.cardcount = 8
        dc1.board = dc1.MAIN
        dc1.save()

        self.assertEquals(tdeck.get_card_count(), 8)

        c2 = Card.objects.filter(multiverseid=1004).first()
        self.assertEquals(c2.basecard.name, 'Mountain')

        dc2 = DeckCard()
        dc2.physicalcard = c2.basecard.physicalcard
        dc2.deck = tdeck
        dc2.cardcount = 3
        dc2.board = dc2.MAIN
        dc2.save()

        self.assertEquals(tdeck.get_card_count(), 11)
示例#9
0
def ajax_createDeck(request):
    if request.is_ajax():
        get_all_cards = request.POST['cards[]']
        name = request.POST['name']
        deck1 = Deck()
        deck1.name = name
        deck1.user = request.user
        deck1.save()
        arrayGetcountDoublon = []
        for i in json.loads(get_all_cards):
            entry = Deck.objects.get(id=deck1.id)
            insert_cards = Deck_user(card_id=i['card_id'], deck_id=entry.id)
            insert_cards.save()
            arrayGetcountDoublon.append(i['card_id'])

        count_cards = {k: arrayGetcountDoublon.count(k) for k in set(arrayGetcountDoublon)}

        for i in count_cards:
            cccmoi = list(Card_user.objects.filter(card_id=i))

            if count_cards[i] == 1:
                Card_user.objects.filter(user_id=request.user.id, card_id=i).delete()
            else:
                for zizi in range(count_cards[i]):
                    Card_user.objects.filter(user_id=request.user.id, id=cccmoi[zizi].id).delete()

    return HttpResponse('ok')
示例#10
0
    def test_all_decks_as_dict(self):
        """Tests the get_all_decks_as_dict() classmethod of the Deck model."""
        # Get the dict containing all decks
        decks_dict = Deck.get_all_decks_as_dict()

        # Check if the dict is correct
        # Note: The order is important because of the way the models get ordered defined in the Meta class of Deck
        self.assertDictEqual(
            decks_dict, {
                "decks": [{
                    "id": 2,
                    "name": "Second",
                    "official": True
                }, {
                    "id": 1,
                    "name": "First",
                    "official": False
                }]
            }, "get_all_decks_as_dict() doesn't give the right result!")
示例#11
0
def recommendations(request):
    context = BASE_CONTEXT.copy()
    context['current_formats'] = Format.objects.filter(start_date__lte=timezone.now(),
                                                       end_date__gt=timezone.now()).order_by('format')
    # REVISIT - unsafe index
    context['format'] = context['current_formats'][0]

    include_lands = 'exclude_lands' not in request.POST
    context['exclude_lands'] = not include_lands

    pcs = list()
    if 'format' in request.POST:
        for ff in context['current_formats']:
            if request.POST['format'] == ff.format:
                context['format'] = ff
                break
    if 'cardlist' in request.POST:
        try:
            pcs_dict = Deck.read_cards_from_text(request.POST['cardlist'], throw_exception=False)
            for key in pcs_dict:
                if key != 'errors' and 'physicalcard' in pcs_dict[key]:
                    pcs.append(pcs_dict[key]['physicalcard'])
        except Deck.CardsNotFoundException as cnfe:
            pass
        #sys.stderr.write("cardlist is '{}'".format(pcs))
    context['card_list'] = (a.get_card_name() for a in pcs)
    context['seeds'] = (a.get_latest_card() for a in pcs)
    context['recommendations'] = ()
    context['spicy'] = list()
    if len(pcs):
        dcr = Recommender()
        context['recommendations'] = dcr.get_recommended_cards(pcs, context['format'], include_lands=include_lands)

        # get spicy...
        basic_supertype = Supertype.objects.filter(supertype='Basic').first()
        #sys.stderr.write("Basic type is {}\n".format(basic_supertype))
        for tcard in context['recommendations']:
            if basic_supertype in tcard.basecard.types.all():
                # Let's not look up similar cards to Basic lands
                continue

            sims = tcard.basecard.physicalcard.find_similar_cards(max_results=4)
            for sim in sims:
                #sys.stderr.write("%%%% SIM IS {} for {}\n".format(sim, tcard))
                if sim.basecard.physicalcard in pcs:
                    #sys.stderr.write("-- skipping {} for spicy because the user already wants it!\n".format(sim))
                    continue
                # Let's not consider Basic lands as spicy
                if basic_supertype in sim.basecard.supertypes.all():
                    #sys.stderr.write("-- skipping basic land for spicy.\n")
                    continue
                # Let's only recommend cards in the current format
                if FormatBasecard.objects.filter(basecard=sim.basecard, format=context['format']).count() == 0:
                    #sys.stderr.write("-- skipping {} for spicy because it isn't in format.\n".format(sim))
                    continue
                if sim in context['recommendations']:
                    #sys.stderr.write("-- skipping {} for spicy because it is already recommended.\n".format(sim))
                    continue
                if sim in context['spicy']:
                    #sys.stderr.write("-- skipping {} for spicy because it is already spicy!\n".format(sim))
                    continue
                #sys.stderr.write("starting with score of {}\n".format(tcard.annotations['match_confidence']))
                sim.annotations['spicy_score'] = tcard.annotations['match_confidence'] + (sim.annotations['similarity_score'] * 50.0)
                context['spicy'].append(sim)
                break
            if len(context['spicy']) >= 8:
                break
    return render(request, 'decks/recommendations.html', context)
示例#12
0
def add(request):
    error_messages = []

    # Must have all info filled out before registering a field
    user_can_register_decks = request.user.profile.is_complete()

    # Can't register too many decks
    max_uploads_in_day = settings.MAX_UPLOADS_PER_DAY
    twenty_four_hours_ago = datetime.datetime.now() - datetime.timedelta(
        hours=24)

    my_uploads_today = DeckRegistration.objects.filter(
        user=request.user, created_on__gte=twenty_four_hours_ago)
    user_hit_register_rate_limit = len(
        my_uploads_today) > max_uploads_in_day - 1

    if request.method == 'POST':
        form = RegiseterNewDeckForm(request.POST, request.FILES)
        signed_nonce = SignedNonce.from_post(request.POST)
        if not signed_nonce.is_valid():
            error_messages.append(
                'This registration code has expired. Please use submit a new registration using the code below.'
            )
        elif form.is_valid():
            # Process the form...
            master_vault_url = form.cleaned_data['master_vault_link']
            master_vault_id = Deck.get_id_from_master_vault_url(
                master_vault_url)

            deck, created = Deck.objects.get_or_create(id=master_vault_id)
            if created:
                r = get(deck.get_master_vault_api_url())
                deck.name = r.json()['data']['name']
                deck.save()
            else:
                # Only allow the user to have one pending registartion per deck
                old_registrations = DeckRegistration.objects.filter(
                    user=request.user,
                    deck=deck,
                    status=DeckRegistration.Status.PENDING).update(
                        is_archived=True)

            registration = DeckRegistration()
            registration.user = request.user
            registration.deck = deck
            registration.verification_code = signed_nonce.nonce

            try:
                registration.verification_photo_url = save_verification_photo(
                    request, form, deck)
                registration.save()

                email = NewDeckRegistrationSubmittedEmail(registration)
                email.send()

                return HttpResponseRedirect(
                    reverse('register-detail', kwargs={'pk': registration.id}))
            except ClientError:
                error_messages.append("Oops! Let's try that again")
    else:
        form = RegiseterNewDeckForm()

    return render(
        request, 'register/page-new.html', {
            'form': form,
            'signed_nonce': SignedNonce.create(),
            'user_can_register_decks': user_can_register_decks,
            'user_hit_register_rate_limit': user_hit_register_rate_limit,
            'error_messages': error_messages
        })
示例#13
0
    def handle(self, *args, **options):
        #logger = logging.getLogger(__name__)
        # the first (and only) arg should be a filename
        if len(args) < 1:
            sys.stderr.write("No directory name given.\n")
            return
        directory = args[0]
        if not os.access(directory, os.R_OK):
            sys.stderr.write("Cannot read directory '{}'.\n".format(filename))
            return

        onlyfiles = [f for f in listdir(directory) if isfile(join(directory, f))]
        for filename in onlyfiles:
            if filename.find('tournament_') > -1:  # and False: # REVISIT - commented out for the moment!
                filehandler = open(join(directory, filename))
                jblob = json.load(filehandler)
                #{"url": "/en/content/2011-great-britain-national-championship", "tournament_format": null, "name": "Great Britain National Championship", "start_date": "2011-08-19"}
                if jblob['name'].lower().find('test deck') > -1:
                    sys.stdout.write("Tournament: skipped test deck tournament: {}\n".format(jblob['name']))
                    pass
                else:
                    turl = jblob['url']
                    # The StarCityGames tournaments will probably not have a URL at all
                    if turl is None or len(turl) == 0:
                        pass
                    # Some of the Wizards-crawled tournaments will not have a fully-qualified URL
                    elif turl.find('http') < 0:
                        turl = 'http://magic.wizards.com' + turl
                    format_string = jblob['tournament_format']
                    if format_string is None:
                        format_string = 'Unknown'
                    elif format_string.find('Modern') > -1:
                        format_string = 'Modern'
                    elif format_string.find('Standard') > -1:
                        format_string = 'Standard'
                    elif format_string.find('Commander') > -1:
                        format_string = 'Commander'
                    elif format_string.find('Tiny') > -1:
                        format_string = 'TinyLeaders'
                    db_format = Format.objects.filter(
                        formatname=format_string,
                        start_date__lte=self.isodate(jblob['start_date']),
                        end_date__gte=self.isodate(jblob['end_date'])).first()
                    if db_format is not None:
                        db_tournament = Tournament.objects.filter(
                            format=db_format,
                            name=jblob['name'],
                            start_date=self.isodate(jblob['start_date'])).first()
                        if db_tournament is None:
                            # let's make one!
                            db_tournament = Tournament(
                                format=db_format,
                                name=jblob['name'],
                                start_date=self.isodate(jblob['start_date']),
                                end_date=self.isodate(jblob['end_date']),
                                url=turl)
                            db_tournament.save()
                            sys.stdout.write("Tournament: created {}\n".format(jblob['name']))
                        else:
                            if turl.find('/node/') < 0:
                                db_tournament.url = turl
                                sys.stdout.write("Tournament: updated {}\n".format(jblob['name']))
                                db_tournament.save()
                            else:
                                sys.stdout.write("Tournament: skipped updated with node {}\n".format(jblob['name']))
                    else:
                        sys.stdout.write("Tournament: skipped no format '{}' found in db {}\n".format(format_string, jblob['name']))

        tournament_url_re = re.compile('^(.+/coverage/([^/]+))/?')

        # Process the deck files
        for filename in onlyfiles:
            if filename.find('deck_') > -1:
                ###fqfilename = join(directory, filename)
                # print "last modified: %s" % time.ctime(getmtime(fqfilename))
                # REVISIT - nothing processes because I was working on only processing the mostrecent files...
                # continue
                filehandler = open(join(directory, filename))
                jblob = json.load(filehandler)

                # let's test if jblob is a set JSON
                if 'name' in jblob and 'mainboard_cards' in jblob:
                    tourna = None
                    # let's deal with decks that have valid tournament URLs
                    if 'tournament_url' in jblob and jblob['tournament_url'] is not None and len(jblob['tournament_url']) > 0:
                        # We are going to skip decks and tournaments that look like draft and sealed
                        if jblob['tournament_url'].find('draft') > 0 or jblob['tournament_url'].find('sealed') > 0:
                            # skip
                            sys.stdout.write("Deck: skipped limited {}\n".format(jblob['name']))
                            continue

                        # now find the tournament
                        tu_match = tournament_url_re.search(jblob['tournament_url'])
                        tournament_url = jblob['tournament_url']
                        tournament_name = ''
                        if tu_match:
                            tournament_url = tu_match.group(1)
                            tournament_name = tu_match.group(2)
                        # find a real tournament that we match to
                        sys.stdout.write("HERE with '{}' and '{}'\n".format(tournament_url, tournament_name))
                        tourna = Tournament.objects.filter(url=tournament_url).first()  # exclude(format__formatname='Unknown').first()
                    elif 'tournament_name' in jblob and 'deck_format' in jblob:
                        # Let's look for tournaments by name and date instead
                        tourna = Tournament.objects.filter(name=jblob['tournament_name'], format__formatname=jblob['deck_format']).first()
                    else:
                        # we just aren't going to have a tournament.
                        pass

                    # Let's see if we already have a deck for this.
                    deck = None

                    # We are going to look at the "deckid" parameter that StarCityGames decks have and match on just that id.
                    dukey_m = SCG_DECK_URL_KEY_RE.search(jblob['url'])
                    if dukey_m:
                        #sys.stdout.write("** MATCHED: {}\n".format(dukey_m.group(1)))
                        deck = Deck.objects.filter(url__icontains='deckid={}'.format(dukey_m.group(1))).first()
                        #sys.stdout.write("** MATCHED: deck is {}\n".format(str(deck)))
                    else:
                        deck = Deck.objects.filter(url=jblob['url']).first()
                    if deck is None:
                        # no deck, so let's add it!
                        deck = Deck(url=jblob['url'], visibility=Deck.HIDDEN)
                        deck.name = jblob['name']
                        deck.authorname = jblob['author']
                        if tourna is not None and tourna.format is not None:
                            deck.format = tourna.format
                        elif 'deck_format' in jblob:
                            try:
                                db_format_q = Format.objects.filter(
                                    formatname=jblob['deck_format'], start_date__lte=self.isodate(
                                        jblob['tournament_date']), end_date__gte=self.isodate(
                                        jblob['tournament_date'])).first()
                                deck.format = db_format
                            except ValueError:
                                # Looks like we cannot find a valid format because we don't have a real
                                # deck_format or a real tournament_date.
                                sys.stdout.write("Deck: skipped '{}' because a valid format cannot be found\n".format(jblob['name']))
                                deck = None
                                pass

                        if deck is not None:
                            deck.save()
                            sys.stdout.write("Deck: created {}\n".format(jblob['name']))
                            deck = Deck.objects.filter(url=jblob['url']).first()  # reload

                    else:
                        # for kicks, let's update name and authorname, since it could be that the
                        # scrapy crawler gets better at figuring those things out
                        deck.name = jblob['name']
                        deck.authorname = jblob['author']
                        deck.url = jblob['url']
                        deck.save()
                        sys.stdout.write("Deck: updated {}\n".format(jblob['name']))

                    #sys.stdout.write("Deck: {} (db card count {})\n".format(jblob['name'], deck.get_card_count()))
                    #sys.stdout.write("  URL: {}\n".format(jblob['url']))

                    if deck is not None:
                        # now we have to add cards to the deck...
                        cardtext = '\n'.join(jblob['mainboard_cards'])
                        cardtext = cardtext + '\nSB:' + '\nSB: '.join(jblob['sideboard_cards'])
                        #sys.stdout.write(cardtext + "\n")
                        # REVISIT - just updating them all for now. Shouldn't hurt since
                        # set_cards_from_text deletes all of the current card associations, right?
                        if deck.get_card_count() == 0 or True:
                            try:
                                deck.set_cards_from_text(cardtext)
                            except Deck.CardsNotFoundException as cnfe:
                                for g in cnfe.cnfes:
                                    try:
                                        sys.stdout.write("ERROR: Could not find card " + str(g.text) + " in file {}\n".format(filename))
                                    except UnicodeEncodeError:
                                        sys.stdout.write(
                                            "ERROR: Could not find card BUT I CAN'T TELL YOU ABOUT IT BECAUSE UNICODE IN PYTHON SUCKS in {}\n".format(filename))

                        if tourna is not None and tourna.name is not None and tourna.name.lower().find('test deck') < 0:
                            # Now we will associate the deck to a tournament
                            td = TournamentDeck.objects.filter(deck=deck, tournament=tourna).first()
                            place = 99999
                            if 'place' in jblob:
                                place = jblob['place']
                            if td is None:
                                td = TournamentDeck(deck=deck, tournament=tourna, place=place)
                                td.save()
                                sys.stdout.write("TournamentDeck: created for {}\n".format(jblob['name']))
                                td = TournamentDeck.objects.filter(deck=deck, tournament=tourna).first()  # RELOAD
                            else:
                                td.place = place
                                td.save()
                                sys.stdout.write("TournamentDeck: updated for {}\n".format(jblob['name']))
                        else:
                            sys.stdout.write("Deck: skipped no valid tournament {}\n".format(jblob['name']))
示例#14
0
    def handle(self, *args, **options):
        #logger = logging.getLogger(__name__)
        # the first (and only) arg should be a filename
        directory = options['inputdir']
        deck_meta_only = options['deck_meta_only']
        self.only_newer = options['only_newer']

        self.start_time = timezone.now()

        if not os.access(directory, os.R_OK):
            sys.stderr.write("Cannot read directory '{}'.\n".format(directory))
            return

        # let's figure out the last time we ran.
        sema_filename = join(directory, 'last_complete.semaphore')
        last_start_time = datetime(2000, 1, 1, 0, 0, 0, 0, self.localtime)

        try:
            sema_in = open(sema_filename, 'r')
            lst_str = sema_in.readline()
            last_start_time = dtparse(lst_str)
            last_start_time = last_start_time.replace(tzinfo=self.localtime)
            sema_in.close()
        except:
            sys.stderr.write("Cannot read the {} file. Proceeding anyway...\n".format(sema_filename))

        onlyfiles = [f for f in listdir(directory) if isfile(join(directory, f))]
        for filename in onlyfiles:
            if filename.find('tournament_') > -1:  # and False: # REVISIT - commented out for the moment!
                filehandler = open(join(directory, filename))
                filetime = datetime.fromtimestamp(os.path.getmtime(join(directory, filename)))
                filetime = filetime.replace(tzinfo=self.localtime)
                if self.only_newer and filetime < last_start_time:
                    continue

                jblob = json.load(filehandler)

                #{"url": "/en/content/2011-great-britain-national-championship", "tournament_format": null, "name": "Great Britain National Championship", "start_date": "2011-08-19"}
                if jblob['name'].lower().find('test deck') > -1:
                    sys.stdout.write("Tournament: skipped test deck tournament: {}\n".format(jblob['name']))
                    pass
                else:
                    turl = jblob['url']
                    # The StarCityGames tournaments will probably not have a URL at all
                    if turl is None or len(turl) == 0:
                        pass
                    # Some of the Wizards-crawled tournaments will not have a fully-qualified URL
                    elif turl.find('http') < 0:
                        turl = 'http://magic.wizards.com' + turl
                    format_string = jblob['tournament_format']
                    if format_string is None:
                        format_string = 'Unknown'
                    elif format_string.find('Modern') > -1:
                        format_string = 'Modern'
                    elif format_string.find('Standard') > -1:
                        format_string = 'Standard'
                    elif format_string.find('Commander') > -1:
                        format_string = 'Commander'
                    elif format_string.find('Pauper') > -1:
                        format_string = 'Pauper'
                    elif format_string.find('Legacy') > -1:
                        format_string = 'Legacy'
                    elif format_string.find('Tiny') > -1:
                        format_string = 'TinyLeaders'
                    elif format_string == '' and 'legacy' in jblob['name'].lower():
                        format_string = 'Legacy'
                    db_format = Format.objects.filter(
                        formatname__iexact=format_string,
                        start_date__lte=self.isodate(jblob['start_date']),
                        end_date__gt=self.isodate(jblob['end_date'])).first()
                    if db_format is not None:
                        db_tournament = Tournament.objects.filter(
                            format=db_format,
                            name__iexact=jblob['name'],
                            start_date=self.isodate(jblob['start_date'])).first()
                        if db_tournament is None:
                            # let's make one!
                            db_tournament = Tournament(
                                format=db_format,
                                name=jblob['name'],
                                start_date=self.isodate(jblob['start_date']),
                                end_date=self.isodate(jblob['end_date']),
                                url=turl)
                            db_tournament.save()
                            sys.stdout.write("Tournament: created {}\n".format(jblob['name']))
                        else:
                            if filetime > db_tournament.updated_at or not self.only_newer:
                                # let's update!!
                                if turl.find('/node/') < 0:
                                    db_tournament.url = turl
                                    sys.stdout.write("Tournament: updated {}\n".format(jblob['name']))
                                    db_tournament.save()
                                else:
                                    sys.stdout.write("Tournament: skipped updated with node {}\n".format(jblob['name']))
                            else:
                                sys.stdout.write("Tournament: not newer... skipped {}\n".format(jblob['name']))
                    else:
                        sys.stdout.write("Tournament: skipped no format '{}' found in db {}\n".format(format_string, jblob['name']))

        tournament_url_re = re.compile('^(.+/coverage/([^/]+))/?')

        # Process the deck files
        for filename in onlyfiles:
            if filename.find('deck_') > -1:
                ###fqfilename = join(directory, filename)
                # print "last modified: %s" % time.ctime(getmtime(fqfilename))
                filehandler = open(join(directory, filename))

                filetime = datetime.fromtimestamp(os.path.getmtime(join(directory, filename)))
                filetime = filetime.replace(tzinfo=self.localtime)
                if self.only_newer and filetime < last_start_time:
                    continue

                jblob = json.load(filehandler)

                # let's test if jblob is a set JSON
                if 'name' in jblob and 'mainboard_cards' in jblob:
                    # TEMP FIX - Legacy decks did not havea format_name for a lot of crawling...
                    if jblob['deck_format'] == '' and jblob['tournament_name'] and 'legacy' in jblob['tournament_name'].lower():
                        jblob['deck_format'] = 'Legacy'
                    tourna = None
                    # let's deal with decks that have valid tournament URLs
                    if 'tournament_url' in jblob and jblob['tournament_url'] is not None and len(jblob['tournament_url']) > 0:
                        # We are going to skip decks and tournaments that look like draft and sealed
                        if jblob['tournament_url'].find('draft') > 0 or jblob['tournament_url'].find('sealed') > 0:
                            # skip
                            sys.stdout.write("Deck: skipped limited {}\n".format(jblob['name']))
                            continue

                        # now find the tournament
                        tu_match = tournament_url_re.search(jblob['tournament_url'])
                        tournament_url = jblob['tournament_url']
                        tournament_name = ''
                        if tu_match:
                            tournament_url = tu_match.group(1)
                            tournament_name = tu_match.group(2)
                        # find a real tournament that we match to
                        #sys.stdout.write("HERE with '{}' and '{}'\n".format(tournament_url, tournament_name))
                        tourna = Tournament.objects.filter(url=tournament_url).first()  # exclude(format__formatname='Unknown').first()
                    elif 'tournament_name' in jblob and 'deck_format' in jblob:
                        # Let's look for tournaments by name and date instead
                        tourna = Tournament.objects.filter(name=jblob['tournament_name'], format__formatname=jblob['deck_format']).first()
                    else:
                        # we just aren't going to have a tournament.
                        pass

                    # Let's see if we already have a deck for this.
                    deck = None
                    sys.stdout.write("Deck: {} - {} by {}\n".format(jblob['url'], jblob['name'], jblob['author']))
                    is_create = False
                    # Should we skip writing this deck to the database?
                    skip_deck = False

                    # We are going to look at the "deckid" parameter that StarCityGames decks have and match on just that id.
                    dukey_m = SCG_DECK_URL_KEY_RE.search(jblob['url'])
                    if dukey_m:
                        #sys.stdout.write("** MATCHED: {}\n".format(dukey_m.group(1)))
                        deck = Deck.objects.filter(url__icontains='deckid={}'.format(dukey_m.group(1))).first()
                        #sys.stdout.write("** MATCHED: deck is {}\n".format(str(deck)))
                    else:
                        if 'page_part' in jblob:
                            if jblob['page_part'] == '0' or jblob['page_part'] == 0:
                                deck = Deck.objects.filter(url=jblob['url']).first()
                                if deck is None:
                                    deck = Deck.objects.filter(url='{}#deck{}'.format(jblob['url'], jblob['page_part'])).first()
                            else:
                                deck = Deck.objects.filter(url='{}#deck{}'.format(jblob['url'], jblob['page_part'])).first()
                        else:
                            deck = Deck.objects.filter(url=jblob['url']).first()
                    if deck is None:
                        # no deck, so let's add it!
                        sys.stdout.write("  creating...\n")
                        is_create = True
                        deck = Deck(url=jblob['url'], visibility=Deck.HIDDEN)
                        if 'page_part' in jblob:
                            deck.url = '{}#deck{}'.format(jblob['url'], jblob['page_part'])
                        deck.name = jblob['name']
                        deck.authorname = jblob['author']
                        if tourna is not None and tourna.format is not None:
                            deck.format = tourna.format
                        elif 'deck_format' in jblob:
                            try:
                                sys.stderr.write(
                                    "Format find: {} - {}\n".format(jblob['deck_format'], self.isodate(jblob['tournament_date'])))
                                db_format_q = Format.objects.filter(
                                    formatname=jblob['deck_format'], start_date__lte=self.isodate(
                                        jblob['tournament_date']), end_date__gt=self.isodate(
                                        jblob['tournament_date'])).first()
                                deck.format = db_format_q
                            except ValueError:
                                # Looks like we cannot find a valid format because we don't have a real
                                # deck_format or a real tournament_date.
                                sys.stdout.write(
                                    "  skipped because a valid format cannot be found for '{}' on date '{}'\n".format(
                                        jblob['deck_format'],
                                        jblob['tournament_date']))
                                deck = None
                                pass

                        if deck is not None:
                            try:
                                deck.save()
                                sys.stdout.write("  Created deck {}!\n".format(str(deck.id)))
                                deck = Deck.objects.get(pk=deck.id)  # reload
                            except IntegrityError as ie:
                                sys.stdout.write("  Could not create deck! Integrity error: {}\n".format(str(ie)))
                                deck = None

                    else:
                        if filetime > deck.updated_at or not self.only_newer:
                            # for kicks, let's update name and authorname, since it could be that the
                            # scrapy crawler gets better at figuring those things out
                            deck.name = jblob['name']
                            deck.authorname = jblob['author']
                            deck.url = jblob['url']
                            if 'page_part' in jblob:
                                deck.url = '{}#deck{}'.format(jblob['url'], jblob['page_part'])
                            deck.format = None
                            try:
                                db_format_q = Format.objects.filter(
                                    formatname=jblob['deck_format'], start_date__lte=self.isodate(
                                        jblob['tournament_date']), end_date__gt=self.isodate(
                                        jblob['tournament_date'])).first()
                                deck.format = db_format_q
                            except ValueError as ve:
                                # Looks like we cannot find a valid format because we don't have a real
                                # deck_format or a real tournament_date.
                                sys.stdout.write(
                                    "  updating '{}' even though could not find a valid format for '{}' on date {} - {}\n".format(
                                        jblob['name'],
                                        jblob['deck_format'],
                                        jblob['tournament_date'],
                                        str(ve)))
                                deck.format = None
                            deck.save()
                            sys.stdout.write("  Updated!\n")
                        else:
                            skip_deck = True
                            sys.stdout.write("  not newer... skipped {}\n".format(jblob['url']))

                    #sys.stdout.write("Deck: {} (db card count {})\n".format(jblob['name'], deck.get_card_count()))
                    #sys.stdout.write("  URL: {}\n".format(jblob['url']))

                    if deck is not None and not skip_deck:
                        # now we have to add cards to the deck...
                        if is_create or not deck_meta_only:
                            sys.stdout.write("  creating or updating deck list...\n")
                            cardtext = '\n'.join(jblob['mainboard_cards'])
                            if 'sideboard_cards' in jblob and jblob['sideboard_cards'] is not None and len(jblob['sideboard_cards']) > 0:
                                cardtext = cardtext + '\nSB:' + '\nSB: '.join(jblob['sideboard_cards'])
                            if 'commandzone_cards' in jblob and jblob[
                                    'commandzone_cards'] is not None and len(jblob['commandzone_cards']) > 0:
                                cardtext = cardtext + '\nCZ:' + '\nCZ: '.join(jblob['commandzone_cards'])
                            #sys.stdout.write(cardtext + "\n")
                            # REVISIT - just updating them all for now. Shouldn't hurt since
                            # set_cards_from_text deletes all of the current card associations, right?
                            if True or deck.get_card_count() == 0:
                                try:
                                    deck.set_cards_from_text(cardtext)
                                except Deck.CardsNotFoundException as cnfe:
                                    for g in cnfe.cnfes:
                                        try:
                                            sys.stdout.write("  ERROR: Could not find card " +
                                                             str(g.text) +
                                                             " in file {}\n".format(filename))
                                        except UnicodeEncodeError:
                                            sys.stdout.write(
                                                "  ERROR: Could not find card BUT I CAN'T TELL YOU ABOUT IT BECAUSE UNICODE IN PYTHON SUCKS in {}\n".format(filename))

                        if tourna is not None and tourna.name is not None and tourna.name.lower().find('test deck') < 0:
                            # Now we will associate the deck to a tournament
                            td = TournamentDeck.objects.filter(deck=deck, tournament=tourna).first()
                            place = 99999
                            if 'place' in jblob:
                                place = jblob['place']
                            if td is None:
                                td = TournamentDeck(deck=deck, tournament=tourna, place=place)
                                td.save()
                                sys.stdout.write("  TournamentDeck: created for {}\n".format(jblob['name']))
                                td = TournamentDeck.objects.filter(deck=deck, tournament=tourna).first()  # RELOAD
                            else:
                                td.place = place
                                td.save()
                                sys.stdout.write("  TournamentDeck: updated for {}\n".format(jblob['name']))
                        else:
                            sys.stdout.write("  TournamentDeck: skipped no valid tournament {}\n".format(jblob['name']))
        sema = open(join(directory, 'last_complete.semaphore'), 'w')
        sema.write(str(self.start_time))
        sema.write("\n")
        sema.close()
示例#15
0
    def test_deck_1xmountain(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        tformat = Format.objects.filter(format='Standard_2015-01-23').first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = tformat

        tdeck.save()

        decklist = '1x Mountain'
        tdeck.set_cards_from_text(decklist)

        self.assertEquals(tdeck.get_card_count(), 1)
示例#16
0
    def test_deck_badname_nosave(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        tformat = Format.objects.filter(format='Standard_2015-01-23').first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = tformat

        tdeck.save()

        decklist = '''3 Mountain
sb: 4x Island'''
        tdeck.set_cards_from_text(decklist)

        self.assertEquals(tdeck.get_card_count(), 7)

        decklist = '''3 Foo jib Battons'''
        try:
            tdeck.set_cards_from_text(decklist)
            self.assertTrue(False)
        except Deck.CardsNotFoundException as cnfes:
            self.assertEquals(cnfes.cnfes[0].text, 'Foo jib Battons'.lower())

        self.assertEquals(tdeck.get_card_count(), 7)
示例#17
0
    def test_empty(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        tformat = Format.objects.all().first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = tformat

        tdeck.save()

        decklist = ''
        tdeck.set_cards_from_text(decklist)

        self.assertEquals(tdeck.get_card_count(), 0)
示例#18
0
    def test_deck_2cards(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        tformat = Format.objects.filter(format='Standard_2015-01-23').first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = tformat

        tdeck.save()

        decklist = '''2 Mountain
4x Island'''
        tdeck.set_cards_from_text(decklist)

        self.assertEquals(tdeck.get_card_count(), 6)

        dcs = DeckCard.objects.filter(deck=tdeck).order_by('cardcount')
        dc = dcs[0]
        self.assertEquals(dc.cardcount, 2)
        self.assertEquals(dc.board, DeckCard.MAIN)
        self.assertEquals(dc.physicalcard.get_card_name(), 'Mountain')
        dc = dcs[1]
        self.assertEquals(dc.cardcount, 4)
        self.assertEquals(dc.board, DeckCard.MAIN)
        self.assertEquals(dc.physicalcard.get_card_name(), 'Island')
示例#19
0
    def test_deck_7mountain(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        tformat = Format.objects.filter(format='Standard_2015-01-23').first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = tformat

        tdeck.save()

        decklist = '7 Mountain'
        tdeck.set_cards_from_text(decklist)

        self.assertEquals(tdeck.get_card_count(), 7)

        dcs = DeckCard.objects.filter(deck=tdeck)
        for dc in dcs:
            self.assertEquals(dc.cardcount, 7)
            self.assertEquals(dc.board, DeckCard.MAIN)
            self.assertEquals(dc.physicalcard.get_card_name(), 'Mountain')
示例#20
0
    def test_one_deck_abs_card(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        mountain = BaseCard.objects.filter(name='Mountain').first().physicalcard
        island = BaseCard.objects.filter(name='Island').first().physicalcard
        myform = Format.objects.filter(formatname='Modern').order_by('-start_date').first()

        tdeck = Deck()
        tdeck.name = 'My Deck Name'
        tdeck.url = 'http://card.ninja/'
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = myform

        tdeck.save()
        tdeck = Deck.objects.get(pk=tdeck.id)

        dc1 = DeckCard()
        dc1.physicalcard = island
        dc1.deck = tdeck
        dc1.cardcount = 60
        dc1.board = DeckCard.MAIN
        dc1.save()

        self.assertEquals(tdeck.get_card_count(), 60)

        tourny = Tournament(name='Test', url='http://foo.dog/', format=myform, start_date=myform.start_date, end_date=myform.start_date)
        tourny.save()
        #tourny = Tournament.objects.all().first()

        td = TournamentDeck(tournament=tourny, deck=tdeck, place=1)
        td.save()
        #td = TournamentDeck.objects.filter(tournament=tourny, deck=tdeck, place=1).first()

        FormatStat.calc_all()
        FormatCardStat.calc_all()

        fstat = FormatStat.objects.filter(format=myform).first()
        mstat = FormatCardStat.objects.filter(format=myform, physicalcard=mountain).first()

        dcount = mstat.deck_count
        self.assertEquals(dcount, 0)
        tdcount = fstat.tournamentdeck_count
        self.assertEquals(tdcount, 1, '1 Tournament Deck in the Format')

        self.assertEquals(mstat.in_decks_percentage(), 0.0, 'Mountain is in 0% of decks')

        self.assertEquals(mstat.occurence_count, 0, 'Mountain shows up 0 times in tournament decks')

        # the number of decks in this format that have this card
        self.assertEquals(mstat.deck_count, 0, '0 Tournament Decks have Mountain in the them')

        # the average card count when this card is included in a deck
        self.assertEquals(mstat.average_card_count_in_deck, 0.0, 'Average count of Mountain in Tournament Decks is 0')

        # the percentage of all cards in the format that are this card
        self.assertEquals(mstat.percentage_of_all_cards, 0.0, 'Average count of Tournament Decks with Mountain in it is 0')

        istat = FormatCardStat.objects.filter(format=myform, physicalcard=island).first()

        dcount = istat.deck_count
        self.assertEquals(dcount, 1, '1 Tournament Deck that has Island in it')
        self.assertEquals(istat.in_decks_percentage(), 100.0, 'Island is in 100% of decks')

        self.assertEquals(istat.occurence_count, 60, 'Island shows up 0 times in tournament decks')

        # the number of decks in this format that have this card
        self.assertEquals(istat.deck_count, 1, '1 Tournament Decks have Island in the them')

        # the average card count when this card is included in a deck
        self.assertEquals(istat.average_card_count_in_deck, 60.0, 'Average count of Island in Tournament Decks is 60')

        # the percentage of all cards in the format that are this card
        self.assertEquals(
            istat.percentage_of_all_cards,
            1.0,
            'Average count of Tournament Decks with Island in it should be 100, not {}'.format(
                istat.percentage_of_all_cards))
示例#21
0
    def test_tcbf_5(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        mountain = BaseCard.objects.filter(name='Mountain').first().physicalcard
        island = BaseCard.objects.filter(name='Island').first().physicalcard
        swamp = BaseCard.objects.filter(name='Swamp').first().physicalcard
        plains = BaseCard.objects.filter(name='Plains').first().physicalcard
        formats = Format.objects.filter(formatname='Modern').order_by('-start_date')
        myform = formats[0]
        prev_form = formats[1]
        old_form = formats[2]

        # current format, all islands
        tourny = Tournament(name='Test {}'.format(myform.pk), url='http://foo.dog/', format=myform,
                            start_date=myform.start_date, end_date=myform.start_date)
        tourny.save()
        for dcc in range(0, 6):
            tdeck = Deck()
            tdeck.name = 'My {} Deck Name in {}'.format(dcc, myform.format)
            tdeck.url = 'http://card.ninja/{}'.format(myform.id)
            tdeck.visibility = tdeck.VISIBLE
            tdeck.authorname = 'Test Dude'
            tdeck.format = myform

            tdeck.save()

            dc1 = DeckCard(physicalcard=island, deck=tdeck, cardcount=31, board=DeckCard.MAIN)
            dc1.save()
            dc2 = DeckCard(physicalcard=swamp, deck=tdeck, cardcount=29, board=DeckCard.MAIN)
            dc2.save()

            td = TournamentDeck(tournament=tourny, deck=tdeck, place=dcc)
            td.save()

        # previous format, 10 islands, 20 swamps, 30 mountains
        tourny = Tournament(name='Test {}'.format(prev_form.pk), url='http://foo.dog/', format=prev_form,
                            start_date=prev_form.start_date, end_date=prev_form.start_date)
        tourny.save()
        for dcc in range(0, 6):
            tdeck = Deck()
            tdeck.name = 'My Deck Name in {}'.format(prev_form.format)
            tdeck.url = 'http://card.ninja/{}'.format(prev_form.id)
            tdeck.visibility = tdeck.VISIBLE
            tdeck.authorname = 'Test Dude'
            tdeck.format = prev_form

            tdeck.save()

            dc1 = DeckCard(physicalcard=island, deck=tdeck, cardcount=10, board=DeckCard.MAIN)
            dc1.save()
            dc2 = DeckCard(physicalcard=swamp, deck=tdeck, cardcount=20, board=DeckCard.MAIN)
            dc2.save()
            dc3 = DeckCard(physicalcard=mountain, deck=tdeck, cardcount=30, board=DeckCard.MAIN)
            dc3.save()

            td = TournamentDeck(tournament=tourny, deck=tdeck, place=dcc)
            td.save()

        # older format, 10 islands, 10 swamps, 10 mountains, 30 plains
        tourny = Tournament(name='Test {}'.format(old_form.pk), url='http://foo.dog/', format=old_form,
                            start_date=old_form.start_date, end_date=old_form.start_date)
        tourny.save()
        for dcc in range(0, 3):
            tdeck = Deck()
            tdeck.name = 'My {} Deck Name in {}'.format(dcc, old_form.format)
            tdeck.url = 'http://card.ninja/{}-{}'.format(old_form.id, dcc)
            tdeck.visibility = tdeck.VISIBLE
            tdeck.authorname = 'Test Dude'
            tdeck.format = old_form
            tdeck.save()

            dc1 = DeckCard(physicalcard=island, deck=tdeck, cardcount=10, board=DeckCard.MAIN)
            dc1.save()
            dc2 = DeckCard(physicalcard=swamp, deck=tdeck, cardcount=10, board=DeckCard.MAIN)
            dc2.save()
            dc3 = DeckCard(physicalcard=mountain, deck=tdeck, cardcount=10, board=DeckCard.MAIN)
            dc3.save()
            dc4 = DeckCard(physicalcard=plains, deck=tdeck, cardcount=30, board=DeckCard.MAIN)
            dc4.save()

            td = TournamentDeck(tournament=tourny, deck=tdeck, place=dcc)
            td.save()

        FormatStat.calc_all()
        FormatCardStat.calc_all()

        fstat = FormatStat.objects.filter(format=myform).first()
        mstat = FormatCardStat.objects.filter(format=myform, physicalcard=mountain).first()
        istat = FormatCardStat.objects.filter(format=myform, physicalcard=island).first()
        sstat = FormatCardStat.objects.filter(format=myform, physicalcard=swamp).first()

        # Try it once with looking back ONLY 1 format, and then again looking back 2 formats
        for lookback_days in (10,):
            cc = FormatCardStat.objects.top_cards_by_format(myform, format_lookback_days=lookback_days)
            first_cc = cc[0]
            self.assertEquals(first_cc.physicalcard, island, "Top card in this format is Island")
            self.assertIs(
                str(
                    prev_form.pk) in first_cc.previous_format_ids,
                True,
                "The previous format ids on the FormatCardStat object should be the previous format id. Not {}".format(
                    first_cc.previous_format_ids))
            if lookback_days == 40:
                self.assertIs(
                    str(
                        old_form.pk) in first_cc.previous_format_ids,
                    True,
                    "The old format ids on the FormatCardStat object should be the old format id Not {}".format(
                        first_cc.previous_format_ids))

            # in prev_format, 1 out of 6 were Island
            self.assertAlmostEqual(
                first_cc.percentage_of_all_cards_previous(),
                1.0 / 6.0,
                msg='Last format was split 1 out of 6 were Islands, so 16.66% is returned')
            # Now Island is 31/60, so 31/60 - 10/60 = 35%
            self.assertAlmostEqual(first_cc.percentage_of_all_cards_delta(),
                                   (31.0 / 60.0) - (10.0 / 60.0),
                                   msg='35.0% points higher, so positive .35 is returned')
            self.assertAlmostEqual(first_cc.percentage_of_all_cards_perchange(),
                                   0.35 / (1.0 / 6.0),
                                   msg='210% change for Island - it is big! Not {}'.format(first_cc.percentage_of_all_cards_perchange()))

            looked_at_mountain = False
            looked_at_swamp = False
            looked_at_plains = False
            for other_cc in cc:
                if other_cc.physicalcard_id == mountain.id:
                    looked_at_mountain = True
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_previous(), 0.5,
                                           msg='Last format was split Islands and Mountains, so 50% is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), -0.5,
                                           msg='50% points lower, so negative .5 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), -1.0,
                                           msg='100% change for Mountain - big loss! Not {}'.format(
                        other_cc.percentage_of_all_cards_perchange()))
                if other_cc.physicalcard_id == swamp.id:
                    looked_at_swamp = True
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_previous(), 1.0 / 3.0,
                                           msg='Last format had Swamps, Mountains, and Islands, so 33.3% is returned')
                    # had been a 1/3, and now 29/60th
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), (29.0 / 60.0) - (1.0 / 3.0),
                                           msg='15% points higher, so negative .15 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), 0.45,
                                           msg='45% change for Swamp - big win! Not {}'.format(
                        other_cc.percentage_of_all_cards_perchange()))
                if other_cc.physicalcard_id == plains.id:
                    looked_at_plains = True
                    self.assertAlmostEqual(
                        other_cc.percentage_of_all_cards_previous(),
                        0.0,
                        msg='Last format had Swamps, Mountains, and Islands, so 0% Plains should be returned, not {}'.format(
                            other_cc.percentage_of_all_cards_previous()))
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), 0.0,
                                           msg='No change for plains, so 0.0 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), 0.0,
                                           msg='0% change for Plains - oh well! Not {}'.format(
                                               other_cc.percentage_of_all_cards_perchange()))
            self.assertIs(looked_at_mountain, True, 'Why did we not look at Mountain?')
            self.assertIs(looked_at_swamp, True, 'Why did we not look at Swamp?')
            self.assertIs(looked_at_plains, True, 'Why did we not look at Plains?')

        for lookback_days in (40,):  # look back 2 formats now!!
            cc = FormatCardStat.objects.top_cards_by_format(myform, format_lookback_days=lookback_days)
            first_cc = cc[0]
            self.assertEquals(first_cc.physicalcard, island, "Top card in this format is Island")
            self.assertIs(
                str(
                    prev_form.pk) in first_cc.previous_format_ids,
                True,
                "The previous format ids on the FormatCardStat object should be the previous format id. Not {}".format(
                    first_cc.previous_format_ids))
            self.assertIs(str(old_form.pk) in first_cc.previous_format_ids,
                          True,
                          "The old format ids on the FormatCardStat object should be the old format id Not {}".format(first_cc.previous_format_ids))

            # in prev_format, 1 out of 6 were Island
            self.assertAlmostEqual(
                first_cc.percentage_of_all_cards_previous(),
                1.0 / 6.0,
                msg='Last 2 formats summed was split 1 out of 6 were Islands, so 16.66% is returned')
            # Now Island is 31/60, so 31/60 - 10/60 = 35%
            self.assertAlmostEqual(first_cc.percentage_of_all_cards_delta(),
                                   (31.0 / 60.0) - (10.0 / 60.0),
                                   msg='35.0% points higher, so positive .35 is returned')
            self.assertAlmostEqual(first_cc.percentage_of_all_cards_perchange(),
                                   0.35 / (1.0 / 6.0),
                                   msg='210% change for Island - it is big! Not {}'.format(first_cc.percentage_of_all_cards_perchange()))

            looked_at_mountain = False
            looked_at_swamp = False
            looked_at_plains = False
            for other_cc in cc:
                if other_cc.physicalcard_id == mountain.id:
                    looked_at_mountain = True
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_previous(), 21.0 / 54.0,
                                           msg='Last formats had 210 Mountains out of 540 cards, so 38.8% is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), -21.0 / 54.0,
                                           msg='38.8% points lower, so negative .388 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), -1.0,
                                           msg='100% change for Mountain - big loss! Not {}'.format(
                        other_cc.percentage_of_all_cards_perchange()))
                if other_cc.physicalcard_id == swamp.id:
                    looked_at_swamp = True
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_previous(), 5.0 / 18.0,
                                           msg='Last formats 5 out of 18 cards as Swamps, so 27.7% is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), 29.0 / 60.0 - 5.0 / 18.0,
                                           msg='20.6% points better, so positive .2066 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), (29.0 / 60.0 - 5.0 / 18.0) / (5.0 / 18.0),
                                           msg='74% change for Swamp - big win! Not {}'.format(
                        other_cc.percentage_of_all_cards_perchange()))
                if other_cc.physicalcard_id == plains.id:
                    looked_at_plains = True
                    self.assertAlmostEqual(
                        other_cc.percentage_of_all_cards_previous(),
                        1.0 / 6.0,
                        msg='Last formats had some Plains, so 16.6% Plains should be returned, not {}'.format(
                            other_cc.percentage_of_all_cards_previous()))
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), -1.0 / 6.0,
                                           msg='All Plains are gone, so delta is negative .1666')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), -1.0,
                                           msg='-100% change for Plains - oh well! Not {}'.format(
                                               other_cc.percentage_of_all_cards_perchange()))
            self.assertIs(looked_at_mountain, True, 'Why did we not look at Mountain?')
            self.assertIs(looked_at_swamp, True, 'Why did we not look at Swamp?')
            self.assertIs(looked_at_plains, True, 'Why did we not look at Plains?')
示例#22
0
    def test_tcbf_4(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        mountain = BaseCard.objects.filter(name='Mountain').first().physicalcard
        island = BaseCard.objects.filter(name='Island').first().physicalcard
        swamp = BaseCard.objects.filter(name='Swamp').first().physicalcard
        plains = BaseCard.objects.filter(name='Plains').first().physicalcard
        formats = Format.objects.filter(formatname='Modern').order_by('-start_date')
        myform = formats[0]
        prev_form = formats[1]
        old_form = formats[2]

        # current format, all islands
        tourny = Tournament(name='Test {}'.format(myform.pk), url='http://foo.dog/', format=myform,
                            start_date=myform.start_date, end_date=myform.start_date)
        tourny.save()
        for dcc in range(0, 3):
            tdeck = Deck()
            tdeck.name = 'My {} Deck Name in {}'.format(dcc, myform.format)
            tdeck.url = 'http://card.ninja/{}'.format(myform.id)
            tdeck.visibility = tdeck.VISIBLE
            tdeck.authorname = 'Test Dude'
            tdeck.format = myform

            tdeck.save()

            dc1 = DeckCard()
            dc1.physicalcard = island
            dc1.deck = tdeck
            dc1.cardcount = 60
            dc1.board = DeckCard.MAIN
            dc1.save()

            td = TournamentDeck(tournament=tourny, deck=tdeck, place=dcc)
            td.save()

        # previous format, 10 islands, 20 swamps, 30 mountains
        tourny = Tournament(name='Test {}'.format(prev_form.pk), url='http://foo.dog/', format=prev_form,
                            start_date=prev_form.start_date, end_date=prev_form.start_date)
        tourny.save()
        for dcc in range(0, 3):
            tdeck = Deck()
            tdeck.name = 'My Deck Name in {}'.format(prev_form.format)
            tdeck.url = 'http://card.ninja/{}'.format(prev_form.id)
            tdeck.visibility = tdeck.VISIBLE
            tdeck.authorname = 'Test Dude'
            tdeck.format = prev_form

            tdeck.save()

            dc1 = DeckCard(physicalcard=island, deck=tdeck, cardcount=10, board=DeckCard.MAIN)
            dc1.save()
            dc2 = DeckCard(physicalcard=swamp, deck=tdeck, cardcount=20, board=DeckCard.MAIN)
            dc2.save()
            dc3 = DeckCard(physicalcard=mountain, deck=tdeck, cardcount=30, board=DeckCard.MAIN)
            dc3.save()

            td = TournamentDeck(tournament=tourny, deck=tdeck, place=dcc)
            td.save()

        # older format, 10 islands, 20 swamps, 30 mountains
        tourny = Tournament(name='Test {}'.format(old_form.pk), url='http://foo.dog/', format=old_form,
                            start_date=old_form.start_date, end_date=old_form.start_date)
        tourny.save()
        for dcc in range(0, 3):
            tdeck = Deck()
            tdeck.name = 'My {} Deck Name in {}'.format(dcc, old_form.format)
            tdeck.url = 'http://card.ninja/{}-{}'.format(old_form.id, dcc)
            tdeck.visibility = tdeck.VISIBLE
            tdeck.authorname = 'Test Dude'
            tdeck.format = old_form
            tdeck.save()

            dc1 = DeckCard(physicalcard=island, deck=tdeck, cardcount=10, board=DeckCard.MAIN)
            dc1.save()
            dc2 = DeckCard(physicalcard=swamp, deck=tdeck, cardcount=20, board=DeckCard.MAIN)
            dc2.save()
            dc3 = DeckCard(physicalcard=mountain, deck=tdeck, cardcount=30, board=DeckCard.MAIN)
            dc3.save()

            td = TournamentDeck(tournament=tourny, deck=tdeck, place=dcc)
            td.save()

        FormatStat.calc_all()
        FormatCardStat.calc_all()

        fstat = FormatStat.objects.filter(format=myform).first()
        mstat = FormatCardStat.objects.filter(format=myform, physicalcard=mountain).first()
        istat = FormatCardStat.objects.filter(format=myform, physicalcard=island).first()
        sstat = FormatCardStat.objects.filter(format=myform, physicalcard=swamp).first()

        # Try it once with looking back ONLY 1 format, and then again looking back 2 formats
        for lookback_days in (10, 40):  # note the test data has Modern formats ever month
            cc = FormatCardStat.objects.top_cards_by_format(myform, format_lookback_days=lookback_days)
            first_cc = cc[0]
            self.assertEquals(first_cc.physicalcard, island, "Top card in this format is Island")
            self.assertIs(
                str(
                    prev_form.pk) in first_cc.previous_format_ids,
                True,
                "The previous format ids on the FormatCardStat object should be the previous format id. Not {}".format(
                    first_cc.previous_format_ids))
            if lookback_days == 40:
                self.assertIs(
                    str(
                        old_form.pk) in first_cc.previous_format_ids,
                    True,
                    "The old format ids on the FormatCardStat object should be the old format id Not {}".format(
                        first_cc.previous_format_ids))

            self.assertAlmostEqual(
                first_cc.percentage_of_all_cards_previous(),
                1.0 / 6.0,
                msg='Last format was split Islands and Mountains, so 16.66% is returned')
            self.assertAlmostEqual(first_cc.percentage_of_all_cards_delta(),
                                   1.0 - (1.0 / 6.0),
                                   msg='83.33% points higher, so positive .8333 is returned')
            self.assertAlmostEqual(first_cc.percentage_of_all_cards_perchange(),
                                   5.0,
                                   msg='500% change for Island - it is big! Not {}'.format(first_cc.percentage_of_all_cards_perchange()))

            looked_at_mountain = False
            looked_at_swamp = False
            looked_at_plains = False
            for other_cc in cc:
                if other_cc.physicalcard_id == mountain.id:
                    looked_at_mountain = True
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_previous(), 0.5,
                                           msg='Last format was split Islands and Mountains, so 50% is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), -0.5,
                                           msg='50% points lower, so negative .5 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), -1.0,
                                           msg='100% change for Mountain - big loss! Not {}'.format(
                        other_cc.percentage_of_all_cards_perchange()))
                if other_cc.physicalcard_id == swamp.id:
                    looked_at_swamp = True
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_previous(), 1.0 / 3.0,
                                           msg='Last format had Swamps, Mountains, and Islands, so 33.3% is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), -1.0 / 3.0,
                                           msg='33.3% points lower, so negative .333 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), -1.0,
                                           msg='100% change for Swamp - big loss! Not {}'.format(
                        other_cc.percentage_of_all_cards_perchange()))
                if other_cc.physicalcard_id == plains.id:
                    looked_at_plains = True
                    self.assertAlmostEqual(
                        other_cc.percentage_of_all_cards_previous(),
                        0.0,
                        msg='Last format had Swamps, Mountains, and Islands, so 0% Plains should be returned, not {}'.format(
                            other_cc.percentage_of_all_cards_previous()))
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_delta(), 0.0,
                                           msg='No change for plains, so 0.0 is returned')
                    self.assertAlmostEqual(other_cc.percentage_of_all_cards_perchange(), 0.0,
                                           msg='0% change for Plains - oh well! Not {}'.format(
                                               other_cc.percentage_of_all_cards_perchange()))
            self.assertIs(looked_at_mountain, True, 'Why did we not look at Mountain?')
            self.assertIs(looked_at_swamp, True, 'Why did we not look at Swamp?')
            self.assertIs(looked_at_plains, True, 'Why did we not look at Plains?')
示例#23
0
    def test_tcbf_3(self):
        tlh = TestLoadHelper()
        tlh.basics_loader()

        mountain = BaseCard.objects.filter(name='Mountain').first().physicalcard
        island = BaseCard.objects.filter(name='Island').first().physicalcard
        formats = Format.objects.filter(formatname='Modern').order_by('-start_date')
        myform = formats[0]
        prev_form = formats[1]

        # current format, all islands
        tdeck = Deck()
        tdeck.name = 'My Deck Name in {}'.format(myform.format)
        tdeck.url = 'http://card.ninja/{}'.format(myform.id)
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = myform

        tdeck.save()

        dc1 = DeckCard()
        dc1.physicalcard = island
        dc1.deck = tdeck
        dc1.cardcount = 60
        dc1.board = DeckCard.MAIN
        dc1.save()

        tourny = Tournament(name='Test {}'.format(myform.pk), url='http://foo.dog/', format=myform,
                            start_date=myform.start_date, end_date=myform.start_date)
        tourny.save()

        td = TournamentDeck(tournament=tourny, deck=tdeck, place=1)
        td.save()

        # previous format, half islands, hald mountains
        tdeck = Deck()
        tdeck.name = 'My Deck Name in {}'.format(prev_form.format)
        tdeck.url = 'http://card.ninja/{}'.format(prev_form.id)
        tdeck.visibility = tdeck.VISIBLE
        tdeck.authorname = 'Test Dude'
        tdeck.format = prev_form

        tdeck.save()

        dc1 = DeckCard()
        dc1.physicalcard = island
        dc1.deck = tdeck
        dc1.cardcount = 30
        dc1.board = DeckCard.MAIN
        dc1.save()
        dc2 = DeckCard()
        dc2.physicalcard = mountain
        dc2.deck = tdeck
        dc2.cardcount = 30
        dc2.board = DeckCard.MAIN
        dc2.save()

        tourny = Tournament(name='Test {}'.format(prev_form.pk), url='http://foo.dog/', format=prev_form,
                            start_date=prev_form.start_date, end_date=prev_form.start_date)
        tourny.save()

        td = TournamentDeck(tournament=tourny, deck=tdeck, place=1)
        td.save()

        FormatStat.calc_all()
        FormatCardStat.calc_all()

        fstat = FormatStat.objects.filter(format=myform).first()
        mstat = FormatCardStat.objects.filter(format=myform, physicalcard=mountain).first()
        istat = FormatCardStat.objects.filter(format=myform, physicalcard=island).first()

        cc = FormatCardStat.objects.top_cards_by_format(myform)
        first_cc = cc[0]
        self.assertEquals(first_cc.physicalcard, island, "Top card in this format is Island")
        self.assertEquals(first_cc.previous_format_ids, str(prev_form.pk),
                          "The previous format ids on the FormatCardStat object should be the previous format id")
        self.assertEquals(
            first_cc.percentage_of_all_cards_previous(),
            0.5,
            'Last format was split Islands and Mountains, so 50% is returned')
        self.assertEquals(first_cc.percentage_of_all_cards_delta(), 0.5, '50% points higher, so positive .5 is returned')
        self.assertEquals(first_cc.percentage_of_all_cards_perchange(),
                          1.0,
                          '100% change for Island - it doubled! Not {}'.format(first_cc.percentage_of_all_cards_perchange()))
        looked_at_mountain = False
        for other_cc in cc:
            if other_cc.physicalcard_id == mountain.id:
                looked_at_mountain = True
                self.assertEquals(other_cc.previous_format_ids, str(prev_form.pk),
                                  "The previous format ids on the FormatCardStat object should be the previous format id")
                self.assertEquals(
                    other_cc.percentage_of_all_cards_previous(),
                    0.5,
                    'Last format was split Islands and Mountains, so 50% is returned')
                self.assertEquals(other_cc.percentage_of_all_cards_delta(), -0.5, '50% points lower, so negative .5 is returned')
                self.assertEquals(other_cc.percentage_of_all_cards_perchange(), -
                                  1.0, '100% change for Mountain - big loss! Not {}'.format(other_cc.percentage_of_all_cards_perchange()))
        self.assertIs(looked_at_mountain, True, 'Why did we not look at Mountain?')