def remove(request, key): if request.method != 'POST': return MethodNotAllowed() if request.user.is_anonymous(): return Unauthorized() recipe = models.Recipe.get(key) if not recipe: return NotFound() # Użytkownik może usunąć swój publiczny przepis tą metodą, ale nie jest to reklamowane! if not (request.user.is_admin or request.user.key() == recipe.parent_key()): return Unauthorized() # Jeśli jest już wyłączony, wykonaj prostsze kroki usuwające if recipe.disabled: to_delete = models.RecipeIngr.all().ancestor(recipe).fetch(20) db.delete(to_delete) Counter.remove_by_name(SHARD_RECIPE_KEY % recipe.key()) recipe.delete() else: # Zmień status na wyłączony recipe.disabled = True recipe.put() # Usuń liczniki, składniki i użytkownika to_delete = models.RecipeIngr.all().ancestor(recipe).fetch(20) db.delete(to_delete) Counter.remove_by_name(SHARD_RECIPE_KEY % recipe.key()) if recipe.rec_vis == VISIBILITY[2]: def utx(): user = PMMUser.get(recipe.parent_key()) user.rec_pub -= 1 if user.rec_pub < 0: user.rec_pub = 0 user.put() cache_delete('gfcu', recipe.parent_key().name()) db.run_in_transaction(utx) # na później odłóż indeksację, uaktualnienie tagów i licznika kategorii deferred_lib.defer(deferred.recipe_update, recipe.key(), 'delete') request.notifications.success('Przepis usunięty!') return render_json_response({'redirectUrl': url_for('przepisy/my_list')})
def count_view(request, key): try: db_key = db.Key(key) if db_key.kind() == 'Recipe': shard_key = SHARD_RECIPE_KEY % key else: shard_key = None if shard_key: Counter.incr(shard_key) except: # Don't care that much if something got wrong logging.exception('Error in count view') pass response = Response('GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;', mimetype='image/gif') response.expires = datetime.datetime(2009, 1, 1) response.cache_control.must_revalidate = True return response
def recalculate_views(start_key=None): def tx(key, incr): recipe = Recipe.get(db.Key(key)) if recipe: recipe.views += incr to_db = [recipe] idx = RecipeIdx.get(db.Key.from_path('RecipeIdx', 'idx', parent=recipe.key())) if idx: idx.views = recipe.views to_db.append(idx) fri = RecipeFriends.get(db.Key.from_path('RecipeFriends', 'fri', parent=recipe.key())) if fri: fri.views = recipe.views to_db.append(fri) db.put(to_db) return True while (True): try: counters = Counter.all() if start_key: counters.filter('__key__ >', start_key) counters.order('__key__') counters = counters.fetch(20) if not counters: break else: start_key = None for counter in counters: _key = counter.key().name() if _key.startswith(SHARD_RECIPE_KEY % u''): if db.run_in_transaction(tx, _key.split('|')[1], counter.counter): key_tmp = counter.key() counter.delete() start_key = key_tmp except (DeadlineExceededError), e: deferred_lib.defer(recalculate_views, start_key) except (CapabilityDisabledError, Timeout), e: break # End if there is no more time...
def post(self): if self.form.validate(self.request.form): try: # utwórz przepis recipe = models.Recipe( parent=self.request.user, key_name=slugify(self.form['title']), title=self.form['title'], recipe=self.form['recipe'], recipe_html=markdown2html(self.form['recipe']), tags=models.Tag.split_elements(self.form['tags']), category=self.form['category'], phase=self.form['phase'], type=self.form['type'], ig=self.form['ig'], time=int(self.form['time']), rec_vis=self.form['rec_vis'], ingr_count=len(self.form['ingr']), disabled=False ) # zapisz dane przepisu recipe.put() # dodaj osobno skladniki # + AC składników ingr_to_save = [] for i, ingr in enumerate(self.form['ingr']): ingr_to_save.append(models.RecipeIngr(parent=recipe, key_name='%2d'%(i+1), product=ingr['product'], portion=ingr['portion'], weight=ingr['weight'])) ingr_to_save.append(models.IngrACIndex(key_name=ingr['product'], idx=models.IngrACIndex.make_index(ingr['product']))) db.put(ingr_to_save) # uaktualnij użytkownika if recipe.rec_vis == VISIBILITY[2]: def utx(): user = PMMUser.get(self.request.user.key()) user.rec_pub += 1 user.put() cache_delete('gfcu', self.request.user.key().name()) db.run_in_transaction(utx) # Dodaj podwójny licznik... Counter.init_shards(SHARD_RECIPE_KEY % recipe.key(), 2) # 2 means about 15 writes/s per recipe # na później odłóż indeksację, uaktualnienie tagów i licznika kategorii deferred_lib.defer(deferred.recipe_update, recipe.key(), 'add') # wyślij powiadomienie o dodaniu przepisu! if recipe.rec_vis != VISIBILITY[0]: try: create_activity(self.request.user.key().name(), u'%s dodał(a) przepis <a href="%s">%s</a>' % (self.request.user.display_name, recipe.get_url(True), recipe.title), u'Przejrzyj go, oceń lub dodaj do ulubionych.' ) except Exception, e: pass self.request.notifications.success('Przepis dodany!') return redirect(recipe.get_url()) except Exception, e: logging.exception('Recipe add failed (%s): ' % self.request.user + str(e)) self.request.notifications.error('Przepisu nie dodano! Wystąpił błąd zapisu, spróbuj ponownie...')