mirror of
				https://github.com/zyphlar/LanternPowerMonitor.git
				synced 2024-03-08 14:07:47 +00:00 
			
		
		
		
	Add BOM generation from within the app.
This commit is contained in:
		
							parent
							
								
									fa606cce84
								
							
						
					
					
						commit
						1a1acb9cbc
					
				@ -51,7 +51,8 @@ public class CurrentMonitor {
 | 
			
		||||
	public void stop() {
 | 
			
		||||
		stopMonitoring();
 | 
			
		||||
		ConcurrencyUtils.sleep(1000);
 | 
			
		||||
		executor.shutdownNow();
 | 
			
		||||
		executor.shutdown();
 | 
			
		||||
		ConcurrencyUtils.sleep(1000);
 | 
			
		||||
		chips.clear();
 | 
			
		||||
		pins.clear();
 | 
			
		||||
		gpio.shutdown();
 | 
			
		||||
 | 
			
		||||
@ -130,7 +130,7 @@ public class MonitorApp {
 | 
			
		||||
						case Restart:
 | 
			
		||||
							LOG.info("Restarting Current Monitor...");
 | 
			
		||||
							try {
 | 
			
		||||
								Runtime.getRuntime().exec("service currentmonitor restart");
 | 
			
		||||
								Runtime.getRuntime().exec("echo \"sudo systemctl restart currentmonitor\" | at now + 1 minute");
 | 
			
		||||
							} catch (IOException _e) {
 | 
			
		||||
								LOG.error("Exception occurred while trying to restart", _e);
 | 
			
		||||
							}
 | 
			
		||||
@ -138,7 +138,7 @@ public class MonitorApp {
 | 
			
		||||
						case Reboot:
 | 
			
		||||
							LOG.info("Rebooting Pi...");
 | 
			
		||||
							try {
 | 
			
		||||
								Runtime.getRuntime().exec("reboot now");
 | 
			
		||||
								Runtime.getRuntime().exec("sudo reboot now");
 | 
			
		||||
							} catch (IOException _e) {
 | 
			
		||||
								LOG.error("Exception occurred while trying to reboot", _e);
 | 
			
		||||
							}
 | 
			
		||||
@ -339,9 +339,9 @@ public class MonitorApp {
 | 
			
		||||
				if (CollectionUtils.length(jar) == DaoSerializer.getInteger(meta, "size") && NullUtils.isEqual(DigestUtils.md5Hex(jar), DaoSerializer.getString(meta, "checksum"))) {
 | 
			
		||||
					LOG.info("Update downloaded, writing jar and restarting...");
 | 
			
		||||
					ResourceLoader.writeFile(WORKING_DIR + "lantern-currentmonitor.jar", jar);
 | 
			
		||||
					ConcurrencyUtils.sleep(5000);
 | 
			
		||||
					ConcurrencyUtils.sleep(10000);
 | 
			
		||||
					try {
 | 
			
		||||
						Runtime.getRuntime().exec("service currentmonitor restart");
 | 
			
		||||
						Runtime.getRuntime().exec("echo \"sudo systemctl restart currentmonitor\" | at now + 1 minute");
 | 
			
		||||
					} catch (IOException _e) {
 | 
			
		||||
						LOG.error("Exception occurred while trying to restart", _e);
 | 
			
		||||
					}
 | 
			
		||||
@ -375,9 +375,9 @@ public class MonitorApp {
 | 
			
		||||
				else if (NullUtils.isEqual(command, "extend_filesystem")) {
 | 
			
		||||
					LOG.info("Extending filesystem and rebooting");
 | 
			
		||||
					try {
 | 
			
		||||
						Runtime.getRuntime().exec("raspi-config --expand-rootfs");
 | 
			
		||||
						ConcurrencyUtils.sleep(3000);
 | 
			
		||||
						Runtime.getRuntime().exec("reboot");
 | 
			
		||||
						Runtime.getRuntime().exec("sudo raspi-config --expand-rootfs");
 | 
			
		||||
						ConcurrencyUtils.sleep(5000);
 | 
			
		||||
						Runtime.getRuntime().exec("sudo reboot now");
 | 
			
		||||
					} catch (IOException _e) {
 | 
			
		||||
						LOG.error("Exception occurred while trying to extend filesystem", _e);
 | 
			
		||||
					}
 | 
			
		||||
@ -386,7 +386,7 @@ public class MonitorApp {
 | 
			
		||||
				else if (NullUtils.isEqual(command, "restart")) {
 | 
			
		||||
					LOG.info("Restarting...");
 | 
			
		||||
					try {
 | 
			
		||||
						Runtime.getRuntime().exec("service currentmonitor restart");
 | 
			
		||||
						Runtime.getRuntime().exec("echo \"sudo systemctl restart currentmonitor\" | at now + 1 minute");
 | 
			
		||||
					} catch (IOException _e) {
 | 
			
		||||
						LOG.error("Exception occurred while trying to restart", _e);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
@ -188,8 +188,10 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
 | 
			
		||||
	public void putConfig(BreakerConfig _config) {
 | 
			
		||||
		DaoQuery configQuery = new DaoQuery("_id", String.valueOf(_config.getAccountId()));
 | 
			
		||||
		BreakerConfig oldConfig = proxy.queryOne(BreakerConfig.class, configQuery);
 | 
			
		||||
		if (oldConfig != null)
 | 
			
		||||
			proxy.delete(BreakerGroup.class, DaoQuery.in("_id", oldConfig.getAllBreakerGroupIds()));
 | 
			
		||||
		if (oldConfig != null) {
 | 
			
		||||
			proxy.saveEntity("config_archive", DaoSerializer.toDaoEntity(oldConfig));
 | 
			
		||||
			_config.setVersion(oldConfig.getVersion() + 1);
 | 
			
		||||
		}
 | 
			
		||||
		proxy.save(_config);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ public class BreakerConfig {
 | 
			
		||||
	private List<BreakerPanel> panels;
 | 
			
		||||
	private List<BreakerHub> breakerHubs;
 | 
			
		||||
	private List<BreakerGroup> breakerGroups;
 | 
			
		||||
	private int version;
 | 
			
		||||
 | 
			
		||||
	public BreakerConfig() {
 | 
			
		||||
	}
 | 
			
		||||
@ -65,6 +66,14 @@ public class BreakerConfig {
 | 
			
		||||
		breakerGroups = _breakerGroups;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int getVersion() {
 | 
			
		||||
		return version;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setVersion(int _version) {
 | 
			
		||||
		version = _version;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List<Breaker> getAllBreakers() {
 | 
			
		||||
		List<Breaker> allBreakers = new ArrayList<>();
 | 
			
		||||
		for (BreakerGroup g : CollectionUtils.makeNotNull(breakerGroups)) {
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,78 @@
 | 
			
		||||
package com.lanternsoftware.datamodel.currentmonitor.bom;
 | 
			
		||||
 | 
			
		||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
 | 
			
		||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
 | 
			
		||||
import com.lanternsoftware.util.CollectionUtils;
 | 
			
		||||
import com.lanternsoftware.util.csv.CSV;
 | 
			
		||||
import com.lanternsoftware.util.dao.DaoSerializer;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.TreeMap;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
			
		||||
 | 
			
		||||
public class BOM {
 | 
			
		||||
	List<LineItem> lineItems;
 | 
			
		||||
 | 
			
		||||
	public static BOM fromConfig(BreakerConfig _config) {
 | 
			
		||||
		BOM bom = new BOM();
 | 
			
		||||
		bom.setLineItems(new ArrayList<>());
 | 
			
		||||
		int hubCnt = (int)Math.ceil(CollectionUtils.size(_config.getAllBreakers())/15.0);
 | 
			
		||||
		bom.getLineItems().add(new LineItem("Lantern Power Monitor Case", "LPMC1", "https://github.com/MarkBryanMilligan/LanternPowerMonitor/tree/main/case", 0.10, 3.00, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("Lantern Power Monitor Case Lid", "LPMCL1", "https://github.com/MarkBryanMilligan/LanternPowerMonitor/tree/main/case", 0.10, 2.00, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("Lantern Power Monitor Soldering Jig", "LPMSJ1", "https://github.com/MarkBryanMilligan/LanternPowerMonitor/tree/main/case", 0.10, 4.00, 1));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("Lantern Power Monitor PCB", "LPMPCB1", "https://github.com/MarkBryanMilligan/LanternPowerMonitor/tree/main/pcb", 1.00, 5.00, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("Raspberry Pi 3 Model A+", "3A+", "https://www.raspberrypi.org/products/raspberry-pi-3-model-a-plus/", 25.0, 35.0, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("Jameco 12V AC/AC Adapter", "10428", "https://www.jameco.com/z/ACU120100Z9121-Jameco-Reliapro-AC-to-AC-Wall-Adapter-Transformer-12-Volt-AC-1000mA-Black-Straight-3-5mm-Male-Plug_10428.html", 10.95, 15.00, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("16gb memory card", "P-SDU16GU185GW-GE", "https://www.microcenter.com/product/486146/micro-center-16gb-microsdhc-class-10-flash-memory-card", 4.00, 5.00, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("40-pin GPIO header", "C169819", "https://lcsc.com/product-detail/Pin-Header-Female-Header_Ckmtw-Shenzhen-Cankemeng-C169819_C169819.html", 0.36, 0.80, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("MCP3008", "MCP3008-I-P", "https://www.digikey.com/en/products/detail/microchip-technology/MCP3008-I-P/319422", 2.41, 4.00, hubCnt*2));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("10uF 25V 4*5 Capacitor", "C43846", "https://lcsc.com/product-detail/Aluminum-Electrolytic-Capacitors-Leaded_CX-Dongguan-Chengxing-Elec-10uF-25V-4-5_C43846.html", 0.01, 0.10, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("22uF 25V 4*7 Capacitor", "C43840", "https://lcsc.com/product-detail/Aluminum-Electrolytic-Capacitors-Leaded_CX-Dongguan-Chengxing-Elec-22uF-25V-4-7_C43840.html", 0.01, 0.10, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("10KΩ Resistor", "C385441", "https://lcsc.com/product-detail/Metal-Film-Resistor-TH_TyoHM-RN1-2WS10K%CE%A9FT-BA1_C385441.html", 0.01, 0.10, hubCnt*2));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("12KΩ Resistor", "C385449", "https://lcsc.com/product-detail/Metal-Film-Resistor-TH_TyoHM-RN1-2WS12K%CE%A9FT-BA1_C385449.html", 0.01, 0.10, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("180KΩ Resistor", "C385460", "https://lcsc.com/product-detail/Metal-Film-Resistor-TH_TyoHM-RN1-2WS180K%CE%A9FT-BA1_C385460.html", 0.01, 0.10, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("33KΩ Resistor", "C385498", "https://lcsc.com/product-detail/Metal-Film-Resistor-TH_TyoHM-RN1-2WS33K%CE%A9FT-BA1_C385498.html", 0.01, 0.10, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("68KΩ Resistor", "C385541", "https://lcsc.com/product-detail/Metal-Film-Resistor-TH_TyoHM-RN1-2WS68K%CE%A9FT-BA1_C385541.html", 0.01, 0.10, hubCnt));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("3.5mm Headphone Jack", "PJ-3583-B", "https://lcsc.com/product-detail/Audio-Video-Connectors_XKB-Enterprise-PJ-3583-B_C397337.html", 0.16, 0.25, hubCnt*16));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("M2.5x10mm Cap Screw", "A15120300ux0225", "https://www.amazon.com/gp/product/B01B1OD7IK", 0.10, 0.20, hubCnt*8));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("M2.5x11mm Female x Female Standoff", "", "https://www.ebay.com/itm/50pcs-M2-5-Female-Hex-Screw-Brass-PCB-Standoffs-Hexagonal-Spacers/172746413434", 0.15, 0.25, hubCnt*4));
 | 
			
		||||
		bom.getLineItems().add(new LineItem("M2.5x12mm Female x Male Standoff", "", "https://www.ebay.com/itm/M2-5-2-5mm-Thread-6mm-Brass-Standoff-Spacer-Male-x-Female-20-50pcs-New/283432513974", 0.15, 0.25, hubCnt*4));
 | 
			
		||||
		Map<Integer, AtomicInteger> ctCnts = new TreeMap<>();
 | 
			
		||||
		for (Breaker breaker : CollectionUtils.makeNotNull(_config.getAllBreakers())) {
 | 
			
		||||
			if (breaker.getSizeAmps() <= 20)
 | 
			
		||||
				ctCnts.computeIfAbsent(20, (_k)->new AtomicInteger(0)).getAndIncrement();
 | 
			
		||||
			else if (breaker.getSizeAmps() <= 30)
 | 
			
		||||
				ctCnts.computeIfAbsent(30, (_k)->new AtomicInteger(0)).getAndIncrement();
 | 
			
		||||
			else
 | 
			
		||||
				ctCnts.computeIfAbsent(50, (_k)->new AtomicInteger(0)).getAndIncrement();
 | 
			
		||||
		}
 | 
			
		||||
		for (Map.Entry<Integer, AtomicInteger> ctCnt : ctCnts.entrySet()) {
 | 
			
		||||
			bom.getLineItems().add(new LineItem(String.format("%d Amp Current Transformer", ctCnt.getKey()), String.format("SCT-013-0%d", ctCnt.getKey()), "N/A", 5.00, 7.00, ctCnt.getValue().get()));
 | 
			
		||||
		}
 | 
			
		||||
		return bom;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List<LineItem> getLineItems() {
 | 
			
		||||
		return lineItems;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setLineItems(List<LineItem> _lineItems) {
 | 
			
		||||
		lineItems = _lineItems;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public CSV toCsv(boolean _includePrices) {
 | 
			
		||||
		double selfCost = CollectionUtils.sum(CollectionUtils.transform(lineItems, _l->_l.getListCost()*_l.getQuantity()));
 | 
			
		||||
		double shippedCost = CollectionUtils.sum(CollectionUtils.transform(lineItems, _l->_l.getOrderCost()*_l.getQuantity()));
 | 
			
		||||
		List<String> headers = CollectionUtils.asArrayList("Item Name", "Part Number", "URL", "Quantity Required", "~Self-Source Unit Price", "Shipped Unit Price", "~Self-Source Total Price", "Shipped Total Price");
 | 
			
		||||
		List<List<String>> rows = CollectionUtils.transform(lineItems, _l->CollectionUtils.asArrayList(_l.getName(), _l.getPartNumber(), _l.getUrl(), DaoSerializer.toString(_l.getQuantity()), String.format("$%.2f", _l.getListCost()), String.format("$%.2f", _l.getOrderCost()), String.format("$%.2f", _l.getListCost() * _l.getQuantity()), String.format("$%.2f", _l.getOrderCost() * _l.getQuantity())));
 | 
			
		||||
		if (!_includePrices) {
 | 
			
		||||
			headers = headers.subList(0, 4);
 | 
			
		||||
			rows = CollectionUtils.transform(rows, _r->_r.subList(0, 4));
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			rows.add(CollectionUtils.asArrayList("Total", "", "", "", "", "", String.format("$%.2f", selfCost), String.format("$%.2f", shippedCost)));
 | 
			
		||||
		return new CSV(headers, rows, headers.size());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,70 @@
 | 
			
		||||
package com.lanternsoftware.datamodel.currentmonitor.bom;
 | 
			
		||||
 | 
			
		||||
public class LineItem {
 | 
			
		||||
	private String name;
 | 
			
		||||
	private String partNumber;
 | 
			
		||||
	private String url;
 | 
			
		||||
	private double listCost;
 | 
			
		||||
	private double orderCost;
 | 
			
		||||
	private int quantity;
 | 
			
		||||
 | 
			
		||||
	public LineItem() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LineItem(String _name, String _partNumber, String _url, double _listCost, double _orderCost, int _quantity) {
 | 
			
		||||
		name = _name;
 | 
			
		||||
		partNumber = _partNumber;
 | 
			
		||||
		url = _url;
 | 
			
		||||
		listCost = _listCost;
 | 
			
		||||
		orderCost = _orderCost;
 | 
			
		||||
		quantity = _quantity;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getName() {
 | 
			
		||||
		return name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setName(String _name) {
 | 
			
		||||
		name = _name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getPartNumber() {
 | 
			
		||||
		return partNumber;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setPartNumber(String _partNumber) {
 | 
			
		||||
		partNumber = _partNumber;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getUrl() {
 | 
			
		||||
		return url;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setUrl(String _url) {
 | 
			
		||||
		url = _url;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public double getListCost() {
 | 
			
		||||
		return listCost;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setListCost(double _listCost) {
 | 
			
		||||
		listCost = _listCost;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public double getOrderCost() {
 | 
			
		||||
		return orderCost;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setOrderCost(double _orderCost) {
 | 
			
		||||
		orderCost = _orderCost;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int getQuantity() {
 | 
			
		||||
		return quantity;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setQuantity(int _quantity) {
 | 
			
		||||
		quantity = _quantity;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -35,6 +35,7 @@ public class BreakerConfigSerializer extends AbstractDaoSerializer<BreakerConfig
 | 
			
		||||
		d.put("panels", DaoSerializer.toDaoEntities(_o.getPanels(), DaoProxyType.MONGO));
 | 
			
		||||
		d.put("breaker_hubs", DaoSerializer.toDaoEntities(_o.getBreakerHubs(), DaoProxyType.MONGO));
 | 
			
		||||
		d.put("breaker_groups", DaoSerializer.toDaoEntities(_o.getBreakerGroups(), DaoProxyType.MONGO));
 | 
			
		||||
		d.put("version", _o.getVersion());
 | 
			
		||||
		return d;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -47,6 +48,7 @@ public class BreakerConfigSerializer extends AbstractDaoSerializer<BreakerConfig
 | 
			
		||||
		o.setPanels(DaoSerializer.getList(_d, "panels", BreakerPanel.class));
 | 
			
		||||
		o.setBreakerHubs(DaoSerializer.getList(_d, "breaker_hubs", BreakerHub.class));
 | 
			
		||||
		o.setBreakerGroups(DaoSerializer.getList(_d, "breaker_groups", BreakerGroup.class));
 | 
			
		||||
		o.setVersion(DaoSerializer.getInteger(_d, "version"));
 | 
			
		||||
		return o;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
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.GoogleIdTokenVerifier;
 | 
			
		||||
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
 | 
			
		||||
import com.google.api.client.http.javanet.NetHttpTransport;
 | 
			
		||||
import com.google.api.client.json.jackson2.JacksonFactory;
 | 
			
		||||
import com.lanternsoftware.currentmonitor.context.Globals;
 | 
			
		||||
@ -18,14 +19,19 @@ import org.slf4j.LoggerFactory;
 | 
			
		||||
import javax.servlet.annotation.WebServlet;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
 | 
			
		||||
@WebServlet("/auth/*")
 | 
			
		||||
public class AuthServlet extends CMServlet {
 | 
			
		||||
	private static final NetHttpTransport transport = new NetHttpTransport();
 | 
			
		||||
	private static final JacksonFactory jsonFactory = new JacksonFactory();
 | 
			
		||||
	private static final Logger logger = LoggerFactory.getLogger(AuthServlet.class);
 | 
			
		||||
	private static final String googleSsoKey = ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "google_sso_key.txt");
 | 
			
		||||
	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) {
 | 
			
		||||
@ -33,20 +39,21 @@ public class AuthServlet extends CMServlet {
 | 
			
		||||
		if (NullUtils.isEmpty(authCode)) {
 | 
			
		||||
			BasicAuth auth = new BasicAuth(_req);
 | 
			
		||||
			if (NullUtils.isEqual(auth.getUsername(), "googlesso")) {
 | 
			
		||||
				GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory).setAudience(Collections.singletonList(googleSsoKey)).build();
 | 
			
		||||
				logger.info("Attempting google SSO");
 | 
			
		||||
				try {
 | 
			
		||||
					GoogleIdToken idToken = verifier.verify(auth.getPassword());
 | 
			
		||||
					if (idToken != null) {
 | 
			
		||||
						GoogleIdToken.Payload payload = idToken.getPayload();
 | 
			
		||||
						String email = payload.getEmail();
 | 
			
		||||
						authCode = Globals.dao.getAuthCodeForEmail(email, DateUtils.fromTimeZoneId(_req.getHeader("timezone")));
 | 
			
		||||
					GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, "https://oauth2.googleapis.com/token", googleClientId, googleClientSecret, auth.getPassword(), "").execute();
 | 
			
		||||
					if (tokenResponse != null) {
 | 
			
		||||
						GoogleIdToken idToken = tokenResponse.parseIdToken();
 | 
			
		||||
						if (idToken != null) {
 | 
			
		||||
							logger.info("Successfully received google id token");
 | 
			
		||||
							authCode = Globals.dao.getAuthCodeForEmail(idToken.getPayload().getEmail(), DateUtils.fromTimeZoneId(_req.getHeader("timezone")));
 | 
			
		||||
							logger.info("Auth code for google user is valid: " + (authCode != null));
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				} catch (Exception _e) {
 | 
			
		||||
					logger.error("Failed to validate google auth code", _e);
 | 
			
		||||
				}
 | 
			
		||||
				catch (Exception _e) {
 | 
			
		||||
					logger.error("Failed to validate google auth token", _e);
 | 
			
		||||
  				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			} else
 | 
			
		||||
				authCode = Globals.dao.authenticateAccount(auth.getUsername(), auth.getPassword());
 | 
			
		||||
		}
 | 
			
		||||
		DaoEntity rep = new DaoEntity("auth_code", authCode);
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,38 @@
 | 
			
		||||
package com.lanternsoftware.currentmonitor.servlet;
 | 
			
		||||
 | 
			
		||||
import com.lanternsoftware.currentmonitor.context.Globals;
 | 
			
		||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
 | 
			
		||||
import com.lanternsoftware.datamodel.currentmonitor.bom.BOM;
 | 
			
		||||
import com.lanternsoftware.util.CollectionUtils;
 | 
			
		||||
import com.lanternsoftware.util.csv.CSVWriter;
 | 
			
		||||
import com.lanternsoftware.util.dao.DaoEntity;
 | 
			
		||||
import com.lanternsoftware.util.dao.DaoQuery;
 | 
			
		||||
import com.lanternsoftware.util.dao.DaoSerializer;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.annotation.WebServlet;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
@WebServlet("/bom/*")
 | 
			
		||||
public class BomServlet extends CMServlet {
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
 | 
			
		||||
		String[] path = path(_req);
 | 
			
		||||
		if (CollectionUtils.size(path) < 1){
 | 
			
		||||
			_rep.setStatus(401);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		DaoEntity id = CollectionUtils.getFirst(Globals.dao.getProxy().queryForEntities("bom", new DaoQuery("_id", path[0])));
 | 
			
		||||
		int acctId = DaoSerializer.getInteger(id, "acct_id");
 | 
			
		||||
		if (acctId == 0) {
 | 
			
		||||
			_rep.setStatus(401);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		BreakerConfig config = Globals.dao.getConfig(acctId);
 | 
			
		||||
		if (config == null) {
 | 
			
		||||
			_rep.setStatus(401);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		setResponseEntity(_rep, "text/csv",CSVWriter.toByteArray(BOM.fromConfig(config).toCsv(false)));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,23 @@
 | 
			
		||||
package com.lanternsoftware.currentmonitor.servlet;
 | 
			
		||||
 | 
			
		||||
import com.lanternsoftware.currentmonitor.context.Globals;
 | 
			
		||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
 | 
			
		||||
import com.lanternsoftware.util.dao.DaoEntity;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.annotation.WebServlet;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
@WebServlet("/generateBom")
 | 
			
		||||
public class GenerateBomServlet extends SecureServlet {
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
 | 
			
		||||
		AuthCode authCode = Globals.dao.decryptAuthCode(_req.getHeader("auth_code"));
 | 
			
		||||
		if (authCode == null) {
 | 
			
		||||
			_rep.setStatus(401);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		String id = Globals.dao.getProxy().saveEntity("bom", new DaoEntity("acct_id", authCode.getAccountId()));
 | 
			
		||||
		jsonResponse(_rep, new DaoEntity("link", "bom/" + id));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -3,4 +3,6 @@ package com.lanternsoftware.util;
 | 
			
		||||
public abstract class LanternFiles {
 | 
			
		||||
	public static final String SOURCE_PATH = "C:\\lantern\\wc\\opensource\\LanternPowerMonitor\\";
 | 
			
		||||
	public static final String OPS_PATH = "D:\\zwave\\";
 | 
			
		||||
//	public static final String OPS_PATH = "D:\\zwave\\linux\\";
 | 
			
		||||
//	public static final String OPS_PATH = "/opt/tomcat/";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,32 @@
 | 
			
		||||
package com.lanternsoftware.util.csv;
 | 
			
		||||
 | 
			
		||||
import com.lanternsoftware.util.CollectionUtils;
 | 
			
		||||
import com.lanternsoftware.util.NullUtils;
 | 
			
		||||
import com.lanternsoftware.util.ResourceLoader;
 | 
			
		||||
 | 
			
		||||
public abstract class CSVWriter {
 | 
			
		||||
	public static void writeCSV(CSV _csv, String _file) {
 | 
			
		||||
		ResourceLoader.writeFile(_file, toString(_csv));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static String toString(CSV _csv) {
 | 
			
		||||
		StringBuilder out = new StringBuilder();
 | 
			
		||||
		if (CollectionUtils.isNotEmpty(_csv.getHeaders())) {
 | 
			
		||||
			out.append(CollectionUtils.transformToCommaSeparated(_csv.getHeaders(), _h -> "\"" + _h + "\""));
 | 
			
		||||
			out.append("\r\n");
 | 
			
		||||
		}
 | 
			
		||||
		for (int r = 0; r < _csv.rows; r++) {
 | 
			
		||||
			for (int c = 0; c < _csv.getColumns(); c++) {
 | 
			
		||||
				if (c > 0)
 | 
			
		||||
					out.append(",");
 | 
			
		||||
				out.append(_csv.cell(r, c));
 | 
			
		||||
			}
 | 
			
		||||
			out.append("\r\n");
 | 
			
		||||
		}
 | 
			
		||||
		return out.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static byte[] toByteArray(CSV _csv) {
 | 
			
		||||
		return NullUtils.toByteArray(toString(_csv));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								util/lantern-util-excel/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								util/lantern-util-excel/pom.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
	<modelVersion>4.0.0</modelVersion>
 | 
			
		||||
 | 
			
		||||
	<groupId>com.lanternsoftware.util</groupId>
 | 
			
		||||
	<artifactId>lantern-util-excel</artifactId>
 | 
			
		||||
	<name>lantern-util-excel</name>
 | 
			
		||||
	<version>1.0.0</version>
 | 
			
		||||
	<packaging>jar</packaging>
 | 
			
		||||
 | 
			
		||||
	<dependencies>
 | 
			
		||||
		<dependency>
 | 
			
		||||
			<groupId>com.lanternsoftware.util</groupId>
 | 
			
		||||
			<artifactId>lantern-util-common</artifactId>
 | 
			
		||||
			<version>1.0.0</version>
 | 
			
		||||
		</dependency>
 | 
			
		||||
		<dependency>
 | 
			
		||||
			<groupId>org.apache.poi</groupId>
 | 
			
		||||
			<artifactId>poi-ooxml</artifactId>
 | 
			
		||||
			<version>5.0.0</version>
 | 
			
		||||
		</dependency>
 | 
			
		||||
	</dependencies>
 | 
			
		||||
	<build>
 | 
			
		||||
		<plugins>
 | 
			
		||||
			<plugin>
 | 
			
		||||
				<groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
				<artifactId>maven-compiler-plugin</artifactId>
 | 
			
		||||
				<version>3.2</version>
 | 
			
		||||
				<executions>
 | 
			
		||||
					<execution>
 | 
			
		||||
						<goals>
 | 
			
		||||
							<goal>testCompile</goal>
 | 
			
		||||
						</goals>
 | 
			
		||||
						<phase>compile</phase>
 | 
			
		||||
					</execution>
 | 
			
		||||
				</executions>
 | 
			
		||||
				<configuration>
 | 
			
		||||
					<optimize>true</optimize>
 | 
			
		||||
					<showDeprecation>true</showDeprecation>
 | 
			
		||||
					<encoding>UTF-8</encoding>
 | 
			
		||||
					<source>1.8</source>
 | 
			
		||||
					<target>1.8</target>
 | 
			
		||||
				</configuration>
 | 
			
		||||
			</plugin>
 | 
			
		||||
			<plugin>
 | 
			
		||||
				<groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
				<artifactId>maven-source-plugin</artifactId>
 | 
			
		||||
				<version>3.2.1</version>
 | 
			
		||||
				<executions>
 | 
			
		||||
					<execution>
 | 
			
		||||
						<phase>package</phase>
 | 
			
		||||
						<goals>
 | 
			
		||||
							<goal>jar</goal>
 | 
			
		||||
						</goals>
 | 
			
		||||
					</execution>
 | 
			
		||||
				</executions>
 | 
			
		||||
			</plugin>
 | 
			
		||||
		</plugins>
 | 
			
		||||
	</build>
 | 
			
		||||
</project>
 | 
			
		||||
@ -0,0 +1,177 @@
 | 
			
		||||
package com.lanternsoftware.util.excel;
 | 
			
		||||
 | 
			
		||||
import com.lanternsoftware.util.CollectionUtils;
 | 
			
		||||
import com.lanternsoftware.util.NullUtils;
 | 
			
		||||
import com.lanternsoftware.util.csv.CSV;
 | 
			
		||||
import org.apache.commons.io.IOUtils;
 | 
			
		||||
import org.apache.poi.ss.usermodel.BorderStyle;
 | 
			
		||||
import org.apache.poi.ss.usermodel.Cell;
 | 
			
		||||
import org.apache.poi.ss.usermodel.CellStyle;
 | 
			
		||||
import org.apache.poi.ss.usermodel.DataFormatter;
 | 
			
		||||
import org.apache.poi.ss.usermodel.Font;
 | 
			
		||||
import org.apache.poi.ss.usermodel.Row;
 | 
			
		||||
import org.apache.poi.ss.usermodel.Sheet;
 | 
			
		||||
import org.apache.poi.ss.usermodel.Workbook;
 | 
			
		||||
import org.apache.poi.ss.util.SheetUtil;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public abstract class ExcelWriter {
 | 
			
		||||
	private static final Logger LOG = LoggerFactory.getLogger(ExcelWriter.class);
 | 
			
		||||
 | 
			
		||||
	public static Workbook toExcel(CSV _csv, String _sSheetName) {
 | 
			
		||||
		try {
 | 
			
		||||
			Workbook wb = new XSSFWorkbook();
 | 
			
		||||
			addSheet(wb, _csv, _sSheetName);
 | 
			
		||||
			return wb;
 | 
			
		||||
		} catch (Throwable t) {
 | 
			
		||||
			LOG.error("Failed to convert CSV to Excel Workbook", t);
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Sheet addSheet(Workbook _wb, CSV _csv, String _sSheetName) {
 | 
			
		||||
		Font font = _wb.createFont();
 | 
			
		||||
		font.setBold(true);
 | 
			
		||||
		font.setFontName("Arial");
 | 
			
		||||
 | 
			
		||||
		CellStyle header = _wb.createCellStyle();
 | 
			
		||||
		header.setWrapText(false);
 | 
			
		||||
		header.setBorderBottom(BorderStyle.THIN);
 | 
			
		||||
		header.setFont(font);
 | 
			
		||||
 | 
			
		||||
		DataFormatter formatter = new DataFormatter();
 | 
			
		||||
		int defaultCharWidth = SheetUtil.getDefaultCharWidth(_wb);
 | 
			
		||||
 | 
			
		||||
		Map<Integer, Integer> mapHeaderWidths = new HashMap<>();
 | 
			
		||||
		Set<Integer> setAutoSizedCols = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
		Sheet sh = _wb.createSheet(_sSheetName);
 | 
			
		||||
		int iHeader = 0;
 | 
			
		||||
		if (!CollectionUtils.isEmpty(_csv.getHeaders())) {
 | 
			
		||||
			Row r = sh.createRow(0);
 | 
			
		||||
			for (int iCol = 0; iCol < _csv.columns; iCol++) {
 | 
			
		||||
				String sContent = _csv.getHeader(iCol);
 | 
			
		||||
				Cell cell = r.createCell(iCol);
 | 
			
		||||
				cell.setCellValue(sContent);
 | 
			
		||||
				cell.setCellStyle(header);
 | 
			
		||||
				int iWidth = (int) (SheetUtil.getCellWidth(cell, defaultCharWidth, formatter, false) * 256) + 10;
 | 
			
		||||
				if (iWidth > 0) {
 | 
			
		||||
					sh.setColumnWidth(iCol, iWidth);
 | 
			
		||||
					mapHeaderWidths.put(iCol, iWidth);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			iHeader = 1;
 | 
			
		||||
			sh.createFreezePane(0, 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (int iRow = 0; iRow < _csv.rows; iRow++) {
 | 
			
		||||
			Row r = sh.createRow(iRow + iHeader);
 | 
			
		||||
			for (int iCol = 0; iCol < _csv.columns; iCol++) {
 | 
			
		||||
				String sContent = _csv.cell(iRow, iCol);
 | 
			
		||||
				Cell cell = r.createCell(iCol);
 | 
			
		||||
				cell.setCellValue(sContent);
 | 
			
		||||
				if (NullUtils.isNotEmpty(sContent)) {
 | 
			
		||||
					if (!setAutoSizedCols.contains(iCol)) {
 | 
			
		||||
						int iWidth = (int) (SheetUtil.getCellWidth(cell, defaultCharWidth, formatter, false) * 256) + 10;
 | 
			
		||||
						Integer headerWidth = mapHeaderWidths.get(iCol);
 | 
			
		||||
						if (headerWidth == null)
 | 
			
		||||
							headerWidth = 0;
 | 
			
		||||
						if (iWidth > headerWidth) {
 | 
			
		||||
							sh.setColumnWidth(iCol, iWidth);
 | 
			
		||||
						}
 | 
			
		||||
						setAutoSizedCols.add(iCol);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return sh;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static CSV fromExcelFile(String _sPath) {
 | 
			
		||||
		return fromExcelFile(_sPath, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static CSV fromExcelFile(String _sPath, int _iTabIdx) {
 | 
			
		||||
		FileInputStream is = null;
 | 
			
		||||
		try {
 | 
			
		||||
			is = new FileInputStream(_sPath);
 | 
			
		||||
			Workbook wb = new XSSFWorkbook(is);
 | 
			
		||||
			return fromExcel(wb, _iTabIdx);
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			LOG.error("Failed to open Excel Workbook", e);
 | 
			
		||||
			return null;
 | 
			
		||||
		} finally {
 | 
			
		||||
			IOUtils.closeQuietly(is);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static CSV fromExcel(Workbook _xls, int _iTabIdx) {
 | 
			
		||||
		Sheet sh = _xls.getSheetAt(_iTabIdx);
 | 
			
		||||
		if (sh == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		DataFormatter formatter = new DataFormatter();
 | 
			
		||||
		int iMaxColumns = 0;
 | 
			
		||||
		List<List<String>> data = new ArrayList<List<String>>();
 | 
			
		||||
		for (int i = 0; i <= sh.getLastRowNum(); i++) {
 | 
			
		||||
			Row r = sh.getRow(i);
 | 
			
		||||
			if (r == null)
 | 
			
		||||
				continue;
 | 
			
		||||
			List<String> listColumns = new ArrayList<String>();
 | 
			
		||||
			for (int c = 0; c < r.getLastCellNum(); c++) {
 | 
			
		||||
				String sCell = "";
 | 
			
		||||
				Cell cell = r.getCell(c);
 | 
			
		||||
				try {
 | 
			
		||||
					sCell = formatter.formatCellValue(cell);
 | 
			
		||||
				} catch (Exception e) {
 | 
			
		||||
				}
 | 
			
		||||
				listColumns.add(sCell);
 | 
			
		||||
			}
 | 
			
		||||
			if (listColumns.size() > iMaxColumns)
 | 
			
		||||
				iMaxColumns = listColumns.size();
 | 
			
		||||
			data.add(listColumns);
 | 
			
		||||
		}
 | 
			
		||||
		return new CSV(null, data, iMaxColumns);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static byte[] toByteArray(Workbook _wb) {
 | 
			
		||||
		if (_wb == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		ByteArrayOutputStream os = null;
 | 
			
		||||
		try {
 | 
			
		||||
			os = new ByteArrayOutputStream();
 | 
			
		||||
			_wb.write(os);
 | 
			
		||||
			return os.toByteArray();
 | 
			
		||||
		} catch (Throwable t) {
 | 
			
		||||
			LOG.error("Failed to convert Excel Workbook to byte array", t);
 | 
			
		||||
			return null;
 | 
			
		||||
		} finally {
 | 
			
		||||
			IOUtils.closeQuietly(os);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static void writeToDisk(Workbook _wb, String _sFileName) {
 | 
			
		||||
		if (_wb == null)
 | 
			
		||||
			return;
 | 
			
		||||
		FileOutputStream os = null;
 | 
			
		||||
		try {
 | 
			
		||||
			os = new FileOutputStream(_sFileName);
 | 
			
		||||
			_wb.write(os);
 | 
			
		||||
		} catch (Throwable t) {
 | 
			
		||||
			LOG.error("Failed to write Excel Workbook to disk", t);
 | 
			
		||||
		} finally {
 | 
			
		||||
			IOUtils.closeQuietly(os);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -91,7 +91,7 @@ public class HttpPool {
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        catch (IOException _e) {
 | 
			
		||||
        catch (Exception _e) {
 | 
			
		||||
            LOG.error("Failed to make http request to " + _request.getURI().toString(), _e);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,7 @@
 | 
			
		||||
		<module>lantern-util-dao</module>
 | 
			
		||||
		<module>lantern-util-dao-ephemeral</module>
 | 
			
		||||
		<module>lantern-util-dao-mongo</module>
 | 
			
		||||
		<module>lantern-util-excel</module>
 | 
			
		||||
		<module>lantern-util-http</module>
 | 
			
		||||
		<module>lantern-util-servlet</module>
 | 
			
		||||
	</modules>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user