mirror of
https://github.com/zyphlar/LanternPowerMonitor.git
synced 2024-03-08 14:07:47 +00:00
Allow exporting all data in bson, json, or csv formats.
This commit is contained in:
+2
-2
@@ -6,7 +6,7 @@ import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.HubCommands;
|
||||
import com.lanternsoftware.rules.RulesEngine;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
@@ -24,7 +24,7 @@ public class Globals implements ServletContextListener {
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.CONFIG_PATH + "mongo.cfg"));
|
||||
RulesEngine.instance().start();
|
||||
RulesEngine.instance().schedule(new CommandTask(), 0);
|
||||
}
|
||||
|
||||
+2
-26
@@ -1,17 +1,10 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.gson.GsonFactory;
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.currentmonitor.util.GoogleAuthHelper;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.servlet.BasicAuth;
|
||||
import com.lanternsoftware.util.servlet.LanternServlet;
|
||||
import org.slf4j.Logger;
|
||||
@@ -23,15 +16,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/auth/*")
|
||||
public class AuthServlet extends LanternServlet {
|
||||
private static final NetHttpTransport transport = new NetHttpTransport();
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuthServlet.class);
|
||||
private static final String googleClientId;
|
||||
private static final String googleClientSecret;
|
||||
static {
|
||||
DaoEntity google = DaoSerializer.parse(ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "google_sso.txt"));
|
||||
googleClientId = DaoSerializer.getString(google, "id");
|
||||
googleClientSecret = DaoSerializer.getString(google, "secret");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
@@ -40,16 +25,7 @@ public class AuthServlet extends LanternServlet {
|
||||
BasicAuth auth = new BasicAuth(_req);
|
||||
if (NullUtils.isEqual(auth.getUsername(), "googlesso")) {
|
||||
logger.info("Attempting google SSO");
|
||||
try {
|
||||
GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(transport, new GsonFactory(), "https://oauth2.googleapis.com/token", googleClientId, googleClientSecret, auth.getPassword(), "").execute();
|
||||
if (tokenResponse != null) {
|
||||
GoogleIdToken idToken = tokenResponse.parseIdToken();
|
||||
if (idToken != null)
|
||||
authCode = Globals.dao.getAuthCodeForEmail(idToken.getPayload().getEmail(), DateUtils.fromTimeZoneId(_req.getHeader("timezone")));
|
||||
}
|
||||
} catch (Exception _e) {
|
||||
logger.error("Failed to validate google auth code", _e);
|
||||
}
|
||||
authCode = GoogleAuthHelper.signin(auth.getPassword(), DateUtils.fromTimeZoneId(_req.getHeader("timezone")));
|
||||
} else
|
||||
authCode = Globals.dao.authenticateAccount(auth.getUsername(), auth.getPassword());
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import javax.ws.rs.core.MediaType;
|
||||
import java.util.Date;
|
||||
|
||||
@WebServlet("/charge/*")
|
||||
public class ChargeServlet extends SecureServlet {
|
||||
public class ChargeServlet extends SecureServiceServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/command")
|
||||
public class CommandServlet extends SecureServlet {
|
||||
public class CommandServlet extends SecureServiceServlet {
|
||||
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/config/*")
|
||||
public class ConfigServlet extends SecureServlet {
|
||||
public class ConfigServlet extends SecureServiceServlet {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ConfigServlet.class);
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import javax.ws.rs.core.MediaType;
|
||||
import java.util.Date;
|
||||
|
||||
@WebServlet("/energy/*")
|
||||
public class EnergyServlet extends SecureServlet {
|
||||
public class EnergyServlet extends SecureServiceServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.util.servlet.FreemarkerConfigUtil;
|
||||
import com.lanternsoftware.util.servlet.FreemarkerServlet;
|
||||
import com.lanternsoftware.util.servlet.FreemarkerUtil;
|
||||
import freemarker.template.Configuration;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class FreemarkerCMServlet extends FreemarkerServlet {
|
||||
protected static final Configuration CONFIG = FreemarkerConfigUtil.createConfig(FreemarkerCMServlet.class, "/templates", 100);
|
||||
|
||||
@Override
|
||||
protected Configuration getFreemarkerConfig() {
|
||||
return CONFIG;
|
||||
}
|
||||
|
||||
public void renderBody(HttpServletResponse _rep, String _sHtmlResourceKey, Map<String, Object> _mapModel) {
|
||||
_mapModel.put("body", FreemarkerUtil.render(getFreemarkerConfig(), _sHtmlResourceKey, _mapModel));
|
||||
render(_rep, "frame.ftl", _mapModel);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -9,7 +9,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/generateBom")
|
||||
public class GenerateBomServlet extends SecureServlet {
|
||||
public class GenerateBomServlet extends SecureServiceServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = Globals.dao.decryptAuthCode(_req.getHeader("auth_code"));
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import javax.ws.rs.core.MediaType;
|
||||
import java.util.*;
|
||||
|
||||
@WebServlet("/energy/group/*")
|
||||
public class GroupEnergyServlet extends SecureServlet {
|
||||
public class GroupEnergyServlet extends SecureServiceServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/power/group/*")
|
||||
public class GroupPowerServlet extends SecureServlet {
|
||||
public class GroupPowerServlet extends SecureServiceServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@WebServlet("/power/*")
|
||||
public class PowerServlet extends SecureServlet {
|
||||
public class PowerServlet extends SecureServiceServlet {
|
||||
private static final Logger logger = LoggerFactory.getLogger(MongoCurrentMonitorDao.class);
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -3,7 +3,6 @@ package com.lanternsoftware.currentmonitor.servlet;
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
|
||||
@@ -12,7 +11,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/rebuildSummaries/*")
|
||||
public class RebuildSummariesServlet extends SecureServlet {
|
||||
public class RebuildSummariesServlet extends SecureServiceServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
if (_authCode.getAccountId() == 100) {
|
||||
|
||||
+4
-3
@@ -1,7 +1,8 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
@@ -30,7 +31,7 @@ import java.io.IOException;
|
||||
public class ResetPasswordServlet extends FreemarkerServlet {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(ResetPasswordServlet.class);
|
||||
protected static final Configuration CONFIG = FreemarkerConfigUtil.createConfig(ResetPasswordServlet.class, "/templates", 100);
|
||||
protected static final String api_key = ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "sendgrid.txt");
|
||||
protected static final String api_key = ResourceLoader.loadFileAsString(LanternFiles.CONFIG_PATH + "sendgrid.txt");
|
||||
|
||||
@Override
|
||||
protected Configuration getFreemarkerConfig() {
|
||||
@@ -40,7 +41,7 @@ public class ResetPasswordServlet extends FreemarkerServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _resp) {
|
||||
String[] path = getPath(_req);
|
||||
String email = Globals.dao.getEmailForResetKey(path[1]);
|
||||
String email = Globals.dao.getEmailForResetKey(CollectionUtils.get(path, 1));
|
||||
if (EmailValidator.getInstance().isValid(email)) {
|
||||
render(_resp, "passwordReset.ftl", model(_req, "key", path[1]));
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import com.lanternsoftware.util.servlet.LanternServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public abstract class SecureServlet extends LanternServlet {
|
||||
public abstract class SecureServiceServlet extends LanternServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = Globals.dao.decryptAuthCode(_req.getHeader("auth_code"));
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.servlet.LanternServlet;
|
||||
@@ -16,8 +16,8 @@ public class UpdateServlet extends LanternServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
if (isPath(_req, 0, "version"))
|
||||
setResponseEntity(_rep, MediaType.APPLICATION_OCTET_STREAM, DaoSerializer.toZipBson(DaoSerializer.parse(ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "release" + File.separator + "version.json"))));
|
||||
setResponseEntity(_rep, MediaType.APPLICATION_OCTET_STREAM, DaoSerializer.toZipBson(DaoSerializer.parse(ResourceLoader.loadFileAsString(LanternFiles.CONFIG_PATH + "release" + File.separator + "version.json"))));
|
||||
else
|
||||
setResponseEntity(_rep, MediaType.APPLICATION_OCTET_STREAM, ResourceLoader.loadFile(LanternFiles.OPS_PATH + "release" + File.separator + "lantern-currentmonitor.jar"));
|
||||
setResponseEntity(_rep, MediaType.APPLICATION_OCTET_STREAM, ResourceLoader.loadFile(LanternFiles.CONFIG_PATH + "release" + File.separator + "lantern-currentmonitor.jar"));
|
||||
}
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet.console;
|
||||
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("")
|
||||
public class ConsoleServlet extends SecureConsoleServlet {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ConsoleServlet.class);
|
||||
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
redirect(_rep, "export");
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet.console;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.archive.ArchiveStatus;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.archive.BreakerEnergyArchive;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.archive.DailyEnergyArchive;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.archive.MonthlyEnergyArchive;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.bson.codecs.DocumentCodec;
|
||||
import org.bson.codecs.EncoderContext;
|
||||
import org.bson.json.JsonWriter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
@WebServlet("/export/*")
|
||||
public class ExportServlet extends SecureConsoleServlet {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ExportServlet.class);
|
||||
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
TimeZone tz = Globals.dao.getTimeZoneForAccount(_authCode.getAccountId());
|
||||
String[] path = path(_req);
|
||||
if (path.length > 1) {
|
||||
synchronized (this) {
|
||||
InputStream is = Globals.dao.streamArchive(_authCode.getAccountId(), new Date(DaoSerializer.toLong(path[0])));
|
||||
if (is == null) {
|
||||
redirect(_rep, _req.getContextPath() + "/export");
|
||||
return;
|
||||
}
|
||||
OutputStream os = null;
|
||||
GZIPOutputStream gout = null;
|
||||
JsonWriter jsonWriter = null;
|
||||
try {
|
||||
os = _rep.getOutputStream();
|
||||
if (NullUtils.makeNotNull(path[1]).contains("csv")) {
|
||||
BreakerConfig config = Globals.dao.getConfig(_authCode.getAccountId()); //TODO: get historical config for this month in case it's changed since then.
|
||||
Map<Integer, Breaker> breakers = CollectionUtils.transformToMap(config.getAllBreakers(), Breaker::getIntKey);
|
||||
os = new GZIPOutputStream(os) {{def.setLevel(Deflater.BEST_SPEED);}};
|
||||
MonthlyEnergyArchive archive = DaoSerializer.fromZipBson(IOUtils.toByteArray(is), MonthlyEnergyArchive.class);
|
||||
DailyEnergyArchive fday = CollectionUtils.getFirst(archive.getDays());
|
||||
if (fday == null) {
|
||||
redirect(_rep, _req.getContextPath() + "/export");
|
||||
return;
|
||||
}
|
||||
StringBuilder header = new StringBuilder("Timestamp");
|
||||
for (BreakerEnergyArchive ba : CollectionUtils.makeNotNull(fday.getBreakers())) {
|
||||
Breaker b = breakers.get(Breaker.intKey(ba.getPanel(), ba.getSpace()));
|
||||
header.append(",");
|
||||
if (b != null) {
|
||||
header.append(b.getKey());
|
||||
header.append("-");
|
||||
header.append(b.getName());
|
||||
}
|
||||
}
|
||||
header.append("\n");
|
||||
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
df.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
os.write(NullUtils.toByteArray(header.toString()));
|
||||
Date dayStart = archive.getMonth();
|
||||
for (DailyEnergyArchive day : CollectionUtils.makeNotNull(archive.getDays())) {
|
||||
Date dayEnd = DateUtils.addDays(dayStart, 1, tz);
|
||||
int secondsInDay = (int) ((dayEnd.getTime() - dayStart.getTime()) / 1000);
|
||||
for (int sec = 0; sec < secondsInDay; sec++) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
line.append(df.format(new Date(dayStart.getTime() + ((long) sec * 1000))));
|
||||
for (BreakerEnergyArchive b : CollectionUtils.makeNotNull(day.getBreakers())) {
|
||||
line.append(",");
|
||||
if ((b.getReadings() == null) || (sec * 4 >= b.getReadings().length))
|
||||
line.append("NaN");
|
||||
else {
|
||||
ByteBuffer readings = ByteBuffer.wrap(b.getReadings());
|
||||
line.append(readings.getFloat(sec * 4));
|
||||
}
|
||||
}
|
||||
line.append("\n");
|
||||
os.write(NullUtils.toByteArray(line.toString()));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (NullUtils.makeNotNull(path[1]).contains("json")) {
|
||||
DaoEntity archive = DaoSerializer.fromZipBson(IOUtils.toByteArray(is));
|
||||
gout = new GZIPOutputStream(os) {{def.setLevel(Deflater.BEST_SPEED);}};
|
||||
jsonWriter = new JsonWriter(new OutputStreamWriter(gout, StandardCharsets.UTF_8), DaoSerializer.JSON_COMPACT_SETTINGS);
|
||||
new DocumentCodec().encode(jsonWriter, archive.toDocument(), EncoderContext.builder().build());
|
||||
return;
|
||||
}
|
||||
IOUtils.copy(is, os);
|
||||
return;
|
||||
} catch (Exception _e) {
|
||||
logger.error("Failed to send archive to browser", _e);
|
||||
redirect(_rep, _req.getContextPath() + "/export");
|
||||
return;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
IOUtils.closeQuietly(jsonWriter);
|
||||
IOUtils.closeQuietly(gout);
|
||||
IOUtils.closeQuietly(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<ArchiveStatus> status = Globals.dao.getArchiveStatus(_authCode.getAccountId());
|
||||
List<MonthDisplay> months = CollectionUtils.transform(status, _s->new MonthDisplay(DateUtils.format("MMMM yyyy", tz, _s.getMonth()), _s.getMonth().getTime(), (int)_s.getProgress()));
|
||||
Map<String, Object> model = model(_req, "months", months);
|
||||
model.put("inprogress", CollectionUtils.anyQualify(months, _m->_m.getProgress() > 0 && _m.getProgress() < 100));
|
||||
renderBody(_rep, "export.ftl", model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
Date month = new Date(DaoSerializer.toLong(_req.getParameter("month")));
|
||||
Globals.dao.archiveMonth(_authCode.getAccountId(), month);
|
||||
redirect(_rep, ".");
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet.console;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.servlet.FreemarkerCMServlet;
|
||||
import com.lanternsoftware.currentmonitor.util.GoogleAuthHelper;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/gso")
|
||||
public class GsoServlet extends FreemarkerCMServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
render(_rep, "login.ftl", model(_req));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String code = getRequestPayloadAsString(_req);
|
||||
if (NullUtils.isNotEmpty(code)) {
|
||||
String authCode = GoogleAuthHelper.signin(code, null);
|
||||
if (NullUtils.isNotEmpty(authCode)) {
|
||||
Cookie authCookie = new Cookie("auth_code", authCode);
|
||||
authCookie.setMaxAge(157680000);
|
||||
authCookie.setSecure(true);
|
||||
_rep.addCookie(authCookie);
|
||||
_req.getSession().setAttribute("auth_code", authCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet.console;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.currentmonitor.servlet.FreemarkerCMServlet;
|
||||
import com.lanternsoftware.currentmonitor.util.GoogleAuthHelper;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
import com.lanternsoftware.util.servlet.LanternServlet;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@WebServlet("/login")
|
||||
public class LoginServlet extends FreemarkerCMServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
render(_rep, "login.ftl", model(_req));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String username = _req.getParameter("username");
|
||||
String password = _req.getParameter("password");
|
||||
String authCode = Globals.dao.authenticateAccount(username, password);
|
||||
if (NullUtils.isNotEmpty(authCode)) {
|
||||
Cookie authCookie = new Cookie("auth_code", authCode);
|
||||
authCookie.setMaxAge(157680000);
|
||||
authCookie.setSecure(true);
|
||||
_rep.addCookie(authCookie);
|
||||
_req.getSession().setAttribute("auth_code", authCode);
|
||||
redirect(_rep, _req.getContextPath());
|
||||
}
|
||||
render(_rep, "login.ftl", model(_req, "error", "Invalid Credentials"));
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet.console;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.servlet.FreemarkerCMServlet;
|
||||
import com.lanternsoftware.currentmonitor.util.GoogleAuthHelper;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/logout")
|
||||
public class LogoutServlet extends FreemarkerCMServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
_req.getSession().removeAttribute("auth_code");
|
||||
Cookie authCookie = new Cookie("auth_code", "");
|
||||
authCookie.setMaxAge(0);
|
||||
authCookie.setSecure(true);
|
||||
_rep.addCookie(authCookie);
|
||||
redirect(_rep, _req.getContextPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet.console;
|
||||
|
||||
public class MonthDisplay {
|
||||
public final String name;
|
||||
public final long date;
|
||||
public final int progress;
|
||||
|
||||
public MonthDisplay(String _name, long _date, int _progress) {
|
||||
name = _name;
|
||||
date = _date;
|
||||
progress = _progress;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return name.replace(" ", "-");
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return String.valueOf(date);
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.lanternsoftware.currentmonitor.servlet.console;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.currentmonitor.servlet.FreemarkerCMServlet;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public abstract class SecureConsoleServlet extends FreemarkerCMServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode code = getAuthCode(_req, _rep);
|
||||
if (code != null)
|
||||
get(code, _req, _rep);
|
||||
}
|
||||
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode code = getAuthCode(_req, _rep);
|
||||
if (code != null)
|
||||
post(code, _req, _rep);
|
||||
}
|
||||
|
||||
private AuthCode getAuthCode(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = Globals.dao.decryptAuthCode(DaoSerializer.toString(_req.getSession().getAttribute("auth_code")));
|
||||
if (authCode == null) {
|
||||
Cookie authCookie = CollectionUtils.filterOne(CollectionUtils.asArrayList(_req.getCookies()), _c-> NullUtils.isEqual(_c.getName(), "auth_code"));
|
||||
if (authCookie != null)
|
||||
authCode = Globals.dao.decryptAuthCode(authCookie.getValue());
|
||||
}
|
||||
if (authCode == null) {
|
||||
redirect(_rep, _req.getContextPath() + "/login");
|
||||
return null;
|
||||
}
|
||||
return authCode;
|
||||
}
|
||||
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.lanternsoftware.currentmonitor.util;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.gson.GsonFactory;
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class GoogleAuthHelper {
|
||||
private static final Logger logger = LoggerFactory.getLogger(GoogleAuthHelper.class);
|
||||
private static final NetHttpTransport transport = new NetHttpTransport();
|
||||
private static final String googleClientId;
|
||||
private static final String googleClientSecret;
|
||||
static {
|
||||
DaoEntity google = DaoSerializer.parse(ResourceLoader.loadFileAsString(LanternFiles.CONFIG_PATH + "google_sso.txt"));
|
||||
googleClientId = DaoSerializer.getString(google, "id");
|
||||
googleClientSecret = DaoSerializer.getString(google, "secret");
|
||||
}
|
||||
|
||||
public static String signin(String _code, TimeZone _tz) {
|
||||
try {
|
||||
GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(transport, new GsonFactory(), "https://oauth2.googleapis.com/token", googleClientId, googleClientSecret, _code, "postmessage").execute();
|
||||
if (tokenResponse != null) {
|
||||
GoogleIdToken idToken = tokenResponse.parseIdToken();
|
||||
if (idToken != null)
|
||||
return Globals.dao.getAuthCodeForEmail(idToken.getPayload().getEmail(), _tz);
|
||||
}
|
||||
} catch (Exception _e) {
|
||||
logger.error("Failed to validate google auth code", _e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<#if inprogress><meta http-equiv="refresh" content="1"></#if>
|
||||
<title>Lantern Console</title>
|
||||
<link href="${link_prefix}/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${link_prefix}bootstrap/css/style.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid login-container">
|
||||
<div class="row">
|
||||
<div class="col-1 col-lg-3 col-4k-4"></div>
|
||||
<div class="col-10 col-lg-6 col-4k-4">
|
||||
<div class="row mt-3">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<#list months as month>
|
||||
<#if month.progress == 0>
|
||||
<form method="POST">
|
||||
</#if>
|
||||
<tr>
|
||||
<td>${month.name!}</td>
|
||||
<#if month.progress == 0>
|
||||
<td><input type="hidden" name="month" value="${month.date}"/><input type="submit" class="btn-primary border-none px-2 py-1" value="Export"/></td>
|
||||
<#elseif month.progress == 1>
|
||||
<td>Queued</td>
|
||||
<#elseif month.progress < 100>
|
||||
<td>Progress ${month.progress!}%</td>
|
||||
<#else>
|
||||
<td>
|
||||
<a href="export/${month.date}/${month.fileName!}.bson.zip" class="btn-primary border-none text-decoration-none p-2" download>BSON</a>
|
||||
<a href="export/${month.date}/${month.fileName!}.json.zip" class="btn-primary border-none text-decoration-none p-2" download>JSON</a>
|
||||
<a href="export/${month.date}/${month.fileName!}.csv.zip" class="btn-primary border-none text-decoration-none p-2" download>CSV</a>
|
||||
</td>
|
||||
</#if>
|
||||
</tr>
|
||||
<#if month.progress == 0>
|
||||
</form>
|
||||
</#if>
|
||||
</#list>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-1 col-lg-3 col-4k-4"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>Lantern Power Monitor</title>
|
||||
<link rel="icon" type="image/png" href="${link_prefix}img/favicon.png">
|
||||
<link href="${link_prefix}bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${link_prefix}bootstrap/css/style.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container-fluid">
|
||||
<div class="row header-menu py-2">
|
||||
<div class="col-2"></div>
|
||||
<div class="col-auto"><img class="img-fluid" alt="Logo" src="${link_prefix}img/logo_40.png"/></div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto mx-2"><a href="${link_prefix}" class="text-decoration-none header-link fmnu1">DATA EXPORT</a></div>
|
||||
<div class="col-auto mx-2"><a href="${link_prefix}logout" class="text-decoration-none header-link fmnu1">LOGOUT</a></div>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
${body}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
|
||||
<script>
|
||||
function start() {
|
||||
gapi.load('auth2', function() {
|
||||
auth2 = gapi.auth2.init({client_id: '412929846491-r3uh0t67mpeouicjvlara580i9cfchol.apps.googleusercontent.com', cookie_policy: 'none', redirect_uri: 'postmessage'});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>Lantern Power Monitor</title>
|
||||
<link rel="icon" type="image/png" href="${link_prefix}img/favicon.png">
|
||||
<link href="${link_prefix}bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${link_prefix}bootstrap/css/style.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container-fluid login-container">
|
||||
<form method="POST">
|
||||
<div class="row">
|
||||
<div class="col-1 col-lg-3 col-4k-4"></div>
|
||||
<div class="col-10 col-lg-6 col-4k-4">
|
||||
<div class="row pt-5">
|
||||
<div class="col-12">
|
||||
<img class="img-fluid" alt='Lantern Logo' src='${link_prefix}img/lantern_cm.png'/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pt-5">
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
<div class="col-10 col-lg-8">
|
||||
<input type="email" name="username" class="login-input" placeholder="email"/>
|
||||
</div>
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
</div>
|
||||
<div class="row pt-2">
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
<div class="col-10 col-lg-8">
|
||||
<input type="password" name="password" class="login-input" placeholder="password"/>
|
||||
</div>
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
</div>
|
||||
<div class="row pt-2">
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
<div class="col-8 col-lg-6 d-flex"><button type="button" id="signinButton" class="gso"></button></div>
|
||||
<div class="col-2 d-flex justify-content-end">
|
||||
<input type="submit" class="btn-primary border-none px-3" value="Login"/>
|
||||
</div>
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
</div>
|
||||
<div class="row pt-5">
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
<div class="col-10 col-lg-8 error">
|
||||
${error!}
|
||||
</div>
|
||||
<div class="col-1 col-lg-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1 col-lg-3 col-4k-4"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="login-bkgnd"></div>
|
||||
<script>
|
||||
$('#signinButton').click(function() {
|
||||
auth2.grantOfflineAccess().then(signInCallback);
|
||||
});
|
||||
function signInCallback(authResult) {
|
||||
if (authResult['code']) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'gso',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
contentType: 'application/octet-stream; charset=utf-8',
|
||||
success: function(result) {
|
||||
window.location.replace('./');
|
||||
},
|
||||
processData: false,
|
||||
data: authResult['code']
|
||||
});
|
||||
} else {
|
||||
// There was an error.
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
<div class="navy-line"></div>
|
||||
<h4><img class="mr-1" src="${context}/img/logo_40.png">Reset Password</h4>
|
||||
<form class="ml-2" method="POST">
|
||||
<input type="hidden" name="reset_key" value="${key}"/>
|
||||
<input type="hidden" name="reset_key" value="${key!}"/>
|
||||
<div>New Password:</div>
|
||||
<input type="password" name="password"/>
|
||||
<input type="submit" class="btn-primary" value="Submit"/>
|
||||
|
||||
Vendored
+4369
-3222
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+5
-5
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+5050
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+7
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Vendored
+260
-104
@@ -1,51 +1,150 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.5.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors
|
||||
* Copyright 2011-2020 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Bootstrap Reboot v5.1.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
:root {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-body-bg: #fff;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||
display: block;
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #212529;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus:not(:focus-visible) {
|
||||
outline: 0 !important;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
background-color: currentColor;
|
||||
border: 0;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
hr:not([size]) {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
@@ -54,12 +153,10 @@ p {
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
text-decoration: underline;
|
||||
abbr[data-bs-original-title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
border-bottom: 0;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
@@ -70,6 +167,11 @@ address {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
@@ -89,7 +191,7 @@ dt {
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@@ -103,42 +205,39 @@ strong {
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.2em;
|
||||
background-color: #fcf8e3;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -.25em;
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -.5em;
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0056b3;
|
||||
color: #0d6efd;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:not([href]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
a:hover {
|
||||
color: #0a58ca;
|
||||
}
|
||||
|
||||
a:not([href]):hover {
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -147,59 +246,94 @@ pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
direction: ltr /* rtl:ignore */;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
-ms-overflow-style: scrollbar;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: #d63384;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.2rem 0.4rem;
|
||||
font-size: 0.875em;
|
||||
color: #fff;
|
||||
background-color: #212529;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: #6c757d;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
@@ -213,54 +347,45 @@ textarea {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role="button"] {
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]::-webkit-calendar-picker-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type="button"]:not(:disabled),
|
||||
[type="reset"]:not(:disabled),
|
||||
[type="submit"]:not(:disabled) {
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
@@ -272,33 +397,59 @@ fieldset {
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
white-space: normal;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
[type=search] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
|
||||
/* rtl:raw:
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
*/
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
@@ -310,16 +461,21 @@ output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||
+1
-1
File diff suppressed because one or more lines are too long
currentmonitor/lantern-service-currentmonitor/src/main/webapp/bootstrap/css/bootstrap-reboot.min.css
Vendored
+5
-5
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
currentmonitor/lantern-service-currentmonitor/src/main/webapp/bootstrap/css/bootstrap-reboot.rtl.css
Vendored
+478
@@ -0,0 +1,478 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.1.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
:root {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-body-bg: #fff;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
background-color: currentColor;
|
||||
border: 0;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
hr:not([size]) {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-bs-original-title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.2em;
|
||||
background-color: #fcf8e3;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0d6efd;
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
color: #0a58ca;
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
direction: ltr ;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: #d63384;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.2rem 0.4rem;
|
||||
font-size: 0.875em;
|
||||
color: #fff;
|
||||
background-color: #212529;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: #6c757d;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]::-webkit-calendar-picker-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: right;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: right;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
||||
+1
File diff suppressed because one or more lines are too long
+8
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Vendored
+4866
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+7
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+4857
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+7
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+8360
-6948
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+7
-6
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+11198
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
Vendored
+7
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+229
@@ -0,0 +1,229 @@
|
||||
.scrollarea {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.fw-semibold { font-weight: 600; }
|
||||
.lh-tight { line-height: 1.25; }
|
||||
|
||||
.menu_link {
|
||||
text-decoration:none!important;
|
||||
}
|
||||
|
||||
.menu_subitem {
|
||||
color:#404040;
|
||||
}
|
||||
|
||||
.menu_item, .menu_subitem:hover, .menu_subitem:focus {
|
||||
background-color: #1a9acc;
|
||||
color:#f0f0f0;
|
||||
}
|
||||
|
||||
.lpm_menu {
|
||||
z-index:1;
|
||||
background:#ffffff;
|
||||
min-height:100%;
|
||||
max-height:100%;
|
||||
}
|
||||
|
||||
#toggle_label {
|
||||
margin-top:0.5rem;
|
||||
display: block;
|
||||
width: 2rem;
|
||||
position:absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.blue, .title {
|
||||
color: #1a9acc;
|
||||
}
|
||||
|
||||
.kill {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.max-w-300 {
|
||||
max-width:min(100%,300px);
|
||||
}
|
||||
|
||||
.max-w-400 {
|
||||
max-width:min(100%,400px);
|
||||
}
|
||||
|
||||
.max-w-500 {
|
||||
max-width:min(100%,500px);
|
||||
}
|
||||
|
||||
.max-w-600 {
|
||||
max-width:min(100%,600px);
|
||||
}
|
||||
|
||||
.max-w-700 {
|
||||
max-width:min(100%,700px);
|
||||
}
|
||||
|
||||
.max-w-800 {
|
||||
max-width:min(100%,800px);
|
||||
}
|
||||
|
||||
.max-w-900 {
|
||||
max-width:min(100%,900px);
|
||||
}
|
||||
|
||||
.max-w-1000 {
|
||||
max-width:min(100%,1000px);
|
||||
}
|
||||
|
||||
.max-w-1200 {
|
||||
max-width:min(100%,1200px);
|
||||
}
|
||||
|
||||
.align-col-right {
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
padding-right: 1vw !important;
|
||||
}
|
||||
|
||||
.align-col-left {
|
||||
display: flex !important;
|
||||
justify-content: flex-start !important;
|
||||
padding-left: 1vw !important;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
#menu_toggle:checked ~ #toggle_label {
|
||||
position:fixed!important;
|
||||
}
|
||||
|
||||
.lpm_menu {
|
||||
display:none!important;
|
||||
}
|
||||
|
||||
#menu_toggle:checked ~ .lpm_menu {
|
||||
display:block!important;
|
||||
}
|
||||
|
||||
#menu_toggle:checked ~ .lpm_body {
|
||||
display: block!important;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.hsy {
|
||||
margin-top: 2.3rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 3000px) {
|
||||
#menu_toggle:checked ~ .lpm_menu {
|
||||
display:block!important;
|
||||
}
|
||||
|
||||
#menu_toggle:checked ~ .lpm_body {
|
||||
display: block!important;
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.fm1 {
|
||||
font-size: calc(1rem + 1.25vw);
|
||||
}
|
||||
|
||||
.fm2 {
|
||||
font-size: calc(0.7rem + 1vw);
|
||||
}
|
||||
|
||||
.fm3 {
|
||||
font-size: calc(0.8rem + 0.5vw);
|
||||
}
|
||||
|
||||
.fmnu1 {
|
||||
font-size: calc(1rem + 0.5vw);
|
||||
}
|
||||
|
||||
.fmnu2 {
|
||||
font-size: calc(0.8rem + 0.5vw);
|
||||
}
|
||||
|
||||
.login-container {
|
||||
z-index:2;
|
||||
position:absolute;
|
||||
}
|
||||
|
||||
.login-bkgnd {
|
||||
z-index:1;
|
||||
position:absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top:0;
|
||||
left:0;
|
||||
background-image:url('../../img/pcb.png');
|
||||
background-size:cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.login-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: #a0a0a0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #1a9acc;
|
||||
border-color: #1a9acc;
|
||||
}
|
||||
|
||||
.btn-primary:hover, .btn-primary:focus{
|
||||
background-color: #20c0ff;
|
||||
border-color: #20c0ff;
|
||||
}
|
||||
|
||||
.header-menu {
|
||||
background-color: #1a9acc;
|
||||
}
|
||||
|
||||
.header-link {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.header-link:hover {
|
||||
color: #d0d0d0;
|
||||
}
|
||||
|
||||
.gso {
|
||||
border-style: none;
|
||||
width: 10rem;
|
||||
height: 2.5rem;
|
||||
background-image: url("../../img/gso.png");
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-color: #0000;
|
||||
}
|
||||
|
||||
.gso:hover {
|
||||
background-color: #0000;
|
||||
}
|
||||
|
||||
.gso:focus {
|
||||
background-image: url("../../img/gso_pressed.png");
|
||||
}
|
||||
|
||||
.border-none {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: darkred;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
.scrollarea{overflow-y:auto}.fw-semibold{font-weight:600}.lh-tight{line-height:1.25}.menu_link{text-decoration:none!important}.menu_subitem{color:#404040}.menu_item,.menu_subitem:focus,.menu_subitem:hover{background-color:#1a9acc;color:#f0f0f0}.lpm_menu{z-index:1;background:#fff;min-height:100%;max-height:100%}#toggle_label{margin-top:.5rem;display:block;width:2rem;position:absolute;z-index:10}.blue,.title{color:#1a9acc}.kill{color:red}.max-w-300{max-width:min(100%,300px)}.max-w-400{max-width:min(100%,400px)}.max-w-500{max-width:min(100%,500px)}.max-w-600{max-width:min(100%,600px)}.max-w-700{max-width:min(100%,700px)}.max-w-800{max-width:min(100%,800px)}.max-w-900{max-width:min(100%,900px)}.max-w-1000{max-width:min(100%,1000px)}.max-w-1200{max-width:min(100%,1200px)}.align-col-right{display:flex!important;justify-content:flex-end!important;padding-right:1vw!important}.align-col-left{display:flex!important;justify-content:flex-start!important;padding-left:1vw!important}.title{font-size:2em}.sub-title{font-size:1.1em}@media (max-width:991px){#menu_toggle:checked~#toggle_label{position:fixed!important}.lpm_menu{display:none!important}#menu_toggle:checked~.lpm_menu{display:block!important}#menu_toggle:checked~.lpm_body{display:block!important;width:50%}}@media (min-width:992px){.hsy{margin-top:2.3rem!important}}@media (min-width:3000px){#menu_toggle:checked~.lpm_menu{display:block!important}#menu_toggle:checked~.lpm_body{display:block!important;width:50%}}.fm1{font-size:calc(1rem + 1.25vw)}.fm2{font-size:calc(.7rem + 1vw)}.fm3{font-size:calc(.8rem + .5vw)}.fmnu1{font-size:calc(1rem + .5vw)}.fmnu2{font-size:calc(.8rem + .5vw)}.login-bkgnd,.login-container{z-index:2;position:absolute}.login-bkgnd{z-index:1;width:100%;height:100%;top:0;left:0;background-image:url(../../img/pcb.png);background-size:cover;background-position:center}.login-input{width:100%}::placeholder{color:#a0a0a0;opacity:1}.btn-primary{background-color:#1a9acc;border-color:#1a9acc}.btn-primary:focus,.btn-primary:hover{background-color:#20c0ff;border-color:#20c0ff}.header-menu{background-color:#1a9acc}.header-link{color:#f0f0f0}.header-link:hover{color:#d0d0d0}.gso{border-style:none;width:10rem;height:2.5rem;background-image:url(../../img/gso.png);background-position:center;background-size:cover}.gso,.gso:hover{background-color:#0000}.gso:focus{background-image:url(../../img/gso_pressed.png)}.border-none{border-style:none}.error{color:#8b0000}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 167 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 295 KiB |
+2
-4
@@ -3,14 +3,12 @@ package com.lanternsoftware.currentmonitor;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CreateAccount {
|
||||
public static void main(String[] args) {
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.CONFIG_PATH + "mongo.cfg"));
|
||||
Account account = new Account();
|
||||
account.setId(1);
|
||||
account.setPassword("*redacted*");
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
|
||||
public class CreateAuthCode {
|
||||
private static final AESTool aes = new AESTool(ResourceLoader.loadFile(LanternFiles.OPS_PATH + "authKey.dat"));
|
||||
private static final AESTool aes = new AESTool(ResourceLoader.loadFile(LanternFiles.CONFIG_PATH + "authKey.dat"));
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(aes.encryptToBase64(DaoSerializer.toZipBson(new AuthCode(100, null))));
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
|
||||
public class CreateAuthKey {
|
||||
public static void main(String[] args) {
|
||||
ResourceLoader.writeFile(LanternFiles.OPS_PATH + "authKey.dat", AESTool.generateRandomSecretKey().getEncoded());
|
||||
ResourceLoader.writeFile(LanternFiles.CONFIG_PATH + "authKey.dat", AESTool.generateRandomSecretKey().getEncoded());
|
||||
}
|
||||
}
|
||||
|
||||
+31
-16
@@ -4,26 +4,14 @@ import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPanel;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPolarity;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Meter;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.IFilter;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CreateBreakers {
|
||||
public static void main(String[] args) {
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.CONFIG_PATH + "mongo.cfg"));
|
||||
|
||||
/* Breaker bf1 = new Breaker("Solar A", 2, 20, 0, 1, 50, 1.6);
|
||||
bf1.setPolarity(BreakerPolarity.SOLAR);
|
||||
@@ -212,7 +200,6 @@ public class CreateBreakers {
|
||||
Map<Integer, Integer> panelToMeter = CollectionUtils.transformToMap(config.getPanels(), BreakerPanel::getIndex, BreakerPanel::getMeter);
|
||||
CollectionUtils.edit(config.getAllBreakers(), _b->_b.setMeter(DaoSerializer.toInteger(panelToMeter.get(_b.getPanel()))));*/
|
||||
|
||||
BreakerConfig config = dao.getConfig(1);
|
||||
// BreakerConfig config = DaoSerializer.parse(ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "breakerconfig_backup_210107.json"), BreakerConfig.class);
|
||||
// ResourceLoader.writeFile(LanternFiles.OPS_PATH + "breakerconfig_backup_210107.json", DaoSerializer.toJson(config));
|
||||
// CollectionUtils.edit(config.getAllBreakerGroups(), _g->{
|
||||
@@ -235,6 +222,34 @@ public class CreateBreakers {
|
||||
// group.setId(String.valueOf(CollectionUtils.getLargest(ids) + 1));
|
||||
// }
|
||||
// }
|
||||
|
||||
BreakerConfig config = dao.getConfig(100);
|
||||
/* TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
BillingRate summer0 = new BillingRate();
|
||||
summer0.setMeter(-1);
|
||||
summer0.setDayBillingCycleStart(13);
|
||||
summer0.setFlow(GridFlow.BOTH);
|
||||
summer0.setRate(0.13806);
|
||||
summer0.setCurrency(BillingCurrency.DOLLAR);
|
||||
summer0.setBeginEffective(DateUtils.date(5, 16, 2021, tz));
|
||||
summer0.setEndEffective(DateUtils.date(9, 16, 2021, tz));
|
||||
summer0.setRecursAnnually(true);
|
||||
|
||||
BillingRate winter0 = summer0.duplicate();
|
||||
winter0.setMonthKWhEnd(1000);
|
||||
winter0.setRate(0.09703);
|
||||
winter0.setBeginEffective(DateUtils.date(9, 16, 2021, tz));
|
||||
winter0.setEndEffective(DateUtils.date(5, 16, 2022, tz));
|
||||
|
||||
BillingRate winter1 = winter0.duplicate();
|
||||
winter1.setMonthKWhStart(1000);
|
||||
winter1.setMonthKWhEnd(0);
|
||||
winter1.setRate(0.063);
|
||||
config.setBillingRates(CollectionUtils.asArrayList(summer0, winter0, winter1));*/
|
||||
IFilter<Breaker> filter = _b->_b.getName().contains("Water") || _b.getName().contains("Furnace") || _b.getName().contains("Basement HP");
|
||||
CollectionUtils.filter(config.getAllBreakers(), filter).forEach(_b->_b.setMeter(0));
|
||||
CollectionUtils.filter(config.getAllBreakers(), _b->!filter.isFiltered(_b)).forEach(_b->_b.setMeter(1));
|
||||
|
||||
dao.putConfig(config);
|
||||
dao.shutdown();
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
public class CreateMongoConfig {
|
||||
public static void main(String[] args) {
|
||||
new MongoConfig("localhost", "*redacted*", "*redacted*", "CURRENT_MONITOR").saveToDisk(LanternFiles.OPS_PATH + "mongo.cfg");
|
||||
new MongoConfig("lanternsoftware.com", "*redacted*", "*redacted*", "CURRENT_MONITOR").saveToDisk(LanternFiles.CONFIG_PATH + "mongo.cfg");
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,13 +1,13 @@
|
||||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.generator.DaoSerializerGenerator;
|
||||
import com.lanternsoftware.util.dao.generator.SwiftModelGenerator;
|
||||
|
||||
public class CurrentMonitorSerializers {
|
||||
public static void main(String[] args) {
|
||||
DaoSerializerGenerator.generateSerializers(LanternFiles.SOURCE_PATH + "currentmonitor", true, null);
|
||||
SwiftModelGenerator.generateModel(LanternFiles.SOURCE_PATH + "currentmonitor", LanternFiles.SOURCE_PATH + "iOS");
|
||||
DaoSerializerGenerator.generateSerializers(LanternFiles.SOURCE_CODE_PATH + "currentmonitor", true, null);
|
||||
SwiftModelGenerator.generateModel(LanternFiles.SOURCE_CODE_PATH + "currentmonitor", LanternFiles.SOURCE_CODE_PATH + "iOS");
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -2,21 +2,21 @@ package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupEnergy;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupSummary;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergySummary;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyTotal;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
public class MigrateSummaries {
|
||||
public static void main(String[] args) {
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.CONFIG_PATH + "mongo.cfg"));
|
||||
// TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
// List<BreakerGroupEnergy> summaries = dao.getProxy().query(BreakerGroupEnergy.class, null);
|
||||
// CollectionUtils.edit(summaries, _s->CollectionUtils.edit(_s.getAllGroups(), _t->_t.setAccountId(1)));
|
||||
// dao.getProxy().save(summaries);
|
||||
|
||||
dao.getProxy().save(CollectionUtils.transform(dao.getProxy().queryAll(BreakerGroupEnergy.class), BreakerGroupSummary::new));
|
||||
dao.getProxy().save(CollectionUtils.transform(dao.getProxy().queryAll(EnergySummary.class), EnergyTotal::new));
|
||||
|
||||
// List<BreakerPower> readings = null;
|
||||
// while ((readings == null) || !readings.isEmpty()) {
|
||||
|
||||
+14
-10
@@ -2,24 +2,28 @@ package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.external.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class RebuildSummaries {
|
||||
public static void main(String[] args) {
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
dao.rebuildSummaries(100, DateUtils.date(8,3,2021, tz), DateUtils.date(8,5,2021, tz));
|
||||
/* List<Account> accounts = dao.getProxy().queryAll(Account.class);
|
||||
for (int accountId : CollectionUtils.transform(accounts, Account::getId)) {
|
||||
if (accountId != 100)
|
||||
continue;
|
||||
dao.rebuildSummaries(accountId, DateUtils.date(4,21,2021, tz), DateUtils.date(4,22,2021, tz));
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.CONFIG_PATH + "mongo.cfg"));
|
||||
for (Account a : dao.getProxy().queryAll(Account.class)) {
|
||||
TimeZone tz = DateUtils.fromTimeZoneId(a.getTimezone());
|
||||
// BreakerConfig config = dao.getConfig(a.getId());
|
||||
// BillingPlan plan = new BillingPlan();
|
||||
// plan.setPlanId(1);
|
||||
// plan.setBillingDay(1);
|
||||
// plan.setName("Standard");
|
||||
// plan.setRates(config.getBillingRates());
|
||||
// config.setBillingPlans(CollectionUtils.asArrayList(plan));
|
||||
// dao.putConfig(config);
|
||||
dao.rebuildSummaries(a.getId(), DateUtils.date(12,18,2021,tz), DateUtils.date(12,19,2021,tz));
|
||||
}
|
||||
*/
|
||||
dao.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user