package cz.muni.fi.rtc.ISImporter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import au.com.bytecode.opencsv.CSVReader;
import cz.muni.fi.rtc.teacherWorkbench.importer.ImporterConfiguration;
import cz.muni.fi.rtc.teacherWorkbench.importer.PasswordGenerator;
import cz.muni.fi.rtc.teacherWorkbench.importer.PeopleImporter;
import cz.muni.fi.rtc.teacherWorkbench.importer.ProjectImporter;
import cz.muni.fi.rtc.teacherWorkbench.importer.Utils;
import cz.muni.fi.rtc.teacherWorkbench.model.ImportedPerson;
import cz.muni.fi.rtc.teacherWorkbench.model.ImportedPersonImpl;
import cz.muni.fi.rtc.teacherWorkbench.model.Project;
import cz.muni.fi.rtc.teacherWorkbench.model.ProjectImpl;

/**
 * Parses the CSV export from "IS MUNI, baliky". The format is given by the
 * system. The package names must be unique. This class does not check it. 
* * Czech howto on exporting from the system: V zaznamniku ucitele * "Export údajů o tématech přihlášených studentů" -> Vybrat pozadovany balik -> * Typ vystupu: "Formát CSV pro Excel", Kodovani cestiny: "Kódování UTF-8" * * @author Jan Stastny * */ public class ISProjectImporter { private static final int ROW_UCO = 0; private static final int ROW_FIRST = 3; private static final int ROW_LAST = 2; private static final int ROW_PROJECT_NAME = 9; private static final int ROW_DESCRIPTION = 16; private static final int ROW_TEACHER_UCO = 11; private String processTemplate = "cz.muni.fi.pa165.imported.v4"; private String[] studentRoles = {"student_PA165"}; private String[] teacherRoles = {"vyucujici_PA165"}; /** * Members of the projects. Without teachers */ private Map> projectMembers = new HashMap>(); /** * Project teachers */ private Map projectTeachers = new HashMap(); /** * Main method. 2 arguments expected. First is the path to the csv, second is path to the configuration * @param args First is the path to the csv, second is path to the configuration */ public static void main(String[] args) { if (args.length < 2) { System.err.println("Incorrect call!"); System.err .println("Usage: ISProjectImporter projects.csv conf.properties [1|0]"); System.exit(1); } String filename = args[0]; String confPath = args[1]; try { ImporterConfiguration conf = Utils .configurationFromProperties(confPath); ISProjectImporter reader = new ISProjectImporter(); reader.parse(new File(filename)); // Import users if requested // NOTICE -- this does not import teachers, // because there is not enough information about them in the CSV export if(args.length == 3 && args[2].equals("1")) { PeopleImporter peopleImporter = new PeopleImporter(conf); Set people = reader.getStudents(); PasswordGenerator.generatePasswordsForPeople(people); peopleImporter.importUsers(people); ISPersonImporter.sendEmails(conf, people); } ProjectImporter projectImporter = new ProjectImporter(conf); Set projects = reader.getProjects(); // Import projects projectImporter.importProjects(projects); } catch (Exception e) { e.printStackTrace(); } } private void parse(File file) { CSVReader reader = null; try { reader = new CSVReader(new BufferedReader(new InputStreamReader(new FileInputStream(file), "WINDOWS-1250")), ';'); String[] line; // Ignore first line -- it's header reader.readNext(); while ((line = reader.readNext()) != null) { ImportedPersonImpl person = new ImportedPersonImpl(); person.setUID(line[ROW_UCO]); person.setFirstName(line[ROW_FIRST]); person.setLastName(line[ROW_LAST]); String projectName = line[ROW_PROJECT_NAME]; String description = line[ROW_DESCRIPTION]; ISProject isProject = new ISProject(projectName, description); if (!projectMembers.containsKey(isProject)) { projectMembers .put(isProject, new HashSet()); } projectMembers.get(isProject).add(person); ImportedPersonImpl teacher = new ImportedPersonImpl(); teacher.setUID(line[ROW_TEACHER_UCO]); projectTeachers.put(isProject, teacher); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Returns the list of the students in this file. Fields filled are: *
    *
  • UID -- UCO *
  • email -- UCO@mail.muni.cz *
  • first *
  • last *
  • description -- * "Batch imported user by IS Package reader at " *
  • rawPassword -- randomly generated *
* First name, Last name, Email File has to be parsed first * * @return Set of students ready to be imported */ public Set getStudents() { String timestamp = DateFormat.getDateTimeInstance().format(new Date()); String description = "Batch imported user by IS Package reader at " + timestamp; // Speed things up and detect duplicates soon Set doneUids = new HashSet(); Set result = new HashSet(); for (Entry> entry : projectMembers .entrySet()) { for (ImportedPerson p : entry.getValue()) { if (!doneUids.contains(p.getUID())) { ImportedPersonImpl pers = (ImportedPersonImpl) p; pers.setDescription(description); pers.setEmailAddress(pers.getUID() + "@mail.muni.cz"); result.add(pers); } } } return result; } /** * Returns instances of project based on the imported file * * @return Set of projects ready to be put in the RTC */ public Set getProjects() { Set result = new HashSet(); for (Entry> entry : projectMembers .entrySet()) { ProjectImpl project = new ProjectImpl(); String name = entry.getKey().name; // Slash is not valid name = name.replace('/', ' '); project.setName(name); project.setSummary(""); // Too long //project.setSummary(entry.getKey().description); // The longest description is left blank project.setDescription(""); project.setMembers(entry.getValue()); // Set roles of the students for (ImportedPerson student : entry.getValue()) { for(String role: studentRoles) { project.addRoleOfUser(student, role); } } // Set role of the teacher ImportedPerson teacher = projectTeachers.get(entry.getKey()); // Add teacher project.addMember(teacher); for(String role : teacherRoles) { project.addRoleOfUser(teacher, role); } // Put teacher of the project to the root project.addRootMember(teacher); // Set the process template project.setProcessTemplate(processTemplate); result.add(project); } return result; } /** * Dumb entity class for parsing * * @author Jan Stastny * */ private class ISProject { public String name; @SuppressWarnings("unused") public String description; public ISProject(String name, String description) { super(); this.name = name; this.description = description; } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + getOuterType().hashCode(); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof ISProject)) { return false; } ISProject other = (ISProject) obj; if (!getOuterType().equals(other.getOuterType())) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } @Override public String toString() { return name; } private ISProjectImporter getOuterType() { return ISProjectImporter.this; } } }