Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Populate user subjects based on documents #634

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ gem 'importmap-rails', '~> 2.1'
gem "omniauth", "~> 2.1"
gem "omniauth-google-oauth2", '~> 1.2'
gem "omniauth-rails_csrf_protection", '~> 1.0'
gem 'pdf-reader'
gem 'pg', '~> 1.5'
gem 'puma', '~> 6.5'
gem 'rollbar', '~> 3.6'
Expand Down
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
Ascii85 (2.0.1)
actioncable (8.0.0.1)
actionpack (= 8.0.0.1)
activesupport (= 8.0.0.1)
Expand Down Expand Up @@ -74,6 +75,7 @@ GEM
uri (>= 0.13.1)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
afm (0.2.2)
ast (2.4.2)
base64 (0.2.0)
bcrypt (3.1.20)
Expand Down Expand Up @@ -126,6 +128,7 @@ GEM
ffi (1.15.5)
globalid (1.2.1)
activesupport (>= 6.1)
hashery (2.1.2)
hashie (5.0.0)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
Expand Down Expand Up @@ -222,6 +225,12 @@ GEM
parser (3.3.7.0)
ast (~> 2.4.1)
racc
pdf-reader (2.13.0)
Ascii85 (>= 1.0, < 3.0, != 2.0.0)
afm (~> 0.2.1)
hashery (~> 2.0)
ruby-rc4
ttfunk
pg (1.5.9)
psych (5.2.2)
date
Expand Down Expand Up @@ -320,6 +329,7 @@ GEM
rubocop (>= 1.52.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
rubyzip (2.4.1)
sassc (2.4.0)
ffi (~> 1.9)
Expand Down Expand Up @@ -360,6 +370,8 @@ GEM
thor (1.3.2)
tilt (2.0.10)
timeout (0.4.2)
ttfunk (1.8.0)
bigdecimal (~> 3.1)
turbo-rails (2.0.11)
actionpack (>= 6.0.0)
railties (>= 6.0.0)
Expand Down Expand Up @@ -402,6 +414,7 @@ DEPENDENCIES
omniauth (~> 2.1)
omniauth-google-oauth2 (~> 1.2)
omniauth-rails_csrf_protection (~> 1.0)
pdf-reader
pg (~> 1.5)
puma (~> 6.5)
rails (~> 8.0.0)
Expand Down
29 changes: 29 additions & 0 deletions app/assets/stylesheets/_utility.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,35 @@
color: #19a819 !important;
}

.color-red {
color: #ff0000 !important;
}

.d-none {
display: none !important;
}

@mixin generate-margin-classes($direction, $property) {
@for $i from 0 through 6 {
.m#{$direction}-#{$i} {
margin-#{$property}: #{$i * 0.5}rem !important;
}
}
}

@include generate-margin-classes(t, top);
@include generate-margin-classes(r, right);
@include generate-margin-classes(b, bottom);
@include generate-margin-classes(l, left);

@mixin generate-margin-axis-classes($axis, $property1, $property2) {
@for $i from 0 through 6 {
.m#{$axis}-#{$i} {
margin-#{$property1}: #{$i * 0.5}rem !important;
margin-#{$property2}: #{$i * 0.5}rem !important;
}
}
}

@include generate-margin-axis-classes(x, left, right);
@include generate-margin-axis-classes(y, top, bottom);
5 changes: 5 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ body {
padding-left: 0px;
}

.subtle-text {
font-size: 0.7em;
color: #666;
}

.show-password-button {
margin-right: -20px;
}
82 changes: 82 additions & 0 deletions app/controllers/academic_histories_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
require 'pdf-reader'

class AcademicHistoriesController < ApplicationController
AcademicEntry = Struct.new(:name, :credits, :number_of_failures, :date_of_completion, :grade) do
def approved?
grade != '***'
end
end

def index
redirect_to new_academic_history_path
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Por que definis el index si el boton en el menu lleva al new? Se podria sacar?

end

def new
end

def create
file = params[:file]
@failed_entries = []
@successful_entries = []

if file && file.content_type == 'application/pdf'
@academic_entries = academic_entries(file)
@academic_entries.each do |entry|
save_academic_entry(entry) if entry.approved?
end
else
flash[:error] = 'Please upload a valid PDF file'
end
render :new
end

private

def save_academic_entry(entry)
subject_match = Subject.where("lower(unaccent(name)) = lower(unaccent(?))", entry.name)
subject_match = subject_match.select { |subject| subject.credits == entry.credits.to_i }
active_subjects = subject_match.select { |subject| !subject.inactive? }
if subject_match.length == 1
save_subject(subject_match.first)
elsif active_subjects.length == 1
save_subject(active_subjects.first)
else
@failed_entries << entry
end
end

def save_subject(subject)
current_student.force_add(subject)
@successful_entries << subject
end

def academic_entries(file)
reader = PDF::Reader.new(file.path)
academic_entries = []

reader.pages.each do |page|
page.text.split("\n").each do |line|
line.match(subject_regex) do |match|
academic_entries << AcademicEntry.new(match[1], match[2], match[3], match[4], match[5])
end
end
end

academic_entries
end

# SubjectName Credits NumberOfFailures DateOfCompletion Grade
def subject_regex
/\s*(.*?)\s+(\d+)\s+(\d+)\s+(#{date_regex.source})\s+(#{grade_regex.source})/
end

# The date can be either a date in the format DD/MM/YYYY or **********
def date_regex
/\*{10}|\d\d\/\d\d\/\d\d\d\d/
end

# The grade can be either a number from 0 to 12, S/N or ***
def grade_regex
/\d+|S\/N|\*{3}/
end
end
6 changes: 6 additions & 0 deletions app/models/base_student.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ def add(approvable)
end
end

def force_add(subject)
ids << subject.exam.id if subject.exam
ids << subject.course.id if subject.course
save!
end

def remove(approvable)
ids.delete(approvable.id)
if !approvable.is_exam? && approvable.subject.exam.present? && ids.include?(approvable.subject.exam.id)
Expand Down
35 changes: 35 additions & 0 deletions app/views/academic_histories/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<h3 class="mdc-deprecated-list-group__subheader mdc-typography--headline5 sign-in mb-3">Resumen por Grupo</h3>
<p class="mb-3">Carga tu escolaridad para marcar automaticamente las materias que ya cursaste.</p>
<p>1) Entrar a <a href="https://bedelias.udelar.edu.uy/" target="_blank">Bedelias</a> e iniciar session</p>
<p>2) Entrar a "Estudiante" -> "Escolaridad" -> "Solicitar Escolaridad"</p>
<p>3) Seleccionar tu carrera y "No" en "Resultados Intermedios"</p>
<%= form_with url: academic_histories_path, method: :post, local: true, html: { multipart: true } do |form| %>
<div class="sign-in my-6">
<%= form.label :file, "Upload PDF" %>
<%= form.file_field :file, accept: "application/pdf" %>

<%= form.button class: "mdc-button mdc-button--raised" do %>
<span class="mdc-button__ripple"></span>
<span class='mdc-button__label'>
Subir
</span>
<% end %>
</div>
<% end %>
<div class="sign-in">
<% if @successful_entries&.present? %>
<p class="color-green mb-2"><%= @successful_entries.length %> Materias marcadas correctamente</p>
<% @successful_entries.each do |entry| %>
<p><%= entry.code %> - <%= entry.name %></p>
<% end %>
<% end %>
<% if @failed_entries&.present? %>
<p class="color-red my-2"><%= @failed_entries.length %> Materias no encontradas</p>
<% @failed_entries.each do |entry| %>
<p><%= entry.name %></p>
<% end %>
<% end %>
</div>
<p class="subtle-text sign-in mt-3">
La escolaridad no incluye codigos de materias, por lo que en caso de multiples candidatos con el mismo nombre, se marca la materia mas reciente y actualmente activa
</p>
6 changes: 6 additions & 0 deletions app/views/shared/_user_menu.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
Editar Perfil
<span>
<% end %>
<%= link_to new_academic_history_path, class: "mdc-deprecated-list-item", tabindex: 0 do %>
<span class="mdc-deprecated-list-item__ripple"></span>
<span class="mdc-deprecated-list-item__text">
Importar Materias
<span>
<% end %>
<%= link_to destroy_user_session_path, method: :delete, class: "mdc-deprecated-list-item", tabindex: 0 do %>
<span class="mdc-deprecated-list-item__ripple"></span>
<span class="mdc-deprecated-list-item__text">
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@

resources :current_optional_subjects, only: :index

resources :academic_histories, only: [:new, :create, :index]

resources :planned_subjects, only: [:index, :create, :destroy], param: :subject_id
end
Loading