Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
MX0100 committed Jun 27, 2024
0 parents commit 1a75652
Show file tree
Hide file tree
Showing 1,423 changed files with 221,841 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions .idea/Safezone-main.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions .idea/dataSources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Safezone-main/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions Safezone-main/.idea/Demo.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions Safezone-main/.idea/dataSources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Safezone-main/.idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Safezone-main/.idea/jsLibraryMappings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Safezone-main/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Safezone-main/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Safezone-main/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file added Safezone-main/__init__.py
Empty file.
1 change: 1 addition & 0 deletions Safezone-main/_configtest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int x;
Empty file added Safezone-main/identifier.sqlite
Empty file.
1 change: 1 addition & 0 deletions Safezone-main/src/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Binary file not shown.
Binary file added Safezone-main/src/__pycache__/config.cpython-36.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
167 changes: 167 additions & 0 deletions Safezone-main/src/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
from flask import Flask, render_template, redirect, url_for, flash, session, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_session import Session
from flask_socketio import SocketIO, emit
from datetime import datetime, timedelta
import os
import socket
from interceptor import login_required

app = Flask(__name__)
app.config.from_object('config.Config')

db = SQLAlchemy(app)
Session(app)
socketio = SocketIO(app)

# 导入表单和模型
from forms import LoginForm, RegistrationForm, ContentForm
from models import User, Content, UserSession

@app.before_request
def create_tables():
db.create_all()

def validate_session():
session_token = session.get('session_token') or request.args.get('session_token')
username = session.get('username')

if not username or not session_token:
return False

user = User.query.filter_by(username=username).first()
if not user:
return False

user_session = UserSession.query.filter_by(session_token=session_token, user_id=user.id).first()
if not user_session:
return False

if user_session.expires_at <= datetime.utcnow():
return False

return True

@app.route('/')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and user.password == form.password.data:
existing_session = UserSession.query.filter_by(user_id=user.id).first()
if existing_session and existing_session.expires_at > datetime.utcnow():
flash('This account is already logged in from another device.', 'danger')
return redirect(url_for('login'))

user_session = UserSession(user_id=user.id)
db.session.add(user_session)
db.session.commit()

session['username'] = user.username
session['session_token'] = user_session.session_token
flash('Login successful!', 'success')
return redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check username and password', 'danger')
return render_template('login.html', form=form)

@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user:
flash('That username is taken. Please choose a different one.', 'danger')
else:
user = User(username=form.username.data, password=form.password.data)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You are now able to log in', 'success')
return redirect(url_for('login'))
return render_template('register.html', form=form)

@app.route('/home', methods=['GET', 'POST'])
@login_required
def home():
if not validate_session():
flash('Session has expired. Please log in again.', 'danger')
return redirect(url_for('login'))

form = ContentForm()
if form.validate_on_submit():
content = Content(text=form.text.data)
db.session.add(content)
db.session.commit()
socketio.emit('new_content', {'text': content.text, 'id': content.id})
flash('Content saved successfully!', 'success')

# 分页
page = request.args.get('page', 1, type=int)
per_page = 6 # 每页显示的条数
pagination = Content.query.order_by(Content.id.desc()).paginate(page, per_page, False)
contents = pagination.items
has_next = pagination.has_next
has_prev = pagination.has_prev # 添加上一页的检查

return render_template('home.html', form=form, contents=contents, page=page, has_next=has_next, has_prev=has_prev)

@app.route('/delete_content/<int:content_id>', methods=['DELETE'])
@login_required
def delete_content(content_id):
content = Content.query.get_or_404(content_id)
try:
content = db.session.merge(content) # 确保对象在当前会话中
db.session.delete(content)
db.session.commit()
socketio.emit('delete_content', {'id': content_id})
return jsonify({'result': 'success'}), 200
except Exception as e:
db.session.rollback()
print(f"Error deleting content: {e}")
return jsonify({'result': 'failure', 'error': str(e)}), 500

@app.route('/logout')
@login_required
def logout():
if 'session_token' in session:
session_token = UserSession.query.filter_by(session_token=session['session_token']).first()
if session_token:
session_token = db.session.merge(session_token) # 确保对象在当前会话中
db.session.delete(session_token)
db.session.commit()
session.pop('username', None)
session.pop('session_token', None)
flash('You have been logged out.', 'success')
return redirect(url_for('login'))


@app.route('/api_logout', methods=['POST'])
@login_required
def api_logout():
if 'session_token' in session:
session_token = UserSession.query.filter_by(session_token=session['session_token']).first()
if session_token:
session_token = db.session.merge(session_token) # 确保对象在当前会话中
db.session.delete(session_token)
db.session.commit()
session.pop('username', None)
session.pop('session_token', None)
return '', 204

# SocketIO事件处理程序
@socketio.on('connect')
def handle_connect():
print('Client connected:', request.sid)

@socketio.on('disconnect')
def handle_disconnect():
print('Client disconnected:', request.sid)

if __name__ == '__main__':
# 获取本机IP地址
hostname = socket.gethostname()
local_ip = socket.gethostbyname(hostname)

print(f'Server running on http://{local_ip}:5000')
socketio.run(app, debug=True, host='0.0.0.0')
13 changes: 13 additions & 0 deletions Safezone-main/src/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import os


class Config:
SECRET_KEY = 'your_secret_key'
SQLALCHEMY_DATABASE_URI = 'sqlite:///site.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SESSION_TYPE = 'filesystem'
SESSION_PERMANENT = False
SESSION_USE_SIGNER = True
SESSION_KEY_PREFIX = 'flask_login_'
SESSION_FILE_DIR = os.path.join(os.path.dirname(__file__), 'instance/sessions')
os.makedirs(SESSION_FILE_DIR, exist_ok=True)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
28 changes: 28 additions & 0 deletions Safezone-main/src/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, TextAreaField
from wtforms.validators import DataRequired, Length, EqualTo, ValidationError
from models import User


class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Login')


def validate_username(username):
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('That username is taken. Please choose a different one.')


class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
password = PasswordField('Password', validators=[DataRequired()])
confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Register')


class ContentForm(FlaskForm):
text = TextAreaField('Text', validators=[DataRequired(), Length(max=1000)])
submit = SubmitField('Save')
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Empty file.
Empty file.
Loading

0 comments on commit 1a75652

Please sign in to comment.