Example #1
0
    def test_selective_delete(self):
        # Create band with member and instantiate a couple of gigs
        the_band, the_member = self._create_test_band_with_member()
        the_gig1 = gig.new_gig(the_band, "Parade1", the_member.key)
        the_gig2 = gig.new_gig(the_band, "Parade2", the_member.key)

        # verify that we have two gigs for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEqual(len(all_gigs),2)

        # verify that we have no trashed gig
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = 0)
        self.assertEmpty(trash_gigs)

        the_gig1.trashed_date = datetime.datetime.now() - datetime.timedelta(days=20)
        self.assertTrue(the_gig1.is_in_trash)
        the_gig1.put()

        the_gig2.trashed_date = datetime.datetime.now() - datetime.timedelta(days=31)
        self.assertTrue(the_gig2.is_in_trash)
        the_gig2.put()

        # show two gigs in the trash
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = 0)
        self.assertEqual(len(trash_gigs),2)

        # sweep the trash
        gig_handlers._do_autoarchive()

        # now should be one in the trash
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = 0)
        self.assertEqual(len(trash_gigs),1)
Example #2
0
    def test_gig_trashcan(self):
        # Create band with member and instantiate a gig
        the_band, the_member = self._create_test_band_with_member()
        the_gig = gig.new_gig(the_band, "Parade", the_member.key)

        # verify that we have one gig for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEqual(len(all_gigs),1)

        # put the gig in the trash can
        the_gig.trashed_date = datetime.datetime.now()
        self.assertTrue(the_gig.is_in_trash)
        the_gig.put()

        # verify that we now have no gigs for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEmpty(all_gigs)

        # verify that we have one trashed gig
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = None)
        self.assertEqual(len(trash_gigs),1)

        # take band out of trash
        the_gig.trashed_date = None
        self.assertFalse(the_gig.is_in_trash)
        the_gig.put()

        # verify that we have one gig for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEqual(len(all_gigs),1)

        # verify that we have no trashed gigs
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = None)
        self.assertEmpty(trash_gigs)
Example #3
0
    def test_newgig_email(self):
        # Create band with member and instantiate a gig
        the_band, the_member = self._create_test_band_with_member()
        the_gig = gig.new_gig(the_band, "Parade", the_member.key)

        goemail.send_newgig_email(the_member, the_gig, the_band, self.TEST_URL, True, True)
        message = self._get_single_message()
        self.assertEqual(message.to, self.TEST_RECIPIENT)
        self.assertNotEmpty(message.subject)
        self.assertRegexpMatches(message.body.payload, self.TEST_URL)
        self.assertRegexpMatches(message.body.payload, "Parade")
Example #4
0
    def test_newgig_email(self):
        # Create band with member and instantiate a gig
        the_band, the_member = self._create_test_band_with_member()
        the_gig = gig.new_gig(the_band, "Parade", the_member.key)

        goemail.send_newgig_email(the_member, the_gig, the_band, self.TEST_URL,
                                  True, True)
        message = self._get_single_message()
        self.assertEqual(message.to, self.TEST_RECIPIENT)
        self.assertNotEmpty(message.subject)
        self.assertRegexpMatches(message.body.payload, self.TEST_URL)
        self.assertRegexpMatches(message.body.payload, "Parade")
Example #5
0
    def test_delete_trash(self):
        # Create band with member and instantiate a gig
        the_band, the_member = self._create_test_band_with_member()
        the_gig = gig.new_gig(the_band, "Parade", the_member.key)

        # verify that we have one gig for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEqual(len(all_gigs),1)

        # sweep for trashed gigs and make sure we didn't lose this one
        gig_handlers._do_autoarchive()

        # verify that we have one gig for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEqual(len(all_gigs),1)

        # put the gig in the trash can 20 days ago
        the_gig.trashed_date = datetime.datetime.now() - datetime.timedelta(days=20)
        self.assertTrue(the_gig.is_in_trash)
        the_gig.put()

        # sweep for trashed gigs and make sure we didn't lose this one
        gig_handlers._do_autoarchive()

        # verify that we now have no gigs for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEmpty(all_gigs)

        # verify that we have one trashed gig
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = 0)
        self.assertEqual(len(trash_gigs),1)

        # verify that we have no month-old trashed gigs
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = 30)
        self.assertEmpty(trash_gigs)

        # put the gig in the trash can 31 days ago
        the_gig.trashed_date = datetime.datetime.now() - datetime.timedelta(days=31)
        the_gig.put()

        # sweep for trashed gigs and make sure we didn't lose this one
        gig_handlers._do_autoarchive()

        # verify that we now have no gigs for this band
        all_gigs = gig.get_gigs_for_band_keys([the_band.key])
        self.assertEmpty(all_gigs)

        # verify that we have no trashed gig
        trash_gigs = gig.get_old_trashed_gigs(minimum_age = 0)
        self.assertEmpty(trash_gigs)
Example #6
0
    def test_rest_api_agenda(self):
        # Create band with member and instantiate a gig
        the_band, the_member = self._create_test_band_with_member()

        # verify that we have no gig for this band
        (upcoming_plans, weighin_plans, number_of_bands) = agenda._get_agenda_contents_for_member(the_member)
        self.assertEmpty(upcoming_plans)
        self.assertEmpty(weighin_plans)

        # add a gig
        the_gig = gig.new_gig(the_band, "Parade", the_member.key, date=datetime.datetime.now() + datetime.timedelta(days=2))

        # verify that we now have one gig for this band
        (upcoming_plans, weighin_plans, number_of_bands) = agenda._get_agenda_contents_for_member(the_member)
        self.assertEmpty(upcoming_plans)
        self.assertEqual(len(weighin_plans),1)
        self.assertEqual(len(weighin_plans[0].keys()),6)
Example #7
0
def test_band():
    """make some test data"""

    # delete the data if there is any
    # Clear datastore entities
    #      for model in [band.Band, member.Member, assoc.Assoc, gig.Gig, plan.Plan]:
    #          ndb.delete_multi(model.query().fetch(999999, keys_only=True))
    #
    #      # Clear memcache
    #      ndb.get_context().clear_cache()

    def make_if_not_here(name):
        the_band = band.get_band_from_name(name)
        if the_band is None:
            the_band = band.new_band(name=name)
        return the_band

#     member1 = member.new_member(name='Aaron', email='*****@*****.**', nickname='aoppenheimer', role=1)
#     member2 = member.new_member(name='Maury', nickname='mmartin')
#     member3 = member.new_member(name='Kate', email='*****@*****.**', nickname='katervw')

    slsaps = make_if_not_here("SLSAPS")
    make_if_not_here("EmperorNorton")
    ee = make_if_not_here("EE")

    #     assoc.new_association(slsaps,member1)
    #     assoc.new_association(ee,member1)
    #     assoc.new_association(slsaps,member2)
    #     assoc.new_association(slsaps,member3)

    # make a pile of random gigs for a couple of months
    n = 1
    for m in range(9, 12):
        for i in range(1, 5):
            d = int(random.random() * 30) + 1
            g1 = gig.new_gig(the_band=slsaps,
                             title="test gig {0}".format(n),
                             date=datetime.datetime.strptime(
                                 "{0}/{1}/2013".format(m, d),
                                 '%m/%d/%Y').date())
            n = n + 1
Example #8
0
def test_band():
    """make some test data"""

# delete the data if there is any
# Clear datastore entities
#      for model in [band.Band, member.Member, assoc.Assoc, gig.Gig, plan.Plan]:
#          ndb.delete_multi(model.query().fetch(999999, keys_only=True))
#   
#      # Clear memcache
#      ndb.get_context().clear_cache()      


    def make_if_not_here(name):
        the_band=band.get_band_from_name(name)
        if the_band is None:
            the_band=band.new_band(name=name)
        return the_band
    
#     member1 = member.new_member(name='Aaron', email='*****@*****.**', nickname='aoppenheimer', role=1)
#     member2 = member.new_member(name='Maury', nickname='mmartin')
#     member3 = member.new_member(name='Kate', email='*****@*****.**', nickname='katervw')
    
    slsaps=make_if_not_here("SLSAPS")
    make_if_not_here("EmperorNorton")
    ee=make_if_not_here("EE")

#     assoc.new_association(slsaps,member1)
#     assoc.new_association(ee,member1)
#     assoc.new_association(slsaps,member2)
#     assoc.new_association(slsaps,member3)

    # make a pile of random gigs for a couple of months
    n=1
    for m in range(9,12):
        for i in range(1,5):
            d=int(random.random()*30)+1
            g1 = gig.new_gig(the_band=slsaps, title="test gig {0}".format(n),
                             date=datetime.datetime.strptime("{0}/{1}/2013".format(m,d),'%m/%d/%Y').date())
            n = n + 1
Example #9
0
    def test_rest_api_agenda(self):
        # Create band with member and instantiate a gig
        the_band, the_member = self._create_test_band_with_member()

        # verify that we have no gig for this band
        (upcoming_plans, weighin_plans,
         number_of_bands) = agenda._get_agenda_contents_for_member(the_member)
        self.assertEmpty(upcoming_plans)
        self.assertEmpty(weighin_plans)

        # add a gig
        the_gig = gig.new_gig(the_band,
                              "Parade",
                              the_member.key,
                              date=datetime.datetime.now() +
                              datetime.timedelta(days=2))

        # verify that we now have one gig for this band
        (upcoming_plans, weighin_plans,
         number_of_bands) = agenda._get_agenda_contents_for_member(the_member)
        self.assertEmpty(upcoming_plans)
        self.assertEqual(len(weighin_plans), 1)
        self.assertEqual(len(weighin_plans[0].keys()), 6)
Example #10
0
    def test_rest_api_agenda(self):
        # Create band with member and instantiate a gig
        the_band, the_member = self._create_test_band_with_member()

        # verify that we have no gig for this band
        the_agenda = agenda._RestGetAgenda(the_member)
        self.assertEqual(len(the_agenda.keys()), 2)
        self.assertEmpty(the_agenda['upcoming_plans'])
        self.assertEmpty(the_agenda['weighin_plans'])

        # add a gig
        the_gig = gig.new_gig(the_band,
                              "Parade",
                              the_member.key,
                              date=datetime.datetime.now() +
                              datetime.timedelta(days=2))

        # verify that we now have one gig for this band
        the_agenda = agenda._RestGetAgenda(the_member)
        self.assertEmpty(the_agenda['upcoming_plans'])
        self.assertEqual(len(the_agenda['weighin_plans']), 1)
        self.assertEqual(len(the_agenda['weighin_plans'][0].keys()), 5)
        self.assertEqual(the_agenda['weighin_plans'][0]['title'], "Parade")
Example #11
0
    def post(self):
        """post handler - if we are edited by the template, handle it here 
           and redirect back to info page"""

        the_gig_key = self.request.get("gk", '0')

        if (the_gig_key == '0'):
            the_gig = None
        else:
            the_gig = gig.gig_key_from_urlsafe(the_gig_key).get()

        edit_date_change = False
        edit_time_change = False
        edit_status_change = False
        edit_detail_change = False

        # first, get the band
        gig_is_new = False
        gig_band_keyurl = self.request.get("gig_band", None)
        if gig_band_keyurl is not None and gig_band_keyurl != '':
            the_band = band.band_key_from_urlsafe(gig_band_keyurl).get()
            if the_gig is None:
                the_gig = gig.new_gig(title="tmp",
                                      the_band=the_band,
                                      creator=self.user.key)
                gig_is_new = True

        # are we authorized to edit a gig for this band?
        ok_band_list = self.user.get_add_gig_band_list(self, self.user.key)
        if not the_band.key in [x.key for x in ok_band_list]:
            logging.error(u'user {0} trying to edit a gig for band {1}'.format(
                self.user.key.urlsafe(), the_band.key.urlsafe()))
            return self.redirect('/')

        # now get the info
        gig_title = self.request.get("gig_title", None)
        if gig_title is not None and gig_title != '':
            the_gig.title = gig_title

        gig_contact = self.request.get("gig_contact", None)
        if gig_contact is not None and gig_contact != '':
            the_gig.contact = member.member_key_from_urlsafe(gig_contact)

        gig_details = self.request.get("gig_details", None)
        if gig_details is not None:
            the_gig.details = gig_details

        gig_setlist = self.request.get("gig_setlist", None)
        if gig_setlist is not None:
            the_gig.setlist = gig_setlist

        gig_rssdescription = self.request.get("gig_rssdescription", None)
        if gig_rssdescription is not None:
            the_gig.rss_description = gig_rssdescription

        gig_date = self.request.get("gig_date", None)
        if gig_date is not None and gig_date != '':
            old_date = the_gig.date
            the_gig.date = datetime.datetime.combine(
                babel.dates.parse_date(gig_date,
                                       locale=self.user.preferences.locale),
                datetime.time(0, 0, 0))
            if old_date != the_gig.date:
                edit_date_change = True

        # todo validate form entry so date isn't bogus

        gig_enddate = self.request.get("gig_enddate", None)
        old_enddate = the_gig.enddate
        if gig_enddate is not None and gig_enddate != '':
            the_gig.enddate = datetime.datetime.combine(
                babel.dates.parse_date(gig_enddate,
                                       locale=self.user.preferences.locale),
                datetime.time(0, 0, 0))
        else:
            the_gig.enddate = None
        if old_enddate != the_gig.enddate:
            edit_date_change = True

        gig_call = self.request.get("gig_call", '')
        if gig_call is not None:
            if the_gig.calltime != gig_call:
                the_gig.set_calltime(gig_call)
                edit_time_change = True

        gig_set = self.request.get("gig_set", '')
        if gig_set is not None:
            if the_gig.settime != gig_set:
                the_gig.set_settime(gig_set)
                edit_time_change = True

        gig_end = self.request.get("gig_end", '')
        if gig_end is not None:
            if the_gig.endtime != gig_end:
                the_gig.set_endtime(gig_end)
                edit_time_change = True

        gig_address = self.request.get("gig_address", '')
        if gig_address is not None:
            the_gig.address = gig_address

        gig_dress = self.request.get("gig_dress", '')
        if gig_dress is not None:
            the_gig.dress = gig_dress

        gig_paid = self.request.get("gig_paid", '')
        if gig_paid is not None:
            the_gig.paid = gig_paid

        gig_leader = self.request.get("gig_leader", '')
        if gig_leader is not None:
            the_gig.leader = gig_leader

        gig_postgig = self.request.get("gig_postgig", '')
        if gig_postgig is not None:
            the_gig.postgig = gig_postgig

        gig_status = self.request.get("gig_status", '0')
        old_status = the_gig.status
        the_gig.status = int(gig_status)
        if old_status != the_gig.status:
            edit_status_change = True

        gig_invite_occasionals = self.request.get("gig_invite_occasionals",
                                                  None)
        if (gig_invite_occasionals):
            the_gig.invite_occasionals = True
        else:
            the_gig.invite_occasionals = False

        gig_hide_from_calendar = self.request.get("gig_hide_from_calendar",
                                                  None)
        if (gig_hide_from_calendar):
            the_gig.hide_from_calendar = True
        else:
            the_gig.hide_from_calendar = False

        gig_private = self.request.get("gig_private", None)
        if (gig_private):
            the_gig.is_private = True
        else:
            the_gig.is_private = False

        gig_default_to_attending = self.request.get("default_to_attend", None)
        if (gig_default_to_attending):
            logging.info("\n\nattending!\n\n")
            the_gig.default_to_attending = True

        the_gig.put()

        # Is this a series?
        is_series = self.request.get("newgig_isseries", False)
        if is_series:
            number_to_copy = int(self.request.get("newgig_seriescount", 1)) - 1
            period = self.request.get("newgig_seriesperiod", None)

            last_date = the_gig.date
            if period == 'day':
                delta = datetime.timedelta(days=1)
            elif period == 'week':
                delta = datetime.timedelta(weeks=1)
            else:
                day_of_month = last_date.day

            if the_gig.enddate:
                end_delta = the_gig.enddate - the_gig.date
            else:
                end_delta = None

            newgigs = []
            for i in range(0, number_to_copy):
                copy_gig = clone.clone_entity(the_gig, gig.Gig)
                if period == 'day' or period == 'week':
                    last_date = last_date + delta
                else:
                    # figure out what the next month is
                    if last_date.month < 12:
                        mo = last_date.month + 1
                        yr = last_date.year
                    else:
                        mo = 1
                        yr = last_date.year + 1
                    # figure out last day of next month
                    nextmonth = last_date.replace(month=mo, day=1, year=yr)
                    nextnextmonth = (nextmonth +
                                     datetime.timedelta(days=35)).replace(
                                         day=1)
                    lastday = (nextnextmonth - datetime.timedelta(days=1)).day
                    if lastday < day_of_month:
                        day_of_gig = lastday
                    else:
                        day_of_gig = day_of_month
                    last_date = last_date.replace(month=mo,
                                                  day=day_of_gig,
                                                  year=yr)
                copy_gig.date = last_date

                if end_delta is not None:
                    copy_gig.enddate = copy_gig.date + end_delta

                newgigs.append(copy_gig)

            if newgigs:
                ndb.put_multi(newgigs)

        gig_notify = self.request.get("gig_notifymembers", None)

        if gig_notify is not None:
            if gig_is_new:
                goemail.announce_new_gig(the_gig,
                                         self.uri_for(
                                             'gig_info',
                                             _full=True,
                                             gk=the_gig.key.urlsafe()),
                                         is_edit=False)
            else:
                if edit_time_change or edit_date_change or edit_status_change:
                    change_strings = []
                    if edit_time_change:
                        change_strings.append(_('Time'))
                    if edit_date_change:
                        change_strings.append(_('Date'))
                    if edit_status_change:
                        change_strings.append(_('Status'))
                    change_str = ', '.join(change_strings)
                else:
                    change_str = _('Details')
                goemail.announce_new_gig(the_gig,
                                         self.uri_for(
                                             'gig_info',
                                             _full=True,
                                             gk=the_gig.key.urlsafe()),
                                         is_edit=True,
                                         change_string=change_str)

        if (the_band.rss_feed):
            rss.make_rss_feed_for_band(the_band)

        band.make_band_cal_dirty(the_band)

        return self.redirect(\
            '/gig_info.html?&gk={0}'.format(the_gig.key.urlsafe()))
Example #12
0
 def _create_test_gig(self, band, name):
     the_gig = gig.new_gig(band, name, None)
     self.assertIsNotNone(the_gig, "did not create gig " + name)
     return (the_gig)
Example #13
0
 def _create_test_gig(self, band, name):
     the_gig = gig.new_gig(band, name, None)
     self.assertIsNotNone(the_gig, "did not create gig " + name)
     return (the_gig)
Example #14
0
    def post(self):
        """post handler - if we are edited by the template, handle it here 
           and redirect back to info page"""


        the_gig_key = self.request.get("gk", '0')
        
        if (the_gig_key == '0'):
            the_gig = None
        else:
            the_gig = gig.gig_key_from_urlsafe(the_gig_key).get()

        edit_date_change = False
        edit_time_change = False
        edit_status_change = False
        edit_detail_change = False

        # first, get the band
        gig_is_new = False
        gig_band_keyurl = self.request.get("gig_band", None)
        if gig_band_keyurl is not None and gig_band_keyurl != '':
            the_band = band.band_key_from_urlsafe(gig_band_keyurl).get()
            if the_gig is None:
                the_gig = gig.new_gig(title="tmp", the_band=the_band, creator=self.user.key)
                gig_is_new = True

        # are we authorized to edit a gig for this band?
        ok_band_list = self.user.get_add_gig_band_list(self, self.user.key)
        if not the_band.key in [x.key for x in ok_band_list]:
            logging.error(u'user {0} trying to edit a gig for band {1}'.format(self.user.key.urlsafe(),the_band.key.urlsafe()))
            return self.redirect('/')            

        # now get the info
        gig_title = self.request.get("gig_title", None)
        if gig_title is not None and gig_title != '':
            the_gig.title = gig_title
        
        gig_contact = self.request.get("gig_contact", None)
        if gig_contact is not None and gig_contact != '':
            the_gig.contact = member.member_key_from_urlsafe(gig_contact)
        
        gig_details = self.request.get("gig_details", None)
        if gig_details is not None:
            the_gig.details = gig_details

        gig_setlist = self.request.get("gig_setlist", None)
        if gig_setlist is not None:
            the_gig.setlist = gig_setlist

        gig_rssdescription = self.request.get("gig_rssdescription", None)
        if gig_rssdescription is not None:
            the_gig.rss_description = gig_rssdescription

        gig_date = self.request.get("gig_date", None)
        if gig_date is not None and gig_date != '':
            old_date = the_gig.date
            the_gig.date = datetime.datetime.combine(babel.dates.parse_date(gig_date,locale=self.user.preferences.locale),datetime.time(0,0,0))
            if old_date != the_gig.date:
                edit_date_change = True
                
        # todo validate form entry so date isn't bogus
       
        gig_enddate = self.request.get("gig_enddate", None)
        old_enddate = the_gig.enddate
        if gig_enddate is not None and gig_enddate != '':
            the_gig.enddate = datetime.datetime.combine(babel.dates.parse_date(gig_enddate,locale=self.user.preferences.locale),datetime.time(0,0,0))
        else:
            the_gig.enddate = None
        if old_enddate != the_gig.enddate:
            edit_date_change = True

        gig_call = self.request.get("gig_call", '')
        if gig_call is not None:
            if the_gig.calltime != gig_call:
                the_gig.set_calltime(gig_call)
                edit_time_change = True

        gig_set = self.request.get("gig_set", '')
        if gig_set is not None:
            if the_gig.settime != gig_set:
                the_gig.set_settime(gig_set)
                edit_time_change = True

        gig_end = self.request.get("gig_end", '')
        if gig_end is not None:
            if the_gig.endtime != gig_end:
                the_gig.set_endtime(gig_end)
                edit_time_change = True

        gig_address = self.request.get("gig_address", '')
        if gig_address is not None:
            the_gig.address = gig_address

        gig_dress = self.request.get("gig_dress", '')
        if gig_dress is not None:
            the_gig.dress = gig_dress

        gig_paid = self.request.get("gig_paid", '')
        if gig_paid is not None:
            the_gig.paid = gig_paid

        gig_leader = self.request.get("gig_leader", '')
        if gig_leader is not None:
            the_gig.leader = gig_leader
        
        gig_postgig = self.request.get("gig_postgig", '')
        if gig_postgig is not None:
            the_gig.postgig = gig_postgig

        gig_status = self.request.get("gig_status", '0')
        old_status = the_gig.status
        the_gig.status = int(gig_status)
        if old_status != the_gig.status:
            edit_status_change = True

        gig_invite_occasionals=self.request.get("gig_invite_occasionals",None)
        if (gig_invite_occasionals):
            the_gig.invite_occasionals = True
        else:
            the_gig.invite_occasionals = False

        gig_hide_from_calendar=self.request.get("gig_hide_from_calendar",None)
        if (gig_hide_from_calendar):
            the_gig.hide_from_calendar = True
        else:
            the_gig.hide_from_calendar = False


        gig_private=self.request.get("gig_private",None)
        if (gig_private):
            the_gig.is_private = True
        else:
            the_gig.is_private = False

        gig_default_to_attending = self.request.get("default_to_attend",None)
        if (gig_default_to_attending):
            logging.info("\n\nattending!\n\n")
            the_gig.default_to_attending = True

        the_gig.put()

        # Is this a series?
        is_series = self.request.get("newgig_isseries", False)
        if is_series:
            number_to_copy = int(self.request.get("newgig_seriescount",1)) - 1
            period = self.request.get("newgig_seriesperiod",None)
            
            last_date = the_gig.date
            if period == 'day':
                delta = datetime.timedelta(days=1)
            elif period == 'week':
                delta = datetime.timedelta(weeks=1)
            else:
                day_of_month = last_date.day
                
            if the_gig.enddate:
                end_delta = the_gig.enddate - the_gig.date
            else:
                end_delta = None

            newgigs=[]                
            for i in range(0, number_to_copy):
                copy_gig = clone.clone_entity(the_gig, gig.Gig)
                if period == 'day' or period == 'week':
                    last_date = last_date + delta
                else:
                    # figure out what the next month is
                    if last_date.month< 12:
                        mo = last_date.month+1
                        yr = last_date.year
                    else:
                        mo = 1
                        yr = last_date.year+1
                    # figure out last day of next month
                    nextmonth = last_date.replace(month=mo, day=1, year=yr)
                    nextnextmonth = (nextmonth + datetime.timedelta(days=35)).replace(day=1)
                    lastday=(nextnextmonth - datetime.timedelta(days=1)).day
                    if lastday < day_of_month:
                        day_of_gig = lastday
                    else:
                        day_of_gig = day_of_month
                    last_date = last_date.replace(month=mo, day=day_of_gig, year=yr)
                copy_gig.date = last_date
                
                if end_delta is not None:
                    copy_gig.enddate = copy_gig.date + end_delta

                newgigs.append(copy_gig)

            if newgigs:
                ndb.put_multi(newgigs)

        gig_notify = self.request.get("gig_notifymembers", None)

        if gig_notify is not None:
            if gig_is_new:
                goemail.announce_new_gig(the_gig, self.uri_for('gig_info', _full=True, gk=the_gig.key.urlsafe()), is_edit=False)
            else:
                if edit_time_change or edit_date_change or edit_status_change:
                    change_strings=[]
                    if edit_time_change:
                        change_strings.append(_('Time'))
                    if edit_date_change:
                        change_strings.append(_('Date'))
                    if edit_status_change:
                        change_strings.append(_('Status'))
                    change_str = ', '.join(change_strings)
                else:
                    change_str = _('Details')
                goemail.announce_new_gig(the_gig, self.uri_for('gig_info', _full=True, gk=the_gig.key.urlsafe()), is_edit=True, change_string=change_str)

        if (the_band.rss_feed):
            rss.make_rss_feed_for_band(the_band)

        band.make_band_cal_dirty(the_band)

        return self.redirect(\
            '/gig_info.html?&gk={0}'.format(the_gig.key.urlsafe()))