예제 #1
0
파일: mods.py 프로젝트: AAIDev/SpaceDock
def follow(mod_id):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    if any(m.id == mod.id for m in current_user.following):
        abort(418)
    event = FollowEvent.query\
            .filter(FollowEvent.mod_id == mod.id)\
            .order_by(desc(FollowEvent.created))\
            .first()
    # Events are aggregated hourly
    if not event or ((datetime.now() - event.created).seconds / 60 / 60) >= 1:
        event = FollowEvent()
        event.mod = mod
        event.delta = 1
        event.events = 1
        db.add(event)
        db.flush()
        db.commit()
        mod.follow_events.append(event)
    else:
        event.delta += 1
        event.events += 1
    mod.follower_count += 1
    current_user.following.append(mod)
    return {"success": True}
예제 #2
0
def register_with_oauth_authorized():
    '''
    This endpoint should be called after authorizing with oauth, by the user.
    '''
    email = request.form.get('email')
    username = request.form.get('username')
    provider = request.form.get('provider')
    remote_user = request.form.get('remote_user')

    good = True
    if check_username_for_registration(username):
        good = False
    if check_email_for_registration(email):
        good = False

    if good:
        password = binascii.b2a_hex(os.urandom(99))
        user = User(username, email, password)
        user.confirmation = binascii.b2a_hex(os.urandom(20)).decode("utf-8")
        db.add(user)
        db.flush()  # to get an ID.
        auth = UserAuth(user.id, remote_user, provider)
        db.add(auth)
        db.commit()  # Commit before trying to email

        send_confirmation(user)
        return redirect("/account-pending")

    return render_register_with_oauth(provider, remote_user, username, email)
예제 #3
0
파일: mods.py 프로젝트: GenPage/KerbalStuff
def follow(mod_id):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    if any(m.id == mod.id for m in current_user.following):
        abort(418)
    event = FollowEvent.query\
            .filter(FollowEvent.mod_id == mod.id)\
            .order_by(desc(FollowEvent.created))\
            .first()
    # Events are aggregated hourly
    if not event or ((datetime.now() - event.created).seconds / 60 / 60) >= 1:
        event = FollowEvent()
        event.mod = mod
        event.delta = 1
        event.events = 1
        db.add(event)
        db.flush()
        db.commit()
        mod.follow_events.append(event)
    else:
        event.delta += 1
        event.events += 1
    mod.follower_count += 1
    current_user.following.append(mod)
    return { "success": True }
예제 #4
0
def register_with_oauth_authorized():
    '''
    This endpoint should be called after authorizing with oauth, by the user.
    '''
    email = request.form.get('email')
    username = request.form.get('username')
    provider = request.form.get('provider')
    remote_user = request.form.get('remote_user')

    good = True
    if check_username_for_registration(username):
        good = False
    if check_email_for_registration(email):
        good = False

    if good:
        password = binascii.b2a_hex(os.urandom(99))
        user = User(username, email, password)
        user.confirmation = binascii.b2a_hex(os.urandom(20)).decode("utf-8")
        db.add(user)
        db.flush()  # to get an ID.
        auth = UserAuth(user.id, remote_user, provider)
        db.add(auth)
        db.commit()  # Commit before trying to email

        send_confirmation(user)
        return redirect("/account-pending")

    return render_register_with_oauth(provider, remote_user, username, email)
예제 #5
0
def download(mod_id, mod_name, version):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    if not mod.published and (not current_user or current_user.id != mod.user_id):
        abort(401)
    version = ModVersion.query.filter(ModVersion.mod_id == mod_id, \
            ModVersion.friendly_version == version).first()
    if not version:
        abort(404)
    download = DownloadEvent.query\
            .filter(DownloadEvent.mod_id == mod.id and DownloadEvent.version_id == version.id)\
            .order_by(desc(DownloadEvent.created))\
            .first()
    if not os.path.isfile(os.path.join(_cfg('storage'), version.download_path)):
        abort(404)
    # Events are aggregated hourly
    if not download or ((datetime.now() - download.created).seconds / 60 / 60) >= 1:
        download = DownloadEvent()
        download.mod = mod
        download.version = version
        download.downloads = 1
        db.add(download)
        db.flush()
        db.commit()
        mod.downloads.append(download)
    else:
        download.downloads += 1
    mod.download_count += 1
    return send_file(os.path.join(_cfg('storage'), version.download_path), as_attachment = True)
예제 #6
0
def disconnect_oauth():
    provider = request.form.get('provider')

    assert provider in list_defined_oauths()  # This is a quick and dirty form of sanitation.

    auths = UserAuth.query.filter(UserAuth.provider == provider, UserAuth.user_id == current_user.id).all()
    for auth in auths:
        db.delete(auth)

    db.flush()  # So that /profile will display currectly
    return redirect('/profile/%s/edit' % current_user.username)
예제 #7
0
def disconnect_oauth():
    provider = request.form.get('provider')

    assert provider in list_defined_oauths(
    )  # This is a quick and dirty form of sanitation.

    auths = UserAuth.query.filter(UserAuth.provider == provider,
                                  UserAuth.user_id == current_user.id).all()
    for auth in auths:
        db.delete(auth)

    db.flush()  # So that /profile will display currectly
    return redirect('/profile/%s/edit' % current_user.username)
예제 #8
0
파일: mods.py 프로젝트: AAIDev/SpaceDock
def download(mod_id, mod_name, version):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    if not mod.published and (not current_user or current_user.id != mod.user_id):
        abort(401)
    version = ModVersion.query.filter(ModVersion.mod_id == mod_id, \
            ModVersion.friendly_version == version).first()
    if not version:
        abort(404)
    download = DownloadEvent.query\
            .filter(DownloadEvent.mod_id == mod.id and DownloadEvent.version_id == version.id)\
            .order_by(desc(DownloadEvent.created))\
            .first()
    if not os.path.isfile(os.path.join(_cfg('storage'), version.download_path)):
        abort(404)
    
    if not 'Range' in request.headers:
        # Events are aggregated hourly
        if not download or ((datetime.now() - download.created).seconds / 60 / 60) >= 1:
            download = DownloadEvent()
            download.mod = mod
            download.version = version
            download.downloads = 1
            db.add(download)
            db.flush()
            db.commit()
            mod.downloads.append(download)
        else:
            download.downloads += 1
        mod.download_count += 1
    
    if _cfg("cdn-domain"):
        return redirect("http://" + _cfg("cdn-domain") + '/' + version.download_path, code=302)
    
    response = None
    if _cfg("use-x-accel") == 'nginx':
        response = make_response("")
        response.headers['Content-Type'] = 'application/zip'
        response.headers['Content-Disposition'] = 'attachment; filename=' + os.path.basename(version.download_path)
        response.headers['X-Accel-Redirect'] = '/internal/' + version.download_path
    if _cfg("use-x-accel") == 'apache':
        response = make_response("")
        response.headers['Content-Type'] = 'application/zip'
        response.headers['Content-Disposition'] = 'attachment; filename=' + os.path.basename(version.download_path)
        response.headers['X-Sendfile'] = os.path.join(_cfg('storage'), version.download_path)
    if response is None:
        response = make_response(send_file(os.path.join(_cfg('storage'), version.download_path), as_attachment = True))
    return response
예제 #9
0
def download(mod_id, mod_name, version):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    if not mod.published and (not current_user
                              or current_user.id != mod.user_id):
        abort(401)
    version = ModVersion.query.filter(ModVersion.mod_id == mod_id, \
            ModVersion.friendly_version == version).first()
    if not version:
        abort(404)
    download = DownloadEvent.query\
            .filter(DownloadEvent.mod_id == mod.id and DownloadEvent.version_id == version.id)\
            .order_by(desc(DownloadEvent.created))\
            .first()
    if not os.path.isfile(os.path.join(_cfg('storage'),
                                       version.download_path)):
        abort(404)

    if not 'Range' in request.headers:
        # Events are aggregated hourly
        if not download or (
            (datetime.now() - download.created).seconds / 60 / 60) >= 1:
            download = DownloadEvent()
            download.mod = mod
            download.version = version
            download.downloads = 1
            db.add(download)
            db.flush()
            db.commit()
            mod.downloads.append(download)
        else:
            download.downloads += 1
        mod.download_count += 1

    response = make_response(
        send_file(os.path.join(_cfg('storage'), version.download_path),
                  as_attachment=True))
    if _cfg("use-x-accel") == 'true':
        response = make_response("")
        response.headers['Content-Type'] = 'application/zip'
        response.headers[
            'Content-Disposition'] = 'attachment; filename=' + os.path.basename(
                version.download_path)
        response.headers[
            'X-Accel-Redirect'] = '/internal/' + version.download_path
    return response
예제 #10
0
def follow(mod_id):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    game = Game.query.filter(Game.id == mod.game_id).first()
    session['game'] = game.id
    session['gamename'] = game.name
    session['gameshort'] = game.short
    session['gameid'] = game.id
    if not mod or not game:
        ga = Game.query.filter(Game.short == 'kerbal-space-program').order_by(
            desc(Game.id)).first()
        session['game'] = ga.id
        session['gamename'] = ga.name
        session['gameshort'] = ga.short
        session['gameid'] = ga.id
        abort(404)
    else:
        session['game'] = game.id
        session['gamename'] = game.name
        session['gameshort'] = game.short
        session['gameid'] = game.id
    if any(m.id == mod.id for m in current_user.following):
        abort(418)
    event = FollowEvent.query\
            .filter(FollowEvent.mod_id == mod.id)\
            .order_by(desc(FollowEvent.created))\
            .first()
    # Events are aggregated hourly
    if not event or ((datetime.now() - event.created).seconds / 60 / 60) >= 1:
        event = FollowEvent()
        event.mod = mod
        event.delta = 1
        event.events = 1
        db.add(event)
        db.flush()
        db.commit()
        mod.follow_events.append(event)
    else:
        event.delta += 1
        event.events += 1
    mod.follower_count += 1
    current_user.following.append(mod)
    return {"success": True}
예제 #11
0
def follow(mod_id):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    game = Game.query.filter(Game.id == mod.game_id).first()
    session['game'] = game.id;
    session['gamename'] = game.name;
    session['gameshort'] = game.short;
    session['gameid'] = game.id;
    if not mod or not game:
        ga = Game.query.filter(Game.short == 'kerbal-space-program').order_by(desc(Game.id)).first()
        session['game'] = ga.id;
        session['gamename'] = ga.name;
        session['gameshort'] = ga.short;
        session['gameid'] = ga.id;
        abort(404)
    else:
        session['game'] = game.id;
        session['gamename'] = game.name;
        session['gameshort'] = game.short;
        session['gameid'] = game.id;
    if any(m.id == mod.id for m in current_user.following):
        abort(418)
    event = FollowEvent.query\
            .filter(FollowEvent.mod_id == mod.id)\
            .order_by(desc(FollowEvent.created))\
            .first()
    # Events are aggregated hourly
    if not event or ((datetime.now() - event.created).seconds / 60 / 60) >= 1:
        event = FollowEvent()
        event.mod = mod
        event.delta = 1
        event.events = 1
        db.add(event)
        db.flush()
        db.commit()
        mod.follow_events.append(event)
    else:
        event.delta += 1
        event.events += 1
    mod.follower_count += 1
    current_user.following.append(mod)
    return { "success": True }
예제 #12
0
def _connect_with_oauth_finalize(remote_user, provider):
    if not current_user:
        return 'Trying to associate an account, but not logged in?'

    auth = UserAuth.query.filter(UserAuth.provider == provider, UserAuth.remote_user == remote_user).first()
    if auth:
        if auth.user_id == current_user.id:
            # You're already set up.
            return redirect('/profile/%s/edit' % current_user.username)

        # This account is already connected with some user.
        full_name = list_defined_oauths()[provider]['full_name']
        return 'Your %s account is already connected to a SpaceDock account.' % full_name

    auth = UserAuth(current_user.id, remote_user, provider)
    db.add(auth)
    db.flush()  # So that /profile will display currectly

    return redirect('/profile/%s/edit' % current_user.username)
예제 #13
0
def _connect_with_oauth_finalize(remote_user, provider):
    if not current_user:
        return 'Trying to associate an account, but not logged in?'

    auth = UserAuth.query.filter(UserAuth.provider == provider,
                                 UserAuth.remote_user == remote_user).first()
    if auth:
        if auth.user_id == current_user.id:
            # You're already set up.
            return redirect('/profile/%s/edit' % current_user.username)

        # This account is already connected with some user.
        full_name = list_defined_oauths()[provider]['full_name']
        return 'Your %s account is already connected to a KerbalStuff account.' % full_name

    auth = UserAuth(current_user.id, remote_user, provider)
    db.add(auth)
    db.flush()  # So that /profile will display currectly

    return redirect('/profile/%s/edit' % current_user.username)
예제 #14
0
def download(mod_id, mod_name, version):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    if not mod.published and (not current_user or current_user.id != mod.user_id):
        abort(401)
    version = ModVersion.query.filter(ModVersion.mod_id == mod_id, ModVersion.friendly_version == version).first()
    if not version:
        abort(404)
    download = (
        DownloadEvent.query.filter(DownloadEvent.mod_id == mod.id and DownloadEvent.version_id == version.id)
        .order_by(desc(DownloadEvent.created))
        .first()
    )
    if not os.path.isfile(os.path.join(_cfg("storage"), version.download_path)):
        abort(404)

    if not "Range" in request.headers:
        # Events are aggregated hourly
        if not download or ((datetime.now() - download.created).seconds / 60 / 60) >= 1:
            download = DownloadEvent()
            download.mod = mod
            download.version = version
            download.downloads = 1
            db.add(download)
            db.flush()
            db.commit()
            mod.downloads.append(download)
        else:
            download.downloads += 1
        mod.download_count += 1

    response = make_response(send_file(os.path.join(_cfg("storage"), version.download_path), as_attachment=True))
    if _cfg("use-x-accel") == "true":
        response = make_response("")
        response.headers["Content-Type"] = "application/zip"
        response.headers["Content-Disposition"] = "attachment; filename=" + os.path.basename(version.download_path)
        response.headers["X-Accel-Redirect"] = "/internal/" + version.download_path
    return response
예제 #15
0
파일: mods.py 프로젝트: GenPage/KerbalStuff
def mod(id, mod_name):
    mod = Mod.query.filter(Mod.id == id).first()
    if not mod:
        abort(404)
    editable = False
    if current_user:
        if current_user.admin:
            editable = True
        if current_user.id == mod.user_id:
            editable = True
    if not mod.published and not editable:
        abort(401)
    latest = mod.default_version()
    referral = request.referrer
    if referral:
        host = urllib.parse.urlparse(referral).hostname
        event = ReferralEvent.query\
                .filter(ReferralEvent.mod_id == mod.id)\
                .filter(ReferralEvent.host == host)\
                .first()
        if not event:
            event = ReferralEvent()
            event.mod = mod
            event.events = 1
            event.host = host
            db.add(event)
            db.flush()
            db.commit()
            mod.referrals.append(event)
        else:
            event.events += 1
    download_stats = None
    follower_stats = None
    referrals = None
    json_versions = None
    thirty_days_ago = datetime.now() - timedelta(days=30)
    referrals = list()
    for r in ReferralEvent.query\
        .filter(ReferralEvent.mod_id == mod.id)\
        .order_by(desc(ReferralEvent.events)):
        referrals.append( { 'host': r.host, 'count': r.events } )
    download_stats = list()
    for d in DownloadEvent.query\
        .filter(DownloadEvent.mod_id == mod.id)\
        .filter(DownloadEvent.created > thirty_days_ago)\
        .order_by(DownloadEvent.created):
        download_stats.append(dumb_object(d))
    follower_stats = list()
    for f in FollowEvent.query\
        .filter(FollowEvent.mod_id == mod.id)\
        .filter(FollowEvent.created > thirty_days_ago)\
        .order_by(FollowEvent.created):
        follower_stats.append(dumb_object(f))
    json_versions = list()
    for v in mod.versions:
        json_versions.append({ 'name': v.friendly_version, 'id': v.id })
    if request.args.get('noedit') != None:
        editable = False
    forumThread = False
    if mod.external_link != None:
        try:
            u = urlparse(mod.external_link)
            if u.netloc == 'forum.kerbalspaceprogram.com':
                forumThread = True
        except e:
            print(e)
            pass
    total_authors = 1
    pending_invite = False
    owner = editable
    for a in mod.shared_authors:
        if a.accepted:
            total_authors += 1
        if current_user:
            if current_user.id == a.user_id and not a.accepted:
                pending_invite = True
            if current_user.id == a.user_id and a.accepted:
                editable = True
    game_versions = GameVersion.query.order_by(desc(GameVersion.id)).all()
    outdated = False
    if latest:
        outdated = game_versions[0].friendly_version != latest.ksp_version
    return render_template("mod.html",
        **{
            'mod': mod,
            'latest': latest,
            'safe_name': secure_filename(mod.name)[:64],
            'featured': any(Featured.query.filter(Featured.mod_id == mod.id).all()),
            'editable': editable,
            'owner': owner,
            'pending_invite': pending_invite,
            'download_stats': download_stats,
            'follower_stats': follower_stats,
            'referrals': referrals,
            'json_versions': json_versions,
            'thirty_days_ago': thirty_days_ago,
            'share_link': urllib.parse.quote_plus(_cfg("protocol") + "://" + _cfg("domain") + "/mod/" + str(mod.id)),
            'game_versions': game_versions,
            'outdated': outdated,
            'forum_thread': forumThread,
            'new': request.args.get('new') != None,
            'stupid_user': request.args.get('stupid_user') != None,
            'total_authors': total_authors,
			"site_name": _cfg('site-name'), 
			"support_mail": _cfg('support-mail')
        })
예제 #16
0
def mod(id, mod_name):
    mod = Mod.query.filter(Mod.id == id).first()
    if not mod:
        abort(404)
    editable = False
    if current_user:
        if current_user.admin:
            editable = True
        if current_user.id == mod.user_id:
            editable = True
    if not mod.published and not editable:
        abort(401)
    latest = mod.default_version()
    referral = request.referrer
    if referral:
        host = urllib.parse.urlparse(referral).hostname
        event = ReferralEvent.query.filter(ReferralEvent.mod_id == mod.id).filter(ReferralEvent.host == host).first()
        if not event:
            event = ReferralEvent()
            event.mod = mod
            event.events = 1
            event.host = host
            db.add(event)
            db.flush()
            db.commit()
            mod.referrals.append(event)
        else:
            event.events += 1
    download_stats = None
    follower_stats = None
    referrals = None
    json_versions = None
    thirty_days_ago = datetime.now() - timedelta(days=30)
    referrals = list()
    for r in ReferralEvent.query.filter(ReferralEvent.mod_id == mod.id).order_by(desc(ReferralEvent.events)):
        referrals.append({"host": r.host, "count": r.events})
    download_stats = list()
    for d in (
        DownloadEvent.query.filter(DownloadEvent.mod_id == mod.id)
        .filter(DownloadEvent.created > thirty_days_ago)
        .order_by(DownloadEvent.created)
    ):
        download_stats.append(dumb_object(d))
    follower_stats = list()
    for f in (
        FollowEvent.query.filter(FollowEvent.mod_id == mod.id)
        .filter(FollowEvent.created > thirty_days_ago)
        .order_by(FollowEvent.created)
    ):
        follower_stats.append(dumb_object(f))
    json_versions = list()
    for v in mod.versions:
        json_versions.append({"name": v.friendly_version, "id": v.id})
    if request.args.get("noedit") != None:
        editable = False
    forumThread = False
    if mod.external_link != None:
        try:
            u = urlparse(mod.external_link)
            if u.netloc == "forum.kerbalspaceprogram.com":
                forumThread = True
        except e:
            print(e)
            pass
    total_authors = 1
    pending_invite = False
    owner = editable
    for a in mod.shared_authors:
        if a.accepted:
            total_authors += 1
        if current_user:
            if current_user.id == a.user_id and not a.accepted:
                pending_invite = True
            if current_user.id == a.user_id and a.accepted:
                editable = True
    game_versions = GameVersion.query.order_by(desc(GameVersion.id)).all()
    outdated = False
    if latest:
        outdated = game_versions[0].friendly_version != latest.ksp_version
    return render_template(
        "mod.html",
        **{
            "mod": mod,
            "latest": latest,
            "safe_name": secure_filename(mod.name)[:64],
            "featured": any(Featured.query.filter(Featured.mod_id == mod.id).all()),
            "editable": editable,
            "owner": owner,
            "pending_invite": pending_invite,
            "download_stats": download_stats,
            "follower_stats": follower_stats,
            "referrals": referrals,
            "json_versions": json_versions,
            "thirty_days_ago": thirty_days_ago,
            "share_link": urllib.parse.quote_plus(_cfg("protocol") + "://" + _cfg("domain") + "/mod/" + str(mod.id)),
            "game_versions": game_versions,
            "outdated": outdated,
            "forum_thread": forumThread,
            "new": request.args.get("new") != None,
            "stupid_user": request.args.get("stupid_user") != None,
            "total_authors": total_authors,
        }
    )
예제 #17
0
def mod(id, mod_name):
    games = Game.query.filter(Game.active == True).order_by(desc(
        Game.id)).all()
    if session.get('gameid'):
        if session['gameid']:
            ga = Game.query.filter(Game.id == session['gameid']).order_by(
                desc(Game.id)).first()
        else:
            ga = Game.query.filter(
                Game.short == 'kerbal-space-program').order_by(desc(
                    Game.id)).first()
    else:
        ga = Game.query.filter(Game.short == 'kerbal-space-program').order_by(
            desc(Game.id)).first()
    session['game'] = ga.id
    session['gamename'] = ga.name
    session['gameshort'] = ga.short
    session['gameid'] = ga.id
    mod = Mod.query.filter(Mod.id == id, Mod.game_id == ga.id).first()
    if not mod:
        abort(404)
    if not mod or not ga:
        abort(404)
    editable = False
    if current_user:
        if current_user.admin:
            editable = True
        if current_user.id == mod.user_id:
            editable = True
    if not mod.published and not editable:
        abort(401)
    latest = mod.default_version()
    referral = request.referrer
    if referral:
        host = urllib.parse.urlparse(referral).hostname
        event = ReferralEvent.query\
                .filter(ReferralEvent.mod_id == mod.id)\
                .filter(ReferralEvent.host == host)\
                .first()
        if not event:
            event = ReferralEvent()
            event.mod = mod
            event.events = 1
            event.host = host
            db.add(event)
            db.flush()
            db.commit()
            mod.referrals.append(event)
        else:
            event.events += 1
    download_stats = None
    follower_stats = None
    referrals = None
    json_versions = None
    thirty_days_ago = datetime.now() - timedelta(days=30)
    referrals = list()
    for r in ReferralEvent.query\
        .filter(ReferralEvent.mod_id == mod.id)\
        .order_by(desc(ReferralEvent.events)):
        referrals.append({'host': r.host, 'count': r.events})
    download_stats = list()
    for d in DownloadEvent.query\
        .filter(DownloadEvent.mod_id == mod.id)\
        .filter(DownloadEvent.created > thirty_days_ago)\
        .order_by(DownloadEvent.created):
        download_stats.append(dumb_object(d))
    follower_stats = list()
    for f in FollowEvent.query\
        .filter(FollowEvent.mod_id == mod.id)\
        .filter(FollowEvent.created > thirty_days_ago)\
        .order_by(FollowEvent.created):
        follower_stats.append(dumb_object(f))
    json_versions = list()
    for v in mod.versions:
        json_versions.append({'name': v.friendly_version, 'id': v.id})
    if request.args.get('noedit') != None:
        editable = False
    forumThread = False
    if mod.external_link != None:
        try:
            u = urlparse(mod.external_link)
            if u.netloc == 'forum.kerbalspaceprogram.com':
                forumThread = True
        except e:
            print(e)
            pass
    total_authors = 1
    pending_invite = False
    owner = editable
    for a in mod.shared_authors:
        if a.accepted:
            total_authors += 1
        if current_user:
            if current_user.id == a.user_id and not a.accepted:
                pending_invite = True
            if current_user.id == a.user_id and a.accepted:
                editable = True
    games = Game.query.filter(Game.active == True).order_by(desc(
        Game.id)).all()

    game_versions = GameVersion.query.filter(
        GameVersion.game_id == mod.game_id).order_by(desc(
            GameVersion.id)).all()

    outdated = False
    if latest:
        outdated = latest.gameversion.id != game_versions[
            0].id and latest.gameversion.friendly_version != '1.0.5'
    return render_template(
        "mod.html", **{
            'mod':
            mod,
            'latest':
            latest,
            'safe_name':
            secure_filename(mod.name)[:64],
            'featured':
            any(Featured.query.filter(Featured.mod_id == mod.id).all()),
            'editable':
            editable,
            'owner':
            owner,
            'pending_invite':
            pending_invite,
            'download_stats':
            download_stats,
            'follower_stats':
            follower_stats,
            'referrals':
            referrals,
            'json_versions':
            json_versions,
            'thirty_days_ago':
            thirty_days_ago,
            'share_link':
            urllib.parse.quote_plus(
                _cfg("protocol") + "://" + _cfg("domain") + "/mod/" +
                str(mod.id)),
            'game_versions':
            game_versions,
            'games':
            games,
            'outdated':
            outdated,
            'forum_thread':
            forumThread,
            'new':
            request.args.get('new') != None,
            'stupid_user':
            request.args.get('stupid_user') != None,
            'total_authors':
            total_authors,
            "site_name":
            _cfg('site-name'),
            "support_mail":
            _cfg('support-mail'),
            'ga':
            ga
        })
예제 #18
0
def download(mod_id, mod_name, version):
    mod = Mod.query.filter(Mod.id == mod_id).first()
    if not mod:
        abort(404)
    game = Game.query.filter(Game.id == mod.game_id).first()
    session['game'] = game.id
    session['gamename'] = game.name
    session['gameshort'] = game.short
    session['gameid'] = game.id
    if not mod or not game:
        ga = Game.query.filter(Game.short == 'kerbal-space-program').order_by(
            desc(Game.id)).first()
        session['game'] = ga.id
        session['gamename'] = ga.name
        session['gameshort'] = ga.short
        session['gameid'] = ga.id
        abort(404)
    else:
        session['game'] = game.id
        session['gamename'] = game.name
        session['gameshort'] = game.short
        session['gameid'] = game.id
    if not mod.published and (not current_user
                              or current_user.id != mod.user_id):
        abort(401)
    version = ModVersion.query.filter(ModVersion.mod_id == mod_id, \
            ModVersion.friendly_version == version).first()
    if not version:
        abort(404)
    download = DownloadEvent.query\
            .filter(DownloadEvent.mod_id == mod.id and DownloadEvent.version_id == version.id)\
            .order_by(desc(DownloadEvent.created))\
            .first()
    if not os.path.isfile(os.path.join(_cfg('storage'),
                                       version.download_path)):
        abort(404)

    if not 'Range' in request.headers:
        # Events are aggregated hourly
        if not download or (
            (datetime.now() - download.created).seconds / 60 / 60) >= 1:
            download = DownloadEvent()
            download.mod = mod
            download.version = version
            download.downloads = 1
            db.add(download)
            db.flush()
            db.commit()
            mod.downloads.append(download)
        else:
            download.downloads += 1
        mod.download_count += 1

    if _cfg("cdn-domain"):
        return redirect("http://" + _cfg("cdn-domain") + '/' +
                        version.download_path,
                        code=302)

    response = None
    if _cfg("use-x-accel") == 'nginx':
        response = make_response("")
        response.headers['Content-Type'] = 'application/zip'
        response.headers[
            'Content-Disposition'] = 'attachment; filename=' + os.path.basename(
                version.download_path)
        response.headers[
            'X-Accel-Redirect'] = '/internal/' + version.download_path
    if _cfg("use-x-accel") == 'apache':
        response = make_response("")
        response.headers['Content-Type'] = 'application/zip'
        response.headers[
            'Content-Disposition'] = 'attachment; filename=' + os.path.basename(
                version.download_path)
        response.headers['X-Sendfile'] = os.path.join(_cfg('storage'),
                                                      version.download_path)
    if response is None:
        response = make_response(
            send_file(os.path.join(_cfg('storage'), version.download_path),
                      as_attachment=True))
    return response