Ejemplo n.º 1
0
def new():
    """
    Create a new project.
    """
    form = ProjectDetailsForm()
    if form.validate_on_submit():
        p = Project.by_name_and_owner(form.name.data, g.user)
        if p:
            form.name.errors = [wtf.ValidationError("Project name must be unique.")]
        else:
            p = Project.new(form.name.data, public=form.public.data, website=form.website.data)
            p.full_name = "{0}/{1}".format(g.user.username, p.name)
            g.user.projects.append(p)
            g.db.session.add(p)

            if p.public:
                # New public projects get added to #commits by default.
                c = Channel.new("#commits", "irc.freenode.net", 6667, ssl=False, public=True)
                p.channels.append(c)

            g.db.session.commit()

            flash("Your project has been created.", "success")
            return redirect(url_for(".details", u=g.user.username, p=p.name))

    return render_template("new_project.html", form=form)
Ejemplo n.º 2
0
def new():
    """
    Create a new project.
    """
    form = ProjectDetailsForm()
    if form.validate_on_submit():
        p = Project.by_name_and_owner(form.name.data, g.user)
        if p:
            form.name.errors = [
                wtf.ValidationError('Project name must be unique.')
            ]
        else:
            p = Project.new(
                form.name.data,
                public=form.public.data,
                website=form.website.data
            )
            p.full_name = '{0}/{1}'.format(g.user.username, p.name)
            g.db.session.add(p)
            g.user.projects.append(p)
            g.db.session.commit()
            flash('Your project has been created.', 'success')
            return redirect(url_for('.overview', u=g.user.username))

    return render_template('new_project.html', form=form)
Ejemplo n.º 3
0
def new():
    """
    Create a new project.
    """
    form = ProjectDetailsForm()
    if form.validate_on_submit():
        p = Project.by_name_and_owner(form.name.data, g.user)
        if p:
            form.name.errors = [
                wtf.ValidationError('Project name must be unique.')
            ]
        else:
            p = Project.new(form.name.data,
                            public=form.public.data,
                            website=form.website.data)
            p.full_name = '{0}/{1}'.format(g.user.username, p.name)
            g.user.projects.append(p)
            db.session.add(p)

            if p.public:
                # New public projects get added to #commits by default.
                c = Channel.new('#commits',
                                'chat.freenode.net',
                                6667,
                                ssl=False,
                                public=True)
                p.channels.append(c)

            db.session.commit()

            return redirect(url_for('.details', u=g.user.username, p=p.name))

    return render_template('new_project.html', form=form)
Ejemplo n.º 4
0
def edit_project(u, p):
    """
    Edit an existing project.
    """
    if p.owner.id != g.user.id:
        # Project isn't public and the viewer isn't the project owner.
        # (403 Forbidden)
        return abort(403)

    form = ProjectDetailsForm(obj=p)
    if form.validate_on_submit():
        old_p = Project.by_name_and_owner(form.name.data, g.user)
        if old_p and old_p.id != p.id:
            form.name.errors = [
                wtf.ValidationError('Project name must be unique.')
            ]
        else:
            p.name = form.name.data
            p.website = form.website.data
            p.public = form.public.data
            p.full_name = '{0}/{1}'.format(g.user.username, p.name)
            g.db.session.commit()
            return redirect(url_for('.dashboard', u=u.username))

    return render_template('edit_project.html',
        project=p,
        form=form
    )
Ejemplo n.º 5
0
def landing():
    """
    Show a landing page giving a short intro blurb to unregistered users
    and very basic metrics such as total users.
    """
    # Create a list of total project counts in the form
    # [(day, count), ...].
    projects_graph_data = []
    now = datetime.datetime.utcnow()
    for day_ago in range(30):
        limit = now - datetime.timedelta(days=day_ago)

        projects_graph_data.append((
            time.mktime(limit.timetuple()) * 1000,
            Project.query.filter(Project.created <= limit).count()
        ))

    # Find the 10 latest public projects.
    new_projects = (
        Project.visible(Project.query, user=g.user)
        .order_by(False)
        .order_by(Project.created.desc())
    ).paginate(1, 10, False)

    # Sum the total number of messages across all projects, caching
    # it for the next two minutes.
    total_messages = g.redis.get('cache_message_count')
    if total_messages is None:
        total_messages = g.db.session.query(
            func.sum(Project.message_count)
        ).scalar()
        if total_messages is None:
            total_messages = 0

        g.redis.setex('cache_message_count', 120, total_messages)

    # Total # of users.
    total_users = User.query.count()

    # Find the 10 most popular networks.
    top_networks = (
        Channel.visible(g.db.session.query(
            Channel.host,
            func.count(func.distinct(Channel.channel)).label('count')
        ), user=g.user)
        .group_by(Channel.host)
        .order_by('count desc')
    )
    total_networks = top_networks.count()
    top_networks = top_networks.limit(10)

    return render_template(
        'landing.html',
        projects_graph_data=projects_graph_data,
        new_projects=new_projects,
        top_networks=top_networks,
        total_networks=total_networks,
        total_messages=total_messages,
        total_users=total_users
    )
Ejemplo n.º 6
0
def edit_project(u, p):
    """
    Edit an existing project.
    """
    if p.owner.id != g.user.id:
        # Project isn't public and the viewer isn't the project owner.
        # (403 Forbidden)
        return abort(403)

    form = ProjectDetailsForm(obj=p)
    if form.validate_on_submit():
        old_p = Project.by_name_and_owner(form.name.data, g.user)
        if old_p and old_p.id != p.id:
            form.name.errors = [
                wtf.ValidationError('Project name must be unique.')
            ]
        else:
            p.name = form.name.data
            p.website = form.website.data
            p.public = form.public.data
            p.full_name = '{0}/{1}'.format(g.user.username, p.name)
            db.session.commit()
            return redirect(url_for('.dashboard', u=u.username))

    return render_template('edit_project.html', project=p, form=form)
Ejemplo n.º 7
0
def new():
    """
    Create a new project.
    """
    form = ProjectDetailsForm()
    if form.validate_on_submit():
        p = Project.by_name_and_owner(form.name.data, g.user)
        if p:
            form.name.errors = [
                wtf.ValidationError('Project name must be unique.')
            ]
        else:
            p = Project.new(
                form.name.data,
                public=form.public.data,
                website=form.website.data
            )
            p.full_name = '{0}/{1}'.format(g.user.username, p.name)
            g.user.projects.append(p)
            g.db.session.add(p)

            if p.public:
                # New public projects get added to #commits by default.
                c = Channel.new(
                    '#commits',
                    'irc.freenode.net',
                    6667,
                    ssl=False,
                    public=True
                )
                p.channels.append(c)

            g.db.session.commit()

            return redirect(url_for('.details', u=g.user.username, p=p.name))

    return render_template('new_project.html', form=form)
Ejemplo n.º 8
0
def projects(page=1):
    per_page = min(int(request.args.get('l', 25)), 100)
    sort_by = request.args.get('s', 'created')

    q = Project.visible(Project.query, user=g.user).order_by(False)
    q = q.order_by({
        'created': Project.created.desc(),
        'messages': Project.message_count.desc()
    }.get(sort_by, Project.created.desc()))

    pagination = q.paginate(page, per_page, False)

    return render_template('projects.html',
                           pagination=pagination,
                           per_page=per_page)
Ejemplo n.º 9
0
    def _wrapped(*args, **kwargs):
        u = User.by_username(kwargs.pop('u'))
        if not u:
            # No such user exists.
            return abort(404)

        p = Project.by_name_and_owner(kwargs.pop('p'), u)
        if not p:
            # Project doesn't exist (404 Not Found)
            return abort(404)

        kwargs['p'] = p
        kwargs['u'] = u

        return f(*args, **kwargs)
Ejemplo n.º 10
0
    def _wrapped(*args, **kwargs):
        u = User.by_username(kwargs.pop('u'))
        if not u:
            # No such user exists.
            return abort(404)

        p = Project.by_name_and_owner(kwargs.pop('p'), u)
        if not p:
            # Project doesn't exist (404 Not Found)
            return abort(404)

        kwargs['p'] = p
        kwargs['u'] = u

        return f(*args, **kwargs)
Ejemplo n.º 11
0
def projects(page=1):
    per_page = min(int(request.args.get('l', 25)), 100)
    sort_by = request.args.get('s', 'created')

    q = Project.visible(Project.query, user=g.user).order_by(False)
    q = q.order_by({
        'created': Project.created.desc(),
        'messages': Project.message_count.desc()
    }.get(sort_by, Project.created.desc()))

    pagination = q.paginate(page, per_page, False)

    return render_template('projects.html',
        pagination=pagination,
        per_page=per_page
    )
Ejemplo n.º 12
0
def landing():
    """
    Show a landing page giving a short intro blurb to unregistered users
    and very basic metrics such as total users.
    """
    # Find the 10 latest public projects.
    new_projects = (Project.visible(Project.query,
                                    user=g.user).order_by(False).order_by(
                                        Project.created.desc())).paginate(
                                            1, 10, False)

    return render_template('landing.html',
                           new_projects=new_projects,
                           top_networks=stats.top_networks(limit=10),
                           total_networks=stats.total_networks(),
                           total_users=stats.total_users())
Ejemplo n.º 13
0
def landing():
    """
    Show a landing page giving a short intro blurb to unregistered users
    and very basic metrics such as total users.
    """
    # Find the 10 latest public projects.
    new_projects = (
        Project.visible(Project.query, user=g.user)
        .order_by(False)
        .order_by(Project.created.desc())
    ).paginate(1, 10, False)

    return render_template(
        'landing.html',
        new_projects=new_projects,
        top_networks=stats.top_networks(limit=10),
        total_networks=stats.total_networks(),
        total_users=stats.total_users()
    )
Ejemplo n.º 14
0
def edit_project(u, p):
    """
    Edit an existing project.
    """
    if p.owner.id != g.user.id:
        # Project isn't public and the viewer isn't the project owner.
        # (403 Forbidden)
        return abort(403)

    form = ProjectDetailsForm(obj=p)
    if form.validate_on_submit():
        old_p = Project.by_name_and_owner(form.name.data, g.user)
        if old_p and old_p.id != p.id:
            form.name.errors = [wtf.ValidationError("Project name must be unique.")]
        else:
            p.name = form.name.data
            p.website = form.website.data
            p.public = form.public.data
            p.full_name = "{0}/{1}".format(g.user.username, p.name)
            g.db.session.commit()
            flash("Your changes have been saved.", "success")
            return redirect(url_for(".overview", u=u.username))

    return render_template("edit_project.html", project=p, form=form)
Ejemplo n.º 15
0
def github():
    """
    Import/merge the users existing Github projects, optionally setting up
    web hooks for them.
    """
    if 'code' in request.args:
        # We've finished step one and have a temporary token.
        r = requests.post('https://github.com/login/oauth/access_token',
            params={
                'client_id': app.config['SERVICE_GITHUB_CLIENT_ID'],
                'client_secret': app.config['SERVICE_GITHUB_CLIENT_SECRET'],
                'code': request.args['code']
        }, headers={
            'Accept': 'application/json'
        })
        result = r.json
        token = AuthToken.new(result['access_token'], 'github')
        g.db.session.add(token)
        g.user.tokens.append(token)
        g.db.session.commit()
        return redirect(url_for('.github'))

    # Check to see if the user has previously authenticated.
    access_token = AuthToken.query.filter_by(
        name='github',
        owner_id=g.user.id
    ).first()

    if access_token is None:
        # The user hasn't setup Github yet, we need to get their OAuth
        # token.
        return redirect(
            'https://github.com/login/oauth/authorize?{0}'.format(
                urllib.urlencode({
                    'client_id': app.config['SERVICE_GITHUB_CLIENT_ID'],
                    'scope': 'repo'
                })
            )
        )

    # Set authentication and pull a JSON blob of all their
    # repos that they have actually created (or forked).
    # If we leave type as the default ("all") we also get
    # repos they have permission on, which we probably don't want.
    git = Github(access_token.token)
    user_repos = git.get_user().get_repos(type='all')

    summary = None
    options_form = GithubForm()
    if options_form.validate_on_submit():
        summary = []
        # WTForms "forgets" disabled fields. This should /always/ be True.
        options_form.projects.data = True

        for repo in user_repos:
            # User didn't check the box, don't import this project.
            # A hack-ish solution to wtform's BooleanField limitation,
            # or I would be using wtf.FieldList(wtf.BooleanField(...)).
            if request.form.get(str(repo.id), None) != 'y':
                continue

            p = Project.by_name_and_owner(repo.name, g.user)
            if p is not None:
                summary.append((
                    (
                        'Skipping {0} as a project with that name already'
                        ' exists.'
                    ).format(repo.name),
                    False
                ))
                continue

            p = Project.new(
                repo.name,
                public=not repo.private,
                website=repo.homepage
            )
            p.full_name = '{0}/{1}'.format(g.user.username, p.name)
            g.user.projects.append(p)
            g.db.session.add(p)

            summary.append((
                'Project {0} created.'.format(repo.name),
                True
            ))

            if options_form.set_hooks.data:
                # The user wanted us to auto-create web hooks for them.
                # We need to commit first to generate the project.id.
                g.db.session.commit()

                # Create the hook on Notifico's side...
                h = Hook.new(10)
                p.hooks.append(h)
                g.db.session.add(h)

                # ... then create the hook on Github's side.
                repo.create_hook('web', {
                    'url': url_for(
                        'projects.hook_recieve',
                        pid=p.id,
                        key=h.key,
                        _external=True
                    )
                })

        g.db.session.commit()

    return render_template('github.html',
        options_form=options_form,
        summary=summary,
        user_repos=user_repos
    )
Ejemplo n.º 16
0
def github():
    """
    Import/merge the users existing Github projects, optionally setting up
    web hooks for them.
    """
    if 'code' in request.args:
        # We've finished step one and have a temporary token.
        r = requests.post('https://github.com/login/oauth/access_token',
            params={
                'client_id': app.config['SERVICE_GITHUB_CLIENT_ID'],
                'client_secret': app.config['SERVICE_GITHUB_CLIENT_SECRET'],
                'code': request.args['code']
        }, headers={
            'Accept': 'application/json'
        })
        result = r.json()
        token = AuthToken.new(result['access_token'], 'github')
        g.db.session.add(token)
        g.user.tokens.append(token)
        g.db.session.commit()
        return redirect(url_for('.github'))

    # Check to see if the user has previously authenticated.
    access_token = AuthToken.query.filter_by(
        name='github',
        owner_id=g.user.id
    ).first()

    if access_token is None:
        # The user hasn't setup Github yet, we need to get their OAuth
        # token.
        return redirect(
            'https://github.com/login/oauth/authorize?{0}'.format(
                urllib.urlencode({
                    'client_id': app.config['SERVICE_GITHUB_CLIENT_ID'],
                    'scope': 'repo'
                })
            )
        )

    # Set authentication and pull a JSON blob of all their
    # repos that they have actually created (or forked).
    # If we leave type as the default ("all") we also get
    # repos they have permission on, which we probably don't want.
    git = Github(access_token.token)
    # Test to make sure our token is still good...
    try:
        git.get_user().login
    except GithubException as exception:
        # Nope!
        if exception.status == 401:
            # The user almost certainly removed the OAuth token
            # from their github applications page. Remove the now-obsolete
            # token and refresh.
            access_token = AuthToken.query.filter_by(
                name='github',
                owner_id=g.user.id
            ).first()
            if access_token:
                g.user.tokens.remove(access_token)
                g.db.session.delete(access_token)
                g.db.session.commit()
            return redirect(request.path)

    user = git.get_user()
    # Get all of the users own repositories
    user_repos = user.get_repos(type='all')
    # ... and get all of the repos in the users organizations ...
    all_repos = chain(user_repos, *[o.get_repos() for o in user.get_orgs()])
    admin_repos = (r for r in all_repos if r.permissions.admin)

    summary = None
    options_form = GithubForm()
    if options_form.validate_on_submit():
        summary = []

        for repo in admin_repos:
            # User didn't check the box, don't import this project.
            # A hack-ish solution to wtform's BooleanField limitation,
            # or I would be using wtf.FieldList(wtf.BooleanField(...)).
            if request.form.get(str(repo.id), None) != 'y':
                continue

            # Make sure this project doesn't already exists.
            p = Project.by_name_and_owner(repo.name, g.user)
            if p is None:
                p = Project.new(
                    repo.name,
                    public=not repo.private,
                    website=repo.homepage
                )
                p.full_name = '{0}/{1}'.format(g.user.username, p.name)
                g.user.projects.append(p)
                g.db.session.add(p)
                # We need to commit to generate the project.id which is
                # used for the following steps.
                g.db.session.commit()

                summary.append((
                    'Project {0} created.'.format(repo.name),
                    True
                ))
            elif p is not None and not options_form.update_projects.data:
                summary.append((
                    'Skipping existing project {0}.'.format(repo.name),
                    False
                ))
                continue
            else:
                summary.append((
                    'Project {0} updated.'.format(repo.name),
                    True
                ))

            if options_form.set_hooks.data:
                # The user wanted us to auto-create web hooks for them.
                h = Hook.query.filter_by(
                    project_id=p.id,
                    service_id=10
                ).first()
                if h is None:
                    # No hooks for github have been setup yet, so go ahead
                    # and create one.
                    h = Hook.new(10)
                    p.hooks.append(h)
                    g.db.session.add(h)

                    repo.create_hook('web', {
                        'url': url_for(
                            'projects.hook_receive',
                            pid=p.id,
                            key=h.key,
                            _external=True
                        )
                    })

            if options_form.set_commits.data and p.public:
                # The user wanted us to add their public projects
                # to #[email protected] for them, but only if it
                # isn't already there.
                c = Channel.query.filter_by(
                    host='irc.freenode.net',
                    channel='#commits',
                    project_id=p.id
                ).first()
                if c is None:
                    # It does *not* already exist, so go ahead and add it.
                    c = Channel.new(
                        '#commits',
                        'irc.freenode.net',
                        6667,
                        ssl=False,
                        public=True
                    )
                    p.channels.append(c)
                    g.db.session.add(c)

        g.db.session.commit()

    return render_template('github.html',
        options_form=options_form,
        summary=summary,
        user_repos=admin_repos
    )
Ejemplo n.º 17
0
def github():
    """
    Import/merge the users existing Github projects, optionally setting up
    web hooks for them.
    """
    if 'code' in request.args:
        # We've finished step one and have a temporary token.
        r = requests.post(
            'https://github.com/login/oauth/access_token',
            params={
                'client_id': current_app.config['SERVICE_GITHUB_CLIENT_ID'],
                'client_secret':
                current_app.config['SERVICE_GITHUB_CLIENT_SECRET'],
                'code': request.args['code']
            },
            headers={'Accept': 'application/json'})
        result = r.json()
        token = AuthToken.new(result['access_token'], 'github')
        db.session.add(token)
        g.user.tokens.append(token)
        db.session.commit()
        return redirect(url_for('.github'))

    # Check to see if the user has previously authenticated.
    access_token = AuthToken.query.filter_by(name='github',
                                             owner_id=g.user.id).first()

    if access_token is None:
        # The user hasn't setup Github yet, we need to get their OAuth
        # token.
        return redirect('https://github.com/login/oauth/authorize?{0}'.format(
            urllib.urlencode({
                'client_id':
                current_app.config['SERVICE_GITHUB_CLIENT_ID'],
                'scope':
                'repo'
            })))

    # Set authentication and pull a JSON blob of all their
    # repos that they have actually created (or forked).
    # If we leave type as the default ("all") we also get
    # repos they have permission on, which we probably don't want.
    git = Github(access_token.token, user_agent="Notifico Github Import/0.1")
    # Test to make sure our token is still good...
    try:
        git.get_user().login
    except GithubException as exception:
        # Nope!
        if exception.status == 401:
            # The user almost certainly removed the OAuth token
            # from their github applications page. Remove the now-obsolete
            # token and refresh.
            access_token = AuthToken.query.filter_by(
                name='github', owner_id=g.user.id).first()
            if access_token:
                g.user.tokens.remove(access_token)
                db.session.delete(access_token)
                db.session.commit()
            return redirect(request.path)

    user = git.get_user()
    # Get all of the users own repositories
    user_repos = user.get_repos(type='all')
    # ... and get all of the repos in the users organizations ...
    all_repos = chain(user_repos, *[o.get_repos() for o in user.get_orgs()])
    admin_repos = (r for r in all_repos if r.permissions.admin)

    summary = None
    options_form = GithubForm()
    if options_form.validate_on_submit():
        summary = []

        for repo in admin_repos:
            # User didn't check the box, don't import this project.
            # A hack-ish solution to wtform's BooleanField limitation,
            # or I would be using wtf.FieldList(wtf.BooleanField(...)).
            if request.form.get(str(repo.id), None) != 'y':
                continue

            # Make sure this project doesn't already exists.
            p = Project.by_name_and_owner(repo.name, g.user)
            if p is None:
                p = Project.new(repo.name,
                                public=not repo.private,
                                website=repo.homepage)
                p.full_name = '{0}/{1}'.format(g.user.username, p.name)
                g.user.projects.append(p)
                db.session.add(p)
                # We need to commit to generate the project.id which is
                # used for the following steps.
                db.session.commit()

                summary.append(
                    ('Project {0} created.'.format(repo.name), True))
            elif p is not None and not options_form.update_projects.data:
                summary.append(
                    ('Skipping existing project {0}.'.format(repo.name),
                     False))
                continue
            else:
                summary.append(
                    ('Project {0} updated.'.format(repo.name), True))

            if options_form.set_hooks.data:
                # The user wanted us to auto-create web hooks for them.
                h = Hook.query.filter_by(project_id=p.id,
                                         service_id=10).first()
                if h is None:
                    # No hooks for github have been setup yet, so go ahead
                    # and create one.
                    h = Hook.new(10)
                    p.hooks.append(h)
                    db.session.add(h)

                    repo.create_hook(
                        'web', {
                            'url':
                            url_for('projects.hook_receive',
                                    pid=p.id,
                                    key=h.key,
                                    _external=True)
                        })

            if options_form.set_commits.data and p.public:
                # The user wanted us to add their public projects
                # to #[email protected] for them, but only if it
                # isn't already there.
                c = Channel.query.filter_by(host='chat.freenode.net',
                                            channel='#commits',
                                            project_id=p.id).first()
                if c is None:
                    # It does *not* already exist, so go ahead and add it.
                    c = Channel.new('#commits',
                                    'chat.freenode.net',
                                    6667,
                                    ssl=False,
                                    public=True)
                    p.channels.append(c)
                    db.session.add(c)

        db.session.commit()

    return render_template('github.html',
                           options_form=options_form,
                           summary=summary,
                           user_repos=admin_repos)