Skip to content
Snippets Groups Projects
Commit 3ad942f1 authored by Inga Kirschnick's avatar Inga Kirschnick
Browse files

Share link implementation for followers

parent 4fab75f0
No related branches found
No related tags found
No related merge requests found
...@@ -57,17 +57,27 @@ def disable_corpus_is_public(corpus_id): ...@@ -57,17 +57,27 @@ def disable_corpus_is_public(corpus_id):
@bp.route('/<hashid:corpus_id>/follow/<token>') @bp.route('/<hashid:corpus_id>/follow/<token>')
@login_required @login_required
def follow_corpus(corpus_id, token): def follow_corpus(corpus_id, token):
try: corpus = Corpus.query.get_or_404(corpus_id)
try:
payload = jwt.decode( payload = jwt.decode(
token, token,
current_app.config['SECRET_KEY'], current_app.config['SECRET_KEY'],
algorithms=['HS256'], algorithms=['HS256'],
issuer=current_app.config['SERVER_NAME'], issuer=current_app.config['SERVER_NAME'],
options={'require': ['iat', 'iss', 'sub']} # options={'require': ['exp', 'iat', 'iss', 'sub']}
) options={'require': ['exp', 'iat', 'iss']}
)
except jwt.PyJWTError: except jwt.PyJWTError:
return False abort(403)
return redirect(url_for('.corpus', corpus_id=corpus_id)) # permission = payload.get('sub')
expiration = payload.get('exp')
if expiration < int(datetime.utcnow().timestamp()):
abort(403)
if not current_user.is_following_corpus(corpus):
current_user.follow_corpus(corpus)
db.session.commit()
flash(f'You are following {corpus.title} now', category='corpus')
return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
@bp.route('/<hashid:corpus_id>/followers/<hashid:follower_id>/unfollow', methods=['POST']) @bp.route('/<hashid:corpus_id>/followers/<hashid:follower_id>/unfollow', methods=['POST'])
...@@ -170,6 +180,9 @@ def create_corpus(): ...@@ -170,6 +180,9 @@ def create_corpus():
def corpus(corpus_id): def corpus(corpus_id):
corpus = Corpus.query.get_or_404(corpus_id) corpus = Corpus.query.get_or_404(corpus_id)
exp_date = (datetime.utcnow() + timedelta(days=7)).strftime('%b %d, %Y') exp_date = (datetime.utcnow() + timedelta(days=7)).strftime('%b %d, %Y')
print(corpus.user)
print(current_user)
print(current_user.is_following_corpus(corpus))
if corpus.user == current_user or current_user.is_administrator(): if corpus.user == current_user or current_user.is_administrator():
return render_template( return render_template(
'corpora/corpus.html.j2', 'corpora/corpus.html.j2',
...@@ -191,15 +204,15 @@ def corpus(corpus_id): ...@@ -191,15 +204,15 @@ def corpus(corpus_id):
@login_required @login_required
def generate_corpus_share_link(corpus_id): def generate_corpus_share_link(corpus_id):
data = request.get_json('data') data = request.get_json('data')
permission = data['permission'] # permission = data['permission']
expiration = data['expiration'] exp_data = data['expiration']
corpus = Corpus.query.get_or_404(corpus_id) expiration = datetime.strptime(exp_data, '%b %d, %Y')
now = datetime.utcnow() now = datetime.utcnow()
payload = { payload = {
'exp': expiration, 'exp': expiration,
'iat': now, 'iat': now,
'iss': current_app.config['SERVER_NAME'], 'iss': current_app.config['SERVER_NAME']
'sub': permission # 'sub': permission
} }
token = jwt.encode( token = jwt.encode(
payload, payload,
......
...@@ -31,6 +31,7 @@ class CorpusDisplay extends RessourceDisplay { ...@@ -31,6 +31,7 @@ class CorpusDisplay extends RessourceDisplay {
this.setStatus(corpus.status); this.setStatus(corpus.status);
this.setTitle(corpus.title); this.setTitle(corpus.title);
this.setNumTokens(corpus.num_tokens); this.setNumTokens(corpus.num_tokens);
this.setShareLink();
} }
onPatch(patch) { onPatch(patch) {
...@@ -117,4 +118,28 @@ class CorpusDisplay extends RessourceDisplay { ...@@ -117,4 +118,28 @@ class CorpusDisplay extends RessourceDisplay {
new Date(creationDate).toLocaleString("en-US") new Date(creationDate).toLocaleString("en-US")
); );
} }
setShareLink() {
let generateShareLinkButton = this.displayElement.querySelector('#generate-share-link-button');
let copyShareLinkButton = this.displayElement.querySelector('#copy-share-link-button');
let shareLinkInput = this.displayElement.querySelector('#share-link-input');
// let permissionSelect = this.displayElement.querySelector('#permission-select');
let expirationDate = this.displayElement.querySelector('#expiration');
generateShareLinkButton.addEventListener('click', () => {
// Utils.generateCorpusShareLinkRequest(`${this.corpusId}`, permissionSelect.value, expirationDate.value)
Utils.generateCorpusShareLinkRequest(`${this.corpusId}`, expirationDate.value)
.then((shareLink) => {
shareLinkInput.parentElement.classList.remove('hide');
shareLinkInput.value = shareLink;
});
});
copyShareLinkButton.addEventListener('click', () => {
shareLinkInput.select();
navigator.clipboard.writeText(shareLinkInput.value);
app.flash(`Copied!`, 'success');
});
}
} }
...@@ -778,9 +778,11 @@ class Utils { ...@@ -778,9 +778,11 @@ class Utils {
}); });
} }
static generateCorpusShareLinkRequest(corpusId, permission, expiration) { // static generateCorpusShareLinkRequest(corpusId, permission, expiration) {
static generateCorpusShareLinkRequest(corpusId, expiration) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const data = {permission: permission, expiration: expiration}; // const data = {permission: permission, expiration: expiration};
const data = {expiration: expiration};
fetch(`/corpora/${corpusId}/generate-corpus-share-link`, {method: 'POST', headers: {Accept: 'text/plain'}, body: JSON.stringify(data)}) fetch(`/corpora/${corpusId}/generate-corpus-share-link`, {method: 'POST', headers: {Accept: 'text/plain'}, body: JSON.stringify(data)})
.then( .then(
(response) => { (response) => {
......
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
</div> </div>
<br> <br>
<p></p> <p></p>
<div class="row"> {# <div class="row">
<div class="col s4"> <div class="col s4">
<div class="input-field"> <div class="input-field">
<select id="permission-select"> <select id="permission-select">
...@@ -107,7 +107,7 @@ ...@@ -107,7 +107,7 @@
<label>Permission</label> <label>Permission</label>
</div> </div>
</div> </div>
</div> </div> #}
<div class="row"> <div class="row">
<div class="col s4"> <div class="col s4">
<div class="input-field"> <div class="input-field">
...@@ -119,8 +119,10 @@ ...@@ -119,8 +119,10 @@
<div class="row"> <div class="row">
<div class="col s12"> <div class="col s12">
<a class="action-button btn waves-effect waves-light" id="generate-share-link-button">Generate Share Link</a> <a class="action-button btn waves-effect waves-light" id="generate-share-link-button">Generate Share Link</a>
<div id="share-link"></div> <div class="hide">
<a class="action-button btn-small waves-effect waves-light hide" id="copy-share-link-button">Copy</a> <input id="share-link-input" readonly>
<a class="action-button btn-small waves-effect waves-light" id="copy-share-link-button">Copy</a>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -142,30 +144,5 @@ ...@@ -142,30 +144,5 @@
{{ super() }} {{ super() }}
<script> <script>
let corpusDisplay = new CorpusDisplay(document.querySelector('#corpus-display')); let corpusDisplay = new CorpusDisplay(document.querySelector('#corpus-display'));
let generateShareLinkButton = document.querySelector('#generate-share-link-button');
let copyShareLinkButton = document.querySelector('#copy-share-link-button');
let shareLink = document.querySelector('#share-link');
let permissionSelect = document.querySelector('#permission-select');
let expirationDate = document.querySelector('#expiration');
generateShareLinkButton.addEventListener('click', () => {
Utils.generateCorpusShareLinkRequest('{{ corpus.hashid }}', permissionSelect.value, expirationDate.value)
.then((corpusShareLink) => {
console.log(corpusShareLink);
let shareLinkElement = document.createElement('input');
shareLinkElement.value = corpusShareLink;
shareLinkElement.setAttribute('readonly', '');
shareLink.appendChild(shareLinkElement);
copyShareLinkButton.classList.remove('hide');
});
});
copyShareLinkButton.addEventListener('click', () => {
let shareLinkElement = document.querySelector('#share-link input');
shareLinkElement.select();
document.execCommand('copy');
app.flash(`Copied!`, 'success');
});
</script> </script>
{% endblock scripts %} {% endblock scripts %}
...@@ -61,13 +61,13 @@ ...@@ -61,13 +61,13 @@
let unfollowRequestElement = document.querySelector('.action-button[data-action="unfollow-request"]'); let unfollowRequestElement = document.querySelector('.action-button[data-action="unfollow-request"]');
unfollowRequestElement.addEventListener('click', () => { unfollowRequestElement.addEventListener('click', () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fetch('{{ url_for("corpora.unfollow_corpus", corpus_id=corpus.id) }}', {method: 'POST', headers: {Accept: 'application/json'}}) fetch('{{ url_for("corpora.current_user_unfollow_corpus", corpus_id=corpus.id) }}', {method: 'POST', headers: {Accept: 'application/json'}})
.then( .then(
(response) => { (response) => {
if (response.status === 403) {app.flash('Forbidden', 'error'); reject(response);} if (response.status === 403) {app.flash('Forbidden', 'error'); reject(response);}
if (response.status === 404) {app.flash('Not Found', 'error'); reject(response);} if (response.status === 404) {app.flash('Not Found', 'error'); reject(response);}
resolve(response); resolve(response);
window.location.href = '{{ url_for("corpora.corpus", corpus_id=corpus.id) }}'; window.location.href = '{{ url_for("main.dashboard") }}';
}, },
(response) => { (response) => {
app.flash('Something went wrong', 'error'); app.flash('Something went wrong', 'error');
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment