Skip to content

Commit

Permalink
Merge branch 'dev' into annotation-tool
Browse files Browse the repository at this point in the history
  • Loading branch information
Splines committed Mar 21, 2024
2 parents e72860a + 4e031a6 commit 933b8e6
Show file tree
Hide file tree
Showing 41 changed files with 487 additions and 71 deletions.
74 changes: 74 additions & 0 deletions app/assets/javascripts/feedback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
$(document).on("turbolinks:load", () => {
if (!shouldRegisterFeedback()) {
return;
}
registerToasts();
registerSubmitButtonHandler();
registerFeedbackBodyValidator();
});

var SUBMIT_FEEDBACK_ID = "#submit-feedback";

var TOAST_OPTIONS = {
animation: true,
autohide: true,
delay: 6000, // autohide after ... milliseconds
};

function shouldRegisterFeedback() {
return $(SUBMIT_FEEDBACK_ID).length > 0;
}

function registerToasts() {
const toastElements = document.querySelectorAll(".toast");
[...toastElements].map((toast) => {
new bootstrap.Toast(toast, TOAST_OPTIONS);
});
}

function registerSubmitButtonHandler() {
// Invoke the hidden submit button inside the actual Rails form
$("#submit-feedback-form-btn-outside").click(() => {
submitFeedback();
});

// Submit form by pressing Ctrl + Enter
document.addEventListener("keydown", (event) => {
const isModalOpen = $(SUBMIT_FEEDBACK_ID).is(":visible");
if (isModalOpen && event.ctrlKey && event.key == "Enter") {
submitFeedback();
}
});
}

function registerFeedbackBodyValidator() {
const feedbackBody = document.getElementById("feedback_feedback");
feedbackBody.addEventListener("input", () => {
validateFeedback();
});
}

function validateFeedback() {
const feedbackBody = document.getElementById("feedback_feedback");
const validityState = feedbackBody.validity;
if (validityState.tooShort) {
const tooShortMessage = feedbackBody.dataset.tooShortMessage;
feedbackBody.setCustomValidity(tooShortMessage);
}
else if (validityState.valueMissing) {
const valueMissingMessage = feedbackBody.dataset.valueMissingMessage;
feedbackBody.setCustomValidity(valueMissingMessage);
}
else {
// render input valid, so that form will submit
feedbackBody.setCustomValidity("");
}

feedbackBody.reportValidity();
}

function submitFeedback() {
const submitButton = $("#submit-feedback-form-btn");
validateFeedback();
submitButton.click();
}
2 changes: 2 additions & 0 deletions app/assets/javascripts/lectures.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ $(document).on 'turbolinks:load', ->
$('#secondnav').show()
$('#lecturesDropdown').appendTo($('#secondnav'))
$('#notificationDropdown').appendTo($('#secondnav'))
$('#feedback-btn').appendTo($('#secondnav'))
$('#searchField').appendTo($('#secondnav'))
$('#second-admin-nav').show()
$('#adminDetails').appendTo($('#second-admin-nav'))
Expand All @@ -259,6 +260,7 @@ $(document).on 'turbolinks:load', ->
$('#secondnav').hide()
$('#lecturesDropdown').appendTo($('#firstnav'))
$('#notificationDropdown').appendTo($('#firstnav'))
$('#feedback-btn').appendTo($('#firstnav'))
$('#searchField').appendTo($('#firstnav'))
$('#second-admin-nav').hide()
$('#teachableDrop').appendTo($('#first-admin-nav'))
Expand Down
4 changes: 4 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,7 @@ a {
text-decoration: underline;
}
}

.toast {
background-color: white;
}
11 changes: 11 additions & 0 deletions app/assets/stylesheets/feedback.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#feedback-btn {
color: white;

&:focus {
box-shadow: none;
}

&:hover {
color: #ffc107;
}
}
12 changes: 6 additions & 6 deletions app/controllers/erdbeere_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def current_ability
end

def show_example
response = Faraday.get(ENV.fetch("ERDBEERE_API", nil) + "/examples/#{params[:id]}")
response = Faraday.get(ENV.fetch("ERDBEERE_API") + "/examples/#{params[:id]}")
@content = if response.status == 200
JSON.parse(response.body)["embedded_html"]
else
Expand All @@ -17,7 +17,7 @@ def show_example
end

def show_property
response = Faraday.get(ENV.fetch("ERDBEERE_API", nil) + "/properties/#{params[:id]}")
response = Faraday.get(ENV.fetch("ERDBEERE_API") + "/properties/#{params[:id]}")

@content = if response.status == 200
JSON.parse(response.body)["embedded_html"]
Expand All @@ -28,7 +28,7 @@ def show_property

def show_structure
params[:id]
response = Faraday.get(ENV.fetch("ERDBEERE_API", nil) + "/structures/#{params[:id]}")
response = Faraday.get(ENV.fetch("ERDBEERE_API") + "/structures/#{params[:id]}")
@content = if response.status == 200
JSON.parse(response.body)["embedded_html"]
else
Expand All @@ -51,7 +51,7 @@ def cancel_edit_tags
def display_info
@id = params[:id]
@sort = params[:sort]
response = Faraday.get(ENV.fetch("ERDBEERE_API", nil) +
response = Faraday.get(ENV.fetch("ERDBEERE_API") +
"/#{@sort.downcase.pluralize}/#{@id}/view_info")
@content = JSON.parse(response.body)
if response.status != 200
Expand Down Expand Up @@ -87,7 +87,7 @@ def update_tags
end

def fill_realizations_select
response = Faraday.get("#{ENV.fetch("ERDBEERE_API", nil)}/structures/")
response = Faraday.get("#{ENV.fetch("ERDBEERE_API")}/structures/")
@tag = Tag.find_by(id: params[:id])
hash = JSON.parse(response.body)
@structures = hash["data"].map do |d|
Expand All @@ -102,7 +102,7 @@ def fill_realizations_select
end

def find_example
response = Faraday.get("#{ENV.fetch("ERDBEERE_API", nil)}/find?#{find_params.to_query}")
response = Faraday.get("#{ENV.fetch("ERDBEERE_API")}/find?#{find_params.to_query}")
@content = if response.status == 200
JSON.parse(response.body)["embedded_html"]
else
Expand Down
21 changes: 21 additions & 0 deletions app/controllers/feedbacks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class FeedbacksController < ApplicationController
authorize_resource except: [:create]

def create
feedback = Feedback.new(feedback_params)
feedback.user_id = current_user.id
@feedback_success = feedback.save

if @feedback_success
FeedbackMailer.with(feedback: feedback).new_user_feedback_email.deliver_later
end

respond_to(&:js)
end

private

def feedback_params
params.require(:feedback).permit(:title, :feedback, :can_contact)
end
end
4 changes: 2 additions & 2 deletions app/controllers/lectures_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def edit_structures

def search_examples
if @lecture.structure_ids.any?
response = Faraday.get("#{ENV.fetch("ERDBEERE_API", nil)}/search")
response = Faraday.get("#{ENV.fetch("ERDBEERE_API")}/search")
@form = JSON.parse(response.body)["embedded_html"]
# rubocop:disable Style/StringConcatenation
@form.gsub!("token_placeholder",
Expand Down Expand Up @@ -430,7 +430,7 @@ def eager_load_stuff

def set_erdbeere_data
@structure_ids = @lecture.structure_ids
response = Faraday.get("#{ENV.fetch("ERDBEERE_API", nil)}/structures")
response = Faraday.get("#{ENV.fetch("ERDBEERE_API")}/structures")
response_hash = if response.status == 200
JSON.parse(response.body)
else
Expand Down
10 changes: 5 additions & 5 deletions app/controllers/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ def verify_captcha
return true unless ENV["USE_CAPTCHA_SERVICE"]

begin
uri = URI.parse(ENV.fetch("CAPTCHA_VERIFY_URL", nil))
uri = URI.parse(ENV.fetch("CAPTCHA_VERIFY_URL"))
data = { message: params["frc-captcha-solution"],
application_token: ENV.fetch("CAPTCHA_APPLICATION_TOKEN", nil) }
application_token: ENV.fetch("CAPTCHA_APPLICATION_TOKEN") }
header = { "Content-Type": "text/json" }
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if ENV["CAPTCHA_VERIFY_URL"].include?("https")
http.use_ssl = true if ENV.fetch("CAPTCHA_VERIFY_URL").include?("https")
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = data.to_json

Expand Down Expand Up @@ -70,9 +70,9 @@ def after_sign_up_path_for(_resource)
private

def check_registration_limit
timeframe = ((ENV["MAMPF_REGISTRATION_TIMEFRAME"] || 15).to_i.minutes.ago..)
timeframe = (ENV.fetch("MAMPF_REGISTRATION_TIMEFRAME", 15).to_i.minutes.ago..)
num_new_registrations = User.where(confirmed_at: nil, created_at: timeframe).count
max_registrations = (ENV["MAMPF_MAX_REGISTRATION_PER_TIMEFRAME"] || 40).to_i
max_registrations = ENV.fetch("MAMPF_MAX_REGISTRATION_PER_TIMEFRAME", 40).to_i
return if num_new_registrations <= max_registrations

# Current number of new registrations is too high
Expand Down
4 changes: 2 additions & 2 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def current_lecture
def host
if Rails.env.production?
# rubocop:disable Style/StringConcatenation
ENV.fetch("MEDIA_SERVER", nil) + "/" + ENV.fetch("INSTANCE_NAME", nil)
ENV.fetch("MEDIA_SERVER") + "/" + ENV.fetch("INSTANCE_NAME")
# rubocop:enable Style/StringConcatenation
else
""
Expand All @@ -29,7 +29,7 @@ def host
# the actual media server.
# This is used for the download buttons for videos and manuscripts.
def download_host
Rails.env.production? ? ENV.fetch("DOWNLOAD_LOCATION", nil) : ""
Rails.env.production? ? ENV.fetch("DOWNLOAD_LOCATION") : ""
end

# Returns the full title on a per-page basis.
Expand Down
2 changes: 1 addition & 1 deletion app/mailers/exception_handler/exception_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class ExceptionMailer < ApplicationMailer

# Defaults
default subject: I18n.t("exception.exception",
host: ENV.fetch("URL_HOST", nil))
host: ENV.fetch("URL_HOST"))
default from: ExceptionHandler.config.email
default template_path: "exception_handler/mailers"
# => http://stackoverflow.com/a/18579046/1143732
Expand Down
15 changes: 15 additions & 0 deletions app/mailers/feedback_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class FeedbackMailer < ApplicationMailer
default from: DefaultSetting::FEEDBACK_EMAIL
layout false

# Mail to the MaMpf developers including the new feedback of a user.
def new_user_feedback_email
@feedback = params[:feedback]
reply_to_mail = @feedback.can_contact ? @feedback.user.email : ""
subject = "Feedback: #{@feedback.title}"
mail(to: DefaultSetting::FEEDBACK_EMAIL,
subject: subject,
content_type: "text/plain",
reply_to: reply_to_mail)
end
end
10 changes: 10 additions & 0 deletions app/models/feedback.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Feedback from users regarding MaMpf itself.
class Feedback < ApplicationRecord
belongs_to :user

BODY_MIN_LENGTH = 10
BODY_MAX_LENGTH = 10_000
validates :feedback, length: { minimum: BODY_MIN_LENGTH,
maximum: BODY_MAX_LENGTH },
allow_blank: false
end
3 changes: 3 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ class User < ApplicationRecord

# a user has a watchlist with watchlist_entries
has_many :watchlists, dependent: :destroy

has_many :feedbacks, dependent: :destroy

include ScreenshotUploader[:image]

# if a homepage is given it should at leat be a valid address
Expand Down
39 changes: 20 additions & 19 deletions app/models/user_cleaner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ class UserCleaner
attr_accessor :imap, :email_dict, :hash_dict

def login
@imap = Net::IMAP.new(ENV.fetch("IMAPSERVER", nil), port: 993, ssl: true)
@imap.authenticate("LOGIN", ENV.fetch("PROJECT_EMAIL_USERNAME", nil),
ENV.fetch("PROJECT_EMAIL_PASSWORD", nil))
@imap = Net::IMAP.new(ENV.fetch("IMAPSERVER"), port: 993, ssl: true)
@imap.authenticate("LOGIN", ENV.fetch("PROJECT_EMAIL_USERNAME"),
ENV.fetch("PROJECT_EMAIL_PASSWORD"))
end

def logout
Expand All @@ -15,7 +15,7 @@ def logout
def search_emails_and_hashes
@email_dict = {}
@hash_dict = {}
@imap.examine(ENV.fetch("PROJECT_EMAIL_MAILBOX", nil))
@imap.examine(ENV.fetch("PROJECT_EMAIL_MAILBOX"))
# Mails containing multiple email addresses (Subject: "Undelivered Mail Returned to Sender")
@imap.search(["SUBJECT",
"Undelivered Mail Returned to Sender"]).each do |message_id|
Expand Down Expand Up @@ -89,11 +89,11 @@ def send_hashes
end

def delete_ghosts
@hash_dict.each do |mail, hash|
u = User.find_by(email: mail, ghost_hash: hash)
move_mail(@email_dict[mail]) if u.present? && @email_dict.present?
u.destroy! if u&.generic?
end
# @hash_dict.each do |mail, hash|
# u = User.find_by(email: mail, ghost_hash: hash)
# move_mail(@email_dict[mail]) if u.present? && @email_dict.present?
# u.destroy! if u&.generic?
# end
end

def move_mail(message_ids, attempt = 0)
Expand All @@ -103,22 +103,23 @@ def move_mail(message_ids, attempt = 0)
return if attempt > 3

begin
@imap.examine(ENV.fetch("PROJECT_EMAIL_MAILBOX", nil))
@imap.examine(ENV.fetch("PROJECT_EMAIL_MAILBOX"))
@imap.move(message_ids, "Other Users/mampf/handled_bounces")
rescue Net::IMAP::BadResponseError
move_mail(message_ids, attempt + 1)
end
end

def clean!
login
search_emails_and_hashes
return if @email_dict.blank?

send_hashes
sleep(10)
search_emails_and_hashes
delete_ghosts
logout
# TODO: Implement new user cleaner logic
# login
# search_emails_and_hashes
# return if @email_dict.blank?

# send_hashes
# sleep(10)
# search_emails_and_hashes
# delete_ghosts
# logout
end
end
6 changes: 3 additions & 3 deletions app/views/devise/registrations/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
target: :_blank)), class: "d-inline", for: "dsgvo-consent" %>
</div>
<%= f.hidden_field :locale, value: I18n.locale %>
<% if ENV['USE_CAPTCHA_SERVICE']%>
<% if ENV["USE_CAPTCHA_SERVICE"]%>
<p>
<div id="captcha-widget" data-sitekey="YOUR_SITE_KEY" data-start="auto" data-captcha-url="<%=ENV['CAPTCHA_PUZZLE_URL']%>" data-lang="<%=I18n.locale %>"></div>
<div id="captcha-widget" data-sitekey="YOUR_SITE_KEY" data-start="auto" data-captcha-url="<%=ENV.fetch('CAPTCHA_PUZZLE_URL') %>" data-lang="<%=I18n.locale %>"></div>
</p>
<%end %>
<div class="mb-3">
<%= f.submit t('.sign_up'), class: 'btn btn-primary', id: 'register-user', disabled:ENV['USE_CAPTCHA_SERVICE'] %>
<%= f.submit t('.sign_up'), class: 'btn btn-primary', id: 'register-user', disabled:ENV.fetch("USE_CAPTCHA_SERVICE") %>
</div>
<% end %>

Expand Down
2 changes: 1 addition & 1 deletion app/views/exception_handler/mailers/new_exception.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= t('exception.exception_report',
host: ENV['URL_HOST']) %>
host: ENV.fetch("URL_HOST")) %>
<strong>
<%= @exception.response %> (<%= @exception.status %>)
</strong>
Expand Down
Loading

0 comments on commit 933b8e6

Please sign in to comment.