All the sources so far
Here is source\app.d:
import vibe.vibe;
import empcontrol;
void main()
{
auto settings = new HTTPServerSettings;
settings.port = 8080;
settings.bindAddresses = ["::1", "127.0.0.1"];
settings.sessionStore = new MemorySessionStore;
auto router = new URLRouter;
router.get("*", serveStaticFiles("public/"));
router.registerWebInterface(new EmployeeController);
auto listener = listenHTTP(settings, router);
scope (exit) listener.stopListening();
runApplication();
}Here is source\empcontrol.d:
module empcontrol;
import vibe.vibe;
import empmodel;
struct User
{
bool loggedIn;
string email;
}
class EmployeeController
{
private EmployeeModel empModel;
private string realm = "The Lorem Ipsum Company";
private SessionVar!(User, "user") m_user;
this()
{
empModel = new EmployeeModel;
}
void index(string _error = null)
{
string error = _error;
m_user = User.init;
terminateSession;
render!("index.dt", error);
}
@auth
void getAddEmployee(string _authUser, string _error = null)
{
string error = _error;
render!("empadd.dt", departments, paygrades, provinces, error);
}
@errorDisplay!getAddEmployee
void postAddEmployee(Employee e)
{
import std.file;
import std.path;
import std.algorithm;
import vibe.http.auth.digest_auth;
auto pic = "picture" in request.files;
if(pic !is null)
{
string photopath = "none yet";
string ext = extension(pic.filename.name);
string[] exts = [".jpg", ".jpeg", ".png", ".gif"];
if(canFind(exts, ext))
{
photopath = "uploads/photos/" ~ e.fname ~ "_" ~ e.lname ~ ext;
string dir = "./public/uploads/photos/";
mkdirRecurse(dir);
string fullpath = dir ~ e.fname ~ "_" ~ e.lname ~ ext;
try moveFile(pic.tempPath, NativePath(fullpath));
catch (Exception ex) copyFile(pic.tempPath, NativePath(fullpath), true);
}
e.photo = photopath;
}
if(e.phone.length == 0) e.phone = "(123) 456 7890";
if(e.paygd.length == 0) e.paygd = "none yet";
if(e.postcode.length == 0) e.postcode = "A1A 1A1";
e.pword = createDigestPassword(realm, e.email, e.pword);
empModel.addEmployee(e);
redirect("all_employees");
}
@auth
void getAllEmployees(string _authUser, string _error = null)
{
string error = _error;
Employee[] emps = empModel.getEmployees;
render!("emplistall.dt", emps, error);
}
@auth
void getEditEmployee(string _authUser, int id, string _error = null)
{
string error = _error;
Employee e = empModel.getEmployee(id);
render!("empedit.dt", e, departments, paygrades, provinces, error);
}
@errorDisplay!getEditEmployee
void postEditEmployee(Employee e)
{
import std.file;
import std.path;
import std.algorithm;
import vibe.http.auth.digest_auth;
string photopath = e.photo;
auto pic = "picture" in request.files;
if(pic !is null)
{
string ext = extension(pic.filename.name);
string[] exts = [".jpg", ".jpeg", ".png", ".gif"];
if(canFind(exts, ext))
{
photopath = "uploads/photos/" ~ e.fname ~ "_" ~ e.lname ~ ext;
string dir = "./public/uploads/photos/";
mkdirRecurse(dir);
string fullpath = dir ~ e.fname ~ "_" ~ e.lname ~ ext;
try moveFile(pic.tempPath, NativePath(fullpath));
catch (Exception ex) copyFile(pic.tempPath, NativePath(fullpath), true);
}
}
e.photo = photopath;
if(e.phone.length == 0) e.phone = "(123) 456 7890";
if(e.paygd.length == 0) e.paygd = "none yet";
if(e.postcode.length == 0) e.postcode = "A1A 1A1";
e.pword = createDigestPassword(realm, e.email, e.pword);
empModel.editEmployee(e);
redirect("all_employees");
}
@auth
void getDeleteEmployee(string _authUser, int id, string _error = null)
{
string error = _error;
Employee e = empModel.getEmployee(id);
render!("empdelete.dt", e, error);
}
@errorDisplay!getDeleteEmployee
void postDeleteEmployee(int id)
{
empModel.deleteEmployee(id);
redirect("all_employees");
}
@auth
@errorDisplay!getAllEmployees
void postFindEmployee(string _authUser, string fname, string lname)
{
import std.uni; //so we can use the toUpper() function
string first = toUpper(fname);
string last = toUpper(lname);
Employee e = empModel.findEmployee(first, last);
enforce(e != Employee.init, fname ~ " " ~ lname ~ " not found.");
render!("employee.dt", e);
}
@errorDisplay!index
void postLogin(string email, string password)
{
import vibe.http.auth.digest_auth;
auto scrambled = createDigestPassword(realm, email, password);
bool isAdmin = empModel.isAdmin(email, scrambled);
enforce(isAdmin, "Email and password combination not found.");
User user = m_user;
user.loggedIn = true;
user.email = email;
m_user = user;
redirect("all_employees");
}
private enum auth = before!ensureAuth("_authUser");
private string ensureAuth(HTTPServerRequest req, HTTPServerResponse res)
{
if(!m_user.loggedIn) redirect("/");
return m_user.email;
}
mixin PrivateAccessProxy;
}And here is source\empmodel.d:
Here is views\cssformgrid.dt:
Here is views\csstable.dt:
Here is views\empadd.dt:
Here is views\empdelete.dt:
Here is views\empedit.dt:
Here is views\emplistall.dt:
Here is views\employee.dt:
Here is views\index.dt:
Here is views\layout.dt:
Here is views\menu.dt:
Here is views\footer.dt:
Here is views\styles.dt:
And here is dub.json:
Now on to the timekeeping system.
Last updated