def add_subadmin(user_id=None): """Add subadmin flag for user_id.""" try: if user_id: user = user_repo.get(user_id) if not user: return format_error('User not found', 404) if not user.enabled: markup = Markup('<strong>{}</strong> {} <strong>{}</strong>') flash( markup.format(gettext('User account '), user.fullname, gettext(' is disabled'))) return redirect(url_for(".subadminusers")) if not can_have_super_user_access(user): markup = Markup('<strong>{} {}</strong> {} {}') flash( markup.format(gettext('Denied subadmin privileges to'), user.fullname, user.email_addr, 'disqualify for subadmin access.')) return redirect_content_type(url_for(".subadminusers")) ensure_authorized_to('update', user) user.subadmin = True user_repo.update(user) msg = generate_invitation_email_for_admins_subadmins( user, "Subadmin") if msg: mail_queue.enqueue(send_mail, msg) return redirect(url_for(".subadminusers")) except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)
def comic_delete(title): comic = Comic.query.filter_by(title=title).first_or_404() if current_user.role.name == 'Administrator': print( "Removing comic from comic databse. This is a destructive process") if os.path.exists( os.path.join(current_app.config['DOWNLOAD_FOLDER'], comic.title, comic.filename)): shutil.rmtree( os.path.join(current_app.config['DOWNLOAD_FOLDER'], comic.title)) msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">Comic {} deleted from global library<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(comic.title)) db.session.delete(comic) db.session.commit() else: print("Removing comic from user database") msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">Comic {} deleted from your library<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(comic.title)) current_user.comics.remove(comic) db.session.add(current_user) db.session.commit() return redirect(url_for('account.mycomics'))
def users(user_id=None): """Manage users of PYBOSSA.""" form = SearchForm(request.body) users = [ user for user in user_repo.filter_by(admin=True) if user.id != current_user.id ] if request.method == 'POST' and form.user.data: query = form.user.data found = [ user for user in user_repo.search_by_name(query) if user.id != current_user.id ] [ensure_authorized_to('update', found_user) for found_user in found] if not found: markup = Markup('<strong>{}</strong> {} <strong>{}</strong>') flash( markup.format( gettext("Ooops!"), gettext("We didn't find a user matching your query:"), form.user.data)) response = dict(template='/admin/users.html', found=found, users=users, title=gettext("Manage Admin Users"), form=form) return handle_content_type(response) response = dict(template='/admin/users.html', found=[], users=users, title=gettext("Manage Admin Users"), form=form) return handle_content_type(response)
def update_announcement(id): announcement = announcement_repo.get_by(id=id) if announcement is None: raise abort(404) def respond(): response = dict(template='admin/new_announcement.html', title=gettext("Edit a post"), form=form) return handle_content_type(response) form = AnnouncementForm() if request.method != 'POST': ensure_authorized_to('update', announcement) form = AnnouncementForm(obj=announcement) return respond() if not form.validate(): flash(gettext('Please correct the errors'), 'error') return respond() ensure_authorized_to('update', announcement) announcement = Announcement(id=form.id.data, title=form.title.data, body=form.body.data, user_id=current_user.id) announcement_repo.update(announcement) msg_1 = gettext('Announcement updated!') markup = Markup('<i class="icon-ok"></i> {}') flash(markup.format(msg_1), 'success') return redirect_content_type(url_for('admin.announcement'))
def new_announcement(): """Create new announcement.""" def respond(): response = dict(template='admin/new_announcement.html', title=gettext("Write a new post"), form=form) return handle_content_type(response) form = AnnouncementForm() del form.id # project_sanitized, owner_sanitized = sanitize_project_owner(project, owner, current_user) if request.method != 'POST': ensure_authorized_to('create', Announcement()) return respond() if not form.validate(): flash(gettext('Please correct the errors'), 'error') return respond() announcement = Announcement(title=form.title.data, body=form.body.data, published=form.published.data, media_url=form.media_url.data, user_id=current_user.id) ensure_authorized_to('create', announcement) announcement_repo.save(announcement) msg_1 = gettext('Annnouncement created!') markup = Markup('<i class="icon-ok"></i> {}') flash(markup.format(msg_1), 'success') return redirect_content_type(url_for('admin.announcement'))
def page_edit(name): form = PageForm() page = Page.query.filter_by(name=name).first_or_404() if request.method == 'GET': form.name.data = page.name form.slug.data = page.slug form.subtitle.data = page.subtitle form.content.data = page.content form.enable_social_links.data = page.enable_social_links if form.validate_on_submit(): page = Page() page.name = form.name.data page.slug = form.name.data.translate(translate).replace( ' ', '-').replace('.', '').lower() page.subtitle = form.subtitle.data page.content = form.content.data page.enable_social_links = form.enable_social_links.data db.session.add(page) db.session.commit() msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">Page {} edited<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(page.name)) return redirect(url_for('account.page_edit', name=name, form=form)) return render_template('admin/page.edit.html', form=form)
def subadminusers(): """Manage subadminusers of PyBossa.""" form = SearchForm(request.form) users = [user for user in user_repo.filter_by(subadmin=True) if user.id != current_user.id] if request.method == 'POST' and form.user.data: query = form.user.data filters = {'subadmin': True, 'enabled': True} found = [user for user in user_repo.search_by_name_orfilters(query, **filters) if user.id != current_user.id] [ensure_authorized_to('update', found_user) for found_user in found] if not found: markup = Markup('<strong>{}</strong> {} <strong>{}</strong>') flash(markup.format(gettext('Ooops!'), gettext("We didn't find any enabled user matching your query:"), form.user.data)) return render_template('/admin/subadminusers.html', found=found, users=users, title=gettext("Manage Subadmin Users"), form=form) return render_template('/admin/subadminusers.html', found=[], users=users, title=gettext("Manage Subadmin Users"), form=form)
def get_killmail_descriptions(): description = Markup(u"Acceptable Killmail Links:<ul>") desc_entry = Markup(u"<li>{}</li>") killmail_descs = [desc_entry.format(km.description) for km in\ current_app.killmail_sources] description += Markup(u"").join(killmail_descs) description += Markup(u"</ul>") return description
def get_posts_from_to(page, page_size): li_home = Markup('<li class="nav-item" >') li_new_post = Markup('<li class="nav-item " >') if page < 1 or page_size < 1: return InputError.raise_error('Page must be positive nuber') link_next_template = Markup( '<a class="page-link" href="/get_posts?page={}&page_size={}"> Next </a>' ) link_next = link_next_template.format(str(page + 1), str(page_size)) link_prev_template = Markup( '<a class="page-link" href="/get_posts?page={}&page_size={}"> Previous </a>' ) link_previous = link_prev_template.format(str(page - 1), str(page_size)) post_len = Storage.post_len() if page * page_size >= post_len: link_next = '' if page == 1: link_previous = '' li_home = Markup('<li class="nav-item active" >') posts_from_to = Storage.select_posts((page - 1) * page_size, page_size) # ovde pravim listu objekata, da bi posle mogao lepo da prikazem u for petlji posts = [] for post in posts_from_to: if not post[4]: image = '' else: image = redirect(url_for('slika', ime_slike=post[2])) posts.append(Post(post[0], post[1], post[2], post[3], image)) if not posts_from_to: return InputError.raise_error('No more posts to show') return render_template('home.html', li_home=li_home, li_new_post=li_new_post, posts=posts, next=link_next, previous=link_previous)
def index(): li = Markup("""<li><a href="{}">{}</a></li>""") results = db.metadata.tables.keys() results.sort() results = [li.format(url_for("app.view_table", table_name=tbl_name), tbl_name) for tbl_name in results] results = Markup("<ul>") + Markup("\n").join(results) + Markup("</ul>") return render_template("layout.html", content=results)
def user_delete(id): user = User.query.filter_by(id=id).first_or_404() msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">User {} deleted<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(user.username)) db.session.delete(user) db.session.commit() return redirect(url_for('account.users'))
def invite_delete(id): invitation = Invitation.query.filter_by(id=id).first_or_404() msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">An invitation sent to {} was used.<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(invitation.email), current_user.username) db.session.delete(invitation) db.session.commit() return redirect(url_for('account.invite'))
def generate_links(query_list, model=None, model_key=None): link = Markup("""<a href="{}">{}</a> - <a href="{}">Delete</a>""") model_key = [key.key for key in model_key.columns][0] for entry in query_list: key = getattr(entry, model_key, 1) name = model.__name__ edit_url = url_for('admin.edit', model_name=name, model_url_key=key) delete_url = url_for('admin.delete', model_name=name, model_url_key=key) yield link.format(edit_url, entry, delete_url)
def delete_announcement(id): announcement = announcement_repo.get_by(id=id) if announcement is None: raise abort(404) ensure_authorized_to('delete', announcement) announcement_repo.delete(announcement) msg_1 = gettext('Announcement deleted!') markup = Markup('<i class="icon-ok"></i> {}') flash(markup.format(msg_1), 'success') return redirect_content_type(url_for('admin.announcement'))
def index(): li = Markup("""<li><a href="{}">{}</a></li>""") results = db.metadata.tables.keys() results.sort() results = [ li.format(url_for("app.view_table", table_name=tbl_name), tbl_name) for tbl_name in results ] results = Markup("<ul>") + Markup("\n").join(results) + Markup("</ul>") return render_template("layout.html", content=results)
def play(): logged = False user_log = '' if (session): if 'logged_in' not in session: return redirect(url_for('login')) else: if session['logged_in']: logged = True user_log = Markup('<a class="nav-link" href="/profile"> Hello, {0} </a>'.format(session['user_name'])) else: return redirect(url_for('login')) else: return redirect(url_for('login')) difficulty = request.args.get("diff") song_id = request.args.get("sg") if not song_id or not difficulty: # display error page pass song = get_song_details(song_id) word_list = get_words_to_hide(song_id, int(difficulty)) song_tags = get_tags_for_song(song_id) lyrics = song.lyrics.replace('\n', '<br>') html_to_replace = Markup('<div class="form-group"> \ <div class="input-group"> \ <input type="text" id="{0}" class="missing-word form-control" size="{1}" maxlength="{1}" data-word="{3}"> \ <span class="glyphicon glyphicon-eye-open input-group-addon" data-toggle="tooltip" data-placement="bottom" aria-hidden="true" title="{2}"> \ </span> \ </div> \ </div>') i = 0 for word in word_list: hint = get_hint_for_word(word, int(difficulty)) lyrics, k = re.subn(r'\s({0})\s'.format(word), html_to_replace.format("word-{0}".format(i), len(word) + 1, hint, word), lyrics, count=max([1, int(difficulty) - 1])) i += k m, s = divmod(int(song.length), 60) song_duration = "%02d:%02d" % (m, s) video_url = song.video_url[song.video_url.index('v=') + 2:] keep_ids, _ = get_user_keep(session['user_id']) keep_next = get_next_keep(session['user_id'], song_id) keep_count = get_keep_count_for_song(song_id) play_count = get_play_count_for_song(song_id) return render_template('play.html', logged_in=logged, profile_login=user_log, user_id=session['user_id'], song_id=song_id, lyrics=lyrics, song_tags=song_tags, song_artist=song.artist, song_title=song.title, release_year=song.release_year, song_duration=song_duration, video_url=video_url, num_of_words=i, difficulty=int(difficulty), keep_ids=keep_ids, keep_next=keep_next, keep_count=keep_count, play_count=play_count)
def post_edit(title): form = PostForm() post = Post.query.filter_by(title=title).first_or_404() categories = PostCategory.query.all() tags = Tag.query.all() if request.method == 'GET': form.title.data = post.title form.permalink.data = post.permalink form.visibility.data = post.visibility form.summary.data = post.summary form.content.data = post.content form.allow_comments.data = post.allow_comments form.allow_pingbacks.data = post.allow_pingbacks form.is_sticky.data = post.is_sticky if form.validate_on_submit(): post.title = form.title.data post.permalink = form.title.data.translate(translate).replace( ' ', '-').replace('.', '').lower() post.visibility = form.visibility.data post.user_id = current_user.id post.summary = form.summary.data post.content = form.content.data featured_image = upload_file('featured_image', filetype='post') if featured_image: post.featured_image = featured_image db.session.add(post) db.session.commit() msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">Post {} edited<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(post.title)) return redirect( url_for('account.post_edit', title=post.title, form=form, categories=categories, tags=tags)) return render_template('admin/post.edit.html', form=form, post=post, categories=categories, tags=tags)
def invite(): form = SendInviteForm() page = request.args.get('page', 1, type=int) pagination = Invitation.query.order_by( Invitation.timestamp.desc()).paginate( page, per_page=current_app.config['ENTRIES_PER_PAGE'], error_out=False) invitations = pagination.items if form.validate_on_submit(): comic = Comic.query.get(randint(1, Comic.query.count())) invitation = Invitation() invitation.first_name = form.first_name.data invitation.last_name = form.last_name.data invitation.email = form.email.data invitation.referer_id = current_user.id invitation.invitation_code = generate_invite_code(form.email.data) subject = "{} {} has invited you to Save All Comics".format( current_user.first_name, current_user.last_name) send_mail(subject, '*****@*****.**', invitation.email, text_body=render_template('email/invitation.txt', invitation=invitation, comic=comic), html_body=render_template('email/invitation.html', invitation=invitation, comic=comic)) if current_user.role.name != "Administrator": current_user.invite_limit -= 1 db.session.add(current_user) db.session.add(invitation) db.session.commit() msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">Invitation was sent to {}<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(invitation.email)) return redirect(url_for('account.invite')) return render_template('admin/invite.html', form=form, invitations=invitations, pagination=pagination)
def project_edit(name): form = ProjectForm() project = Project.query.filter_by(name=name).first_or_404() categories = PostCategory.query.all() tags = Tag.query.all() if request.method == 'GET': form.name.data = project.name form.content.data = project.content if form.validate_on_submit(): project.name = form.name.data project.slug = form.name.data.translate(translate).replace( ' ', '-').replace('.', '').lower() project.content = form.content.data project.summary = summarize(form.content.data) featured_image = upload_file('featured_image', filetype='project') if featured_image: project.featured_image = featured_image db.session.add(project) db.session.commit() msg = Markup( '<div class="alert alert-light alert-dismissible mb-4 py-3 border-left-success">Project {} edited<button role="button" class="close" data-dismiss="alert" type="button">×</button></div>' ) flash(msg.format(project.name)) return redirect( url_for('account.project_edit', name=project.name, form=form, categories=categories, tags=tags)) return render_template('admin/project.edit.html', form=form, project=project, categories=categories, tags=tags)
def users(user_id=None): """Manage users of PYBOSSA.""" form = SearchForm(request.body) users = [user for user in user_repo.filter_by(admin=True) if user.id != current_user.id] if request.method == 'POST' and form.user.data: query = form.user.data found = [user for user in user_repo.search_by_name(query) if user.id != current_user.id] [ensure_authorized_to('update', found_user) for found_user in found] if not found: markup = Markup('<strong>{}</strong> {} <strong>{}</strong>') flash(markup.format(gettext("Ooops!"), gettext("We didn't find a user matching your query:"), form.user.data)) response = dict(template='/admin/users.html', found=found, users=users, title=gettext("Manage Admin Users"), form=form) return handle_content_type(response) response = dict(template='/admin/users.html', found=[], users=users, title=gettext("Manage Admin Users"), form=form) return handle_content_type(response)
def update_announcement(id): announcement = announcement_repo.get_by(id=id) if announcement is None: raise abort(404) def respond(): response = dict(template='admin/new_announcement.html', title=gettext("Edit a post"), form=form) return handle_content_type(response) form = AnnouncementForm() if request.method != 'POST': ensure_authorized_to('update', announcement) form = AnnouncementForm(obj=announcement) return respond() if not form.validate(): flash(gettext('Please correct the errors'), 'error') return respond() ensure_authorized_to('update', announcement) announcement = Announcement(id=form.id.data, title=form.title.data, body=form.body.data, published=form.published.data, media_url=form.media_url.data, user_id=current_user.id) announcement_repo.update(announcement) msg_1 = gettext('Announcement updated!') markup = Markup('<i class="icon-ok"></i> {}') flash(markup.format(msg_1), 'success') return redirect_content_type(url_for('admin.announcement'))
def generate_pages(current_page, num_of_pages, search=None, showPaused=None, window=7): """ Generates the HTML for a paging component using a similar logic to the paging auto-generated by Flask managed views. The paging component defines a number of pages visible in the pager (window) and once the user goes to a page beyond the largest visible, it would scroll to the right the page numbers and keeps the current one in the middle of the pager component. When in the last pages, the pages won't scroll and just keep moving until the last page. Pager also contains <first, previous, ..., next, last> pages. This component takes into account custom parameters such as search and showPaused, which could be added to the pages link in order to maintain the state between client and server. It also allows to make a bookmark on a specific paging state. :param current_page: the current page number, 0-indexed :param num_of_pages: the total number of pages :param search: the search query string, if any :param showPaused: false if paused dags will be hidden, otherwise true to show them :param window: the number of pages to be shown in the paging component (7 default) :return: the HTML string of the paging component """ void_link = 'javascript:void(0)' first_node = Markup( """<li class="paginate_button {disabled}" id="dags_first"> <a href="{href_link}" aria-controls="dags" data-dt-idx="0" tabindex="0">«</a> </li>""") previous_node = Markup( """<li class="paginate_button previous {disabled}" id="dags_previous"> <a href="{href_link}" aria-controls="dags" data-dt-idx="0" tabindex="0">‹</a> </li>""") next_node = Markup( """<li class="paginate_button next {disabled}" id="dags_next"> <a href="{href_link}" aria-controls="dags" data-dt-idx="3" tabindex="0">›</a> </li>""") last_node = Markup( """<li class="paginate_button {disabled}" id="dags_last"> <a href="{href_link}" aria-controls="dags" data-dt-idx="3" tabindex="0">»</a> </li>""") page_node = Markup("""<li class="paginate_button {is_active}"> <a href="{href_link}" aria-controls="dags" data-dt-idx="2" tabindex="0">{page_num}</a> </li>""") output = [Markup('<ul class="pagination" style="margin-top:0px;">')] is_disabled = 'disabled' if current_page <= 0 else '' output.append( first_node.format(href_link="?{}".format( get_params(page=0, search=search, showPaused=showPaused)), disabled=is_disabled)) page_link = void_link if current_page > 0: page_link = '?{}'.format( get_params(page=(current_page - 1), search=search, showPaused=showPaused)) output.append( previous_node.format(href_link=page_link, disabled=is_disabled)) mid = int(window / 2) last_page = num_of_pages - 1 if current_page <= mid or num_of_pages < window: pages = [i for i in range(0, min(num_of_pages, window))] elif mid < current_page < last_page - mid: pages = [i for i in range(current_page - mid, current_page + mid + 1)] else: pages = [i for i in range(num_of_pages - window, last_page + 1)] def is_current(current, page): return page == current for page in pages: vals = { 'is_active': 'active' if is_current(current_page, page) else '', 'href_link': void_link if is_current(current_page, page) else '?{}'.format( get_params(page=page, search=search, showPaused=showPaused)), 'page_num': page + 1 } output.append(page_node.format(**vals)) is_disabled = 'disabled' if current_page >= num_of_pages - 1 else '' page_link = ( void_link if current_page >= num_of_pages - 1 else '?{}'.format( get_params( page=current_page + 1, search=search, showPaused=showPaused))) output.append(next_node.format(href_link=page_link, disabled=is_disabled)) output.append( last_node.format(href_link="?{}".format( get_params(page=last_page, search=search, showPaused=showPaused)), disabled=is_disabled)) output.append(Markup('</ul>')) return Markup('\n'.join(output))
def generate_pages(current_page, num_of_pages, search=None, showPaused=None, window=7): """ Generates the HTML for a paging component using a similar logic to the paging auto-generated by Flask managed views. The paging component defines a number of pages visible in the pager (window) and once the user goes to a page beyond the largest visible, it would scroll to the right the page numbers and keeps the current one in the middle of the pager component. When in the last pages, the pages won't scroll and just keep moving until the last page. Pager also contains <first, previous, ..., next, last> pages. This component takes into account custom parameters such as search and showPaused, which could be added to the pages link in order to maintain the state between client and server. It also allows to make a bookmark on a specific paging state. :param current_page: the current page number, 0-indexed :param num_of_pages: the total number of pages :param search: the search query string, if any :param showPaused: false if paused dags will be hidden, otherwise true to show them :param window: the number of pages to be shown in the paging component (7 default) :return: the HTML string of the paging component """ void_link = 'javascript:void(0)' first_node = Markup("""<li class="paginate_button {disabled}" id="dags_first"> <a href="{href_link}" aria-controls="dags" data-dt-idx="0" tabindex="0">«</a> </li>""") previous_node = Markup("""<li class="paginate_button previous {disabled}" id="dags_previous"> <a href="{href_link}" aria-controls="dags" data-dt-idx="0" tabindex="0"><</a> </li>""") next_node = Markup("""<li class="paginate_button next {disabled}" id="dags_next"> <a href="{href_link}" aria-controls="dags" data-dt-idx="3" tabindex="0">></a> </li>""") last_node = Markup("""<li class="paginate_button {disabled}" id="dags_last"> <a href="{href_link}" aria-controls="dags" data-dt-idx="3" tabindex="0">»</a> </li>""") page_node = Markup("""<li class="paginate_button {is_active}"> <a href="{href_link}" aria-controls="dags" data-dt-idx="2" tabindex="0">{page_num}</a> </li>""") output = [Markup('<ul class="pagination" style="margin-top:0px;">')] is_disabled = 'disabled' if current_page <= 0 else '' output.append(first_node.format(href_link="?{}" .format(get_params(page=0, search=search, showPaused=showPaused)), disabled=is_disabled)) page_link = void_link if current_page > 0: page_link = '?{}'.format(get_params(page=(current_page - 1), search=search, showPaused=showPaused)) output.append(previous_node.format(href_link=page_link, disabled=is_disabled)) mid = int(window / 2) last_page = num_of_pages - 1 if current_page <= mid or num_of_pages < window: pages = [i for i in range(0, min(num_of_pages, window))] elif mid < current_page < last_page - mid: pages = [i for i in range(current_page - mid, current_page + mid + 1)] else: pages = [i for i in range(num_of_pages - window, last_page + 1)] def is_current(current, page): return page == current for page in pages: vals = { 'is_active': 'active' if is_current(current_page, page) else '', 'href_link': void_link if is_current(current_page, page) else '?{}'.format(get_params(page=page, search=search, showPaused=showPaused)), 'page_num': page + 1 } output.append(page_node.format(**vals)) is_disabled = 'disabled' if current_page >= num_of_pages - 1 else '' page_link = (void_link if current_page >= num_of_pages - 1 else '?{}'.format(get_params(page=current_page + 1, search=search, showPaused=showPaused))) output.append(next_node.format(href_link=page_link, disabled=is_disabled)) output.append(last_node.format(href_link="?{}" .format(get_params(page=last_page, search=search, showPaused=showPaused)), disabled=is_disabled)) output.append(Markup('</ul>')) return Markup('\n'.join(output))