mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-14 16:55:42 +00:00
Merge branch 'development' of gitlab.ub.uni-bielefeld.de:sfb1288inf/opaque into development
This commit is contained in:
commit
eb5e5c3253
@ -17,10 +17,13 @@ def before_request():
|
||||
Checks if a user is unconfirmed when visiting specific sites. Redirects to
|
||||
unconfirmed view if user is unconfirmed.
|
||||
"""
|
||||
if (current_user.is_authenticated and not current_user.confirmed
|
||||
and request.blueprint != 'auth'
|
||||
and request.endpoint != 'static'):
|
||||
return redirect(url_for('auth.unconfirmed'))
|
||||
if current_user.is_authenticated:
|
||||
current_user.ping()
|
||||
if not current_user.confirmed \
|
||||
and request.endpoint \
|
||||
and request.blueprint != 'auth' \
|
||||
and request.endpoint != 'static':
|
||||
return redirect(url_for('auth.unconfirmed'))
|
||||
|
||||
|
||||
@auth.route('/login', methods=['GET', 'POST'])
|
||||
|
@ -26,13 +26,12 @@ def add_corpus():
|
||||
try:
|
||||
os.makedirs(dir)
|
||||
except OSError:
|
||||
flash('[ERROR]: Could not add corpus!')
|
||||
flash('[ERROR]: Could not add corpus!', 'corpus')
|
||||
corpus.delete()
|
||||
else:
|
||||
corpus_url = url_for('corpora.corpus', corpus_id=corpus.id)
|
||||
flash('<i class="left material-icons">book</i>'
|
||||
'[<a href="{}">{}</a>] added'.format(corpus_url,
|
||||
corpus.title))
|
||||
url = url_for('corpora.corpus', corpus_id=corpus.id)
|
||||
flash('[<a href="{}">{}</a>] added'.format(url, corpus.title),
|
||||
'corpus')
|
||||
return redirect(url_for('corpora.corpus', corpus_id=corpus.id))
|
||||
return render_template('corpora/add_corpus.html.j2',
|
||||
add_corpus_form=add_corpus_form,
|
||||
@ -82,7 +81,7 @@ def delete_corpus(corpus_id):
|
||||
if not (corpus.creator == current_user or current_user.is_administrator()):
|
||||
abort(403)
|
||||
tasks.delete_corpus(corpus_id)
|
||||
flash('Corpus deleted!')
|
||||
flash('Corpus deleted!', 'corpus')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
|
||||
|
||||
@ -121,7 +120,7 @@ def add_corpus_file(corpus_id):
|
||||
db.session.add(corpus_file)
|
||||
corpus.status = 'unprepared'
|
||||
db.session.commit()
|
||||
flash('Corpus file added!')
|
||||
flash('Corpus file added!', 'corpus')
|
||||
return make_response(
|
||||
{'redirect_url': url_for('corpora.corpus', corpus_id=corpus.id)},
|
||||
201)
|
||||
@ -141,7 +140,7 @@ def delete_corpus_file(corpus_id, corpus_file_id):
|
||||
or current_user.is_administrator()):
|
||||
abort(403)
|
||||
tasks.delete_corpus_file(corpus_file_id)
|
||||
flash('Corpus file deleted!')
|
||||
flash('Corpus file deleted!', 'corpus')
|
||||
return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
|
||||
|
||||
|
||||
@ -188,7 +187,7 @@ def edit_corpus_file(corpus_id, corpus_file_id):
|
||||
corpus_file.title = edit_corpus_file_form.title.data
|
||||
corpus.status = 'unprepared'
|
||||
db.session.commit()
|
||||
flash('Corpus file edited!')
|
||||
flash('Corpus file edited!', 'corpus')
|
||||
return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
|
||||
# If no form is submitted or valid, fill out fields with current values
|
||||
edit_corpus_file_form.address.data = corpus_file.address
|
||||
@ -217,7 +216,7 @@ def prepare_corpus(corpus_id):
|
||||
abort(403)
|
||||
if corpus.files.all():
|
||||
tasks.build_corpus(corpus_id)
|
||||
flash('Corpus gets build now.')
|
||||
flash('Corpus gets build now.', 'corpus')
|
||||
else:
|
||||
flash('Can not build corpus, please add corpus file(s).')
|
||||
flash('Can not build corpus, please add corpus file(s).', 'corpus')
|
||||
return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
|
||||
|
@ -16,6 +16,7 @@ def create_message(recipient, subject, template, **kwargs):
|
||||
|
||||
|
||||
@background
|
||||
def send(app, msg):
|
||||
def send(msg, *args, **kwargs):
|
||||
app = kwargs['app']
|
||||
with app.app_context():
|
||||
mail.send(msg)
|
||||
|
@ -23,7 +23,7 @@ def delete_job(job_id):
|
||||
if not (job.creator == current_user or current_user.is_administrator()):
|
||||
abort(403)
|
||||
tasks.delete_job(job_id)
|
||||
flash('Job has been deleted!')
|
||||
flash('Job has been deleted!', 'job')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
|
||||
|
||||
|
@ -106,13 +106,18 @@ class User(UserMixin, db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
# Fields
|
||||
confirmed = db.Column(db.Boolean, default=False)
|
||||
last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
|
||||
email = db.Column(db.String(254), unique=True, index=True)
|
||||
password_hash = db.Column(db.String(128))
|
||||
registration_date = db.Column(db.DateTime(), default=datetime.utcnow)
|
||||
member_since = db.Column(db.DateTime(), default=datetime.utcnow)
|
||||
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
|
||||
username = db.Column(db.String(64), unique=True, index=True)
|
||||
# Setting Fields
|
||||
setting_dark_mode = db.Column(db.Boolean, default=False)
|
||||
setting_job_status_mail_notifications = db.Column(db.String(16),
|
||||
default='end')
|
||||
setting_job_status_site_notifications = db.Column(db.String(16),
|
||||
default='all')
|
||||
# Relationships
|
||||
corpora = db.relationship('Corpus', backref='creator', lazy='dynamic',
|
||||
cascade='save-update, merge, delete')
|
||||
@ -205,6 +210,10 @@ class User(UserMixin, db.Model):
|
||||
"""
|
||||
return self.can(Permission.ADMIN)
|
||||
|
||||
def ping(self):
|
||||
self.last_seen = datetime.utcnow()
|
||||
db.session.add(self)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Delete the user and its corpora and jobs from database and filesystem.
|
||||
|
@ -1,6 +1,6 @@
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import (BooleanField, PasswordField, StringField, SubmitField,
|
||||
ValidationError)
|
||||
from wtforms import (BooleanField, PasswordField, SelectField, StringField,
|
||||
SubmitField, ValidationError)
|
||||
from wtforms.validators import DataRequired, Email, EqualTo
|
||||
|
||||
|
||||
@ -11,6 +11,20 @@ class EditEmailForm(FlaskForm):
|
||||
|
||||
class EditGeneralSettingsForm(FlaskForm):
|
||||
dark_mode = BooleanField('Dark mode')
|
||||
job_status_mail_notifications = SelectField(
|
||||
'Job status mail notifications',
|
||||
choices=[('', 'Choose your option'),
|
||||
('all', 'Notify on all status changes'),
|
||||
('end', 'Notify only when a job ended'),
|
||||
('none', 'No status update notifications')],
|
||||
validators=[DataRequired()])
|
||||
job_status_site_notifications = SelectField(
|
||||
'Job status site notifications',
|
||||
choices=[('', 'Choose your option'),
|
||||
('all', 'Notify on all status changes'),
|
||||
('end', 'Notify only when a job ended'),
|
||||
('none', 'No status update notifications')],
|
||||
validators=[DataRequired()])
|
||||
save_settings = SubmitField('Save settings')
|
||||
|
||||
|
||||
|
@ -11,8 +11,7 @@ from .. import db
|
||||
def settings():
|
||||
edit_email_form = EditEmailForm(prefix='edit-email-form')
|
||||
edit_general_settings_form = EditGeneralSettingsForm(
|
||||
prefix='edit-general-settings-form'
|
||||
)
|
||||
prefix='edit-general-settings-form')
|
||||
edit_password_form = EditPasswordForm(prefix='edit-password-form',
|
||||
user=current_user)
|
||||
# Check if edit_email_form is submitted and valid
|
||||
@ -25,7 +24,12 @@ def settings():
|
||||
# Check if edit_settings_form is submitted and valid
|
||||
if (edit_general_settings_form.save_settings.data
|
||||
and edit_general_settings_form.validate_on_submit()):
|
||||
current_user.setting_dark_mode = edit_general_settings_form.dark_mode.data
|
||||
current_user.setting_dark_mode = \
|
||||
edit_general_settings_form.dark_mode.data
|
||||
current_user.setting_job_status_mail_notifications = \
|
||||
edit_general_settings_form.job_status_mail_notifications.data
|
||||
current_user.setting_job_status_site_notifications = \
|
||||
edit_general_settings_form.job_status_site_notifications.data
|
||||
db.session.add(current_user)
|
||||
db.session.commit()
|
||||
flash('Your settings have been updated.')
|
||||
@ -41,6 +45,10 @@ def settings():
|
||||
# If no form is submitted or valid, fill out fields with current values
|
||||
edit_email_form.email.data = current_user.email
|
||||
edit_general_settings_form.dark_mode.data = current_user.setting_dark_mode
|
||||
edit_general_settings_form.job_status_site_notifications.data = \
|
||||
current_user.setting_job_status_site_notifications
|
||||
edit_general_settings_form.job_status_mail_notifications.data = \
|
||||
current_user.setting_job_status_mail_notifications
|
||||
return render_template(
|
||||
'profile/settings.html.j2',
|
||||
edit_email_form=edit_email_form,
|
||||
|
@ -61,7 +61,7 @@ def service(service):
|
||||
os.makedirs(absolut_dir)
|
||||
except OSError:
|
||||
job.delete()
|
||||
flash('Internal Server Error')
|
||||
flash('Internal Server Error', 'job')
|
||||
return make_response({'redirect_url': url_for('services.service',
|
||||
service=service)},
|
||||
500)
|
||||
@ -74,9 +74,8 @@ def service(service):
|
||||
db.session.add(job_input)
|
||||
job.status = 'submitted'
|
||||
db.session.commit()
|
||||
job_url = url_for('jobs.job', job_id=job.id)
|
||||
flash('<i class="left material-icons">work</i>'
|
||||
'[<a href="{}">{}</a>] added'.format(job_url, job.title))
|
||||
url = url_for('jobs.job', job_id=job.id)
|
||||
flash('[<a href="{}">{}</a>] added'.format(url, job.title), 'job')
|
||||
return make_response(
|
||||
{'redirect_url': url_for('jobs.job', job_id=job.id)}, 201)
|
||||
return render_template('services/{}.html.j2'.format(service),
|
||||
|
@ -67,7 +67,7 @@ class CorpusAnalysisClient {
|
||||
}
|
||||
} else {
|
||||
errorText = `Error ${response.payload.code} - ${response.payload.msg}`;
|
||||
nopaque.flash("error", errorText);
|
||||
nopaque.flash(errorText, "error");
|
||||
if (this.displays.query.errorContainer != undefined) {
|
||||
this.displays.query.errorContainer.innerHTML = `<p class="red-text">`+
|
||||
`<i class="material-icons tiny">error</i> ${errorText}</p>`;
|
||||
|
@ -43,13 +43,6 @@ nopaque.socket.init = function() {
|
||||
var patch;
|
||||
|
||||
patch = JSON.parse(msg);
|
||||
for (operation of patch) {
|
||||
/* "/corpusId/valueName" -> ["corpusId", "valueName"] */
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
if (operation.op === "replace" && pathArray[1] === "status") {
|
||||
nopaque.flash(`<i class="left material-icons">book</i>[<a href="/jobs/${pathArray[0]}">${nopaque.corpora[pathArray[0]].title}</a>] New status: ${operation.value}`);
|
||||
}
|
||||
}
|
||||
nopaque.corpora = jsonpatch.apply_patch(nopaque.corpora, patch);
|
||||
for (let subscriber of nopaque.corporaSubscribers) {subscriber._update(patch);}
|
||||
});
|
||||
@ -58,14 +51,17 @@ nopaque.socket.init = function() {
|
||||
var patch;
|
||||
|
||||
patch = JSON.parse(msg);
|
||||
for (operation of patch) {
|
||||
/* "/jobId/valueName" -> ["jobId", "valueName"] */
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
if (operation.op === "replace" && pathArray[1] === "status") {
|
||||
nopaque.flash(`<i class="left material-icons">work</i>[<a href="/jobs/${pathArray[0]}">${nopaque.jobs[pathArray[0]].title}</a>] New status: ${operation.value}`);
|
||||
nopaque.jobs = jsonpatch.apply_patch(nopaque.jobs, patch);
|
||||
if (["all", "end"].includes(nopaque.user.settings.jobStatusSiteNotifications)) {
|
||||
for (operation of patch) {
|
||||
/* "/jobId/valueName" -> ["jobId", "valueName"] */
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
if (operation.op === "replace" && pathArray[1] === "status") {
|
||||
if (nopaque.user.settings.jobStatusSiteNotifications === "end" && !["complete", "failed"].includes(operation.value)) {continue;}
|
||||
nopaque.flash(`[<a href="/jobs/${pathArray[0]}">${nopaque.jobs[pathArray[0]].title}</a>] New status: ${operation.value}`, "job");
|
||||
}
|
||||
}
|
||||
}
|
||||
nopaque.jobs = jsonpatch.apply_patch(nopaque.jobs, patch);
|
||||
for (let subscriber of nopaque.jobsSubscribers) {subscriber._update(patch);}
|
||||
});
|
||||
|
||||
@ -188,23 +184,28 @@ nopaque.flash = function() {
|
||||
message = arguments[0];
|
||||
break;
|
||||
case 2:
|
||||
category = arguments[0];
|
||||
message = arguments[1];
|
||||
message = arguments[0];
|
||||
category = arguments[1];
|
||||
break;
|
||||
default:
|
||||
console.error("Usage: nopaque.flash(message) or nopaque.flash(category, message)")
|
||||
console.error("Usage: nopaque.flash(message) or nopaque.flash(message, category)")
|
||||
}
|
||||
|
||||
switch (category) {
|
||||
case "corpus":
|
||||
message = `<i class="left material-icons">book</i>${message}`;
|
||||
break;
|
||||
case "error":
|
||||
classes = "red";
|
||||
message = `<i class="left material-icons red-text">error</i>${message}`;
|
||||
break;
|
||||
case "job":
|
||||
message = `<i class="left material-icons">work</i>${message}`;
|
||||
break;
|
||||
default:
|
||||
classes = "";
|
||||
message = `<i class="left material-icons">notifications</i>${message}`;
|
||||
}
|
||||
|
||||
toast = M.toast({classes: classes,
|
||||
html: `<span>${message}</span>
|
||||
toast = M.toast({html: `<span>${message}</span>
|
||||
<button data-action="close" class="btn-flat toast-action white-text">
|
||||
<i class="material-icons">close</i>
|
||||
</button>`});
|
||||
@ -229,7 +230,8 @@ document.addEventListener("DOMContentLoaded", function() {
|
||||
nopaque.Forms.init();
|
||||
nopaque.Navigation.init();
|
||||
while (nopaque.flashedMessages.length) {
|
||||
nopaque.flash(...nopaque.flashedMessages.shift());
|
||||
flashedMessage = nopaque.flashedMessages.shift();
|
||||
nopaque.flash(flashedMessage[1], flashedMessage[0]);
|
||||
}
|
||||
if (nopaque.user.isAuthenticated) {
|
||||
if (nopaque.user.settings.darkMode) {
|
||||
|
@ -378,7 +378,7 @@ class ResultsList extends List {
|
||||
if (expertModeSwitchElement.checked) {
|
||||
this.expertModeOn("query-display"); // page holds new result rows, so add new tooltips
|
||||
}
|
||||
nopaque.flash("Updated matches per page.")
|
||||
nopaque.flash("Updated matches per page.", "corpus")
|
||||
} catch (e) {
|
||||
// console.log(e);
|
||||
// console.log("resultsList has no results right now.");
|
||||
@ -394,7 +394,7 @@ class ResultsList extends List {
|
||||
let rc;
|
||||
try {
|
||||
if (event.type === "change") {
|
||||
nopaque.flash("Updated context per match!");
|
||||
nopaque.flash("Updated context per match!", "corpus");
|
||||
}
|
||||
} catch (e) {
|
||||
} finally {
|
||||
|
@ -15,8 +15,9 @@
|
||||
<li>Username: {{ user.username }}</li>
|
||||
<li>Email: {{ user.email }}</li>
|
||||
<li>ID: {{ user.id }}</li>
|
||||
<li>Registration date: {{ user.registration_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}</li>
|
||||
<li>Member sinse: {{ user.member_since.strftime('%m/%d/%Y, %H:%M:%S %p') }}</li>
|
||||
<li>Confirmed status: {{ user.confirmed }}</li>
|
||||
<li>Last seen: {{ user.last_seen.strftime('%m/%d/%Y, %H:%M:%S %p') }}</li>
|
||||
<li>Role ID: {{ user.role_id }}</li>
|
||||
<li>Permissions as Int: {{ user.role.permissions }}</li>
|
||||
<li>Role name: {{ user.role.name }}</li>
|
||||
|
@ -175,7 +175,6 @@
|
||||
|
||||
for (let operation of patch) {
|
||||
/* "/jobId/valueName" -> ["jobId", "valueName"] */
|
||||
console.log(operation.value);
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
if (pathArray[0] != this.jobId) {continue;}
|
||||
switch(operation.op) {
|
||||
|
@ -29,12 +29,15 @@
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_boolean_field(field) %}
|
||||
{% set label = kwargs.pop('label', True) %}
|
||||
<div class="switch">
|
||||
{% if 'material_icon' in kwargs %}
|
||||
<i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
|
||||
{% endif %}
|
||||
<label>
|
||||
{% if label %}
|
||||
{{ field.label.text }}
|
||||
{% endif %}
|
||||
{{ field(*args, **kwargs) }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
@ -44,12 +47,6 @@
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_decimal_range_field(field) %}
|
||||
<p class="range-field">
|
||||
{{ field(*args, **kwargs) }}
|
||||
</p>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_file_field(field) %}
|
||||
{% set placeholder = kwargs.pop('placeholder', '') %}
|
||||
<div class="file-field input-field">
|
||||
@ -64,12 +61,15 @@
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_generic_field(field) %}
|
||||
{% set label = kwargs.pop('label', True) %}
|
||||
<div class="input-field">
|
||||
{% if 'material_icon' in kwargs %}
|
||||
<i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
|
||||
{% endif %}
|
||||
{{ field(*args, **kwargs) }}
|
||||
{% if label %}
|
||||
{{ field.label }}
|
||||
{% endif %}
|
||||
{% for error in field.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
|
@ -49,9 +49,15 @@
|
||||
<script src="{{ url_for('static', filename='js/nopaque.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/nopaque.lists.js') }}"></script>
|
||||
<script>
|
||||
nopaque.user.isAuthenticated = {{ current_user.is_authenticated|tojson }};
|
||||
nopaque.user.settings.darkMode = {{ (current_user.is_authenticated and current_user.setting_dark_mode)|tojson }};
|
||||
nopaque.flashedMessages = {{ get_flashed_messages(with_categories=true)|tojson }};
|
||||
{% if current_user.is_authenticated %}
|
||||
nopaque.user.isAuthenticated = true;
|
||||
nopaque.user.settings.darkMode = {{ current_user.setting_dark_mode|tojson }};
|
||||
nopaque.user.settings.jobStatusMailNotifications = {{ current_user.setting_job_status_mail_notifications|tojson }};
|
||||
nopaque.user.settings.jobStatusSiteNotifications = {{ current_user.setting_job_status_site_notifications|tojson }};
|
||||
{% else %}
|
||||
nopaque.user.isAuthenticated = false;
|
||||
{% endif %}
|
||||
nopaque.flashedMessages = {{ get_flashed_messages(with_categories=True)|tojson }};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -16,27 +16,27 @@
|
||||
<p class="light">Activate dark mode to ease your eyes.</p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
{{ edit_general_settings_form.dark_mode() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
{{ M.render_field(edit_general_settings_form.dark_mode, label=False) }}
|
||||
</div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s9">
|
||||
<p><i class="material-icons left">notifications</i>Email notifications</p>
|
||||
<p class="light">Receive emails when a job completes.</p>
|
||||
<div class="col s12 m8">
|
||||
<p><i class="material-icons left">notifications</i>Job status site notifications</p>
|
||||
<p class="light">Receive site notifications about job status changes.</p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input disabled type="checkbox">
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col s12 m4 right-align">
|
||||
{{ M.render_field(edit_general_settings_form.job_status_site_notifications, label=False) }}
|
||||
</div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 m8">
|
||||
<p><i class="material-icons left">notifications</i>Job status mail notifications</p>
|
||||
<p class="light">Receive mail notifications about job status changes.</p>
|
||||
</div>
|
||||
<div class="col s12 m4 right-align">
|
||||
{{ M.render_field(edit_general_settings_form.job_status_mail_notifications, label=False) }}
|
||||
</div>
|
||||
<!--
|
||||
Seperate each setting with the following two elements
|
||||
|
30
migrations/versions/099037c4aa06_.py
Normal file
30
migrations/versions/099037c4aa06_.py
Normal file
@ -0,0 +1,30 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 099037c4aa06
|
||||
Revises: 66253783654f
|
||||
Create Date: 2020-04-27 09:17:15.039728
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '099037c4aa06'
|
||||
down_revision = '66253783654f'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('users', sa.Column('last_seen', sa.DateTime(), nullable=True))
|
||||
op.add_column('users', sa.Column('setting_site_job_status_notifications', sa.String(length=16), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('users', 'setting_site_job_status_notifications')
|
||||
op.drop_column('users', 'last_seen')
|
||||
# ### end Alembic commands ###
|
36
migrations/versions/49a42c69e523_.py
Normal file
36
migrations/versions/49a42c69e523_.py
Normal file
@ -0,0 +1,36 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 49a42c69e523
|
||||
Revises: 099037c4aa06
|
||||
Create Date: 2020-04-27 11:18:32.999099
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '49a42c69e523'
|
||||
down_revision = '099037c4aa06'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('users', sa.Column('member_since', sa.DateTime(), nullable=True))
|
||||
op.add_column('users', sa.Column('setting_job_status_mail_notifications', sa.String(length=16), nullable=True))
|
||||
op.add_column('users', sa.Column('setting_job_status_site_notifications', sa.String(length=16), nullable=True))
|
||||
op.drop_column('users', 'setting_site_job_status_notifications')
|
||||
op.drop_column('users', 'registration_date')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('users', sa.Column('registration_date', postgresql.TIMESTAMP(), autoincrement=False, nullable=True))
|
||||
op.add_column('users', sa.Column('setting_site_job_status_notifications', sa.VARCHAR(length=16), autoincrement=False, nullable=True))
|
||||
op.drop_column('users', 'setting_job_status_site_notifications')
|
||||
op.drop_column('users', 'setting_job_status_mail_notifications')
|
||||
op.drop_column('users', 'member_since')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue
Block a user