Пример #1
0
def json_add_suggestion(request):
    if request.method == "POST":
        text = request.POST.get('addSuggestion', '(someone input invalid text)')
        sug = Suggestion(text=text)
        sug.save()
        return HttpResponseRedirect('/thanks_for_suggestion')
    return HttpResponse("failure")
def add_keyword(bot, update, chat_data):
    user = User.from_telegram_object(update.effective_user)
    if check_suggestion_limit(bot, update, user):
        return
    kw = update.message.text
    bot_to_edit = chat_data.get('edit_bot')
    kw = helpers.format_keyword(kw)

    # Sanity checks
    if kw in settings.FORBIDDEN_KEYWORDS:
        update.message.reply_text('The keyword {} is forbidden.'.format(kw))
        return
    if len(kw) <= 1:
        update.message.reply_text('Keywords must be longer than 1 character.')
        return
    if len(kw) >= 20:
        update.message.reply_text(
            'Keywords must not be longer than 20 characters.')

    # Ignore duplicates
    try:
        Keyword.get((Keyword.name == kw) & (Keyword.entity == bot_to_edit))
        return
    except Keyword.DoesNotExist:
        pass

    Suggestion.add_or_update(user=user,
                             action='add_keyword',
                             subject=bot_to_edit,
                             value=kw)
    set_keywords(bot, update, chat_data, bot_to_edit)
    Statistic.of(update, 'added keyword to'.format(kw), bot_to_edit.username)
Пример #3
0
 def post(self):
     suggestion = Suggestion(title=self.request.get('title'),
                             content=self.request.get('content'))
     suggestion.put()
     self.response.out.write(
         self._render_template('thank_you.html')
     )
def accept_suggestion(bot, update, suggestion: Suggestion):
    user = User.from_telegram_object(update.effective_user)
    suggestion.apply()

    if suggestion.action == 'offline':
        suggestion_text = '{} went {}.'.format(
            suggestion.subject.str_no_md,
            'offline' if suggestion.subject.offline else 'online')
    else:
        suggestion_text = str(suggestion)

    suggestion_text = suggestion_text[0].upper() + suggestion_text[1:]
    suggestion_text += '\nApproved by ' + user.markdown_short
    bot.send_message(settings.BOTLIST_NOTIFICATIONS_ID,
                     suggestion_text,
                     parse_mode='markdown',
                     disable_web_page_preview=True)

    if user != suggestion.user.chat_id:
        submittant_notification = '*Thank you* {}, your suggestion has been accepted:' \
                                  '\n\n{}'.format(util.escape_markdown(suggestion.user.first_name),
                                                  str(suggestion))
        try:
            bot.send_message(suggestion.user.chat_id,
                             submittant_notification,
                             parse_mode='markdown',
                             disable_web_page_preview=True)
        except BadRequest:
            update.effective_message.reply_text("Could not contact {}.".format(
                suggestion.user.markdown_short),
                                                parse_mode='markdown',
                                                disable_web_page_preview=True)
def set_text_property(bot, update, chat_data, property_name, to_edit=None):
    uid = util.uid_from_update(update)
    user = User.from_update(update)
    if check_suggestion_limit(bot, update, user):
        return

    if to_edit:
        text = (util.escape_markdown(getattr(to_edit, property_name)) +
                "\n\n" if getattr(to_edit, property_name) else '')
        text += mdformat.action_hint(
            messages.SET_BOTPROPERTY.format(
                property_name, util.escape_markdown(to_edit.username),
                CLEAR_QUERY))
        if property_name == 'description':
            text += ', markdown enabled.'
        update.effective_message.reply_text(
            text,
            reply_markup=ForceReply(selective=True),
            parse_mode=ParseMode.MARKDOWN)
        chat_data['edit_bot'] = to_edit
    elif update.message:
        value = None
        text = update.message.text

        to_edit = chat_data.get('edit_bot', None)

        def too_long(n):
            bot.formatter.send_failure(
                uid, "Your {} text is too long, it must be shorter "
                "than {} characters. Please try again.".format(
                    property_name, n))
            util.wait(bot, update)
            return admin.edit_bot(bot, update, chat_data, to_edit)

        # Validation
        if property_name == 'description' and len(text) > 300:
            return too_long(300)
        if property_name == 'username':
            value = helpers.validate_username(text)
            if value:
                to_edit = chat_data.get('edit_bot', None)
            else:
                bot.formatter.send_failure(
                    uid,
                    "The username you entered is not valid. Please try again..."
                )
                return admin.edit_bot(bot, update, chat_data, to_edit)

        if not value:
            value = text

        if to_edit:
            if _is_clear_query(text):
                Suggestion.add_or_update(user, property_name, to_edit, None)
            else:
                Suggestion.add_or_update(user, property_name, to_edit, value)
            admin.edit_bot(bot, update, chat_data, to_edit)
        else:
            bot.formatter.send_failure(uid, "An unexpected error occured.")
def remove_keyword(bot, update, chat_data, context):
    user = User.from_telegram_object(update.effective_user)
    if check_suggestion_limit(bot, update, user):
        return
    to_edit = context.get('to_edit')
    kw = context.get('keyword')
    Suggestion.add_or_update(user=user,
                             action='remove_keyword',
                             subject=to_edit,
                             value=kw.name)
    return set_keywords(bot, update, chat_data, to_edit)
Пример #7
0
    def add_suggestions(payload):
        body = request.get_json()
        suggestion = body.get('suggestion', None)
        category = body.get('category', None)

        new_sug = Suggestion(suggestion=suggestion, category=category)
        new_sug.insert()

        all_suggestions = Suggestion.query.all()
        formatted_sugg = [sug.format() for sug in all_suggestions]
        return jsonify({'success': True, 'all_suggestion': formatted_sugg})
def change_category(bot, update, to_edit, category):
    uid = update.effective_user.id
    user = User.get(User.chat_id == uid)

    if uid == 918962:
        # Special for t3chno
        to_edit.category = category
        to_edit.save()
    else:
        if check_suggestion_limit(bot, update, user):
            return
        Suggestion.add_or_update(user, 'category', to_edit, category.id)
def set_country(bot, update, to_edit, country):
    user = User.from_update(update)

    if check_suggestion_limit(bot, update, user):
        return
    if isinstance(country, Country):
        value = country.id
    elif country is None or country == 'None':
        value = None
    else:
        raise AttributeError("Error setting country to {}.".format(country))
    Suggestion.add_or_update(user, 'country', to_edit, value)
Пример #10
0
	def post(self):
		cancel = self.request.get('cancel')
		day = date.fromordinal(int(self.request.get('day')))
		
		if cancel == 'true':
			self.currentuser.lastvoted = day
			self.currentuser.put()
			self.render('thanks')
			return

		rating = int(self.request.get('rating'))

		restaurant = cgi.escape(self.request.get('restaurant'))
		
		if restaurant == "other":
			restaurant = cgi.escape(self.request.get('others'))
				
		suggestion = Suggestion.find(day, restaurant)
		author = suggestion.author if suggestion else None

		restaurant=db.get(restaurant)
		comment = cgi.escape(self.request.get('comment'))
		if comment != "":
			comment = comment.replace('\n', '<br/>')	
			comment = RestaurantComment(text=comment, restaurant=restaurant,
						author=self.currentuser, rating=rating)
			comment.put()

		self.add_rating(day, restaurant, author, rating)
		self.render_plain('thanks')
Пример #11
0
 def delete_suggestion(self, args, user):
     messages = []
     search = ''
     if len(args) <= 1:
         raise Exception(
             'Suggestion delte syntax\n```css\n.d suggestion delete "NAME"```'
         )
     if len(args) > 1:
         search = ' '.join(args[1:])
         suggestion = Suggestion().find(search)
     if not suggestion:
         return [f'_"{search}"_ was not found. No changes made.']
     else:
         search = str(suggestion.text)
         suggestion.archived = True
         self.save(suggestion, user)
         messages.append(f'***{search}*** removed')
         return messages
Пример #12
0
def apply_all_changes(bot, update, chat_data, to_edit):
    user = User.from_update(update)

    user_suggestions = Suggestion.select_all_of_user(user)
    for suggestion in user_suggestions:
        suggestion.apply()

    refreshed_bot = Bot.get(id=to_edit.id)
    edit_bot(bot, update, chat_data, refreshed_bot)
    Statistic.of(update, "apply", refreshed_bot.username)
Пример #13
0
 def get_by_sugid_user(self, sugid, user):
     if not isinstance(user, User):
         raise TypeError()
     try:
         sugid = long(sugid)
     except:
         return None
     sugkey = db.Key.from_path(Suggestion.kind(), sugid)
     return self._klass.all().filter('suggestion =',
                                     sugkey).filter('user =', user).get()
Пример #14
0
	def post(self):
		action = cgi.escape(self.request.get('action'))
		
		if action == 'add_suggestion':
			restaurant = cgi.escape(self.request.get('restaurant'))
			if restaurant == '':
				self.error(400)
				return

			sug = Suggestion(restaurant=db.get(restaurant), author=self.currentuser, 
							 group=self.currentgroup)
			sug.put()
			self.currentuser.lastposted = date.today()
			self.currentuser.put()
			notify_suggestion(sug)
			
		elif action == "remove_suggestion":
			suggestion = cgi.escape(self.request.get('suggestion'))
			suggestion = db.get(suggestion)
			if suggestion.author.user == self.currentuser.user:
				suggestion.delete()	
			else:
				logging.error('user: %s tried to delete suggestion he doesn\'t own' % self.currentuser.nickname)

		elif action == "add_comment":
			text = cgi.escape(self.request.get('text'))
			suggestion = db.get(cgi.escape(self.request.get('suggestion')))
			post_comment(text, self.currentuser, suggestion)
			
		elif action == "remove_comment":
			comment = cgi.escape(self.request.get('comment'))
			comment = db.get(comment)
			if comment.author.user == self.currentuser.user:
				comment.delete()
			else:
				logging.error('user: %s tried to delete comment he doesn\'t own' % self.currentuser.nickname)

		else:
			self.error(400)
			return
		
		self.get()
def check_suggestion_limit(bot, update, user):
    cid = update.effective_chat.id
    if Suggestion.over_limit(user):
        bot.formatter.send_failure(
            cid,
            "You have reached the limit of {} suggestions. Please wait for "
            "the Moderators to approve of some of them.".format(
                settings.SUGGESTION_LIMIT))
        Statistic.of(update, 'hit the suggestion limit')
        return True
    return False
Пример #16
0
def edit_bot(bot, update, chat_data, to_edit=None):
    uid = util.uid_from_update(update)
    message_id = util.mid_from_update(update)
    user = User.from_update(update)

    if not to_edit:
        if update.message:
            command = update.message.text

            if "edit" in command:
                b_id = re.match(r"^/edit(\d+)$", command).groups()[0]
            elif "approve" in command:
                b_id = re.match(r"^/approve(\d+)$", command).groups()[0]
            else:
                raise ValueError("No 'edit' or 'approve' in command.")

            try:
                to_edit = Bot.get(id=b_id)
            except Bot.DoesNotExist:
                update.message.reply_text(
                    util.failure("No bot exists with this id."))
                return
        else:
            bot.formatter.send_failure(uid, "An unexpected error occured.")
            return

    # if not to_edit.approved:
    #     return approve_bots(bot, update, override_list=[to_edit])

    pending_suggestions = Suggestion.pending_for_bot(to_edit, user)
    reply_markup = InlineKeyboardMarkup(
        _edit_bot_buttons(to_edit, pending_suggestions, uid
                          in settings.MODERATORS))
    pending_text = ("\n\n{} Some changes are pending approval{}.".format(
        captions.SUGGESTION_PENDING_EMOJI,
        "" if user.chat_id in settings.MODERATORS else " by a moderator",
    ) if pending_suggestions else "")
    meta_text = ("\n\nDate added: {}\nMember since revision {}\n"
                 "Submitted by {}\nApproved by {}".format(
                     to_edit.date_added,
                     to_edit.revision,
                     to_edit.submitted_by,
                     to_edit.approved_by,
                 ))
    bot.formatter.send_or_edit(
        uid,
        "🛃 Edit {}{}{}".format(
            to_edit.detail_text,
            meta_text if user.id in settings.MODERATORS else "",
            pending_text,
        ),
        to_edit=message_id,
        reply_markup=reply_markup,
    )
Пример #17
0
    def name(self, args):
        """Display and create a new Suggestion by name
        
        Parameters
        ----------
        args : list(str)
            List of strings with subcommands

        Returns
        -------
        list(str) - the response messages string array
        """

        messages = []
        if len(args) < 2:
            raise Exception('syntax: ```css\n.d suggest "SUGGESTION TEXT"```')
        suggestion = Suggestion().create_new(name=self.user.name,
                                             text=' '.join(args[1:]))
        messages.append(suggestion.get_string(self.user))
        return messages
Пример #18
0
    def test_edit_get_objet(self):
        view = EditSuggestionView()
        request = RequestFactory()
        view.request = request
        self.moxx.StubOutWithMock(views, 'get_client_ip')
        views.get_client_ip(request).AndReturn(self.ip)
        self.moxx.StubOutWithMock(Box, 'get_unread')
        Box.get_unread(self.ip).AndReturn(Suggestion(ip_address=self.ip))

        self.moxx.ReplayAll()
        view.get_object()
        self.moxx.VerifyAll()
Пример #19
0
def send_anime_recommendation(anime_lst, anime_id, comment, username,
                              curr_list):
    anime_by_id = next(item for item in anime_lst['results']
                       if item['mal_id'] == anime_id)
    suggestion = Suggestion(list_id=curr_list.id,
                            anime_id=anime_id,
                            anime_title=anime_by_id['title'],
                            mal_url=anime_by_id['url'],
                            comment=comment or 'No comment from suggester.',
                            username=username)
    db.session.add(suggestion)
    db.session.commit()
Пример #20
0
def cron_suggestions(request=None, cursor=None):
    q = Suggestion.all().filter('_vis =', 'public')
    if cursor is None:
        suggs = q.fetch(10)
    else:
        suggs = q.with_cursor(cursor).fetch(10)
    if len(suggs) >= 10:
        try:
            defer(cron_suggestions, cursor=q.cursor(), _queue="fusiontables")
        except PermanentTaskFailure, e:
            import logging
            logging.error('ERROR FUSIONTABLES update relevance: %s' % e)
Пример #21
0
def suggest(request):
  if request.method == 'POST':
    form = SuggestionForm(request.POST)
    if form.is_valid():
      clean_subject = form.cleaned_data['subject']
      clean_message = form.cleaned_data['message']
      clean_sender = form.cleaned_data.get('sender', '*****@*****.**')

      stamp = datetime.now()
      suggestion = Suggestion(
                        subject = clean_subject, 
                        message = clean_message, 
                        sender = clean_sender,
                        created = stamp,
                        last_modified = stamp
                        )
      suggestion.save()

      
      suggestion_email = render_to_string('email/suggestion_made.txt', 
            {
               'suggestion': suggestion
            })
      people_to_email = [settings.CSESOC_SUGGEST_LIST]
      if form.cleaned_data.get('sender'):
         people_to_email.append(clean_sender)

      # send an email to the suggestions mailing list
      send_mail(
            '[CSESoc Suggestion] %s' % clean_subject, 
            suggestion_email,
            clean_sender,
            people_to_email
            )

      return render_to_response('thanks-suggestion.html', context_instance=RequestContext(request))
  else:
    form = SuggestionForm()

  return render_to_response('suggest.html', context_instance=RequestContext(request, {'form': form}))
Пример #22
0
	def get(self):
		
		if self.currentuser.lastposted == None:
			self.redirect('/profile')
			return
		
		group = self.currentgroup
		
		context = { 'ask_to_rate' : can_vote(self.currentuser, self.currentgroup),
					'active_crew': get_active_crew(group),
					'dead_crew': get_dead_crew(group), 
					'suggestions': Suggestion.get_todays(group),
					'restaurants': Restaurant.get_for_group(group) }

		self.render('home', context)
Пример #23
0
def _admin_buttons(send_botlist_button=False, logs_button=False):
    n_unapproved = len(Bot.select().where(Bot.approved == False,
                                          Bot.disabled == False))
    n_suggestions = len(Suggestion.select_all())
    n_pending = len(Bot.select_pending_update())

    second_row = list()
    if n_unapproved > 0:
        second_row.append(
            KeyboardButton(
                captions.APPROVE_BOTS +
                " {}🆕".format(mdformat.number_as_emoji(n_unapproved))))
    if n_suggestions > 0:
        second_row.append(
            KeyboardButton(
                captions.APPROVE_SUGGESTIONS +
                " {}⁉️".format(mdformat.number_as_emoji(n_suggestions))))

    buttons = [
        [KeyboardButton(captions.EXIT),
         KeyboardButton(captions.REFRESH)],
        [
            KeyboardButton(captions.FIND_OFFLINE),
            KeyboardButton(captions.SEND_CONFIG_FILES),
        ],
    ]

    update_row = list()
    if n_pending > 0:
        update_row.append(
            KeyboardButton(captions.PENDING_UPDATE + " {}{}".format(
                mdformat.number_as_emoji(n_pending),
                captions.SUGGESTION_PENDING_EMOJI,
            )))
    if send_botlist_button:
        update_row.append(KeyboardButton(captions.SEND_BOTLIST))
    if logs_button:
        update_row.append(KeyboardButton(captions.SEND_ACTIVITY_LOGS))

    if len(update_row) > 0:
        buttons.insert(1, update_row)
    if len(second_row) > 0:
        buttons.insert(1, second_row)

    return buttons
Пример #24
0
def handle_suggestion_response(result, current_asset_id, asset_metas):
    for asset_meta in asset_metas:
        asset_id = asset_meta.asset_id
        # skip if it is the same id as the classified image
        if current_asset_id == asset_id:
            continue
        cropped_id = asset_meta.cropped_id
        path = fetch_cropped_path(asset_id, cropped_id)
        if asset_id not in result.suggestions:
            result.suggestions[asset_id] = Suggestion([Frame(cropped_id, asset_meta.faiss_idx, path)])
        else:
            contains = False
            for frame in result.suggestions[asset_id].frames:
                if frame.frame_id == cropped_id:
                    contains = True
                    break
            if not contains:
                result.suggestions[asset_id].frames += [Frame(cropped_id, asset_meta.faiss_idx, path)]
Пример #25
0
def ban_user(_bot, update, user: User, ban_state: bool):
    if user.banned and ban_state is True:
        update.message.reply_text(
            mdformat.none_action("User {} is already banned.".format(user)),
            parse_mode="markdown",
        )
        raise DispatcherHandlerStop
    if not user.banned and ban_state is False:
        update.message.reply_text(
            mdformat.none_action("User {} is not banned.".format(user)),
            parse_mode="markdown",
        )
        raise DispatcherHandlerStop
    user.banned = ban_state
    if ban_state is True:
        with db.atomic():
            user_submissions = Bot.select().where(
                (Bot.approved == False)
                & (Bot.submitted_by == user)
                # TODO: does this need to include `Bot.deleted == True`?
            )
            for b in user_submissions:
                b.delete_instance()

            users_suggestions = Suggestion.select().where(
                (Suggestion.executed == False) & (Suggestion.user == user))
            for s in users_suggestions:
                s.delete_instance()
        update.message.reply_text(
            mdformat.success(
                "User {} banned, all bot submissions and suggestions removed.".
                format(user)),
            parse_mode="markdown",
        )
        Statistic.of(update, "ban", user.markdown_short)
    else:
        update.message.reply_text(mdformat.success(
            "User {} unbanned.".format(user)),
                                  parse_mode="markdown")
        Statistic.of(update, "unban", user.markdown_short)
    user.save()
Пример #26
0
	def get(self):
		if is_morning():
			day = datetime.now() - timedelta(1)
			day_title = "yesterday"
		else:
			day = datetime.now()
			day_title = "today"
		
		suggestions = Suggestion.get_for_day(day, self.currentgroup)
		restaurants = [ s.restaurant for s in suggestions ]
		res_keys = [ r.key() for r in restaurants ]

		other_restaurants = []
		all_restaurants = Restaurant.gql("WHERE group=:1 ORDER BY name", self.currentgroup)
		for res in all_restaurants:
			if res.key() not in res_keys:
				other_restaurants.append(res)
				
		context = { 'day': day.toordinal(),
					'day_title': day_title, 
					'restaurants': restaurants,
					'other_restaurants': other_restaurants }			
		self.render('rate', context)		
Пример #27
0
def register(dp: Dispatcher, bot_checker: "BotChecker"):
    def add(*args, **kwargs):
        dp.add_handler(*args, **kwargs)

    keywords_handler = ConversationHandler(
        entry_points=[
            InlineCallbackHandler(
                CallbackActions.EDIT_BOT_KEYWORDS,
                botproperties.set_keywords_init,
                serialize=lambda data: dict(to_edit=Bot.get(id=data["id"])),
                pass_chat_data=True,
            )
        ],
        states={
            BotStates.SENDING_KEYWORDS: [
                MessageHandler(Filters.text,
                               botproperties.add_keyword,
                               pass_chat_data=True),
                InlineCallbackHandler(
                    CallbackActions.REMOVE_KEYWORD,
                    botproperties.remove_keyword,
                    serialize=lambda data: dict(
                        to_edit=Bot.get(id=data["id"]),
                        keyword=Keyword.get(id=data["kwid"]),
                    ),
                    pass_chat_data=True,
                ),
                InlineCallbackHandler(
                    CallbackActions.DELETE_KEYWORD_SUGGESTION,
                    botproperties.delete_keyword_suggestion,
                    serialize=lambda data: dict(
                        to_edit=Bot.get(id=data["id"]),
                        suggestion=Suggestion.get(id=data["suggid"]),
                    ),
                    pass_chat_data=True,
                ),
            ]
        },
        fallbacks=[
            CallbackQueryHandler(
                callback_router,
                pass_chat_data=True,
                pass_user_data=True,
                pass_job_queue=True,
            )
        ],
        per_user=True,
        allow_reentry=False,
    )
    add(keywords_handler)

    broadcasting_handler = ConversationHandler(
        entry_points=[
            InlineCallbackHandler("broadcast",
                                  broadcasts.broadcast,
                                  pass_user_data=True),
            CommandHandler("broadcast",
                           broadcasts.broadcast,
                           pass_user_data=True),
            CommandHandler("bc", broadcasts.broadcast, pass_user_data=True),
        ],
        states={
            BotStates.BROADCASTING: [
                MessageHandler(Filters.text,
                               broadcasts.broadcast_preview,
                               pass_user_data=True)
            ]
        },
        fallbacks=[],
        per_user=True,
        per_chat=False,
        allow_reentry=True,
    )
    add(broadcasting_handler)

    add(
        CallbackQueryHandler(
            callback_router,
            pass_chat_data=True,
            pass_user_data=True,
            pass_job_queue=True,
        ))

    add(
        CommandHandler(("cat", "category", "categories"),
                       select_category,
                       pass_chat_data=True))
    add(
        CommandHandler(("s", "search"),
                       search_handler,
                       pass_args=True,
                       pass_chat_data=True))

    add(MessageHandler(Filters.reply, reply_router, pass_chat_data=True),
        group=-1)
    add(MessageHandler(Filters.forwarded, forward_router, pass_chat_data=True))

    add(CommandHandler("admin", admin.menu))
    add(CommandHandler("a", admin.menu))

    add(
        CommandHandler(("rej", "reject"),
                       admin.reject_bot_submission,
                       pass_args=True))
    add(
        CommandHandler(
            ("rejsil", "rejectsil", "rejsilent", "rejectsilent"),
            lambda bot, update: admin.reject_bot_submission(
                bot, update, None, notify_submittant=False),
        ))

    # admin menu
    add(RegexHandler(captions.APPROVE_BOTS + ".*", admin.approve_bots))
    add(
        RegexHandler(captions.APPROVE_SUGGESTIONS + ".*",
                     admin.approve_suggestions))
    add(RegexHandler(captions.PENDING_UPDATE + ".*", admin.pending_update))
    add(
        RegexHandler(captions.SEND_BOTLIST,
                     admin.prepare_transmission,
                     pass_chat_data=True))
    add(RegexHandler(captions.FIND_OFFLINE, admin.send_offline))
    add(RegexHandler(captions.SEND_CONFIG_FILES, admin.send_runtime_files))
    add(RegexHandler(captions.SEND_ACTIVITY_LOGS, admin.send_activity_logs))

    # main menu
    add(RegexHandler(captions.ADMIN_MENU, admin.menu))
    add(RegexHandler(captions.REFRESH, admin.menu))
    add(RegexHandler(captions.CATEGORIES, select_category,
                     pass_chat_data=True))
    add(RegexHandler(captions.EXPLORE, explore.explore, pass_chat_data=True))
    add(RegexHandler(captions.FAVORITES, favorites.send_favorites_list))
    add(RegexHandler(captions.NEW_BOTS, show_new_bots, pass_chat_data=True))
    add(RegexHandler(captions.SEARCH, search_handler, pass_chat_data=True))
    add(RegexHandler(captions.CONTRIBUTING, help.contributing))
    add(RegexHandler(captions.EXAMPLES, help.examples))
    add(RegexHandler(captions.HELP, help.help))

    add(RegexHandler("^/edit\d+$", admin.edit_bot, pass_chat_data=True),
        group=1)

    add(RegexHandler("^/approve\d+$", admin.edit_bot, pass_chat_data=True),
        group=1)
    add(CommandHandler("approve", admin.short_approve_list))

    add(CommandHandler(("manybot", "manybots"), admin.manybots))

    add(
        CommandHandler(
            "new",
            partial(contributions.new_bot_submission, bot_checker=bot_checker),
            pass_args=True,
            pass_chat_data=True,
        ))
    add(
        RegexHandler(
            ".*#new.*",
            lambda bot, update, chat_data: contributions.new_bot_submission(
                bot, update, chat_data, args=None, bot_checker=bot_checker),
            pass_chat_data=True,
        ),
        group=1,
    )
    add(
        CommandHandler("offline",
                       contributions.notify_bot_offline,
                       pass_args=True))
    add(RegexHandler(".*#offline.*", contributions.notify_bot_offline),
        group=1)
    add(CommandHandler("spam", contributions.notify_bot_spam, pass_args=True))
    add(RegexHandler(".*#spam.*", contributions.notify_bot_spam), group=1)

    add(CommandHandler("help", help.help))
    add(CommandHandler(("contribute", "contributing"), help.contributing))
    add(CommandHandler("examples", help.examples))
    add(CommandHandler("rules", help.rules))

    add(
        CommandHandler(("addfav", "addfavorite"),
                       favorites.add_favorite_handler,
                       pass_args=True))
    add(
        CommandHandler(("f", "fav", "favorites"),
                       favorites.send_favorites_list))

    add(CommandHandler(("e", "explore"), explore.explore, pass_chat_data=True))
    add(CommandHandler("official", explore.show_official))

    add(
        CommandHandler(
            "ban",
            partial(admin.ban_handler, ban_state=True),
            pass_args=True,
            pass_chat_data=True,
        ))
    add(
        CommandHandler(
            "unban",
            partial(admin.ban_handler, ban_state=False),
            pass_args=True,
            pass_chat_data=True,
        ))
    add(CommandHandler("t3chno", t3chnostats))
    add(CommandHandler("random", eastereggs.send_random_bot))
    add(
        CommandHandler("easteregg",
                       eastereggs.send_next,
                       pass_args=True,
                       pass_job_queue=True))

    add(CommandHandler("subscribe", manage_subscription))
    add(CommandHandler("newbots", show_new_bots, pass_chat_data=True))

    add(CommandHandler("accesstoken", access_token))

    add(
        CommandHandler(("stat", "stats", "statistic", "statistics"),
                       admin.send_statistic))

    add(
        CommandHandler(("log", "logs"),
                       admin.send_activity_logs,
                       pass_args=True))
    add(
        CommandHandler(
            ("debug", "analysis", "ana", "analyze"),
            lambda bot, update, args: admin.send_activity_logs(
                bot, update, args, Statistic.ANALYSIS),
            pass_args=True,
        ))
    add(
        CommandHandler(
            "info",
            lambda bot, update, args: admin.send_activity_logs(
                bot, update, args, Statistic.INFO),
            pass_args=True,
        ))
    add(
        CommandHandler(
            ("detail", "detailed"),
            lambda bot, update, args: admin.send_activity_logs(
                bot, update, args, Statistic.DETAILED),
            pass_args=True,
        ))
    add(
        CommandHandler(
            ("warn", "warning"),
            lambda bot, update, args: admin.send_activity_logs(
                bot, update, args, Statistic.WARN),
            pass_args=True,
        ))
    add(
        CommandHandler(
            "important",
            lambda bot, update, args: admin.send_activity_logs(
                bot, update, args, Statistic.IMPORTANT),
            pass_args=True,
        ))

    add(
        MessageHandler(
            Filters.text,
            lambda bot, update: botlistchat.text_message_logger(
                bot, update, log),
        ),
        group=99,
    )

    for hashtag in HINTS.keys():
        add(
            RegexHandler(r"{}.*".format(hashtag),
                         botlistchat.hint_handler,
                         pass_job_queue=True),
            group=1,
        )
    add(CommandHandler(("hint", "hints"), botlistchat.show_available_hints))

    add(
        RegexHandler(
            "^{}$".format(settings.REGEX_BOT_ONLY),
            send_bot_details,
            pass_chat_data=True,
        ))

    add(
        ChosenInlineResultHandler(inlinequeries.chosen_result,
                                  pass_chat_data=True))
    add(
        InlineQueryHandler(inlinequeries.inlinequery_handler,
                           pass_chat_data=True))
    add(MessageHandler(Filters.all, all_handler, pass_chat_data=True),
        group=98)
Пример #28
0
def approve_suggestions(bot, update, page=0):
    uid = util.uid_from_update(update)
    suggestions = Suggestion.select_all()
    if page * settings.PAGE_SIZE_SUGGESTIONS_LIST >= len(suggestions):
        # old item deleted, list now too small
        page = page - 1 if page > 0 else 0
    start = page * settings.PAGE_SIZE_SUGGESTIONS_LIST
    end = start + settings.PAGE_SIZE_SUGGESTIONS_LIST

    has_prev_page = page > 0
    has_next_page = (page + 1) * settings.PAGE_SIZE_SUGGESTIONS_LIST < len(
        suggestions)

    suggestions = suggestions[start:end]

    if len(suggestions) == 0:
        bot.formatter.send_or_edit(uid,
                                   "No more suggestions available.",
                                   to_edit=util.mid_from_update(update))
        return

    buttons = []
    count = 1
    text = "Please choose suggestions to accept.\n"
    for x in suggestions:
        number = str(count) + "."
        text += "\n{} {}".format(number, str(x))
        row = []

        # Should the suggestion be editable and is it too long?
        if x.action in Suggestion.TEXTUAL_ACTIONS:
            row.append(
                InlineKeyboardButton(
                    "{} {}📝".format(number, Emoji.WHITE_HEAVY_CHECK_MARK),
                    callback_data=util.callback_for_action(
                        CallbackActions.CHANGE_SUGGESTION, {
                            "id": x.id,
                            "page": page
                        }),
                ))
        else:
            row.append(
                InlineKeyboardButton(
                    "{} {}".format(number, Emoji.WHITE_HEAVY_CHECK_MARK),
                    callback_data=util.callback_for_action(
                        CallbackActions.ACCEPT_SUGGESTION, {
                            "id": x.id,
                            "page": page
                        }),
                ))

        row.append(
            InlineKeyboardButton(
                "{} {}".format(number, Emoji.CROSS_MARK),
                callback_data=util.callback_for_action(
                    CallbackActions.REJECT_SUGGESTION, {
                        "id": x.id,
                        "page": page
                    }),
            ))
        buttons.append(row)
        count += 1

    page_arrows = list()
    if has_prev_page:
        page_arrows.append(
            InlineKeyboardButton(
                Emoji.LEFTWARDS_BLACK_ARROW,
                callback_data=util.callback_for_action(
                    CallbackActions.SWITCH_SUGGESTIONS_PAGE,
                    {"page": page - 1}),
            ))
    if has_next_page:
        page_arrows.append(
            InlineKeyboardButton(
                Emoji.BLACK_RIGHTWARDS_ARROW,
                callback_data=util.callback_for_action(
                    CallbackActions.SWITCH_SUGGESTIONS_PAGE,
                    {"page": page + 1}),
            ))
    buttons.append(page_arrows)

    reply_markup = InlineKeyboardMarkup(buttons)

    bot.formatter.send_or_edit(
        uid,
        util.action_hint(text),
        reply_markup=reply_markup,
        to_edit=util.mid_from_update(update),
        disable_web_page_preview=True,
    )
    return CallbackStates.APPROVING_BOTS
Пример #29
0
	def get(self):
		context = { 'suggestions': Suggestion.get_todays(self.currentgroup) }
		self.render('suggestions', context)
Пример #30
0
def notify_bot_offline(bot, update, args=None):
    tg_user = update.message.from_user
    user = User.from_telegram_object(tg_user)
    reply_to = util.original_reply_id(update)

    if args:
        text = " ".join(args)
    else:
        text = update.message.text
        command_no_args = (len(re.findall(r"^/new\s*$", text)) > 0
                           or text.lower().strip() == "/offline@botlistbot")
        if command_no_args:
            update.message.reply_text(
                util.action_hint(
                    "Please use this command with an argument. For example:\n/offline @mybot"
                ),
                reply_to_message_id=reply_to,
            )
            return

    # `#offline` is already checked by handler
    try:
        username = re.match(settings.REGEX_BOT_IN_TEXT, text).groups()[0]
        if username == "@" + settings.SELF_BOT_NAME:
            log.info("Ignoring {}".format(text))
            return
    except AttributeError:
        if args:
            update.message.reply_text(
                util.failure(
                    "Sorry, but you didn't send me a bot `@username`."),
                quote=True,
                parse_mode=ParseMode.MARKDOWN,
                reply_to_message_id=reply_to,
            )
        else:
            log.info("Ignoring {}".format(text))
            # no bot username, ignore update
            pass
        return

    try:
        offline_bot = Bot.get(
            fn.lower(Bot.username)**username.lower(), Bot.approved == True)
        try:
            Suggestion.get(action="offline", subject=offline_bot)
        except Suggestion.DoesNotExist:
            suggestion = Suggestion(
                user=user,
                action="offline",
                date=datetime.date.today(),
                subject=offline_bot,
            )
            suggestion.save()
        update.message.reply_text(
            util.success(
                "Thank you! We will review your suggestion and set the bot offline."
            ),
            reply_to_message_id=reply_to,
        )
    except Bot.DoesNotExist:
        update.message.reply_text(
            util.action_hint("The bot you sent me is not in the @BotList."),
            reply_to_message_id=reply_to,
        )
    return ConversationHandler.END
Пример #31
0
def route_suggestion(suggestion_id):
    suggestion = Suggestion.get(suggestion_id)
    return render_template('suggestion.html', suggestion=suggestion)
def toggle_value(bot, update, property_name, to_edit, value):
    user = User.from_update(update)

    if check_suggestion_limit(bot, update, user):
        return
    Suggestion.add_or_update(user, property_name, to_edit, bool(value))
def set_keywords(bot, update, chat_data, to_edit):
    chat_id = util.uid_from_update(update)
    keywords = Keyword.select().where(Keyword.entity == to_edit)
    chat_data['edit_bot'] = to_edit
    set_keywords_msgid = chat_data.get('set_keywords_msg')

    pending = Suggestion.select().where(
        Suggestion.executed == False, Suggestion.subject == to_edit,
        Suggestion.action << ['add_keyword', 'remove_keyword'])
    pending_removal = [y for y in pending if y.action == 'remove_keyword']

    # Filter keywords by name to not include removal suggestions
    # We don't need to do this for add_keyword suggestions, because duplicates are not allowed.
    keywords = [
        k for k in keywords
        if k.name not in [s.value for s in pending_removal]
    ]

    kw_remove_buttons = [
        InlineCallbackButton('{} ✖️'.format(x),
                             callback_action=CallbackActions.REMOVE_KEYWORD,
                             params={
                                 'id': to_edit.id,
                                 'kwid': x.id
                             }) for x in keywords
    ]
    kw_remove_buttons.extend([
        InlineKeyboardButton('#{} 👓✖️'.format(x.value),
                             callback_data=util.callback_for_action(
                                 CallbackActions.DELETE_KEYWORD_SUGGESTION, {
                                     'id': to_edit.id,
                                     'suggid': x.id
                                 }))
        for x in [y for y in pending if y.action == 'add_keyword']
    ])
    kw_remove_buttons.extend([
        InlineKeyboardButton('#{} 👓❌'.format(x.value),
                             callback_data=util.callback_for_action(
                                 CallbackActions.DELETE_KEYWORD_SUGGESTION, {
                                     'id': to_edit.id,
                                     'suggid': x.id
                                 })) for x in pending_removal
    ])
    buttons = util.build_menu(
        kw_remove_buttons,
        2,
        header_buttons=[
            InlineKeyboardButton(captions.DONE,
                                 callback_data=util.callback_for_action(
                                     CallbackActions.ABORT_SETTING_KEYWORDS,
                                     {'id': to_edit.id}))
        ])
    reply_markup = InlineKeyboardMarkup(buttons)
    msg = util.send_or_edit_md_message(
        bot,
        chat_id,
        util.action_hint(
            'Send me the keywords for {} one by one...\n\n{}'.format(
                util.escape_markdown(to_edit.username),
                messages.KEYWORD_BEST_PRACTICES)),
        to_edit=set_keywords_msgid,
        reply_markup=reply_markup)

    if msg:
        # message might not have been edited if the user adds an already-existing keyword
        # TODO: should the user be notified about this?
        chat_data['set_keywords_msg'] = msg.message_id

    return BotStates.SENDING_KEYWORDS
Пример #34
0
 def test_suggestion_unicode(self):
     mod = Suggestion(ip_address=self.ip)
     self.assertTrue(self.ip in '%s' % mod)
Пример #35
0
 def test_suggestion_property(self):
     mod = Suggestion(ip_address=self.ip, message='x'*90)
     self.assertTrue(mod.message_start, 'x'*80)
Пример #36
0
def callback_router(bot, update, chat_data, user_data, job_queue):
    obj = json.loads(str(update.callback_query.data))
    user = User.from_update(update)

    try:
        if "a" in obj:
            action = obj["a"]

            # BOTLISTCHAT
            if action == CallbackActions.DELETE_CONVERSATION:
                botlistchat.delete_conversation(bot, update, chat_data)
            # HELP
            elif action == CallbackActions.HELP:
                help.help(bot, update)
            elif action == CallbackActions.CONTRIBUTING:
                help.contributing(bot, update)
            elif action == CallbackActions.EXAMPLES:
                help.examples(bot, update)
            # BASIC QUERYING
            elif action == CallbackActions.SELECT_CATEGORY:
                select_category(bot, update, chat_data)
            elif action == CallbackActions.SELECT_BOT_FROM_CATEGORY:
                category = Category.get(id=obj["id"])
                send_category(bot, update, chat_data, category)
            elif action == CallbackActions.SEND_BOT_DETAILS:
                item = Bot.get(id=obj["id"])
                send_bot_details(bot, update, chat_data, item)
            # FAVORITES
            elif action == CallbackActions.TOGGLE_FAVORITES_LAYOUT:
                value = obj["v"]
                favorites.toggle_favorites_layout(bot, update, value)
            elif action == CallbackActions.ADD_FAVORITE:
                favorites.add_favorite_handler(bot, update)
            elif action == CallbackActions.REMOVE_FAVORITE_MENU:
                favorites.remove_favorite_menu(bot, update)
            elif action == CallbackActions.REMOVE_FAVORITE:
                to_remove = Favorite.get(id=obj["id"])
                bot_details = to_remove.bot
                to_remove.delete_instance()
                if obj.get("details"):
                    send_bot_details(bot, update, chat_data, bot_details)
                else:
                    favorites.remove_favorite_menu(bot, update)
            elif action == CallbackActions.SEND_FAVORITES_LIST:
                favorites.send_favorites_list(bot, update)
            elif action == CallbackActions.ADD_ANYWAY:
                favorites.add_custom(bot, update, obj["u"])
            elif action == CallbackActions.ADD_TO_FAVORITES:
                details = obj.get("details")
                discreet = obj.get("discreet", False) or details
                item = Bot.get(id=obj["id"])
                favorites.add_favorite(bot,
                                       update,
                                       item,
                                       callback_alert=discreet)
                if details:
                    send_bot_details(bot, update, chat_data, item)
            # ACCEPT/REJECT BOT SUBMISSIONS
            elif action == CallbackActions.APPROVE_REJECT_BOTS:
                custom_approve_list = [Bot.get(id=obj["id"])]
                admin.approve_bots(bot,
                                   update,
                                   override_list=custom_approve_list)
            elif action == CallbackActions.ACCEPT_BOT:
                to_accept = Bot.get(id=obj["id"])
                admin.edit_bot_category(bot, update, to_accept,
                                        CallbackActions.BOT_ACCEPTED)
                # Run in x minutes, giving the moderator enough time to edit bot details
                job_queue.run_once(
                    lambda b, job: botlistchat.
                    notify_group_submission_accepted(b, job, to_accept),
                    settings.BOT_ACCEPTED_IDLE_TIME * 60,
                )
            elif action == CallbackActions.RECOMMEND_MODERATOR:
                bot_in_question = Bot.get(id=obj["id"])
                admin.recommend_moderator(bot, update, bot_in_question,
                                          obj["page"])
            elif action == CallbackActions.SELECT_MODERATOR:
                bot_in_question = Bot.get(id=obj["bot_id"])
                moderator = User.get(id=obj["uid"])
                admin.share_with_moderator(bot, update, bot_in_question,
                                           moderator)
                admin.approve_bots(bot, update, obj["page"])
            elif action == CallbackActions.REJECT_BOT:
                to_reject = Bot.get(id=obj["id"])
                notification = obj.get("ntfc", True)
                admin.reject_bot_submission(
                    bot,
                    update,
                    None,
                    to_reject,
                    verbose=False,
                    notify_submittant=notification,
                )
                admin.approve_bots(bot, update, obj["page"])
            elif action == CallbackActions.BOT_ACCEPTED:
                to_accept = Bot.get(id=obj["bid"])
                category = Category.get(id=obj["cid"])
                admin.accept_bot_submission(bot, update, to_accept, category)
            elif action == CallbackActions.COUNT_THANK_YOU:
                new_count = obj.get("count", 1)
                basic.count_thank_you(bot, update, new_count)
            # ADD BOT
            # elif action == CallbackActions.ADD_BOT_SELECT_CAT:
            #     category = Category.get(id=obj['id'])
            #     admin.add_bot(bot, update, chat_data, category)
            # EDIT BOT
            elif action == CallbackActions.EDIT_BOT:
                to_edit = Bot.get(id=obj["id"])
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_SELECT_CAT:
                to_edit = Bot.get(id=obj["id"])
                admin.edit_bot_category(bot, update, to_edit)
            elif action == CallbackActions.EDIT_BOT_CAT_SELECTED:
                to_edit = Bot.get(id=obj["bid"])
                cat = Category.get(id=obj["cid"])
                botproperties.change_category(bot, update, to_edit, cat)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_COUNTRY:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_country_menu(bot, update, to_edit)
            elif action == CallbackActions.SET_COUNTRY:
                to_edit = Bot.get(id=obj["bid"])
                if obj["cid"] == "None":
                    country = None
                else:
                    country = Country.get(id=obj["cid"])
                botproperties.set_country(bot, update, to_edit, country)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_DESCRIPTION:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_text_property(bot, update, chat_data,
                                                "description", to_edit)
            elif action == CallbackActions.EDIT_BOT_EXTRA:
                to_edit = Bot.get(id=obj["id"])
                # SAME IS DONE HERE, but manually
                botproperties.set_text_property(bot, update, chat_data,
                                                "extra", to_edit)
            elif action == CallbackActions.EDIT_BOT_NAME:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_text_property(bot, update, chat_data, "name",
                                                to_edit)
            elif action == CallbackActions.EDIT_BOT_USERNAME:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_text_property(bot, update, chat_data,
                                                "username", to_edit)
            # elif action == CallbackActions.EDIT_BOT_KEYWORDS:
            #     to_edit = Bot.get(id=obj['id'])
            #     botproperties.set_keywords_init(bot, update, chat_data, to_edit)
            elif action == CallbackActions.APPLY_ALL_CHANGES:
                to_edit = Bot.get(id=obj["id"])
                admin.apply_all_changes(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_INLINEQUERIES:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "inlinequeries",
                                           to_edit, value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_OFFICIAL:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "official", to_edit,
                                           value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_OFFLINE:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "offline", to_edit,
                                           value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_SPAM:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "spam", to_edit, value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.CONFIRM_DELETE_BOT:
                to_delete = Bot.get(id=obj["id"])
                botproperties.delete_bot_confirm(bot, update, to_delete)
            elif action == CallbackActions.DELETE_BOT:
                to_edit = Bot.get(id=obj["id"])
                botproperties.delete_bot(bot, update, to_edit)
                # send_category(bot, update, chat_data, to_edit.category)
            elif action == CallbackActions.ACCEPT_SUGGESTION:
                suggestion = Suggestion.get(id=obj["id"])
                components.botproperties.accept_suggestion(
                    bot, update, suggestion)
                admin.approve_suggestions(bot, update, page=obj["page"])
            elif action == CallbackActions.REJECT_SUGGESTION:
                suggestion = Suggestion.get(id=obj["id"])
                suggestion.delete_instance()
                admin.approve_suggestions(bot, update, page=obj["page"])
            elif action == CallbackActions.CHANGE_SUGGESTION:
                suggestion = Suggestion.get(id=obj["id"])
                botproperties.change_suggestion(bot,
                                                update,
                                                suggestion,
                                                page_handover=obj["page"])
            elif action == CallbackActions.SWITCH_SUGGESTIONS_PAGE:
                page = obj["page"]
                admin.approve_suggestions(bot, update, page)
            elif action == CallbackActions.SWITCH_APPROVALS_PAGE:
                admin.approve_bots(bot, update, page=obj["page"])
            elif action == CallbackActions.SET_NOTIFICATIONS:
                set_notifications(bot, update, obj["value"])
            elif action == CallbackActions.NEW_BOTS_SELECTED:
                show_new_bots(bot, update, chat_data, back_button=True)
            elif action == CallbackActions.ABORT_SETTING_KEYWORDS:
                to_edit = Bot.get(id=obj["id"])
                admin.edit_bot(bot, update, chat_data, to_edit)
            # SENDING BOTLIST
            elif action == CallbackActions.SEND_BOTLIST:
                silent = obj.get("silent", False)
                re_send = obj.get("re", False)
                botlist.send_botlist(bot,
                                     update,
                                     resend=re_send,
                                     silent=silent)
            elif action == CallbackActions.RESEND_BOTLIST:
                botlist.send_botlist(bot, update, resend=True)
            # BROADCASTING
            elif action == "send_broadcast":
                broadcasts.send_broadcast(bot, update, user_data)
            elif action == "pin_message":
                broadcasts.pin_message(bot, update, obj["mid"])
            elif action == "add_thank_you":
                basic.add_thank_you_button(bot, update, obj["cid"], obj["mid"])
            # EXPLORING
            elif action == CallbackActions.EXPLORE_NEXT:
                explore.explore(bot, update, chat_data)
    except Exception as e:
        traceback.print_exc()

        # get the callback action in plaintext
        actions = dict(CallbackActions.__dict__)
        a = next(k for k, v in actions.items() if v == obj.get("a"))
        util.send_md_message(
            bot,
            settings.DEVELOPER_ID,
            "Exception in callback query for {}:\n{}\n\nWith CallbackAction {}\n\nWith data:\n{}"
            .format(
                user.markdown_short,
                util.escape_markdown(e),
                util.escape_markdown(a),
                util.escape_markdown(str(obj)),
            ),
        )
    finally:
        bot.answerCallbackQuery(update.callback_query.id)
        return ConversationHandler.END
Пример #37
0
 def test_suggestion_clean_raise(self):
     Suggestion.objects.create(ip_address=self.ip)
     mod = Suggestion(ip_address=self.ip)
     self.assertRaises(ValidationError, mod.clean)
Пример #38
0
	def can_vote_for_day(day):
		return (not userinfo.voted_for_day(day)
			    and Suggestion.get_for_day(day, group).count() > 0)