package elw.web;
import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import com.google.common.io.Files;
import org.akraievoy.couch.CouchDao;
import org.akraievoy.couch.Squab;
import elw.dao.Ctx;
import elw.dp.mips.TaskBean;
import elw.vo.*;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MarkdownImport {
protected static final Pattern PATTERN_LR_NO =
Pattern.compile("# Комп.?ютерний практикум №(\\d+)");
protected static final Pattern PATTERN_VER_START =
Pattern.compile("## Варіанти завдань");
protected static final Pattern PATTERN_VER_NO =
Pattern.compile("^(\\d+)\\. ");
protected static final Pattern PATTERN_VER_NAME =
Pattern.compile("\\*\\*([^\\*]+)\\*\\*");
protected static final Pattern PATTERN_TEST_NO =
Pattern.compile("^\\s*\\* Приклад (\\d+):");
public static void main(String[] args) throws IOException {
// you'll also need to comment out 'scope=provided' in web/pom.xml
// for this to work, as servlet api is not visible by default
final FileSystemXmlApplicationContext appCtx =
new FileSystemXmlApplicationContext(
"file://" +
"/home/w/Projects/github/elw" +
"/web/src/main/webapp/WEB-INF/elw-mvc-servlet.xml"
);
appCtx.start(); // finally: destroy the context
final CouchDao metaDao =
(CouchDao) appCtx.getBean("metaDao", CouchDao.class);
final CouchDao attachmentDao =
(CouchDao) appCtx.getBean("attachmentDao", CouchDao.class);
final String fileName = args.length == 1 ? args[0] :
"/home/w/Projects/github/aos-tasks/aos-tasks.md";
final List<String> lines = CharStreams.readLines(Files.newReader(
new File(fileName),
Charsets.UTF_8
));
final Course course = metaDao.findOne(Course.class, "aos_w11");
final TaskType tType = course.getTaskTypes().get("lr");
tType.setId("lr");
final Ctx ctx = Ctx.forAssType(course, tType);
Integer lrNo = null;
boolean versStarted = false;
Integer verNo = null;
String statement = null;
Integer testNo = null;
String test = null;
SortedMap<Integer, String> names = new TreeMap<Integer, String>();
SortedMap<Integer, String> statements = new TreeMap<Integer, String>();
SortedMap<Integer, String> tests = new TreeMap<Integer, String>();
for (int i = 0, linesSize = lines.size(); i < linesSize; i++) {
final String line = lines.get(i);
final Matcher matcherLrNo = PATTERN_LR_NO.matcher(line);
final Matcher matcherVerStart = PATTERN_VER_START.matcher(line);
final Matcher matcherVerNo = PATTERN_VER_NO.matcher(line);
final Matcher matcherTestNo = PATTERN_TEST_NO.matcher(line);
boolean verMatch = false;
boolean testMatch = false;
if (i + 1 == lines.size() || line.equals("# Л.тература")) {
if (
(lrNo != null && verNo != null)
) {
if (testNo != null && test != null) {
tests.put(testNo, test);
}
updateTests(attachmentDao, ctx, lrNo, verNo, tests);
updateTask(metaDao, ctx, lrNo, names);
updateStatements(attachmentDao, ctx, lrNo, statements);
}
tests.clear();
names.clear();
statements.clear();
test = null;
testNo = null;
verNo = null;
lrNo = null;
} else if (matcherLrNo.find()) {
if (
(lrNo != null && verNo != null)
) {
if (testNo != null && test != null) {
tests.put(testNo, test);
}
if (!tests.isEmpty()) {
updateTests(attachmentDao, ctx, lrNo, verNo, tests);
}
updateTask(metaDao, ctx, lrNo, names);
updateStatements(attachmentDao, ctx, lrNo, statements);
}
names.clear();
statements.clear();
tests.clear();
lrNo = Integer.parseInt(matcherLrNo.group(1));
versStarted = false;
testNo = null;
test = null;
} else if (matcherVerStart.find()) {
versStarted = true;
} else if (versStarted && (verMatch = matcherVerNo.find())) {
if (testNo != null && test != null) {
tests.put(testNo, test);
updateTests(attachmentDao, ctx, lrNo, verNo, tests);
}
tests.clear();
verNo = Integer.parseInt(matcherVerNo.group(1));
testNo = null;
test = null;
String verName = null;
final Matcher matcherVerName = PATTERN_VER_NAME.matcher(line);
if (matcherVerName.find()) {
verName = matcherVerName.group(1);
statement = line.substring(matcherVerName.end() + 1);
} else {
verName = "Ver #" + verNo;
statement = line.substring(matcherVerNo.end() + 1);
}
names.put(verNo, verName);
} else if (
versStarted &&
verNo != null &&
(testMatch = matcherTestNo.find())
) {
if (statement != null) {
statements.put(verNo, statement);
statement = null;
}
if (testNo != null && test != null) {
tests.put(testNo, test);
}
testNo = Integer.parseInt(matcherTestNo.group(1));
test = "";
}
if (versStarted && verNo != null) {
if (testNo == null && !verMatch && !line.trim().isEmpty()) {
statement += "\n" + line.trim();
} else if (
test != null &&
!testMatch &&
!line.trim().isEmpty()
) {
final TaskBean.Test testRes = TaskBean.parseTest(line);
if (!testRes.parseErrors.getLineToErrors().isEmpty()) {
System.err.println(
testRes.errors(
testRes.parseErrors.getLineToErrors()
)
);
}
if (!test.trim().isEmpty()) {
test += "\n" + line.trim();
} else {
test = line.trim();
}
}
}
}
}
private static void updateTask(
CouchDao metaDao, Ctx ctx, Integer lrNo,
SortedMap<Integer, String> names
) {
final Task task;
final Task taskSome = metaDao.findSome(
Task.class,
ctx.getCourse().getId(),
ctx.getAssType().getId(),
String.valueOf("lr" + lrNo)
);
if (taskSome != null) {
task = taskSome;
} else {
task = new Task(
new String[] {
ctx.getCourse().getId(),
ctx.getAssType().getId()
}
);
task.setId("lr" + lrNo);
}
final TreeMap<String, Version> versions =
new TreeMap<String, Version>();
for (Integer verId : names.keySet()) {
versions.put(
String.valueOf(verId),
new Version().withName(names.get(verId))
);
}
task.setName("ЛР №" + lrNo);
task.setVersions(versions);
metaDao.update(task);
}
private static void updateStatements(
CouchDao attachmentDao, Ctx ctx, Integer lrNo,
SortedMap<Integer, String> statements
) {
for (Integer verId : statements.keySet()) {
final Attachment attachment;
final Attachment attachmentSome = attachmentDao.findLast(
Attachment.class,
ctx.getCourse().getId(),
ctx.getAssType().getId(),
"lr" + lrNo,
String.valueOf(verId),
"statement",
"statement.txt"
);
if (attachmentSome != null) {
attachment = attachmentSome;
} else {
attachment = new Attachment();
attachment.setAuthor("akraievoy");
attachment.setComment("Import from markdown");
final TreeMap<String, FileType> fileType =
new TreeMap<String, FileType>();
fileType.put("plaintext", null);
attachment.setFileType(fileType);
attachment.setName("statement.txt");
attachment.setSourceAddress("lynx");
final Version ver = new Version().withId(String.valueOf(verId));
final Task task = new Task().withId("lr" + lrNo);
task.setVersions(IdNamed._.singleton(ver));
ctx.getAssType().setTasks(IdNamed._.singleton(task));
final Ctx ctxTask = ctx.extendTask(task);
final Ctx ctxVer = ctxTask.extendVer(ver);
attachment.setupPathElems(
ctxVer,
new FileSlot().withId("statement")
);
}
final Squab.CouchFile couchFile = new Squab.CouchFile();
couchFile.setContentType("text/plain");
couchFile.setData(statements.get(verId).getBytes());
couchFile.setLength((long) couchFile.getData().length);
attachment.putCouchFile(
FileBase.CONTENT,
couchFile
);
attachmentDao.update(attachment, false);
}
}
private static void updateTests(
CouchDao attachmentDao, Ctx ctx, Integer lrNo, Integer verNo,
SortedMap<Integer, String> tests
) {
for (Integer testId : tests.keySet()) {
final Attachment attachment;
final Attachment attachmentSome = attachmentDao.findLast(
Attachment.class,
ctx.getCourse().getId(),
ctx.getAssType().getId(),
"lr" + lrNo,
String.valueOf(verNo),
"test",
"test." + testId + ".txt"
);
if (attachmentSome != null) {
attachment = attachmentSome;
} else {
attachment = new Attachment();
attachment.setAuthor("akraievoy");
attachment.setComment("Import from markdown");
final TreeMap<String, FileType> fileType =
new TreeMap<String, FileType>();
fileType.put("plaintext", null);
attachment.setFileType(fileType);
attachment.setName("test." + testId + ".txt");
attachment.setSourceAddress("lynx");
final Version ver = new Version().withId(
String.valueOf(verNo)
);
final Task task = new Task().withId("lr" + lrNo);
task.setVersions(IdNamed._.singleton(ver));
ctx.getAssType().setTasks(IdNamed._.singleton(task));
final Ctx ctxTask = ctx.extendTask(task);
final Ctx ctxVer = ctxTask.extendVer(ver);
attachment.setupPathElems(
ctxVer,
new FileSlot().withId("test")
);
}
final Squab.CouchFile couchFile = new Squab.CouchFile();
couchFile.setContentType("text/plain");
couchFile.setData(tests.get(testId).getBytes());
couchFile.setLength((long) couchFile.getData().length);
attachment.putCouchFile(
FileBase.CONTENT,
couchFile
);
attachmentDao.update(attachment, false);
}
}
}