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

setup a build script to prepare dataset to be consumed from kuliya:d package #101

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions d/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ d-test-*
*.o
*.obj
*.lst
data.d
5 changes: 5 additions & 0 deletions d/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ Algeria's college hierarchy dataset as a D package
cd d && dub test
```

- Build data:
```sh
cd d/build && dub
```

# Contribute

Feel free to ask for help in [#kuliya](https://dzcode.slack.com/archives/C01C0155CKC) group chat
1 change: 1 addition & 0 deletions d/build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build*
6 changes: 6 additions & 0 deletions d/build/dub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"dependencies": {
"asdf": "~>0.7.17"
},
"name": "build"
}
9 changes: 9 additions & 0 deletions d/build/dub.selections.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"fileVersion": 1,
"versions": {
"asdf": "0.7.17",
"mir-algorithm": "3.22.1",
"mir-core": "1.7.1",
"silly": "1.1.1"
}
}
237 changes: 237 additions & 0 deletions d/build/source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
/++
This module is responsible for generating the data file from the info.json files.
+/
module app;

import std.file : readText, write, exists, remove;
import std.typecons : Nullable;
import asdf;
import std.stdio : writeln, File;
import std.algorithm;
import std.array;

/++
Data path to the info.json files
+/
const string DATA_PATH = "../../_data/";
/++
Data D file to save the schema
+/
const string DATA_FILE = "../source/kuliya/data.d";

/++
Kuliya types
+/
enum Type
{
UNIVERSITY,
ACADEMY,
PRIVATE_SCHOOL,
INSTITUTE,
FACULTY,
DEPARTMENT,
SPECIALTY,
SECTOR
}

/++
Kuliya name
+/
struct Name
{
/// Arabic name
string ar;
/// English name
string en;
/// French name
string fr;
}

/++
Kuliya terms
+/
struct Terms
{
/// Number of slots per year
int perYear;
/// Slots
int[] slots;
}

/++
Kuliya schema
+/
struct Schema
{
/// Name
Name name;
/// Type
Type type;
/// Terms
@serdeOptional
Nullable!Terms terms;
}

/++
Save schema to file
Params:
schema = Schema to save
path = Path of the info.json file
+/
void saveToFile(const Schema schema, string path) @trusted
{
// remove ../_data/ prefix and /info.json suffix from path
const auto pathParts = path.splitter('/').array;
const auto filePath = pathParts[3 .. $ - 1].join("/");
// replace / with _ in filePath
const auto filePathUnderscored = filePath.replace("/", "_");
File file = File(DATA_FILE, "a");
file.writeln("immutable Schema ", filePathUnderscored, " = Schema(");
file.writeln(" Name(\"", schema.name.ar, "\", \"", schema.name.en, "\", \"", schema.name.fr, "\"),");
file.writeln(" Type.", schema.type, ",");
if (schema.terms.isNull)
{
file.writeln(" Terms.init");
}
else
{
// file.writeln(" Nullable!Terms({", schema.terms.get.perYear, ", [", schema.terms.get.slots.join(", "), "]});"); // no propery join on const(int[]) error
file.write(" Terms(", schema.terms.get.perYear, ", [", schema
.terms.get.slots[0]);
foreach (i, slot; schema.terms.get.slots[1 .. $])
{
file.write(", ", slot);
}
file.writeln("])");
}
file.writeln(");");
file.writeln();
file.close();
}

/++
Parse info.json file to Schema struct
Params:
path = Path of the info.json file
Returns:
Schema
+/
Schema parseInfoJson(string path) @trusted
{
const auto data = readText(path);
Schema schema;
schema = asdf.deserialize!Schema(data);
return schema;
}

/++
Walk through directories and parse info.json files
Params:
path = Path of the directory
+/
void walkDirs(string path) @trusted
{
import std.file : DirEntry, dirEntries, isDir, isFile, SpanMode;

foreach (entry; dirEntries(path, SpanMode.shallow, false))
{
if (isDir(entry.name))
{
walkDirs(entry.name);
}
else if (isFile(entry.name) && entry.name.endsWith("info.json"))
{
const auto schema = parseInfoJson(entry.name);
saveToFile(schema, entry.name);
}
}
}

/++
Prepare data file with the schema structure
+/
void prepareDataFile() @trusted
{
File file = File(DATA_FILE, "w");
file.writeln("// This is an auto generated file, do not edit it!");
file.writeln("module kuliya.data;");
file.writeln();
file.writeln("import std.typecons : Nullable;");
file.writeln();
file.writeln("/++");
file.writeln("Kuliya types");
file.writeln("+/");
file.writeln("enum Type");
file.writeln("{");
file.writeln(" UNIVERSITY,");
file.writeln(" ACADEMY,");
file.writeln(" PRIVATE_SCHOOL,");
file.writeln(" INSTITUTE,");
file.writeln(" FACULTY,");
file.writeln(" DEPARTMENT,");
file.writeln(" SPECIALTY,");
file.writeln(" SECTOR");
file.writeln("}");
file.writeln();
file.writeln("/++");
file.writeln("Kuliya name");
file.writeln("+/");
file.writeln("struct Name");
file.writeln("{");
file.writeln(" /// Arabic name");
file.writeln(" string ar;");
file.writeln(" /// English name");
file.writeln(" string en;");
file.writeln(" /// French name");
file.writeln(" string fr;");
file.writeln("}");
file.writeln();
file.writeln("/++");
file.writeln("Kuliya terms");
file.writeln("+/");
file.writeln("struct Terms");
file.writeln("{");
file.writeln(" /// Number of slots per year");
file.writeln(" int perYear;");
file.writeln(" /// Slots");
file.writeln(" int[] slots;");
file.writeln("}");
file.writeln();
file.writeln("/++");
file.writeln("Kuliya schema");
file.writeln("+/");
file.writeln("struct Schema");
file.writeln("{");
file.writeln(" /// Name");
file.writeln(" Name name;");
file.writeln(" /// Type");
file.writeln(" Type type;");
file.writeln(" /// Terms");
file.writeln(" Nullable!Terms terms;");
file.writeln();
file.writeln(" this(Name name, Type type, Terms terms)");
file.writeln(" {");
file.writeln(" this.name = name;");
file.writeln(" this.type = type;");
file.writeln(" this.terms = Nullable!Terms(terms);");
file.writeln(" }");
file.writeln("}");
file.writeln();
file.close();
}

void main() @trusted
{
try
{
if (exists(DATA_FILE))
remove(DATA_FILE);
prepareDataFile();
walkDirs(DATA_PATH);
}
catch (Exception e)
{
writeln("Error: ", e.msg);
return;
}
}
Loading