new setup.sh

This commit is contained in:
nocci 2025-04-21 11:06:38 +00:00
parent 11760988ee
commit 8bc257aec6
2 changed files with 119 additions and 12 deletions

71
README.md Normal file
View File

@ -0,0 +1,71 @@
# 🗝️ Game Key Management System 🔑
![Project Logo - ideally a nerdy picture of keys or a gamepad]
**Welcome!** 👋
This project helps you keep track of your collected game keys. Does this sound familiar? You have a key here, a key there, from Humble Bundle, Fanatical, or just given to you, but you can't remember if you redeemed it, gifted it, or if it's still lurking somewhere? Don't panic, this is the solution!
## ✨ Features ✨
* **Key Management:** Enter your game keys, along with the corresponding game, platform (Steam, GOG, etc.) and where you got the key.
* **Status Tracking:** Mark keys as "Redeemed", "Gifted" or "Available". So you always know where you stand.
* **Clear Database:** All your keys in one place, easily searchable and sortable.
* **(Planned Features):**
* Import/Export of Keys (CSV, JSON)
* Integration with Steam API (to automatically check if a key has already been redeemed)
* Dark Mode! (Because who doesn't love Dark Mode?)
## 🚀 Get Started! 🚀
1. **Clone the Repository:**
```bash
git clone [Repository URL]
cd [Project Directory]
```
2. **Installation (if required - e.g. for a web application):**
* Describe the necessary installation steps here. Example:
```bash
npm install # Or yarn install, whatever you prefer!
```
3. **Configuration:**
* Explain here which configuration steps are necessary (e.g. setting up a database connection).
* Example: Create a `.env` file and enter your database access data.
4. **Start the Application:**
```bash
npm start # Or however the application is started
```
5. **Use the Application!** Open your browser and go to `http://localhost:[Port]` (or wherever your application is running).
## 🛠️ Technology Stack 🛠️
* **Frontend:** [Enter the frontend technology here - e.g. React, Vue.js, Angular]
* **Backend:** [Enter the backend technology here - e.g. Node.js, Python/Flask, Java/Spring]
* **Database:** [Enter the database here - e.g. PostgreSQL, MySQL, SQLite]
## 🙌 Contribute! 🙌
This project is open source and thrives on your help! If you find bugs, have suggestions, or want to contribute code yourself, you are welcome!
* **Bug Reports:** Please report bugs as Issues.
* **Feature Requests:** Suggest new features!
* **Pull Requests:** Submit your code changes!
Before contributing code, please read the [CONTRIBUTING.md](CONTRIBUTING.md) file.
## 📜 License 📜
This project is licensed under the [MIT License](LICENSE).
## 💖 Acknowledgements 💖
A big thank you to everyone who supports and contributes to this project!

60
setup.sh Executable file → Normal file
View File

@ -41,6 +41,7 @@ app.config['BABEL_DEFAULT_LOCALE'] = 'de'
app.config['BABEL_SUPPORTED_LOCALES'] = ['de', 'en']
app.config['BABEL_TRANSLATION_DIRECTORIES'] = 'translations'
db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
@ -76,6 +77,7 @@ class Game(db.Model):
created_at = db.Column(db.DateTime, default=datetime.utcnow)
redeem_date = db.Column(db.DateTime)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
steam_appid = db.Column(db.String(20))
@login_manager.user_loader
def load_user(user_id):
@ -139,18 +141,31 @@ def logout():
logout_user()
return redirect(url_for('login'))
import re
def extract_steam_appid(url):
match = re.search(r'store\.steampowered\.com/app/(\d+)', url or '')
if match:
return match.group(1)
return ''
@app.route('/add', methods=['GET', 'POST'])
@login_required
def add_game():
if request.method == 'POST':
try:
url = request.form.get('url', '')
steam_appid = request.form.get('steam_appid', '').strip()
if not steam_appid:
steam_appid = extract_steam_appid(url)
new_game = Game(
name=request.form['name'],
steam_key=request.form['steam_key'],
status=request.form['status'],
recipient=request.form.get('recipient', ''),
notes=request.form.get('notes', ''),
url=request.form.get('url', ''),
url=url,
steam_appid=steam_appid, # <- jetzt wird sie gesetzt!
redeem_date=datetime.strptime(request.form['redeem_date'], '%Y-%m-%d') if request.form['redeem_date'] else None,
user_id=current_user.id
)
@ -163,31 +178,45 @@ def add_game():
flash(_('Error: ') + str(e), 'danger')
return render_template('add_game.html')
@app.route('/edit/<int:game_id>', methods=['GET', 'POST'])
@login_required
def edit_game(game_id):
game = Game.query.get_or_404(game_id)
if game.owner != current_user:
game = db.session.get(Game, game_id) # SQLAlchemy 2.x-kompatibel
if not game or game.owner != current_user:
return _("Not allowed!"), 403
if request.method == 'POST':
try:
# Steam AppID aus Formular oder URL extrahieren
url = request.form.get('url', '')
steam_appid = request.form.get('steam_appid', '').strip()
if not steam_appid:
steam_appid = extract_steam_appid(url)
# Aktualisiere alle Felder
game.name = request.form['name']
game.steam_key = request.form['steam_key']
game.status = request.form['status']
game.recipient = request.form.get('recipient', '')
game.notes = request.form.get('notes', '')
game.url = request.form.get('url', '')
game.url = url
game.steam_appid = steam_appid # <- FEHLTE HIER
game.redeem_date = datetime.strptime(request.form['redeem_date'], '%Y-%m-%d') if request.form['redeem_date'] else None
db.session.commit()
flash(_('Changes saved!'), 'success')
return redirect(url_for('index'))
except Exception as e:
db.session.rollback()
flash(_('Error: ') + str(e), 'danger')
return render_template('edit_game.html',
game=game,
redeem_date=game.redeem_date.strftime('%Y-%m-%d') if game.redeem_date else '')
@app.route('/delete/<int:game_id>', methods=['POST'])
@login_required
def delete_game(game_id):
@ -395,6 +424,7 @@ cat <<HTML_END > templates/index.html
<table class="table table-hover align-middle">
<thead class="table-dark">
<tr>
<th>{{ _('Cover') }}</th>
<th>{{ _('Name') }}</th>
<th>{{ _('Key') }}</th>
<th>{{ _('Status') }}</th>
@ -407,6 +437,12 @@ cat <<HTML_END > templates/index.html
<tbody>
{% for game in games %}
<tr>
<td>
{% if game.steam_appid %}
<img src="https://cdn.cloudflare.steamstatic.com/steam/apps/{{ game.steam_appid }}/header.jpg"
alt="Steam Header" style="height:64px;max-width:120px;object-fit:cover;">
{% endif %}
</td>
<td>{{ game.name }}</td>
<td class="font-monospace">{{ game.steam_key }}</td>
<td>
@ -430,14 +466,9 @@ cat <<HTML_END > templates/index.html
{% endif %}
</td>
<td class="text-nowrap">
<a href="{{ url_for('edit_game', game_id=game.id) }}"
class="btn btn-sm btn-warning">✏️</a>
<form method="POST"
action="{{ url_for('delete_game', game_id=game.id) }}"
class="d-inline">
<button type="submit"
class="btn btn-sm btn-danger"
onclick="return confirm('{{ _('Really delete?') }}')">🗑️</button>
<a href="{{ url_for('edit_game', game_id=game.id) }}" class="btn btn-sm btn-warning">✏️</a>
<form method="POST" action="{{ url_for('delete_game', game_id=game.id) }}" class="d-inline">
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('{{ _('Really delete?') }}')">🗑️</button>
</form>
</td>
</tr>
@ -452,6 +483,7 @@ cat <<HTML_END > templates/index.html
HTML_END
cat <<HTML_END > templates/add_game.html
{% extends "base.html" %}
{% block content %}
@ -517,6 +549,10 @@ cat <<HTML_END > templates/edit_game.html
<label class="form-label">{{ _('Steam Key') }} *</label>
<input type="text" name="steam_key" class="form-control" value="{{ game.steam_key }}" required>
</div>
<div class="col-md-6">
<label class="form-label">{{ _('Steam AppID (optional)') }}</label>
<input type="text" name="steam_appid" class="form-control" value="{{ game.steam_appid or '' }}">
</div>
<div class="col-md-4">
<label class="form-label">{{ _('Status') }} *</label>
<select name="status" class="form-select" required>