Java tutorial
package webserver; // 30/03 import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLDecoder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.eclipse.jetty.util.StringUtil; import org.glassfish.jersey.media.multipart.FormDataBodyPart; import org.glassfish.jersey.media.multipart.FormDataParam; import org.json.simple.JSONObject; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import com.google.common.base.Charsets; import com.mitchellbosecke.pebble.error.PebbleException; import api.ApiErrorFactory; import api.BlogPostResource; import api.NameStorageResource; import controller.Controller; import core.account.Account; import core.account.PrivateKeyAccount; import core.blockexplorer.BlockExplorer; import core.crypto.Base58; import core.crypto.Base64; import core.item.assets.AssetCls; import core.naming.Name; import core.payment.Payment; import core.transaction.ArbitraryTransaction; import core.transaction.Transaction; import core.web.BlogBlackWhiteList; import core.web.BlogProfile; import core.web.HTMLSearchResult; import core.web.NameStorageMap; import core.web.NameStorageTransactionHistory; import core.web.NavbarElements; import core.web.Profile; import core.web.ProfileHelper; import core.web.ServletUtils; import core.web.WebNameStorageHistoryHelper; import core.web.blog.BlogEntry; import database.DBSet; import database.NameMap; import lang.Lang; import ntp.NTP; import settings.Settings; import utils.APIUtils; import utils.AccountBalanceComparator; import utils.BlogUtils; import utils.DiffHelper; import utils.NameUtils; import utils.NameUtils.NameResult; import webserver.wrapper.WebAccount; import utils.Pair; import utils.PebbleHelper; import utils.Corekeys; import utils.StorageUtils; import utils.StrJSonFine; import utils.UpdateUtil; @Path("/") public class WebResource { @Context HttpServletRequest request; private static final Logger LOGGER = Logger.getLogger(WebResource.class); @GET public Response Default() { // REDIRECT return Response.status(302).header("Location", "index/main.html").build(); } public Response handleDefault() { try { String searchValue = request.getParameter("search"); PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/main.mini.html", request); if (searchValue == null) { return Response.ok(PebbleHelper.getPebbleHelper("web/main.html", request).evaluate(), "text/html; charset=utf-8").build(); } if (StringUtils.isBlank(searchValue)) { return Response.ok( pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } List<Pair<String, String>> searchResults; searchResults = NameUtils.getWebsitesByValue(searchValue); List<HTMLSearchResult> results = generateHTMLSearchresults(searchResults); pebbleHelper.getContextMap().put("searchresults", results); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } public List<HTMLSearchResult> generateHTMLSearchresults(List<Pair<String, String>> searchResults) throws IOException, PebbleException { List<HTMLSearchResult> results = new ArrayList<>(); for (Pair<String, String> result : searchResults) { String name = result.getA(); String websitecontent = result.getB(); Document htmlDoc = Jsoup.parse(websitecontent); String title = selectTitleOpt(htmlDoc); title = title == null ? "" : title; String description = selectDescriptionOpt(htmlDoc); description = description == null ? "" : description; description = StringUtils.abbreviate(description, 150); results.add(new HTMLSearchResult(title, description, name, "/" + name, "/" + name, "/namestorage:" + name, null)); } return results; } @SuppressWarnings("rawtypes") @Path("index/blockexplorer.json") @GET public Response jsonQueryMain(@Context UriInfo info) { Map output = null; try { output = BlockExplorer.getInstance().jsonQueryMain(info); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(StrJSonFine.convert(output)).build(); } @Path("index/blockexplorer") @GET public Response blockexplorer() { return blockexplorerhtml(); } @Path("index/blockexplorer.html") @GET public Response blockexplorerhtml() { String content; JSONObject langObj; String lang = request.getParameter("lang"); try { content = readFile("web/blockexplorer.html", StandardCharsets.UTF_8); } catch (IOException e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } Document doc = null; doc = Jsoup.parse(content); // Element element = doc.getElementById("menu_top_100_"); // if (element != null) element.text("werwfyrtyryrtyrtyrtyrtyrtyrtyrtytyrerwer"); // if (lang != null) { langObj = Lang.openLangFile(lang + ".json"); Elements el = doc.select("translate"); for (Element e : el) { e.text(Lang.getInstance().translate_from_langObj(e.text(), langObj)); } } return Response.ok(doc.toString(), "text/html; charset=utf-8").build(); } @Path("index/blogsearch.html") @GET public Response doBlogSearch() { String searchValue = request.getParameter("search"); try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/main.mini.html", request); if (StringUtil.isBlank(searchValue)) { return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } List<HTMLSearchResult> results = handleBlogSearch(searchValue); pebbleHelper.getContextMap().put("searchresults", results); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/nsrepopulate.html") @GET public Response doNsRepopulate() { UpdateUtil.repopulateNameStorage(70000); return error404(request, "Namestorage repopulated!"); } @Path("index/deleteunconfirmed.html") @GET public Response doDeleteUnconfirmedTxs() { Collection<Transaction> values = DBSet.getInstance().getTransactionMap().getValues(); List<PrivateKeyAccount> privateKeyAccounts = Controller.getInstance().getPrivateKeyAccounts(); for (Transaction transaction : values) { if (privateKeyAccounts.contains(transaction.getCreator())) { DBSet.getInstance().getTransactionMap().delete(transaction); } } return error404(request, "Unconfirmed transactions removed."); } @Path("index/namestorage.html") @GET public Response doNameStorage() { String name = request.getParameter("name"); String key = request.getParameter("key"); try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/namestorage.html", request); List<Name> namesAsList = new CopyOnWriteArrayList<Name>(Controller.getInstance().getNamesAsList()); pebbleHelper.getContextMap().put("names", namesAsList); Name nameobj = null; if (name != null) { nameobj = Controller.getInstance().getName(name); if (nameobj == null) { return error404(request, "You don't own this name or it is not confirmed by now!"); } } if (namesAsList.size() > 0) { if (name == null) { Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (activeProfileOpt != null) { nameobj = activeProfileOpt.getName(); } else { nameobj = namesAsList.get(0); } } String websiteOpt; if (key != null) { websiteOpt = DBSet.getInstance().getNameStorageMap().getOpt(nameobj.getName(), key); pebbleHelper.getContextMap().put("key", key); } else { websiteOpt = DBSet.getInstance().getNameStorageMap().getOpt(nameobj.getName(), Corekeys.WEBSITE.toString()); } pebbleHelper.getContextMap().put("name", nameobj.getName()); pebbleHelper.getContextMap().put("website", websiteOpt); } else { pebbleHelper.getContextMap().put("result", "<div class=\"alert alert-danger\" role=\"alert\">You need to register a name to create a website.<br></div>"); } return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/blogdirectory.html") @GET public Response doBlogdirectory() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/main.mini.html", request); List<HTMLSearchResult> results = handleBlogSearch(null); pebbleHelper.getContextMap().put("searchresults", results); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/namestoragehistory.html") @GET public Response getNameStorage() { try { String amount = request.getParameter("amount"); String name = request.getParameter("name"); Integer maxAmount = 20; try { maxAmount = Integer.valueOf(amount); } catch (Throwable e) { // then we use default! } if (StringUtils.isBlank(name)) { Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (activeProfileOpt != null) { name = activeProfileOpt.getName().getName(); } else { List<Name> namesAsList = new CopyOnWriteArrayList<Name>( Controller.getInstance().getNamesAsList()); if (namesAsList.size() > 0) { name = namesAsList.get(0).getName(); } } } name = name == null ? "" : name; PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/namestoragehistory.html", request); List<NameStorageTransactionHistory> history = WebNameStorageHistoryHelper.getHistory(name, maxAmount); pebbleHelper.getContextMap().put("history", history); pebbleHelper.getContextMap().put("name", name); pebbleHelper.getContextMap().put("amount", maxAmount); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/messaging.html") @GET public Response getMessaging() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/messaging.html", request); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @POST @Path("index/websitepreview.html") @Consumes("application/x-www-form-urlencoded") public Response previewWebsite(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { try { String website = form.getFirst("website"); website = website == null ? "" : website; return enhanceAndShowWebsite(website); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @SuppressWarnings("unchecked") @POST @Path("index/api.html") @Consumes("application/x-www-form-urlencoded") public Response createApiCall(@Context HttpServletRequest request, MultivaluedMap<String, String> form) throws IOException { String type = form.getFirst("type"); String apiurl = form.getFirst("apiurl"); String jsonContent = form.getFirst("json"); JSONObject jsonanswer = new JSONObject(); if (StringUtils.isBlank(type) || (!type.equalsIgnoreCase("get") && !type.equalsIgnoreCase("post") && !type.equalsIgnoreCase("delete"))) { jsonanswer.put("type", "apicallerror"); jsonanswer.put("errordetail", "type parameter must be post, get or delete"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .header("Access-Control-Allow-Origin", "*").entity(jsonanswer.toJSONString()).build(); } if (StringUtils.isBlank(apiurl)) { jsonanswer.put("type", "apicallerror"); jsonanswer.put("errordetail", "apiurl parameter must be correct set"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .header("Access-Control-Allow-Origin", "*").entity(jsonanswer.toJSONString()).build(); } // CREATE CONNECTION apiurl = apiurl.startsWith("/") ? apiurl.substring(1) : apiurl; URL urlToCall = new URL("http://127.0.0.1:" + Settings.getInstance().getRpcPort() + "/" + apiurl); HttpURLConnection connection = (HttpURLConnection) urlToCall.openConnection(); connection.setRequestProperty("X-FORWARDED-FOR", ServletUtils.getRemoteAddress(request)); // EXECUTE connection.setRequestMethod(type.toUpperCase()); if (type.equalsIgnoreCase("POST")) { connection.setDoOutput(true); connection.getOutputStream().write(jsonContent.getBytes(StandardCharsets.UTF_8)); connection.getOutputStream().flush(); connection.getOutputStream().close(); } // READ RESULT InputStream stream; if (connection.getResponseCode() == 400) { stream = connection.getErrorStream(); } else { stream = connection.getInputStream(); } InputStreamReader isReader = new InputStreamReader(stream, "UTF-8"); BufferedReader br = new BufferedReader(isReader); String result = br.readLine(); if (result.contains("message") && result.contains("error")) { jsonanswer.put("type", "apicallerror"); jsonanswer.put("errordetail", result); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .header("Access-Control-Allow-Origin", "*").entity(jsonanswer.toJSONString()).build(); } else { jsonanswer.put("type", "success"); jsonanswer.put("result", result); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .header("Access-Control-Allow-Origin", "*").entity(jsonanswer.toJSONString()).build(); } } @SuppressWarnings("unchecked") @POST @Path("index/encodefile.html") @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadMultipart(@FormDataParam("file") FormDataBodyPart is) throws IOException { try { InputStream valueAs = is.getValueAs(InputStream.class); byte[] byteArray = IOUtils.toByteArray(valueAs); String encode = Base64.encode(byteArray); MediaType mediaType = is.getMediaType(); String result = "data:" + mediaType.getType() + "/" + mediaType.getSubtype() + ";base64, "; result += encode; JSONObject json = new JSONObject(); if (StringUtils.isEmpty(encode)) { json.put("type", "error"); json.put("result", "You did not choose a file or the file was empty!"); } else if (checkPlainTypes(mediaType)) { json.put("type", "success"); json.put("result", new String(byteArray)); } else { json.put("type", "success"); json.put("result", result); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } return null; // prepare the response } public boolean checkPlainTypes(MediaType mediaType) { List<Pair<String, String>> pairsToCheck = new ArrayList<Pair<String, String>>(); pairsToCheck.add(new Pair<String, String>("text", "html")); pairsToCheck.add(new Pair<String, String>("text", "plain")); for (Pair<String, String> pair : pairsToCheck) { if (pair.getA().equalsIgnoreCase(mediaType.getType()) && pair.getB().equalsIgnoreCase(mediaType.getSubtype())) { return true; } } return false; } @SuppressWarnings("unchecked") @POST @Path("index/websitesave.html") @Consumes("application/x-www-form-urlencoded") public Response saveWebsite(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { String name = form.getFirst("name"); String website = form.getFirst("website"); String key = form.getFirst("key"); JSONObject json = new JSONObject(); if (key != null && !key.equalsIgnoreCase(Corekeys.WEBSITE.toString())) { if (Corekeys.isPartOf(key)) { json.put("type", "badKey"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } if (StringUtils.isBlank(name)) { json.put("type", "parametersMissing"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } // TODO Pair<String, String> websitepair; if (StringUtils.isNotBlank(key)) { websitepair = new Pair<String, String>(key, website); } else { websitepair = new Pair<String, String>(Corekeys.WEBSITE.toString(), website); } JSONObject storageJsonObject = null; if (website == null || website.isEmpty()) { storageJsonObject = StorageUtils.getStorageJsonObject(null, Collections.singletonList(StringUtils.isBlank(key) ? Corekeys.WEBSITE.toString() : key), null, null, null, null); } else { try { String source = DBSet.getInstance().getNameStorageMap().getOpt(name, websitepair.getA()); if (StringUtils.isNotBlank(source)) { String diff = DiffHelper.getDiff(source, website); if (website.length() > diff.length() && diff.length() < 3500) { websitepair.setB(diff); storageJsonObject = StorageUtils.getStorageJsonObject(null, null, null, null, null, Collections.singletonList(websitepair)); } } } catch (Throwable e) { LOGGER.error(e.getMessage(), e); } if (storageJsonObject == null) { storageJsonObject = StorageUtils.getStorageJsonObject(Collections.singletonList(websitepair), null, null, null, null, null); } } new NameStorageResource().updateEntry(storageJsonObject.toString(), name); json.put("type", "settingsSuccessfullySaved"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } @SuppressWarnings("unchecked") @POST @Path("index/settingssave.html") @Consumes("application/x-www-form-urlencoded") public Response saveProfileSettings(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { JSONObject json = new JSONObject(); try { String profileName = form.getFirst("profilename"); if (StringUtils.isBlank(profileName)) { json.put("type", "parametersMissing"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } Name name = null; name = Controller.getInstance().getName(profileName); if (name == null || !Profile.isAllowedProfileName(profileName)) { json.put("type", "profileNameisnotAllowed"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } boolean blogenable = Boolean.valueOf(form.getFirst(Corekeys.BLOGENABLE.toString())); boolean blockComments = Boolean.valueOf(form.getFirst(Corekeys.BLOGBLOCKCOMMENTS.toString())); boolean profileenable = Boolean.valueOf(form.getFirst(Corekeys.PROFILEENABLE.toString())); String titleOpt = form.getFirst(Corekeys.BLOGTITLE.toString()); titleOpt = decodeIfNotNull(titleOpt); String blogDescrOpt = form.getFirst(Corekeys.BLOGDESCRIPTION.toString()); blogDescrOpt = decodeIfNotNull(blogDescrOpt); String profileAvatarOpt = form.getFirst(Corekeys.PROFILEAVATAR.toString()); String profileBannerOpt = form.getFirst(Corekeys.PROFILEMAINGRAPHIC.toString()); String bwlistkind = form.getFirst("bwlistkind"); String blackwhitelist = form.getFirst("blackwhitelist"); blackwhitelist = URLDecoder.decode(blackwhitelist, "UTF-8"); profileAvatarOpt = decodeIfNotNull(profileAvatarOpt); profileBannerOpt = decodeIfNotNull(profileBannerOpt); Profile profile = Profile.getProfileOpt(name); profile.saveAvatarTitle(profileAvatarOpt); profile.saveProfileMainGraphicOpt(profileBannerOpt); profile.saveBlogDescription(blogDescrOpt); profile.saveBlogTitle(titleOpt); profile.setBlogEnabled(blogenable); profile.setBlockComments(blockComments); profile.setProfileEnabled(profileenable); profile.getBlogBlackWhiteList().clearList(); profile.getBlogBlackWhiteList().setWhitelist(!bwlistkind.equals("black")); String[] bwList = StringUtils.split(blackwhitelist, ";"); for (String listentry : bwList) { profile.getBlogBlackWhiteList().addAddressOrName(listentry); } try { profile.saveProfile(null); json.put("type", "settingsSuccessfullySaved"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } catch (WebApplicationException e) { json = new JSONObject(); json.put("type", "error"); json.put("error", e.getResponse().getEntity()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } catch (Throwable e) { LOGGER.error(e.getMessage(), e); json.put("type", "error"); json.put("error", e.getMessage()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } @Path("index/settings.html") @GET public Response doProfileSettings() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/settings.html", request); if (ServletUtils.isRemoteRequest(request)) { return error404(request, "This page is disabled for remote usage"); } String profileName = request.getParameter("profilename"); List<Name> namesAsList = new CopyOnWriteArrayList<Name>(Controller.getInstance().getNamesAsList()); for (Name name : namesAsList) { if (!Profile.isAllowedProfileName(name.getName())) { namesAsList.remove(name); } } pebbleHelper.getContextMap().put("names", namesAsList); handleSelectNameAndProfile(pebbleHelper, profileName, namesAsList); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } public void handleSelectNameAndProfile(PebbleHelper pebbleHelper, String profileName, List<Name> namesAsList) { Name name = null; if (profileName != null) { name = Controller.getInstance().getName(profileName); } if (namesAsList.size() > 0) { if (name == null) { Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (activeProfileOpt != null) { name = activeProfileOpt.getName(); } else { name = namesAsList.get(0); } } // WE HAVE HERE ONLY ALLOWED NAMES SO PROFILE CAN'T BE NULL HERE Profile profile = Profile.getProfileOpt(name); pebbleHelper.getContextMap().put("profile", profile); pebbleHelper.getContextMap().put("name", name); } else { pebbleHelper.getContextMap().put("result", "<div class=\"alert alert-danger translate\" role=\"alert\">" + "You need to register a name to create a profile.<br>" + "</div>"); } } public String decodeIfNotNull(String parameter) throws UnsupportedEncodingException { return parameter != null ? URLDecoder.decode(parameter, "UTF-8") : null; } @Path("index/webdirectory.html") @GET public Response doWebdirectory() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/main.mini.html", request); List<Pair<String, String>> websitesByValue = NameUtils.getWebsitesByValue(null); List<HTMLSearchResult> results = generateHTMLSearchresults(websitesByValue); pebbleHelper.getContextMap().put("searchresults", results); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/status.html") @GET public Response getStatus() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/status.html", request); pebbleHelper.getContextMap().put("walletstatus", Controller.getInstance().isWalletUnlocked() ? "<img src=\"/index/img/unlocked.png\" /> <span class=\"translate\">Wallet is unlocked</span>" : "<img src=\"/index/img/locked.png\" /> <span class=\"translate\">Wallet is locked</span>"); pebbleHelper.getContextMap().put("forgestatus", Controller.getInstance().getForgingStatus().getName()); pebbleHelper.getContextMap().put("version", "ARONICLE.com " + Controller.getInstance().getVersion()); int status = Controller.getInstance().getStatus(); String statustext = ""; //TODO this needs to be moved to another place if (Controller.getInstance().getWalletSyncHeight() > 0) { statustext = "<span class=\"translate\">Wallet Synchronizing</span> "; statustext += 100 * Controller.getInstance().getWalletSyncHeight() / Controller.getInstance().getMyHWeight(false).a + "%<br>"; statustext += "<span class=\"translate\">Height</span>: " + Controller.getInstance().getWalletSyncHeight() + "/" + Controller.getInstance().getMyHWeight(false).a + "/" + Controller.getInstance().getMaxPeerHWeight().a; } else if (status == Controller.STATUS_OK) { statustext = "OK<br>"; statustext += "<span class=\"translate\">Height</span>: " + Controller.getInstance().getMyHWeight(false).a; statustext += " <span class=\"translate\">Weight</span>: " + Controller.getInstance().getMyHWeight(false).b; } else if (status == Controller.STATUS_NO_CONNECTIONS) { statustext = "<span class=\"translate\">No connections</span><br>"; statustext += "<span class=\"translate\">Height</span>: " + Controller.getInstance().getMyHWeight(false).a; statustext += " <span class=\"translate\">Weight</span>: " + Controller.getInstance().getMyHWeight(false).b; } else if (status == Controller.STATUS_SYNCHRONIZING) { statustext = "<span class=\"translate\">Synchronizing</span> "; statustext += 100 * Controller.getInstance().getMyHWeight(false).a / Controller.getInstance().getMaxPeerHWeight().a + "%<br>"; statustext += "<span class=\"translate\">Height</span>: " + Controller.getInstance().getMyHWeight(false).a + "/" + Controller.getInstance().getMaxPeerHWeight().a; } pebbleHelper.getContextMap().put("status", statustext); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (PebbleException e) { LOGGER.error(e.getMessage(), e); return Response.status(404).build(); } } private List<HTMLSearchResult> handleBlogSearch(String blogSearchOpt) { List<HTMLSearchResult> results = new ArrayList<>(); List<BlogProfile> allEnabledBlogs = BlogUtils.getEnabledBlogs(blogSearchOpt); for (BlogProfile blogProfile : allEnabledBlogs) { String name = blogProfile.getProfile().getName().getName(); String title = blogProfile.getProfile().getBlogTitleOpt(); String description = blogProfile.getProfile().getBlogDescriptionOpt(); results.add(new HTMLSearchResult(title, description, name, "/index/blog.html?blogname=" + name, "/index/blog.html?blogname=" + name, "/namestorage:" + name, blogProfile.getFollower())); } return results; } public static String selectTitleOpt(Document htmlDoc) { String title = selectFirstElementOpt(htmlDoc, "title"); return title; } public static String selectFirstElementOpt(Document htmlDoc, String tag) { Elements titleElements = htmlDoc.select(tag); String title = null; if (titleElements.size() > 0) { title = titleElements.get(0).text(); } return title; } public static String selectDescriptionOpt(Document htmlDoc) { String result = ""; Elements descriptions = htmlDoc.select("meta[name=\"description\"]"); if (descriptions.size() > 0) { Element descr = descriptions.get(0); if (descr.hasAttr("content")) { result = descr.attr("content"); } } return result; } @Path("index/main.html") @GET public Response handleIndex() { return handleDefault(); } @Path("favicon.ico") @GET public Response favicon() { File file = new File("web/favicon.ico"); if (file.exists()) { return Response.ok(file, "image/vnd.microsoft.icon").build(); } else { return error404(request, null); } } @Path("index/favicon.ico") @GET public Response indexfavicon() { File file = new File("web/favicon.ico"); if (file.exists()) { return Response.ok(file, "image/vnd.microsoft.icon").build(); } else { return error404(request, null); } } String[] imgsArray = { "ARONICLE.com.png", "logo_header.png", "ARONICLE.com-user.png", "logo_bottom.png", "banner_01.png", "loading.gif", "00_generating.png", "01_genesis.jpg", "02_payment_in.png", "02_payment_out.png", "03_name_registration.png", "04_name_update.png", "05_name_sale.png", "06_cancel_name_sale.png", "07_name_purchase_in.png", "07_name_purchase_out.png", "08_poll_creation.jpg", "09_poll_vote.jpg", "10_arbitrary_transaction.png", "11_asset_issue.png", "12_asset_transfer_in.png", "12_asset_transfer_out.png", "13_order_creation.png", "14_cancel_order.png", "15_multi_payment_in.png", "15_multi_payment_out.png", "16_deploy_at.png", "17_message_in.png", "17_message_out.png", "asset_trade.png", "at_tx_in.png", "at_tx_out.png", "grleft.png", "grright.png", "redleft.png", "redright.png", "bar.gif", "bar_left.gif", "bar_right.gif", "locked.png", "unlocked.png" }; @Path("index/img/{filename}") @GET public Response image(@PathParam("filename") String filename) { ArrayList<String> imgs = new ArrayList<String>(); imgs.addAll(Arrays.asList(imgsArray)); int imgnum = imgs.indexOf(filename); if (imgnum == -1) { return error404(request, null); } File file = new File("web/img/" + imgs.get(imgnum)); String type = ""; switch (getFileExtention(imgs.get(imgnum))) { case "png": type = "image/png"; break; case "gif": type = "image/gif"; break; case "jpg": type = "image/jpeg"; break; } if (file.exists()) { return Response.ok(file, type).build(); } else { return error404(request, null); } } public static String getFileExtention(String filename) { int dotPos = filename.lastIndexOf(".") + 1; return filename.substring(dotPos); } @Path("index/libs/css/style.css") @GET public Response style() { File file = new File("web/libs/css/style.css"); if (file.exists()) { return Response.ok(file, "text/css").build(); } else { return error404(request, null); } } @Path("index/libs/css/sidebar.css") @GET public Response sidebarcss() { File file = new File("web/libs/css/sidebar.css"); if (file.exists()) { return Response.ok(file, "text/css").build(); } else { return error404(request, null); } } @Path("index/libs/css/timeline.css") @GET public Response timelinecss() { File file = new File("web/libs/css/timeline.css"); if (file.exists()) { return Response.ok(file, "text/css").build(); } else { return error404(request, null); } } @Path("index/libs/js/sidebar.js") @GET public Response sidebarjs() { File file = new File("web/libs/js/sidebar.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/third-party/highlight.pack.js") @GET public Response highlightpackjs() { File file = new File("web/libs/js/third-party/highlight.pack.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/third-party/github.css") @GET public Response highgitcss() { File file = new File("web/libs/js/third-party/github.css"); if (file.exists()) { return Response.ok(file, "text/css").build(); } else { return error404(request, null); } } @Path("index/libs/js/clipboard.js") @GET public Response clipboard() { File file = new File("web/libs/js/clipboard.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/explorerStatements.js") @GET public Response explorerStatements() { File file = new File("web/libs/js/explorerStatements.js"); if (file.exists()) { return Response.ok(file, "text/explorerStatements").build(); } else { return error404(request, null); } } @Path("index/libs/js/explorerTransactionsTable.js") @GET public Response explorerTransactionsTable() { File file = new File("web/libs/js/explorerTransactionsTable.js"); if (file.exists()) { return Response.ok(file, "text/explorerTransactionsTable").build(); } else { return error404(request, null); } } @Path("index/libs/js/third-party/ZeroClipboard.min.js") @GET public Response ZeroClipboardmin() { File file = new File("web/libs/js/third-party/ZeroClipboard.min.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/third-party/ZeroClipboard.swf") @GET public Response ZeroClipboard() { File file = new File("web/libs/js/third-party/ZeroClipboard.swf"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/biginteger.js") @GET public Response biginteger() { File file = new File("web/libs/js/biginteger.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/converters.js") @GET public Response converters() { File file = new File("web/libs/js/converters.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/crypto/curve25519.js") @GET public Response curve25519() { File file = new File("web/libs/js/crypto/curve25519.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/crypto/curve25519_.js") @GET public Response curve25519_() { File file = new File("web/libs/js/crypto/curve25519_.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/crypto/3rdparty/cryptojs/sha256.js") @GET public Response sha256() { File file = new File("web/libs/js/crypto/3rdparty/cryptojs/sha256.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @SuppressWarnings("unchecked") @POST @Path("index/postblogprocessing.html") @Consumes("application/x-www-form-urlencoded") public Response postBlogProcessing(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { JSONObject json = new JSONObject(); String title = form.getFirst(BlogPostResource.TITLE_KEY); String creator = form.getFirst("creator"); String contentparam = form.getFirst("content"); String preview = form.getFirst("preview"); String blogname = form.getFirst(BlogPostResource.BLOGNAME_KEY); String postid = form.getFirst(BlogPostResource.COMMENT_POSTID_KEY); if (StringUtil.isNotBlank(creator) && StringUtil.isNotBlank(contentparam)) { JSONObject jsonBlogPost = new JSONObject(); Pair<Account, NameResult> nameToAdress = NameUtils.nameToAdress(creator); String authorOpt = null; if (nameToAdress.getB() == NameResult.OK) { authorOpt = creator; jsonBlogPost.put(BlogPostResource.AUTHOR, authorOpt); jsonBlogPost.put("creator", nameToAdress.getA().getAddress()); } else { jsonBlogPost.put("creator", creator); } jsonBlogPost.put("title", title); jsonBlogPost.put("body", contentparam); if (StringUtils.isNotBlank(preview) && preview.equals("true")) { json.put("type", "preview"); BlogEntry entry = new BlogEntry(title, contentparam, authorOpt, new Date().getTime(), creator, "", blogname); json.put("previewBlogpost", entry.toJson()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } try { jsonBlogPost.put("fee", /* Controller .getInstance() .calcRecommendedFeeForArbitraryTransaction( jsonBlogPost.toJSONString().getBytes(StandardCharsets.UTF_8), null) .getA().toPlainString() */ 0); String result; //COMMENT OR REAL BLOGPOST? if (postid != null) { jsonBlogPost.put(BlogPostResource.COMMENT_POSTID_KEY, postid); result = new BlogPostResource().commentBlogEntry(jsonBlogPost.toJSONString()); } else { result = new BlogPostResource().addBlogEntry(jsonBlogPost.toJSONString(), blogname); } json.put("type", "postSuccessful"); json.put("result", result); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } catch (WebApplicationException e) { json = new JSONObject(); json.put("type", "error"); json.put("error", e.getResponse().getEntity()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } @Path("index/postcomment.html") @GET public Response postComment() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/postblog.html", request); pebbleHelper.getContextMap().put("errormessage", ""); pebbleHelper.getContextMap().put("font", ""); pebbleHelper.getContextMap().put("content", ""); pebbleHelper.getContextMap().put("option", ""); pebbleHelper.getContextMap().put("oldtitle", ""); pebbleHelper.getContextMap().put("oldcreator", ""); pebbleHelper.getContextMap().put("oldcontent", ""); pebbleHelper.getContextMap().put("oldfee", ""); pebbleHelper.getContextMap().put("preview", ""); List<Account> resultingAccounts; /** * Currently we allow all names and accounts, that needs to be restricted later */ if (Controller.getInstance().doesWalletDatabaseExists()) { resultingAccounts = new ArrayList<Account>(Controller.getInstance().getAccounts()); } else { resultingAccounts = new ArrayList<Account>(); } List<Name> resultingNames = new ArrayList<Name>(Controller.getInstance().getNamesAsList()); for (Name name : resultingNames) { // No balance account not shown if (name.getOwner().getConfBalance3(0, Transaction.FEE_KEY).a.compareTo(BigDecimal.ZERO) <= 0) { resultingNames.remove(name); } } for (Account account : resultingAccounts) { if (account.getConfBalance3(0, Transaction.FEE_KEY).a.compareTo(BigDecimal.ZERO) <= 0) { resultingAccounts.remove(account); } } // Pair<List<Account>, List<Name>> accountdAndNames = new Pair<List<Account>, List<Name>>(resultingAccounts, // resultingNames); Collections.sort(resultingAccounts, new AccountBalanceComparator()); Collections.reverse(resultingAccounts); String accountStrings = ""; for (Name name : resultingNames) { accountStrings += "<option value=" + name.getName() + ">" + name.getNameBalanceString() + "</option>"; } for (Account account : resultingAccounts) { accountStrings += "<option value=" + account.getAddress() + ">" + account + "</option>"; } // are we allowed to post if (resultingNames.size() == 0 && resultingAccounts.size() == 0) { pebbleHelper.getContextMap().put("errormessage", "<div id=\"result\"><div class=\"alert alert-dismissible alert-danger\" role=\"alert\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">x</button>You can't post to this blog! None of your accounts has balance or the blog owner did not allow your accounts to post!<br></div></div>"); } Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (activeProfileOpt != null && resultingNames.contains(activeProfileOpt.getName())) { pebbleHelper.getContextMap().put("primaryname", activeProfileOpt.getName().getName()); } pebbleHelper.getContextMap().put("option", accountStrings); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/postblog.html") @GET public Response postBlog() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/postblog.html", request); pebbleHelper.getContextMap().put("errormessage", ""); pebbleHelper.getContextMap().put("font", ""); pebbleHelper.getContextMap().put("content", ""); pebbleHelper.getContextMap().put("option", ""); pebbleHelper.getContextMap().put("oldtitle", ""); pebbleHelper.getContextMap().put("oldcreator", ""); pebbleHelper.getContextMap().put("oldcontent", ""); pebbleHelper.getContextMap().put("oldfee", ""); pebbleHelper.getContextMap().put("preview", ""); String blogname = request.getParameter(BlogPostResource.BLOGNAME_KEY); BlogBlackWhiteList blogBlackWhiteList = BlogBlackWhiteList.getBlogBlackWhiteList(blogname); Pair<List<Account>, List<Name>> ownAllowedElements = blogBlackWhiteList.getOwnAllowedElements(true); List<Account> resultingAccounts = new ArrayList<Account>(ownAllowedElements.getA()); List<Name> resultingNames = ownAllowedElements.getB(); Collections.sort(resultingAccounts, new AccountBalanceComparator()); Collections.reverse(resultingAccounts); String accountStrings = ""; for (Name name : resultingNames) { accountStrings += "<option value=" + name.getName() + ">" + name.getNameBalanceString() + "</option>"; } for (Account account : resultingAccounts) { accountStrings += "<option value=" + account.getAddress() + ">" + account + "</option>"; } // are we allowed to post if (resultingNames.size() == 0 && resultingAccounts.size() == 0) { pebbleHelper.getContextMap().put("errormessage", "<div id=\"result\"><div class=\"alert alert-dismissible alert-danger\" role=\"alert\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">x</button>You can't post to this blog! None of your accounts has balance or the blog owner did not allow your accounts to post!<br></div></div>"); } Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (activeProfileOpt != null && resultingNames.contains(activeProfileOpt.getName())) { pebbleHelper.getContextMap().put("primaryname", activeProfileOpt.getName().getName()); } pebbleHelper.getContextMap().put("option", accountStrings); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @SuppressWarnings("unchecked") @POST @Path("index/followblog.html") @Consumes("application/x-www-form-urlencoded") public Response followBlog(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { try { JSONObject json = new JSONObject(); String blogname = form.getFirst(BlogPostResource.BLOGNAME_KEY); String followString = form.getFirst("follow"); NameMap nameMap = DBSet.getInstance().getNameMap(); Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (followString != null && activeProfileOpt != null && blogname != null && nameMap.contains(blogname)) { boolean follow = Boolean.valueOf(followString); Name name = nameMap.get(blogname); Profile profile = Profile.getProfileOpt(name); if (activeProfileOpt.isProfileEnabled()) { if (follow) { if (profile != null && profile.isProfileEnabled() && profile.isBlogEnabled()) { String result; if (activeProfileOpt.getFollowedBlogs().contains(blogname)) { result = "<center><div class=\"alert alert-danger\" role=\"alert\">Blog follow not successful<br>" + "You already follow this blog" + "</div></center>"; json.put("type", "youAlreadyFollowThisBlog"); json.put("follower", profile.getFollower().size()); json.put("isFollowing", activeProfileOpt.getFollowedBlogs().contains(blogname)); return Response.status(200) .header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } // Prevent following of own profiles if (Controller.getInstance().getNamesAsListAsString().contains(blogname)) { result = "<center><div class=\"alert alert-danger\" role=\"alert\">Blog follow not successful<br>" + "You can't follow your own profiles" + "</div></center>"; json.put("type", "youCantFollowYourOwnProfiles"); json.put("follower", profile.getFollower().size()); json.put("isFollowing", activeProfileOpt.getFollowedBlogs().contains(blogname)); return Response.status(200) .header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } boolean isFollowing = activeProfileOpt.getFollowedBlogs().contains(blogname); try { activeProfileOpt.addFollowedBlog(blogname); result = activeProfileOpt.saveProfile(null); result = "<div class=\"alert alert-success\" role=\"alert\">You follow this blog now<br>" + result + "</div>"; json.put("type", "YouFollowThisBlogNow"); json.put("result", result); json.put("follower", profile.getFollower().size()); json.put("isFollowing", activeProfileOpt.getFollowedBlogs().contains(blogname)); } catch (WebApplicationException e) { result = "<center><div class=\"alert alert-danger\" role=\"alert\">Blog follow not successful<br>" + e.getResponse().getEntity() + "</div></center>"; json.put("type", "BlogFollowNotSuccessful"); json.put("result", e.getResponse().getEntity()); json.put("follower", profile.getFollower().size()); json.put("isFollowing", isFollowing); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } else { boolean isFollowing = activeProfileOpt.getFollowedBlogs().contains(blogname); if (activeProfileOpt.getFollowedBlogs().contains(blogname)) { activeProfileOpt.removeFollowedBlog(blogname); String result; try { result = activeProfileOpt.saveProfile(null); result = "<div class=\"alert alert-success\" role=\"alert\">Unfollow successful<br>" + result + "</div>"; json.put("type", "unfollowSuccessful"); json.put("result", result); json.put("follower", profile.getFollower().size()); json.put("isFollowing", activeProfileOpt.getFollowedBlogs().contains(blogname)); } catch (WebApplicationException e) { result = "<center><div class=\"alert alert-danger\" role=\"alert\">Blog unfollow not successful<br>" + e.getResponse().getEntity() + "</div></center>"; json.put("type", "blogUnfollowNotSuccessful"); json.put("result", e.getResponse().getEntity()); json.put("follower", profile.getFollower().size()); json.put("isFollowing", isFollowing); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } } } return getBlog(null); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return Response.status(200).header("Content-Type", "application/json; charset=utf-8").entity("{}") .build(); } } @SuppressWarnings("unchecked") @POST @Path("index/deletecomment.html") @Consumes("application/x-www-form-urlencoded") public Response deleteComment(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { JSONObject jsonanswer = new JSONObject(); try { String signature = form.getFirst("signature"); if (signature != null) { BlogEntry blogEntryOpt = BlogUtils.getCommentBlogEntryOpt(signature); if (blogEntryOpt == null) { // TODO put this snippet in method jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "The comment you are trying to delete does not exist!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } if (!Controller.getInstance().doesWalletDatabaseExists()) { jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "You don't have a wallet!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } String creator = BlogUtils.getCreatorOrBlogOwnerOpt(blogEntryOpt); if (creator == null) { jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "You are not allowed to delete this comment! You need to be the owner of the blog or author of the comment!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } try { String result = new BlogPostResource().deleteCommentEntry(signature); jsonanswer.put("type", "deleteSuccessful"); jsonanswer.put("result", result); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } catch (WebApplicationException e) { jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", e.getResponse().getEntity()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } } jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "the signature parameter must be set!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", e.getMessage()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } } @SuppressWarnings("unchecked") @POST @Path("index/deletepost.html") @Consumes("application/x-www-form-urlencoded") public Response deletePost(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { JSONObject jsonanswer = new JSONObject(); try { String signature = form.getFirst("signature"); if (signature != null) { BlogEntry blogEntryOpt = BlogUtils.getBlogEntryOpt(signature); if (blogEntryOpt == null) { // TODO put this snippet in method jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "The blog entry you are trying to delete does not exist!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } if (!Controller.getInstance().doesWalletDatabaseExists()) { jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "You don't have a wallet!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } String creator = blogEntryOpt.getCreator(); Account accountByAddress = Controller.getInstance().getAccountByAddress(creator); String blognameOpt = blogEntryOpt.getBlognameOpt(); // Did I create that blogpost? JSONObject jsonBlogPost = new JSONObject(); jsonBlogPost.put(BlogPostResource.DELETE_KEY, signature); jsonBlogPost.put("body", "delete"); if (accountByAddress != null) { /* // TODO create blogpost json in method --> move to BlogUtils // (for every kind delete/share and so on) jsonBlogPost.put("creator", creator); Pair<BigDecimal, Integer> fee = Controller.getInstance() .calcRecommendedFeeForArbitraryTransaction( jsonBlogPost.toJSONString().getBytes(StandardCharsets.UTF_8), null ); jsonBlogPost.put("fee", fee.getA().toPlainString()); */ jsonBlogPost.put("fee", 0); // I am not author, but am I the owner of the blog? } else if (blognameOpt != null && Controller.getInstance().getNamesAsListAsString().contains(blognameOpt)) { Name name = DBSet.getInstance().getNameMap().get(blognameOpt); jsonBlogPost.put("creator", name.getOwner().getAddress()); jsonBlogPost.put(BlogPostResource.AUTHOR, blognameOpt); } else { jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "You are not allowed to delete this post! You need to be owner of the blog or author of the blogpost!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } try { String result = new BlogPostResource().addBlogEntry(jsonBlogPost.toJSONString(), null); jsonanswer.put("type", "deleteSuccessful"); jsonanswer.put("result", result); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } catch (WebApplicationException e) { jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", e.getResponse().getEntity()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } } jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", "the signature parameter must be set!"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); jsonanswer.put("type", "deleteError"); jsonanswer.put("errordetail", e.getMessage()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(jsonanswer.toJSONString()).build(); } } @SuppressWarnings("unchecked") @POST @Path("index/sharepost.html") @Consumes("application/x-www-form-urlencoded") public Response sharePost(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { JSONObject json = new JSONObject(); // TODO CHANGE ERROR RETURNING --> less html code! see delete post and // also processlike! try { String signature = form.getFirst("signature"); String sourceBlog = form.getFirst("blogname"); Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (activeProfileOpt != null && signature != null && sourceBlog != null) { if (activeProfileOpt.isProfileEnabled()) { if (!activeProfileOpt.isBlogEnabled()) { json.put("type", "BlogIsDisabled"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } List<String> list = DBSet.getInstance().getSharedPostsMap().get(Base58.decode(signature)); if (list != null && list.contains(activeProfileOpt.getName().getName())) { json.put("type", "YouAlreadySharedThisPost"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } if (activeProfileOpt.getName().getName().equals(sourceBlog)) { json.put("type", "YouCantShareYourOwnPosts"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } JSONObject jsonBlogPost = new JSONObject(); String profileName = activeProfileOpt.getName().getName(); jsonBlogPost.put(BlogPostResource.AUTHOR, profileName); jsonBlogPost.put("creator", activeProfileOpt.getName().getOwner().getAddress()); jsonBlogPost.put(BlogPostResource.SHARE_KEY, signature); jsonBlogPost.put("body", "share"); /* Pair<BigDecimal, Integer> fee = Controller.getInstance() .calcRecommendedFeeForArbitraryTransaction( jsonBlogPost.toJSONString().getBytes(StandardCharsets.UTF_8), null); jsonBlogPost.put("fee", fee.getA().toPlainString()); */ jsonBlogPost.put("fee", "0.0"); try { String result = new BlogPostResource().addBlogEntry(jsonBlogPost.toJSONString(), profileName); json.put("type", "ShareSuccessful"); json.put("result", result); } catch (WebApplicationException e) { json.put("type", "ShareNotSuccessful"); json.put("result", e.getResponse().getEntity()); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } } catch (Throwable e) { LOGGER.error(e.getMessage(), e); json.put("type", "error"); json.put("error", e.getMessage()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8").entity("{}").build(); } @SuppressWarnings("unchecked") @POST @Path("index/likepost.html") @Consumes("application/x-www-form-urlencoded") public Response likePost(@Context HttpServletRequest request, MultivaluedMap<String, String> form) { JSONObject json = new JSONObject(); try { String signature = form.getFirst("signature"); String likeString = form.getFirst("like"); Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); if (likeString != null && activeProfileOpt != null) { boolean like = Boolean.valueOf(likeString); if (activeProfileOpt.isProfileEnabled()) { if (like) { String result; if (activeProfileOpt.getLikedPosts().contains(signature)) { json.put("type", "YouAlreadyLikeThisPost"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } BlogEntry blogEntryOpt = BlogUtils.getBlogEntryOpt((ArbitraryTransaction) Controller .getInstance().getTransaction(Base58.decode(signature))); boolean ownPost = false; if (blogEntryOpt != null) { if (Controller.getInstance().getAccountByAddress(blogEntryOpt.getCreator()) != null) { ownPost = true; } } if (ownPost) { json.put("type", "YouCantLikeYourOwnPosts"); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } activeProfileOpt.addLikePost(signature); try { String creator = blogEntryOpt.getCreator(); List<Payment> payments = new ArrayList<>(); if (creator != null) { BigDecimal amount = BigDecimal.TEN; amount = amount.setScale(8); payments.add(new Payment(new Account(creator), AssetCls.FEE_KEY, amount)); } result = activeProfileOpt.saveProfile(payments); json.put("type", "LikeSuccessful"); json.put("result", result); } catch (WebApplicationException e) { json.put("type", "LikeNotSuccessful"); json.put("result", e.getResponse().getEntity()); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } else { if (activeProfileOpt.getLikedPosts().contains(signature)) { activeProfileOpt.removeLikeProfile(signature); String result; try { result = activeProfileOpt.saveProfile(null); json.put("type", "LikeRemovedSuccessful"); json.put("result", result); } catch (WebApplicationException e) { json.put("type", "LikeRemovedNotSuccessful"); json.put("result", e.getResponse().getEntity()); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } } } } } catch (Throwable e) { LOGGER.error(e.getMessage(), e); json.put("type", "error"); json.put("error", e.getMessage()); return Response.status(200).header("Content-Type", "application/json; charset=utf-8") .entity(json.toJSONString()).build(); } return Response.status(200).header("Content-Type", "application/json; charset=utf-8").entity("{}").build(); } @Path("index/showpost.html") @GET public Response showPost() { try { String msg = request.getParameter("msg"); PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/blog.html", request, NavbarElements.NoNavbar); pebbleHelper.getContextMap().put("hideprofile", true); pebbleHelper.getContextMap().put("blogenabled", true); if (StringUtils.isEmpty(msg)) { return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } if (msg != null) { pebbleHelper.getContextMap().put("msg", msg); } BlogEntry blogEntryOpt = BlogUtils.getBlogEntryOpt(Base58.decode(msg)); if (blogEntryOpt == null) { // TODO SHOW NOT FOUND MESSAGE return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); String signature = blogEntryOpt.getSignature(); addSharingAndLiking(blogEntryOpt, signature); if (activeProfileOpt != null) { blogEntryOpt.setLiking(activeProfileOpt.getLikedPosts().contains(signature)); } pebbleHelper.getContextMap().put("blogposts", Arrays.asList(blogEntryOpt)); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/mergedblog.html") @GET public Response mergedBlog() { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/blog.html", request, NavbarElements.BlogNavbar); String blogname = request.getParameter(BlogPostResource.BLOGNAME_KEY); String msg = request.getParameter("msg"); if (msg != null) { pebbleHelper.getContextMap().put("msg", msg); } Profile profile = null; if (blogname == null) { Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); profile = activeProfileOpt; } else { profile = Profile.getProfileOpt(blogname); } if (profile == null || !profile.isProfileEnabled()) { pebbleHelper = PebbleHelper.getPebbleHelper("web/profiledisabled.html", request); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } pebbleHelper.getContextMap().put("postblogurl", "postblog.html?blogname=" + blogname); pebbleHelper.getContextMap().put("blogprofile", profile); pebbleHelper.getContextMap().put("blogenabled", true); pebbleHelper.getContextMap().put("hideprofile", true); List<String> followedBlogs = new ArrayList<String>(profile.getFollowedBlogs()); followedBlogs.add(profile.getName().getName()); List<BlogEntry> blogPosts = BlogUtils.getBlogPosts(followedBlogs); Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); for (BlogEntry blogEntry : blogPosts) { String signature = blogEntry.getSignature(); addSharingAndLiking(blogEntry, signature); if (activeProfileOpt != null) { blogEntry.setLiking(activeProfileOpt.getLikedPosts().contains(signature)); } } pebbleHelper.getContextMap().put("blogposts", blogPosts); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } public static void addSharingAndLiking(BlogEntry blogEntry, String signature) { List<String> list = DBSet.getInstance().getSharedPostsMap().get(Base58.decode(blogEntry.getSignature())); if (list != null) { for (String name : list) { blogEntry.addSharedUser(name); } } NameStorageMap nameStorageMap = DBSet.getInstance().getNameStorageMap(); Set<String> keys = nameStorageMap.getKeys(); for (String name : keys) { Profile profileOpt = Profile.getProfileOpt(name); if (profileOpt != null) { if (profileOpt.getLikedPosts().contains(signature)) { blogEntry.addLikingUser(profileOpt.getName().getName()); } } } } @Path("index/hashtag.html") @GET public Response getHashTagPosts() { try { String hashtag = request.getParameter("hashtag"); String msg = request.getParameter("msg"); PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/blog.html", request, NavbarElements.Searchnavbar); pebbleHelper.getContextMap().put("hideprofile", true); pebbleHelper.getContextMap().put("blogenabled", true); hashtag = hashtag == null ? "" : hashtag; if (StringUtils.isEmpty(hashtag)) { return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } hashtag = hashtag.toLowerCase(); hashtag = "#" + hashtag; if (msg != null) { pebbleHelper.getContextMap().put("msg", msg); } List<BlogEntry> blogPosts = BlogUtils.getHashTagPosts(hashtag); Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); for (BlogEntry blogEntry : blogPosts) { String signature = blogEntry.getSignature(); addSharingAndLiking(blogEntry, signature); if (activeProfileOpt != null) { blogEntry.setLiking(activeProfileOpt.getLikedPosts().contains(signature)); } } pebbleHelper.getContextMap().put("blogposts", blogPosts); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/blog.html") @GET public Response getBlog(@PathParam("messageOpt") String messageOpt) { try { String blogname = request.getParameter(BlogPostResource.BLOGNAME_KEY); String switchprofile = request.getParameter("switchprofile"); String disconnect = request.getParameter("disconnect"); String msg = request.getParameter("msg"); if (StringUtils.isNotBlank(disconnect)) { ProfileHelper.getInstance().disconnect(); } else { ProfileHelper.getInstance().switchProfileOpt(switchprofile); } PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/blog.html", request, NavbarElements.BlogNavbar); pebbleHelper.getContextMap().put("namestoragemap", NameStorageWebResource.getInstance()); pebbleHelper.getContextMap().put("postblogurl", "postblog.html"); pebbleHelper.getContextMap().put("apimessage", messageOpt); if (msg != null) { pebbleHelper.getContextMap().put("msg", msg); } NameMap nameMap = DBSet.getInstance().getNameMap(); if (blogname != null) { if (!nameMap.contains(blogname)) { return Response.ok(PebbleHelper.getPebbleHelper("web/profiledisabled.html", request).evaluate(), "text/html; charset=utf-8").build(); } Name name = nameMap.get(blogname); Profile profile = Profile.getProfileOpt(name); if (profile == null || !profile.isProfileEnabled()) { pebbleHelper = PebbleHelper.getPebbleHelper("web/profiledisabled.html", request); if (Controller.getInstance().getAccountByAddress(name.getOwner().getAddress()) != null) { pebbleHelper.getContextMap().put("ownProfileName", blogname); } return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } pebbleHelper.getContextMap().put("postblogurl", "postblog.html?blogname=" + blogname); pebbleHelper.getContextMap().put("blogprofile", profile); pebbleHelper.getContextMap().put("blogenabled", profile.isBlogEnabled()); if (Controller.getInstance().doesWalletDatabaseExists()) { if (Controller.getInstance().getAccountByAddress(name.getOwner().getAddress()) != null) { pebbleHelper.getContextMap().put("ownProfileName", blogname); } } pebbleHelper.getContextMap().put("follower", profile.getFollower()); } else { pebbleHelper.getContextMap().put("hideprofile", true); pebbleHelper.getContextMap().put("blogenabled", true); } Profile activeProfileOpt = ProfileHelper.getInstance().getActiveProfileOpt(request); pebbleHelper.getContextMap().put("isFollowing", activeProfileOpt != null && activeProfileOpt.getFollowedBlogs().contains(blogname)); pebbleHelper.getContextMap().put("isLikeing", activeProfileOpt != null && activeProfileOpt.getLikedPosts().contains(blogname)); List<BlogEntry> blogPosts = BlogUtils.getBlogPosts(blogname); for (BlogEntry blogEntry : blogPosts) { String signature = blogEntry.getSignature(); addSharingAndLiking(blogEntry, signature); if (activeProfileOpt != null) { blogEntry.setLiking(activeProfileOpt.getLikedPosts().contains(signature)); } } pebbleHelper.getContextMap().put("blogposts", blogPosts); return Response.ok(pebbleHelper.evaluate(), "text/html; charset=utf-8").build(); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("index/libs/js/Base58.js") @GET public Response Base58js() { File file = new File("web/libs/js/Base58.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/common.js") @GET public Response commonjs() { File file = new File("web/libs/js/common.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("/index/libs/third-party/jquery.form.min.js") @GET public Response getFormMin() { File file = new File("web/libs/js/third-party/jquery.form.min.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/jquery/jquery.{version}.js") @GET public Response jquery(@PathParam("version") String version) { File file; if (version.equals("1")) { file = new File("web/libs/jquery/jquery-1.11.3.min.js"); } else if (version.equals("2")) { file = new File("web/libs/jquery/jquery-2.1.4.min.js"); } else { file = new File("web/libs/jquery/jquery-2.1.4.min.js"); } if (file.exists()) { return Response.ok(file, "text/javascript; charset=utf-8").build(); } else { return error404(request, null); } } @Path("index/libs/angular/angular.{version}.js") @GET public Response angular(@PathParam("version") String version) { File file; if (version.equals("1.3")) { file = new File("web/libs/angular/angular.min.1.3.15.js"); } else if (version.equals("1.4")) { file = new File("web/libs/angular/angular.min.1.4.0.js"); } else { file = new File("web/libs/angular/angular.min.1.3.15.js"); } if (file.exists()) { return Response.ok(file, "text/javascript; charset=utf-8").build(); } else { return error404(request, null); } } @Path("index/libs/bootstrap/{version}/{folder}/{filename}") @GET public Response bootstrap(@PathParam("version") String version, @PathParam("folder") String folder, @PathParam("filename") String filename) { String fullname = "web/libs/bootstrap-3.3.4-dist/"; String type = "text/html; charset=utf-8"; switch (folder) { case "css": { fullname += "css/"; type = "text/css"; switch (filename) { case "bootstrap.css": fullname += "bootstrap.css"; break; case "theme.css": fullname += "theme.css"; break; case "bootstrap.css.map": fullname += "bootstrap.css.map"; break; case "bootstrap.min.css": fullname += "bootstrap.min.css"; break; case "bootstrap-theme.css": fullname += "bootstrap-theme.css"; break; case "bootstrap-theme.css.map": fullname += "bootstrap-theme.css.mapp"; break; case "bootstrap-theme.min.css": fullname += "bootstrap-theme.min.css"; break; } break; } case "fonts": { fullname += "fonts/"; switch (filename) { case "glyphicons-halflings-regular.eot": fullname += "glyphicons-halflings-regular.eot"; type = "application/vnd.ms-fontobject"; break; case "glyphicons-halflings-regular.svg": fullname += "glyphicons-halflings-regular.svg"; type = "image/svg+xml"; break; case "glyphicons-halflings-regular.ttf": fullname += "glyphicons-halflings-regular.ttf"; type = "application/x-font-ttf"; break; case "glyphicons-halflings-regular.woff": fullname += "glyphicons-halflings-regular.woff"; type = "application/font-woff"; break; case "glyphicons-halflings-regular.woff2": fullname += "glyphicons-halflings-regular.woff2"; type = "application/font-woff"; break; } break; } case "js": { fullname += "js/"; type = "text/javascript"; switch (filename) { case "bootstrap.js": fullname += "bootstrap.js"; break; case "bootstrap.min.js": fullname += "bootstrap.js"; break; case "npm.js": fullname += "npm.js"; break; } break; } } File file = new File(fullname); if (file.exists()) { return Response.ok(file, type).build(); } else { return error404(request, null); } } @Path("index/libs/ckeditor/{folder : .+}") @GET public Response ckeditor(@PathParam("folder") String folder) { String[] files = { "adapters/jquery.js", "README.md", "CHANGES.md", "styles.js", "lang/sk.js", "lang/fi.js", "lang/it.js", "lang/he.js", "lang/uk.js", "lang/sv.js", "lang/en-ca.js", "lang/sr-latn.js", "lang/ru.js", "lang/zh-cn.js", "lang/no.js", "lang/fr.js", "lang/fa.js", "lang/da.js", "lang/mk.js", "lang/ko.js", "lang/ro.js", "lang/mn.js", "lang/tr.js", "lang/bg.js", "lang/ka.js", "lang/de.js", "lang/el.js", "lang/pt.js", "lang/af.js", "lang/eu.js", "lang/cy.js", "lang/en-au.js", "lang/hi.js", "lang/en.js", "lang/fr-ca.js", "lang/nb.js", "lang/sr.js", "lang/en-gb.js", "lang/ms.js", "lang/pl.js", "lang/is.js", "lang/lv.js", "lang/km.js", "lang/tt.js", "lang/th.js", "lang/hu.js", "lang/bn.js", "lang/zh.js", "lang/ja.js", "lang/et.js", "lang/nl.js", "lang/ar.js", "lang/eo.js", "lang/lt.js", "lang/gl.js", "lang/ku.js", "lang/cs.js", "lang/vi.js", "lang/ca.js", "lang/ug.js", "lang/fo.js", "lang/id.js", "lang/si.js", "lang/sl.js", "lang/pt-br.js", "lang/es.js", "lang/hr.js", "lang/sq.js", "lang/bs.js", "lang/gu.js", "skins/moono/dialog_ie7.css", "skins/moono/dialog_ie.css", "skins/moono/editor_iequirks.css", "skins/moono/icons_hidpi.png", "skins/moono/editor.css", "skins/moono/readme.md", "skins/moono/dialog_ie8.css", "skins/moono/editor_ie.css", "skins/moono/dialog.css", "skins/moono/icons.png", "skins/moono/dialog_iequirks.css", "skins/moono/editor_ie7.css", "skins/moono/editor_gecko.css", "skins/moono/editor_ie8.css", "skins/moono/images/spinner.gif", "skins/moono/images/arrow.png", "skins/moono/images/lock-open.png", "skins/moono/images/lock.png", "skins/moono/images/close.png", "skins/moono/images/refresh.png", "skins/moono/images/hidpi/lock-open.png", "skins/moono/images/hidpi/lock.png", "skins/moono/images/hidpi/close.png", "skins/moono/images/hidpi/refresh.png", "build-config.js", "config.js", "ckeditor.js", "LICENSE.md", "plugins/preview/preview.html", "plugins/templates/templates/default.js", "plugins/templates/templates/images/template3.gif", "plugins/templates/templates/images/template1.gif", "plugins/templates/templates/images/template2.gif", "plugins/templates/dialogs/templates.css", "plugins/templates/dialogs/templates.js", "plugins/tabletools/dialogs/tableCell.js", "plugins/icons_hidpi.png", "plugins/dialog/dialogDefinition.js", "plugins/iframe/dialogs/iframe.js", "plugins/iframe/images/placeholder.png", "plugins/liststyle/dialogs/liststyle.js", "plugins/magicline/images/icon-rtl.png", "plugins/magicline/images/icon.png", "plugins/magicline/images/hidpi/icon-rtl.png", "plugins/magicline/images/hidpi/icon.png", "plugins/image/dialogs/image.js", "plugins/image/images/noimage.png", "plugins/link/dialogs/link.js", "plugins/link/dialogs/anchor.js", "plugins/link/images/anchor.png", "plugins/link/images/hidpi/anchor.png", "plugins/flash/dialogs/flash.js", "plugins/flash/images/placeholder.png", "plugins/about/dialogs/logo_ckeditor.png", "plugins/about/dialogs/about.js", "plugins/about/dialogs/hidpi/logo_ckeditor.png", "plugins/icons.png", "plugins/div/dialogs/div.js", "plugins/specialchar/dialogs/lang/sk.js", "plugins/specialchar/dialogs/lang/fi.js", "plugins/specialchar/dialogs/lang/it.js", "plugins/specialchar/dialogs/lang/he.js", "plugins/specialchar/dialogs/lang/uk.js", "plugins/specialchar/dialogs/lang/_translationstatus.txt", "plugins/specialchar/dialogs/lang/sv.js", "plugins/specialchar/dialogs/lang/ru.js", "plugins/specialchar/dialogs/lang/zh-cn.js", "plugins/specialchar/dialogs/lang/no.js", "plugins/specialchar/dialogs/lang/fr.js", "plugins/specialchar/dialogs/lang/fa.js", "plugins/specialchar/dialogs/lang/da.js", "plugins/specialchar/dialogs/lang/ko.js", "plugins/specialchar/dialogs/lang/tr.js", "plugins/specialchar/dialogs/lang/bg.js", "plugins/specialchar/dialogs/lang/de.js", "plugins/specialchar/dialogs/lang/el.js", "plugins/specialchar/dialogs/lang/pt.js", "plugins/specialchar/dialogs/lang/af.js", "plugins/specialchar/dialogs/lang/eu.js", "plugins/specialchar/dialogs/lang/cy.js", "plugins/specialchar/dialogs/lang/en.js", "plugins/specialchar/dialogs/lang/fr-ca.js", "plugins/specialchar/dialogs/lang/nb.js", "plugins/specialchar/dialogs/lang/en-gb.js", "plugins/specialchar/dialogs/lang/pl.js", "plugins/specialchar/dialogs/lang/lv.js", "plugins/specialchar/dialogs/lang/km.js", "plugins/specialchar/dialogs/lang/tt.js", "plugins/specialchar/dialogs/lang/th.js", "plugins/specialchar/dialogs/lang/hu.js", "plugins/specialchar/dialogs/lang/zh.js", "plugins/specialchar/dialogs/lang/ja.js", "plugins/specialchar/dialogs/lang/et.js", "plugins/specialchar/dialogs/lang/nl.js", "plugins/specialchar/dialogs/lang/ar.js", "plugins/specialchar/dialogs/lang/eo.js", "plugins/specialchar/dialogs/lang/lt.js", "plugins/specialchar/dialogs/lang/gl.js", "plugins/specialchar/dialogs/lang/ku.js", "plugins/specialchar/dialogs/lang/cs.js", "plugins/specialchar/dialogs/lang/vi.js", "plugins/specialchar/dialogs/lang/ca.js", "plugins/specialchar/dialogs/lang/ug.js", "plugins/specialchar/dialogs/lang/id.js", "plugins/specialchar/dialogs/lang/si.js", "plugins/specialchar/dialogs/lang/sl.js", "plugins/specialchar/dialogs/lang/pt-br.js", "plugins/specialchar/dialogs/lang/es.js", "plugins/specialchar/dialogs/lang/hr.js", "plugins/specialchar/dialogs/lang/sq.js", "plugins/specialchar/dialogs/specialchar.js", "plugins/table/dialogs/table.js", "plugins/showblocks/images/block_address.png", "plugins/showblocks/images/block_blockquote.png", "plugins/showblocks/images/block_pre.png", "plugins/showblocks/images/block_h2.png", "plugins/showblocks/images/block_h3.png", "plugins/showblocks/images/block_h1.png", "plugins/showblocks/images/block_h4.png", "plugins/showblocks/images/block_h6.png", "plugins/showblocks/images/block_div.png", "plugins/showblocks/images/block_p.png", "plugins/showblocks/images/block_h5.png", "plugins/find/dialogs/find.js", "plugins/smiley/dialogs/smiley.js", "plugins/smiley/images/lightbulb.gif", "plugins/smiley/images/cry_smile.png", "plugins/smiley/images/heart.gif", "plugins/smiley/images/thumbs_up.png", "plugins/smiley/images/wink_smile.png", "plugins/smiley/images/teeth_smile.gif", "plugins/smiley/images/teeth_smile.png", "plugins/smiley/images/heart.png", "plugins/smiley/images/regular_smile.gif", "plugins/smiley/images/cry_smile.gif", "plugins/smiley/images/shades_smile.gif", "plugins/smiley/images/embarrassed_smile.png", "plugins/smiley/images/broken_heart.gif", "plugins/smiley/images/shades_smile.png", "plugins/smiley/images/sad_smile.gif", "plugins/smiley/images/omg_smile.gif", "plugins/smiley/images/regular_smile.png", "plugins/smiley/images/angel_smile.png", "plugins/smiley/images/devil_smile.png", "plugins/smiley/images/kiss.gif", "plugins/smiley/images/whatchutalkingabout_smile.gif", "plugins/smiley/images/omg_smile.png", "plugins/smiley/images/envelope.gif", "plugins/smiley/images/confused_smile.png", "plugins/smiley/images/envelope.png", "plugins/smiley/images/tongue_smile.gif", "plugins/smiley/images/embarrassed_smile.gif", "plugins/smiley/images/confused_smile.gif", "plugins/smiley/images/angel_smile.gif", "plugins/smiley/images/tounge_smile.gif", "plugins/smiley/images/thumbs_down.png", "plugins/smiley/images/thumbs_up.gif", "plugins/smiley/images/lightbulb.png", "plugins/smiley/images/tongue_smile.png", "plugins/smiley/images/sad_smile.png", "plugins/smiley/images/angry_smile.gif", "plugins/smiley/images/angry_smile.png", "plugins/smiley/images/devil_smile.gif", "plugins/smiley/images/thumbs_down.gif", "plugins/smiley/images/kiss.png", "plugins/smiley/images/whatchutalkingabout_smile.png", "plugins/smiley/images/wink_smile.gif", "plugins/smiley/images/broken_heart.png", "plugins/smiley/images/embaressed_smile.gif", "plugins/forms/dialogs/textfield.js", "plugins/forms/dialogs/select.js", "plugins/forms/dialogs/hiddenfield.js", "plugins/forms/dialogs/button.js", "plugins/forms/dialogs/checkbox.js", "plugins/forms/dialogs/textarea.js", "plugins/forms/dialogs/form.js", "plugins/forms/dialogs/radio.js", "plugins/forms/images/hiddenfield.gif", "plugins/pastefromword/filter/default.js", "plugins/pagebreak/images/pagebreak.gif", "plugins/wsc/README.md", "plugins/wsc/dialogs/ciframe.html", "plugins/wsc/dialogs/wsc.css", "plugins/wsc/dialogs/wsc_ie.js", "plugins/wsc/dialogs/wsc.js", "plugins/wsc/dialogs/tmpFrameset.html", "plugins/wsc/LICENSE.md", "plugins/scayt/README.md", "plugins/scayt/dialogs/toolbar.css", "plugins/scayt/dialogs/options.js", "plugins/scayt/CHANGELOG.md", "plugins/scayt/LICENSE.md", "plugins/colordialog/dialogs/colordialog.js", "plugins/clipboard/dialogs/paste.js", "plugins/a11yhelp/dialogs/a11yhelp.js", "plugins/a11yhelp/dialogs/lang/sk.js", "plugins/a11yhelp/dialogs/lang/fi.js", "plugins/a11yhelp/dialogs/lang/it.js", "plugins/a11yhelp/dialogs/lang/he.js", "plugins/a11yhelp/dialogs/lang/uk.js", "plugins/a11yhelp/dialogs/lang/_translationstatus.txt", "plugins/a11yhelp/dialogs/lang/sv.js", "plugins/a11yhelp/dialogs/lang/sr-latn.js", "plugins/a11yhelp/dialogs/lang/ru.js", "plugins/a11yhelp/dialogs/lang/zh-cn.js", "plugins/a11yhelp/dialogs/lang/no.js", "plugins/a11yhelp/dialogs/lang/fr.js", "plugins/a11yhelp/dialogs/lang/fa.js", "plugins/a11yhelp/dialogs/lang/da.js", "plugins/a11yhelp/dialogs/lang/mk.js", "plugins/a11yhelp/dialogs/lang/ko.js", "plugins/a11yhelp/dialogs/lang/ro.js", "plugins/a11yhelp/dialogs/lang/mn.js", "plugins/a11yhelp/dialogs/lang/tr.js", "plugins/a11yhelp/dialogs/lang/bg.js", "plugins/a11yhelp/dialogs/lang/de.js", "plugins/a11yhelp/dialogs/lang/el.js", "plugins/a11yhelp/dialogs/lang/pt.js", "plugins/a11yhelp/dialogs/lang/af.js", "plugins/a11yhelp/dialogs/lang/eu.js", "plugins/a11yhelp/dialogs/lang/cy.js", "plugins/a11yhelp/dialogs/lang/hi.js", "plugins/a11yhelp/dialogs/lang/en.js", "plugins/a11yhelp/dialogs/lang/fr-ca.js", "plugins/a11yhelp/dialogs/lang/nb.js", "plugins/a11yhelp/dialogs/lang/sr.js", "plugins/a11yhelp/dialogs/lang/en-gb.js", "plugins/a11yhelp/dialogs/lang/pl.js", "plugins/a11yhelp/dialogs/lang/lv.js", "plugins/a11yhelp/dialogs/lang/km.js", "plugins/a11yhelp/dialogs/lang/tt.js", "plugins/a11yhelp/dialogs/lang/th.js", "plugins/a11yhelp/dialogs/lang/hu.js", "plugins/a11yhelp/dialogs/lang/zh.js", "plugins/a11yhelp/dialogs/lang/ja.js", "plugins/a11yhelp/dialogs/lang/et.js", "plugins/a11yhelp/dialogs/lang/nl.js", "plugins/a11yhelp/dialogs/lang/ar.js", "plugins/a11yhelp/dialogs/lang/eo.js", "plugins/a11yhelp/dialogs/lang/lt.js", "plugins/a11yhelp/dialogs/lang/gl.js", "plugins/a11yhelp/dialogs/lang/ku.js", "plugins/a11yhelp/dialogs/lang/cs.js", "plugins/a11yhelp/dialogs/lang/vi.js", "plugins/a11yhelp/dialogs/lang/ca.js", "plugins/a11yhelp/dialogs/lang/ug.js", "plugins/a11yhelp/dialogs/lang/fo.js", "plugins/a11yhelp/dialogs/lang/id.js", "plugins/a11yhelp/dialogs/lang/si.js", "plugins/a11yhelp/dialogs/lang/sl.js", "plugins/a11yhelp/dialogs/lang/pt-br.js", "plugins/a11yhelp/dialogs/lang/es.js", "plugins/a11yhelp/dialogs/lang/hr.js", "plugins/a11yhelp/dialogs/lang/sq.js", "plugins/a11yhelp/dialogs/lang/gu.js", "contents.css" }; String fullname = ""; String type = "text/plain"; File file; for (String filename : files) { if (filename.equals(folder)) { fullname = "web/libs/ckeditor/" + filename; switch (filename.substring(filename.lastIndexOf(".") + 1)) { case "js": type = "text/javascript"; break; case "css": type = "text/css"; break; case "html": type = "text/html"; break; case "txt": case "md": type = "text/plain"; break; case "png": type = "image/png"; break; case "gif": type = "image/gif"; break; } } } file = new File(fullname); if (file.exists()) { return Response.ok(file, type).build(); } else { return error404(request, null); } } @Path("index/translation.json") @GET public Response translationjson() { File file = new File("languages/" + Settings.getInstance().getLang()); if (file.exists()) { return Response.ok(file, "application/json").build(); } else { return error404(request, null); } } @Path("index/libs/js/translation.js") @GET public Response translationjs() { File file = new File("web/libs/js/translation.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } @Path("index/libs/js/third-party/qrcode.js") @GET public Response qrcodejs() { File file = new File("web/libs/js/third-party/qrcode.js"); if (file.exists()) { return Response.ok(file, "text/javascript").build(); } else { return error404(request, null); } } public Response error404(HttpServletRequest request, String titleOpt) { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/404.html", request); pebbleHelper.getContextMap().put("title", titleOpt == null ? "Sorry, that page does not exist!" : titleOpt); return Response.status(404).header("Content-Type", "text/html; charset=utf-8") .entity(pebbleHelper.evaluate()).build(); } catch (PebbleException e) { LOGGER.error(e.getMessage(), e); return Response.status(404).build(); } } public static String readFile(String path, Charset encoding) throws IOException { byte[] encoded = Files.readAllBytes(Paths.get(path)); return new String(encoded, encoding); } @SuppressWarnings("unchecked") @Path("namestorage:{name}") @GET public Response showNamestorage(@PathParam("name") String name) { try { PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper("web/main.mini.html", request); NameStorageMap nameStorageMap = DBSet.getInstance().getNameStorageMap(); Map<String, String> map = nameStorageMap.get(name); if (map != null) { Set<String> keySet = map.keySet(); JSONObject resultJson = new JSONObject(); for (String key : keySet) { String value = map.get(key); resultJson.put(key, value); } pebbleHelper.getContextMap().put("keyvaluepairs", resultJson); pebbleHelper.getContextMap().put("dataname", name); return Response.status(200).header("Content-Type", "text/html; charset=utf-8") .entity(pebbleHelper.evaluate()).build(); } else { return error404(request, "This namestorage does not contain any entries"); } } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } public String miniIndex() { try { return readFile("web/main.mini.html", StandardCharsets.UTF_8); } catch (IOException e) { LOGGER.error(e.getMessage(), e); return "ERROR"; } } @Path("/index/{html}") @GET public Response getHtml(@PathParam("html") String html) { return error404(request, null); } @Path("{name}/{key}") @GET public Response getKeyAsWebsite(@PathParam("name") String nameName, @PathParam("key") String key) { try { String website = DBSet.getInstance().getNameStorageMap().getOpt(nameName, key); if (website == null) { try { return error404(request, "This key is empty"); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } return enhanceAndShowWebsite(website); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } @Path("{name}") @GET public Response getNames(@PathParam("name") String nameName) { Name name = Controller.getInstance().getName(nameName); try { // CHECK IF NAME EXISTS if (name == null) { return error404(request, null); } String website = DBSet.getInstance().getNameStorageMap().getOpt(nameName, Corekeys.WEBSITE.toString()); if (website == null) { try { return error404(request, "This name has currently no <a href=\"/index/namestorage.html\">website<a/>!"); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } return enhanceAndShowWebsite(website); } catch (Throwable e) { LOGGER.error(e.getMessage(), e); return error404(request, null); } } private Response enhanceAndShowWebsite(String website) throws IOException, PebbleException { website = injectValues(website); File tmpFile = File.createTempFile("web", ".site"); FileUtils.writeStringToFile(tmpFile, website, Charsets.UTF_8); PebbleHelper pebbleHelper = PebbleHelper.getPebbleHelper(tmpFile.getAbsolutePath(), request); pebbleHelper.getContextMap().put("namestoragemap", NameStorageWebResource.getInstance()); // pebbleHelper.getContextMap().put("atmap",DBSet.getInstance().getATMap()); // pebbleHelper.getContextMap().put("attxsmap",DBSet.getInstance().getATTransactionMap()); pebbleHelper.getContextMap().put("ats", ATWebResource.getInstance()); pebbleHelper.getContextMap().put("controller", ControllerWebResource.getInstance()); pebbleHelper.getContextMap().put("request", this.request); tmpFile.delete(); // SHOW WEB-PAGE String evaluate = pebbleHelper.evaluate(); String pictureRegex = "data.([a-zA-Z]+).([a-zA-Z]+);base64, (.+)"; if (!evaluate.isEmpty()) { if (evaluate.matches(pictureRegex)) { String type = evaluate.replaceAll(pictureRegex, "$1"); String subtype = evaluate.replaceAll(pictureRegex, "$2"); byte[] dataOfImage = Base64.decode(evaluate.replaceAll(pictureRegex, "$3")); Response build = Response.ok(dataOfImage, type + "/" + subtype + "; charset=utf-8") .header("X-XSS-Protection", "0").build(); return build; } } Response build = Response.ok(evaluate, "text/html; charset=utf-8").header("X-XSS-Protection", "0").build(); return build; } public static String injectValues(String value) { // PROCESSING TAG INJ Pattern pattern = Pattern.compile("(?i)(<inj.*>(.*?)</inj>)"); Matcher matcher = pattern.matcher(value); while (matcher.find()) { Document doc = Jsoup.parse(matcher.group(1)); Elements inj = doc.select("inj"); Element element = inj.get(0); NameStorageMap nameMap = DBSet.getInstance().getNameStorageMap(); String name = matcher.group(2); String result = ""; if (nameMap.contains(name)) { if (element.hasAttr("key")) { String key = element.attr("key"); String opt = nameMap.getOpt(name, key); result = opt != null ? opt : ""; } } value = value.replace(matcher.group(), result); } return value; } }