Mercurial Hosting > nabble
diff src/nabble/view/web/template/NabbleNamespace.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children | 18cf4872fd7f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nabble/view/web/template/NabbleNamespace.java Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,1368 @@ +package nabble.view.web.template; + +import fschmidt.db.DbDatabase; +import fschmidt.html.Html; +import fschmidt.util.java.HtmlUtils; +import fschmidt.util.mail.AlternativeMultipartContent; +import fschmidt.util.mail.Content; +import fschmidt.util.mail.HtmlTextContent; +import fschmidt.util.mail.Mail; +import fschmidt.util.mail.MailAddress; +import fschmidt.util.mail.MailHome; +import fschmidt.util.mail.PlainTextContent; +import nabble.model.Executors; +import nabble.model.Init; +import nabble.model.Lucene; +import nabble.model.Message; +import nabble.model.ModelException; +import nabble.model.ModelHome; +import nabble.model.Node; +import nabble.model.Person; +import nabble.model.Site; +import nabble.model.SystemProperties; +import nabble.model.User; +import nabble.modules.ModuleManager; +import nabble.naml.compiler.Command; +import nabble.naml.compiler.CommandSpec; +import nabble.naml.compiler.CompileException; +import nabble.naml.compiler.Encoder; +import nabble.naml.compiler.IPrintWriter; +import nabble.naml.compiler.Interpreter; +import nabble.naml.compiler.Macro; +import nabble.naml.compiler.Meaning; +import nabble.naml.compiler.Namespace; +import nabble.naml.compiler.Program; +import nabble.naml.compiler.ScopedInterpreter; +import nabble.naml.compiler.Source; +import nabble.naml.compiler.Template; +import nabble.naml.compiler.TemplatePrintWriter; +import nabble.naml.compiler.Usage; +import nabble.naml.namespaces.BasicNamespace; +import nabble.naml.namespaces.StringList; +import nabble.naml.namespaces.TemplateException; +import nabble.view.lib.Jtp; +import nabble.view.lib.Permissions; +import nabble.view.lib.Shared; +import nabble.view.lib.help.Help; +import nabble.view.web.Javascript; +import nabble.view.web.user.OnlineStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletException; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.regex.Pattern; + + +@Namespace ( + name = "nabble", + global = true +) +public final class NabbleNamespace { + private static final Logger logger = LoggerFactory.getLogger(NabbleNamespace.class); + + public static final String newsflash = (String)Init.get("newsflash"); + + private static ThreadLocal<NabbleNamespace> tl = new ThreadLocal<NabbleNamespace>(); + + public static NabbleNamespace current() { + return tl.get(); + } + + private Site site; + + public NabbleNamespace(Site site) { + if( site == null ) + throw new NullPointerException("site is null"); + this.site = site; + tl.set(this); + } + + public Site site() { + return site; + } + + public DbDatabase db() { + return site.getDb(); + } + + public static final CommandSpec root_node = CommandSpec.DO; + + @Command public void root_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + NodeNamespace ns = new NodeNamespace(site().getRootNode()); + out.print( interp.getArg(ns,"do") ); + } + + @Command public void site_id(IPrintWriter out,Interpreter interp) { + out.print( site.getId() ); + } + + @Command public void base_url(IPrintWriter out,Interpreter interp) { + out.print( interp.encode( site.getBaseUrl() ) ); + } + + public static final CommandSpec terms_of_use_url = CommandSpec.DO() + .optionalParameters("is_registration_form") + .build() + ; + + @Command public static void terms_of_use_url(IPrintWriter out,Interpreter interp) { + boolean isRegistrationForm = interp.getArgAsBoolean("is_registration_form", false); + out.print( interp.encode(Jtp.termsUrl(isRegistrationForm))); + } + + + public static final CommandSpec javascript_string_encode = CommandSpec.TEXT; + + @Command public void javascript_string_encode(IPrintWriter out,Interpreter interp) { + out.print( HtmlUtils.javascriptStringEncode(interp.getArgString("text")) ); + } + + public static final CommandSpec break_up = CommandSpec.TEXT; + + @Command public void break_up(IPrintWriter out,Interpreter interp) { + out.print( Jtp.breakUp(interp.getArgString("text")) ); + } + + public static final CommandSpec hide_emails = CommandSpec.TEXT; + + @Command public void hide_emails(IPrintWriter out,Interpreter interp) { + Encoder encoder = interp.getEncoder(); + interp.setEncoder(Encoder.TEXT); + String text = interp.getArgString("text"); + interp.setEncoder(encoder); + out.print( interp.encode( ModelHome.hideAllEmails(text) ) ); + } + + + + @Namespace ( + name = "help_instance", + global = false + ) + public static class HelpNs { + private final Help help; + + private HelpNs(Help help) { + this.help = help; + } + + @Command public void url(IPrintWriter out,Interpreter interp) { + out.print( help.url() ); + } + + @Command public void link(IPrintWriter out,Interpreter interp) { + out.print( help.link() ); + } + } + + @Namespace ( + name = "help", + global = false + ) + public static class HelpsNs { + + private static void print(IPrintWriter out,ScopedInterpreter<HelpNs> interp,Help help) { + out.print( interp.getArg(new HelpNs(help),"do") ); + } + + @Command public void index_path(IPrintWriter out,Interpreter interp) { + out.print( interp.encode( "/help/Index.jtp" ) ); + } + + public static final CommandSpec mailing_list_intro = CommandSpec.DO; + + @Command public void mailing_list_intro(IPrintWriter out,ScopedInterpreter<HelpNs> interp) { + print(out,interp,Help.mailingListIntro); + } + + public static final CommandSpec search = CommandSpec.DO; + + @Command public void search(IPrintWriter out,ScopedInterpreter<HelpNs> interp) { + print(out,interp,Help.search); + } + + public static final CommandSpec cataloging = CommandSpec.DO; + + @Command public void cataloging(IPrintWriter out,ScopedInterpreter<HelpNs> interp) { + print(out,interp,Help.cataloging); + } + + public static final CommandSpec embed_what_how = CommandSpec.DO; + + @Command public void embed_what_how(IPrintWriter out,ScopedInterpreter<HelpNs> interp) { + print(out,interp,Help.embed_what_how); + } + + public static final CommandSpec mixed_lengths = CommandSpec.DO; + + @Command public void mixed_lengths(IPrintWriter out,ScopedInterpreter<HelpNs> interp) { + print(out,interp,Help.mixed_lengths); + } + + public static final CommandSpec password = CommandSpec.DO; + + @Command public void password(IPrintWriter out,ScopedInterpreter<HelpNs> interp) { + print(out,interp,Help.password); + } + + public static final CommandSpec userid = CommandSpec.DO; + + @Command public void userid(IPrintWriter out,ScopedInterpreter<HelpNs> interp) { + print(out,interp,Help.userid); + } + } + private static final HelpsNs helpsNs = new HelpsNs(); + + public static final CommandSpec help = CommandSpec.DO; + + @Command public void help(IPrintWriter out,ScopedInterpreter<HelpsNs> interp) { + out.print( interp.getArg(helpsNs,"do") ); + } + + + + + + public static final CommandSpec truncate = new CommandSpec.Builder() + .dotParameter("text") + .parameters("size") + .optionalParameters("if_truncated") + .build() + ; + + @Command public void truncate(IPrintWriter out,Interpreter interp) { + String text = interp.getArgString("text"); + String size = interp.getArgString("size"); + int n; + try { + n = Integer.valueOf(size); + } catch (NumberFormatException e) { + throw new RuntimeException("Invalid \"size\" attribute: " + size); + } + if (text.length() > n) { + text = text.substring(0, n-4) + "..."; + out.print(text); + Object ifTruncated = interp.getArg("if_truncated"); + if (ifTruncated != null) { + out.print(ifTruncated); + } + } else + out.print(text); + } + + + + private static final BasicNamespace.ExceptionNamespaceFactory<ErrorNamespace> myExceptionNamespaceFactory = + new BasicNamespace.ExceptionNamespaceFactory<ErrorNamespace>() { + public ErrorNamespace newExceptionNamespace(TemplateException ex) { + return new ErrorNamespace(ex); + } + } + ; + + public static final CommandSpec handle_exception = BasicNamespace.handle_exception; + + @Command public void handle_exception(IPrintWriter out,ScopedInterpreter<ErrorNamespace> interp) { + interp.getFromStack(BasicNamespace.class).handleException(out,interp,myExceptionNamespaceFactory); + } + + + @Command public static void tabs_library_path(IPrintWriter out,Interpreter interp) { + out.print( interp.encode( Shared.getTabsPath() ) ); + } + + @Command public static void nabble_global_apps_url(IPrintWriter out,Interpreter interp) { + out.print( interp.encode( Jtp.homeContextUrl() + "/UserSites.jtp" ) ); + } + + @Command public void get_newsflash(IPrintWriter out,Interpreter interp) { + out.print( newsflash ); + } + + + /** Number of pages to be displayed before/after the current page*/ + private static final int NEIGHBOR_PAGES = 3; + + public static final CommandSpec paging = new CommandSpec.Builder() + .parameters("total_rows","current_row","rows_per_page") + .scopedParameters("do") + .dotParameter("do") + .build() + ; + + @Command public void paging(IPrintWriter out,ScopedInterpreter<PagingNamespace> interp) { + int totalRows = interp.getArgAsInt("total_rows"); + int currentRow = interp.getArgAsInt("current_row",0); + int rowsPerPage = interp.getArgAsInt("rows_per_page"); + out.print( interp.getArg( new PagingNamespace(totalRows,currentRow,rowsPerPage,NEIGHBOR_PAGES), "do" ) ); + } + + + + // Basic Nabble Urls + + @Command public void nabble_homepage(IPrintWriter out,Interpreter interp) { + out.print(Jtp.homePage()); + } + + public static final CommandSpec get_int = new CommandSpec.Builder() + .parameters("exception") + .optionalParameters("default") + .dotParameter("int") + .build() + ; + + @Command public void get_int(IPrintWriter out,Interpreter interp) + throws TemplateException + { + String ex = interp.getArgString("exception"); + String s = interp.getArgString("int"); + if( s != null ) { + s = s.trim(); + if( s.length() > 0 ) { + try { + out.print( Integer.parseInt(s) ); + return; + } catch(NumberFormatException e) { + throw TemplateException.newInstance( ex ); + } + } + } + String def = interp.getArgString("default"); + if( def == null ) + throw TemplateException.newInstance( ex ); + out.print( Integer.parseInt(def) ); + } + + @Command public void site_activity(IPrintWriter out,Interpreter interp) { + out.print( site().getActivity() ); + } + + @Command public void site_has_delete_date(IPrintWriter out,Interpreter interp) { + out.print( site().getDeleteDate() != null ); + } + + public static final CommandSpec site_delete_date = CommandSpec.DO; + + @Command public void site_delete_date(IPrintWriter out,ScopedInterpreter<DateNamespace> interp) { + out.print( interp.getArg( new DateNamespace(site().getDeleteDate()), "do" ) ); + } + + public static final CommandSpec new_email = CommandSpec.DO; + + @Command public void new_email(IPrintWriter out,ScopedInterpreter<EmailNamespace> interp) { + out.print( interp.getArg( new EmailNamespace(), "do" ) ); + } + + public static final CommandSpec parse_email = new CommandSpec.Builder() + .dotParameter("text") + .build() + ; + + @Command public void parse_email(IPrintWriter out,Interpreter interp) + throws ModelException.EmailFormat + { + String email = null; + String text = interp.getArgString("text"); + if( text != null ) { + text = text.trim(); + if( text.length() > 0 ) { + int posOpen = text.indexOf('<'); + int posClose = text.indexOf('>'); + if (posOpen >= 0 && posClose > posOpen) + text = text.substring(posOpen+1, posClose).trim(); + if (!new MailAddress(text).isValid()) + throw new ModelException.EmailFormat(text); + email = text; + } + } + out.print(email); + } + + public static final CommandSpec is_valid_node= CommandSpec.DO() + .parameters("node_id") + .build() + ; + + @Command public void is_valid_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + long nodeId = interp.getArgAsLong("node_id"); + Node node = site.getNode(nodeId); + out.print(node != null); + } + + public static final CommandSpec get_node_from_id = CommandSpec.DO() + .parameters("node_id") + .build() + ; + + @Command public void get_node_from_id(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + long nodeId = interp.getArgAsLong("node_id"); + Node node = site.getNode(nodeId); + out.print( interp.getArg(new NodeNamespace(node),"do") ); + } + + public static final CommandSpec get_user_from_id = CommandSpec.DO() + .parameters("user_id") + .build(); + + @Command public void get_user_from_id(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) + throws IOException, ServletException + { + String userId = interp.getArgString("user_id"); + Person person = site().getPerson(userId); + out.print( interp.getArg(new UserNamespace(person),"do") ); + } + + public static final CommandSpec user_groups = CommandSpec.DO; + + @Command public void user_groups(IPrintWriter out,ScopedInterpreter<GroupList> interp) { + List<String> groups = Permissions.getGroups(site()); + Object block = interp.getArg(new GroupList(groups),"do"); + out.print(block); + } + + @Namespace ( + name = "group_list", + global = true + ) + public static final class GroupList extends StringList { + + GroupList(List<String> groups) { + super(groups); + } + + @Command public void current_group(IPrintWriter out,Interpreter interp) { + out.print(get()); + } + } + + public static final CommandSpec permissions = CommandSpec.DO() + .optionalParameters("values") + .build() + ; + + @Command public void permissions(IPrintWriter out,ScopedInterpreter<PermissionList> interp) + throws IOException, ServletException + { + List<String> list = new ArrayList<String>(); + String values = interp.getArgString("values"); + for( String s : values.split(",") ) { + list.add( s.trim() ); + } + Object block = interp.getArg(new PermissionList(list),"do"); + out.print(block); + } + + @Namespace ( + name = "permission_list", + global = true + ) + public static final class PermissionList extends StringList { + + PermissionList(List<String> list) { + super(list); + } + + @Command public void current_permission(IPrintWriter out,Interpreter interp) { + out.print(get()); + } + } + + + public static final CommandSpec get_node = CommandSpec.DO() + .parameters("node") + .build() + ; + + @Command public void get_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + NodeNamespace nodeNs = interp.getArgAsNamespace(NodeNamespace.class,"node"); + if( nodeNs == null ) + throw new RuntimeException("node is null"); + out.print( interp.getArg(nodeNs,"do") ); + } + + public static final CommandSpec get_user = CommandSpec.DO() + .parameters("user") + .build() + ; + + @Command public void get_user(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) { + UserNamespace userNs = interp.getArgAsNamespace(UserNamespace.class,"user"); + if( userNs == null ) { + out.print( (String)null ); + return; + } + out.print( interp.getArg(userNs,"do") ); + } + + public static final CommandSpec get_subscription = CommandSpec.DO() + .parameters("subscription") + .build() + ; + + @Command public void get_subscription(IPrintWriter out,ScopedInterpreter<SubscriptionNamespace> interp) { + SubscriptionNamespace subscriptionNs = interp.getArgAsNamespace(SubscriptionNamespace.class,"subscription"); + out.print( interp.getArg(subscriptionNs,"do") ); + } +/* +not needed yet + public static final CommandSpec get_mailing_list = CommandSpec.DO() + .parameters("mailing_list") + .build() + ; + + @Command public void get_mailing_list(IPrintWriter out,ScopedInterpreter<MailingListNamespace> interp) { + MailingListNamespace ns = interp.getArgAsNamespace(MailingListNamespace.class,"mailing_list"); + out.print( interp.getArg(ns,"do") ); + } +*/ + + + @Command public void anyone_group(IPrintWriter out,Interpreter interp) { + out.print( Permissions.ANYONE_GROUP ); + } + + @Command public void registered_group(IPrintWriter out,Interpreter interp) { + out.print( Permissions.REGISTERED_GROUP ); + } + + @Command public void authors_group(IPrintWriter out,Interpreter interp) { + out.print( Permissions.AUTHOR_GROUP ); + } + + @Command public void administrators_group(IPrintWriter out,Interpreter interp) { + out.print( Permissions.ADMINISTRATORS_GROUP ); + } + + @Command public void view_permission(IPrintWriter out,Interpreter interp) { + out.print( Permissions.VIEW_PERMISSION ); + } + + public static final CommandSpec set_default_permissions = CommandSpec.NO_OUTPUT() + .scopedParameters("do") + .dotParameter("do") + .parameters("version") + .build() + ; + + @Command public void set_default_permissions(IPrintWriter out,ScopedInterpreter<DefaultPermissionEditorNamespace> interp) { + String version = interp.getArgString("version"); + synchronized( ("permission-lock-"+site().getId()).intern() ) { + site = site.getGoodCopy(); + if( !Permissions.isPermissionVersion(site,interp.getArgString("version")) ) { + DefaultPermissionEditorNamespace ns; + while(true) { + db().beginTransaction(); + try { + Site site = this.site.getGoodCopy(); + Permissions.setPermissionVersion(site,version); + ns = new DefaultPermissionEditorNamespace(site); + interp.getArgString(ns,"do"); + db().commitTransaction(); + } finally { + db().endTransaction(); + } + site = site.getGoodCopy(); + if( ns.ok(site) ) + break; + logger.error("set_default_permissions failed for "+site+", trying again"); + } + } + } + } + + @Namespace ( + name = "default_permission_editor", + global = true + ) + public static final class DefaultPermissionEditorNamespace { + private static class PermGroup { + final String perm; + final String group; + + PermGroup(String perm,String group) { + this.perm = perm; + this.group = group; + } + } + + private final Site site; + private final List<PermGroup> permissions = new ArrayList<PermGroup>(); + private final List<PermGroup> sitePermissions = new ArrayList<PermGroup>(); + + DefaultPermissionEditorNamespace(Site site) { + this.site = site; + } + + public static final CommandSpec add_permission = CommandSpec.NO_OUTPUT() + .parameters("group","permission") + .build() + ; + + @Command public void add_permission(IPrintWriter out,Interpreter interp) { + String perm = interp.getArgString("permission"); + String group = interp.getArgString("group"); + Permissions.addPermission(site,perm,group); + permissions.add(new PermGroup(perm,group)); + } + + public static final CommandSpec add_site_permission = add_permission; + + @Command public void add_site_permission(IPrintWriter out,Interpreter interp) { + String perm = interp.getArgString("permission"); + String group = interp.getArgString("group"); + Permissions.addSiteDefaultPermission(site,perm,group); + sitePermissions.add(new PermGroup(perm,group)); + } + + boolean ok(Site site) { + for( PermGroup pg : permissions ) { + if( !Permissions.hasPermission(site,pg.group,pg.perm) ) { + logger.error("add_permission failed for "+site+" permission="+pg.perm+" group="+pg.group); + return false; + } + } + for( PermGroup pg : sitePermissions ) { + if( !Permissions.hasSiteDefaultPermission(site,pg.group,pg.perm) ) { + logger.error("add_site_permission failed for "+site+" permission="+pg.perm+" group="+pg.group); + return false; + } + } + return true; + } + } + + public static final CommandSpec save_site_permissions = CommandSpec.DO; + + @Command public void save_site_permissions(IPrintWriter out,ScopedInterpreter<SitePermissionEditorNamespace> interp) { + db().beginTransaction(); + try { + interp.getArgString(new SitePermissionEditorNamespace(site()),"do"); + db().commitTransaction(); + } finally { + db().endTransaction(); + } + } + + @Namespace ( + name = "site_permission_editor", + global = true + ) + public static final class SitePermissionEditorNamespace { + private final Site site; + + SitePermissionEditorNamespace(Site site) { + this.site = site; + } + + public static final CommandSpec remove_site_permissions = CommandSpec.NO_OUTPUT; + + @Command public void remove_site_permissions(IPrintWriter out,Interpreter interp) { + Permissions.removeSitePermissions(site); + } + + public static final CommandSpec add_site_permission = CommandSpec.NO_OUTPUT() + .parameters("permission") + .optionalParameters("group") + .build() + ; + + @Command public void add_site_permission(IPrintWriter out,Interpreter interp) { + String perm = interp.getArgString("permission"); + String group = interp.getArgString("group"); + if( group == null ) + Permissions.addSitePermission(site,perm); + else + Permissions.addSitePermission(site,perm,group); + } + + public static final CommandSpec remove_site_permission = CommandSpec.NO_OUTPUT() + .parameters("permission") + .optionalParameters("group") + .build() + ; + + @Command public void remove_site_permission(IPrintWriter out,Interpreter interp) { + String group = interp.getArgString("group"); + String perm = interp.getArgString("permission"); + if (group == null) + Permissions.removeSitePermission(site,perm); + else + Permissions.removeSitePermission(site,perm,group); + } + + } + + public static final CommandSpec has_default_permission = new CommandSpec.Builder() + .parameters("group","permission") + .build() + ; + + @Command public void has_default_permission(IPrintWriter out,Interpreter interp) { + String group = interp.getArgString("group"); + String perm = interp.getArgString("permission"); + out.print( Permissions.hasPermission(site(),group,perm) ); + } + + public static final CommandSpec has_site_default_permission = has_default_permission; + + @Command public void has_site_default_permission(IPrintWriter out,Interpreter interp) { + String group = interp.getArgString("group"); + String perm = interp.getArgString("permission"); + out.print( Permissions.hasSiteDefaultPermission(site(),group,perm) ); + } + + public static final CommandSpec group_has_site_permission = has_default_permission; + + @Command public void group_has_site_permission(IPrintWriter out,Interpreter interp) { + String group = interp.getArgString("group"); + String perm = interp.getArgString("permission"); + out.print( Permissions.hasSitePermission(site(),group,perm) ); + } + + public static final CommandSpec site_has_site_permission = new CommandSpec.Builder() + .dotParameter("permission") + .build() + ; + + @Command public void site_has_site_permission(IPrintWriter out,Interpreter interp) { + String perm = interp.getArgString("permission"); + out.print( Permissions.siteHasSitePermission(site(),perm) ); + } + + public static final CommandSpec remove_group = CommandSpec.NO_OUTPUT() + .parameters("group") + .build() + ; + + @Command public void remove_group(IPrintWriter out,Interpreter interp) { + String group = interp.getArgString("group"); + Permissions.removeGroup(site(),group); + } + + public static final CommandSpec users_in_group = CommandSpec.DO() + .parameters("group") + .build() + ; + + @Command public void users_in_group(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) { + String group = interp.getArgString("group"); + List<User> users = Permissions.getUsersInGroup(site,group); + UserNamespace.UserList usersNs = new UserNamespace.UserList(users); + out.print( interp.getArg(usersNs,"do") ); + } + + public static final CommandSpec site_users = new CommandSpec.Builder() + .parameters("length") + .optionalParameters("start", "filter") + .scopedParameters("do") + .dotParameter("do") + .outputtedParameters("do") + .build() + ; + + @Command public void site_users(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) { + int start = interp.getArgAsInt("start",0); + int length = interp.getArgAsInt("length"); + String cnd = interp.getArgString("filter"); + List<User> users = site.getUsersByNodeCount(start,length,cnd); + UserNamespace.UserList usersNs = new UserNamespace.UserList(users); + out.print( interp.getArg(usersNs,"do") ); + } + + public static final CommandSpec site_user_count = CommandSpec.DO() + .optionalParameters("filter") + .build(); + + @Command public void site_user_count(IPrintWriter out,Interpreter interp) { + String cnd = interp.getArgString("filter"); + out.print( site.getUserCount(cnd) ); + } + + @Command public void registered_filter(IPrintWriter out,Interpreter interp) { + out.print( "registered is not null" ); + } + + public static final CommandSpec online_users = CommandSpec.DO() + .optionalParameters("include_invisible_users") + .build(); + + @Command public void online_users(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) { + boolean includeInvisibleUsers = interp.getArgAsBoolean("include_invisible_users", false); + List<User> users = OnlineStatus.getOnlineUsers(site, includeInvisibleUsers); + UserNamespace.UserList usersNs = new UserNamespace.UserList(users); + out.print( interp.getArg(usersNs,"do") ); + } + + @Command public void online_anonymous_users_count(IPrintWriter out,Interpreter interp) { + out.print( OnlineStatus.getOnlineAnonymousUsersCount(site) ); + } + + @Command public void online_invisible_users_count(IPrintWriter out,Interpreter interp) { + out.print( OnlineStatus.getOnlineInvisibleUsersCount(site) ); + } + + public static final CommandSpec url_belongs_to_site = new CommandSpec.Builder() + .parameters("url") + .build() + ; + + @Command public void url_belongs_to_site(IPrintWriter out,Interpreter interp) + throws TemplateException + { + try { + String url = interp.getArgString("url"); + String domain = new URL(url).getHost(); + Long siteId = Jtp.getSiteIdFromDomain(domain); + out.print( siteId != null && siteId.longValue() == site().getId() ); + } catch(MalformedURLException e) { + throw new ModelException.InvalidPermalink(); + } + } + + public static final CommandSpec check_registered_user = new CommandSpec.Builder() + .parameters("email","password_hash") + .build() + ; + + @Command public void check_registered_user(IPrintWriter out,Interpreter interp) { + String email = interp.getArgString("email"); + String pwd = interp.getArgString("password_hash"); + User user = site.getUserFromEmail(email); + out.print( user != null && user.isRegistered() && user.checkPasscookie(pwd) ); + } + + public static final CommandSpec get_or_create_user = CommandSpec.DO() + .parameters("email") + .build() + ; + + @Command public void get_or_create_user(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) + throws ModelException.EmailFormat + { + String email = interp.getArgString("email"); + if (!new MailAddress(email).isValid()) + throw new ModelException.EmailFormat(email); + User user = site.getOrCreateUser(email); + out.print( interp.getArg(new UserNamespace(user),"do") ); + } + + public static final CommandSpec exists_user_for_email = new CommandSpec.Builder() + .dotParameter("email") + .build() + ; + + @Command public void exists_user_for_email(IPrintWriter out,Interpreter interp) + throws ModelException.EmailFormat + { + String email = interp.getArgString("email"); + User user = site.getUserFromEmail(email); + out.print( user != null ); + } + + public static final CommandSpec get_user_from_email = CommandSpec.DO() + .parameters("email") + .build() + ; + + @Command public void get_user_from_email(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) + throws ModelException.EmailFormat + { + String email = interp.getArgString("email"); + User user = site.getUserFromEmail(email); + if( user==null ) { + out.print( (String)null ); + return; + } + out.print( interp.getArg(new UserNamespace(user),"do") ); + } + + public static final CommandSpec has_authenticated_user_with_name = new CommandSpec.Builder() + .parameters("name") + .build() + ; + + @Command public void has_authenticated_user_with_name(IPrintWriter out,Interpreter interp) { + String name = interp.getArgString("name"); + out.print( site.getUserFromName(name) != null ); + } + + public static final CommandSpec get_authenticated_user_with_name = CommandSpec.DO() + .parameters("name") + .build() + ; + + @Command public void get_authenticated_user_with_name(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) + throws ModelException.EmailFormat + { + String name = interp.getArgString("name"); + User user = site.getUserFromName(name); + out.print( interp.getArg(new UserNamespace(user),"do") ); + } + + public static final CommandSpec banned_users = CommandSpec.DO; + + @Command public void banned_users(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) { + List<User> banned = Permissions.getBannedUsers(site()); + Object block = interp.getArg(new UserNamespace.UserList(banned),"do"); + out.print(block); + } + + @Command public void administrator_notice(IPrintWriter out,Interpreter interp) { + out.print( SystemProperties.get("administrator.notice") ); + } + + @Command public void administrator_notice_version(IPrintWriter out,Interpreter interp) { + String version = SystemProperties.get("administrator.notice.version"); + out.print( version == null? "0" : version ); + } + + +/* + public static final CommandSpec macro_text = new CommandSpec.Builder() + .parameters("macro") + .optionalParameters("namespace") + .build() + ; + + @Command public void macro_text(IPrintWriter out,Interpreter interp) { + String macro = interp.getArgString("macro"); + String namespace = interp.getArgString("namespace"); + out.print( site.getTemplates().source().getMacro(macro,namespace) ); + } +*/ + + + public static final CommandSpec log = new CommandSpec.Builder() + .dotParameter("text") + .outputtedParameters() + .build() + ; + + @Command public void log(IPrintWriter out,Interpreter interp) { + interp.setEncoder(Encoder.TEXT); + String text = interp.getArgString("text"); + NamlLogger.getLogger(site).log(text); + } + + @Command public void get_log(IPrintWriter out,Interpreter interp) { + out.print( interp.encode( NamlLogger.getLogger(site).getLog() ) ); + } + + public static final CommandSpec clear_log = CommandSpec.NO_OUTPUT; + + @Command public void clear_log(IPrintWriter out,Interpreter interp) { + NamlLogger.removeLogger(site); + } + + + @Command public void lucene_is_ready(IPrintWriter out,Interpreter interp) { + out.print( Lucene.isReady(site) ); + } + + @Command public void support_url(IPrintWriter out,Interpreter interp) { + out.print( Jtp.supportUrl() ); + } + + @Command public void dot_pack(IPrintWriter out,Interpreter interp) { + } + + + + + + public static final CommandSpec call_later = new CommandSpec.Builder() + .dotParameter("param") + .optionalParameters("value") + .build() + ; + + private Map<String,Set<String>> callLaterMap = new LinkedHashMap<String,Set<String>>(); + + @Command public void call_later(IPrintWriter out,Interpreter interp) { + String param = interp.getArgString("param"); + Set<String> values = callLaterMap.get(param); + if( values == null ) { + values = new LinkedHashSet<String>(); + callLaterMap.put(param,values); + } + String value = interp.getArgString("value"); + if( value == null ) + value = ""; + values.add(value); + } + + private static final int JS_PATH_LIM = 1200; + + @Command public void load_call_later_script(IPrintWriter out,Interpreter interp) + throws IOException, ServletException + { + if( !callLaterMap.isEmpty() ) { + String jsPath = "/template/NamlServlet.jtp?macro=js_page"; + StringBuilder path = new StringBuilder(); + path.append(jsPath); + for (Map.Entry<String, Set<String>> entry : callLaterMap.entrySet()) { + String param = entry.getKey(); + Set<String> values = entry.getValue(); + boolean isFirst = true; + for (String value : values) { + if (path.length() > JS_PATH_LIM) { + loadScript(out,path); + path.setLength(0); + path.append(jsPath); + isFirst = true; + } + if( isFirst ) { + path.append('&').append(param).append('='); + isFirst = false; + } else { + path.append('|'); + } + path.append(HtmlUtils.urlEncode(HtmlUtils.urlEncode(value))); + } + } + loadScript(out,path); + } + callLaterMap = null; + } + + private static void loadScript(IPrintWriter out,Object path) { + out.print( "<script type='text/javascript'>\n" ); + out.print( "var scriptUrl = '" + path + "';\n" ); + out.print( "scriptUrl += '&_=' + Math.floor(Math.random()*9999);\n" ); + out.print( "$.getScript(scriptUrl, function() { Nabble.resizeFrames(); });\n" ); + out.print( "</script>\n" ); + } + + public static final CommandSpec get_parameters_from_run_later = CommandSpec.DO() + .parameters("name") + .build() + ; + + @Command public void get_parameters_from_run_later(IPrintWriter out,ScopedInterpreter<RequestNamespace.ParameterValueList> interp) { + String name = interp.getArgString("name"); + Set<String> values = callLaterMap.get(name); + List<String> list = values == null ? Collections.<String>emptyList() : new ArrayList<String>(values); + Object block = interp.getArg(new RequestNamespace.ParameterValueList(list),"do"); + out.print(block); + } + + // Tweaks & NAML code + + public static final CommandSpec macro_source = new CommandSpec.Builder() + .parameters("id") + .optionalParameters("base", "breadcrumbs") + .scopedParameters("do") + .dotParameter("do") + .build() + ; + + @Command public void macro_source(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace> interp) { + MacroSourceNamespace ns = new MacroSourceNamespace(site(),interp.getArgString("id"), interp.getArgString("base"), interp.getArgString("breadcrumbs")); + out.print( interp.getArg( ns, "do" ) ); + } + + public static final CommandSpec macro_editor = CommandSpec.DO() + .optionalParameters("id", "base", "breadcrumbs") + .build() + ; + + @Command public void macro_editor(IPrintWriter out,ScopedInterpreter<MacroEditorNamespace> interp) { + MacroEditorNamespace ns = new MacroEditorNamespace(site(),interp.getArgString("id"),interp.getArgString("base"), interp.getArgString("breadcrumbs")); + out.print( interp.getArg( ns, "do" ) ); + } + + public static final CommandSpec macro_search = CommandSpec.DO() + .parameters("query", "search_by") + .build(); + + @Command public void macro_search(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace.Commands> interp) + throws IOException, ServletException, CompileException { + String query = interp.getArgString("query"); + String searchBy = interp.getArgString("search_by"); + boolean byName = "name".equals(searchBy); + Map<String,MacroSourceNamespace.CommandInfo> map = new TreeMap<String, MacroSourceNamespace.CommandInfo>(); + if (query != null) { + query = query.toLowerCase(); + Pattern ptn = compileWildcardPattern(query); + Program program = site().getProgram(); + List<Source> sources = program.getSources(); + for (Source s : sources) { + for (Macro m : s.getMacros()) { + if (byName) { + boolean isOverridden = program.getMacroWhichOverrides(m) != null; + if (isOverridden) + continue; + } + boolean matches = byName? ptn.matcher(m.getName().toLowerCase()).matches() : ptn.matcher(m.element.toString().toLowerCase()).find(); + if (matches) { + // Now we look for the first usage of this meaning + MacroSourceNamespace.CommandInfo info = getCommandInfo(m); + String key = m.getName() + '-' + MacroSourceNamespace.csv(m.getRequiredNamespaces()); + map.put(key, info); + } + } + } + } + List<MacroSourceNamespace.CommandInfo> list = new ArrayList<MacroSourceNamespace.CommandInfo>(map.values()); + Object block = interp.getArg(new MacroSourceNamespace.Commands(list),"do"); + out.print(block); + } + + private MacroSourceNamespace.CommandInfo getCommandInfo(Macro m) { + MacroSourceNamespace.CommandInfo info; + Set<Usage> usages = site.getProgram().getUsages(m); + if (usages == null || usages.size() == 0) { + info = new MacroSourceNamespace.CommandInfo(m, null, null); + } else { + Usage u = usages.iterator().next(); + String usageBase = MacroSourceNamespace.asBaseParam(u.baseIds()); + String breadcrumbs = MacroSourceNamespace.asBreadcrumbsParam(u.macroPath()); + info = new MacroSourceNamespace.CommandInfo(m, usageBase, breadcrumbs); + } + return info; + } + + private static Pattern compileWildcardPattern(String query) { + String[] a = query.split("\\*",-1); + StringBuilder regex = new StringBuilder(); + boolean isFirst = true; + for( String s : a ) { + if( isFirst ) + isFirst = false; + else + regex.append( ".*" ); + if( s.length() > 0 ) + regex.append( Pattern.quote(s) ); + } + return Pattern.compile(regex.toString()); + } + + @Command public void has_custom_macros(IPrintWriter out,Interpreter interp) + throws CompileException + { + out.print(ModuleManager.getCustomMacros(site.getProgram()).size() > 0); + } + + public static final CommandSpec custom_macros = CommandSpec.DO; + + @Command public void custom_macros(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace.Commands> interp) + throws IOException, ServletException, CompileException + { + Collection<Macro> macros = ModuleManager.getCustomMacros(site.getProgram()); + printMacros(macros, out, interp); + } + + private void printMacros(Collection<Macro> macros, IPrintWriter out, ScopedInterpreter<MacroSourceNamespace.Commands> interp) { + List<MacroSourceNamespace.CommandInfo> list = new ArrayList<MacroSourceNamespace.CommandInfo>(); + Set<String> names = new HashSet<String>(); + for (Macro m : macros) { + String key = m.getName() + '-' + MacroSourceNamespace.csv(m.getRequiredNamespaces()); + if (names.contains(key)) + continue; + names.add(key); + MacroSourceNamespace.CommandInfo info = getCommandInfo(m); + list.add(info); + } + Collections.sort(list, MacroSourceNamespace.CommandInfo.MACRO_NAME_COMPARATOR); + Object block = interp.getArg(new MacroSourceNamespace.Commands(list),"do"); + out.print(block); + } + + @Command public void has_configuration_macros(IPrintWriter out,Interpreter interp) + throws CompileException + { + out.print(ModuleManager.getConfigurationMacros(site.getProgram()).size() > 0); + } + + public static final CommandSpec configuration_macros = CommandSpec.DO; + + @Command public void configuration_macros(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace.Commands> interp) + throws IOException, ServletException, CompileException + { + Collection<Macro> macros = ModuleManager.getConfigurationMacros(site.getProgram()); + printMacros(macros, out, interp); + } + + @Command public void has_tweak_exception(IPrintWriter out,Interpreter interp) + throws CompileException + { + out.print(site.getTweakException() != null); + } + + @Command public void tweak_exception_message(IPrintWriter out,Interpreter interp) + throws CompileException + { + Exception e = site.getTweakException(); + out.print(e == null? null : e.getMessage()); + } + + public static final CommandSpec advanced_editor_path = new CommandSpec.Builder() + .parameters("prev_url") + .build(); + + @Command public void advanced_editor_path(IPrintWriter out,Interpreter interp) { + String prev = interp.getArgString("prev_url"); + out.print("/template/NamlEditor.jtp?prev=" + HtmlUtils.urlEncode(prev)); + } + + static boolean isCompiledAll(Program program) { + Meaning meaning = program.getMeaning(COMPILED_ALL_CHECK_ID); + return meaning != null && program.isCompiled(meaning); + } + + private static final String COMPILED_ALL_CHECK_ID = "compiled_all_check!nabble:compile_all.naml"; + + @Command public void is_compiled_all(IPrintWriter out, Interpreter interp) { + Program program = interp.template().program(); + out.print(isCompiledAll(program)); + } + + @Command public void run_compile_all(IPrintWriter out,Interpreter interp) throws CompileException { + CompileTest.compileAll(site.getProgram()); + } + + public static final CommandSpec naml_configuration = CommandSpec.DO; + + @Command public void naml_configuration(IPrintWriter out,ScopedInterpreter<NamlConfigurationNamespace> interp) + throws IOException, ServletException, CompileException + { + out.print(interp.getArg(new NamlConfigurationNamespace(),"do")); + } + + @Command public void js_basic_nabble_functions(IPrintWriter out,Interpreter interp) + throws CompileException + { + StringWriter sw = new StringWriter(); + PrintWriter jsOut = new PrintWriter(sw); + Javascript.basicNabbleFunctions(jsOut); + jsOut.close(); + out.print(sw.toString()); + } + + public static final CommandSpec NAME = new CommandSpec.Builder() + .dotParameter("name") + .build() + ; + + public static final CommandSpec has_site_property = NAME; + + @Command public void has_site_property(IPrintWriter out,Interpreter interp) { + String name = interp.getArgString("name"); + out.print(site.getProperty(name) != null); + } + + public static final CommandSpec get_site_property = NAME; + + @Command public void get_site_property(IPrintWriter out,Interpreter interp) { + String name = interp.getArgString("name"); + out.print(site.getProperty(name)); + } + + public static final CommandSpec delete_site_property = CommandSpec.NO_OUTPUT() + .parameters("name") + .build() + ; + + @Command public void delete_site_property(IPrintWriter out,Interpreter interp) { + String name = interp.getArgString("name"); + site.setProperty(name, null); + site.update(); + } + + public static final CommandSpec set_site_property = CommandSpec.NO_OUTPUT() + .parameters("name", "value") + .build() + ; + + @Command public void set_site_property(IPrintWriter out,Interpreter interp) { + String name = interp.getArgString("name"); + String value = interp.getArgString("value"); + site.setProperty(name, value); + site.update(); + } + + + public static final CommandSpec to_html_list = CommandSpec.DO() + .parameters("text") + .build() + ; + + @Command public void to_html_list(IPrintWriter out,ScopedInterpreter<HtmlListNamespace> interp) { + String text = interp.getArgString("text"); + HtmlListNamespace html = new HtmlListNamespace(new Html(text), null, Message.Format.HTML); + interp.getArgString(html,"do"); // processing, no output + out.print(html); + } + + + @Command public void is_embarrassing(IPrintWriter out,Interpreter interp) { + out.print(site.isEmbarrassing()); + } + + public static final Set<Long> sitesRunningBackup = Collections.synchronizedSet(new HashSet<Long>()); + + @Command public void is_running_backup(IPrintWriter out,Interpreter interp) { + out.print(sitesRunningBackup.contains(site.getId())); + } + + public static final CommandSpec make_backup = CommandSpec.NO_OUTPUT() + .parameters("email") + .build() + ; + + @Command public void make_backup(IPrintWriter out,Interpreter interp) { + synchronized (sitesRunningBackup) { + if (sitesRunningBackup.contains(site.getId())) + return; + sitesRunningBackup.add(site.getId()); + final String email = interp.getArgString("email"); + Executors.executeSometime(new Runnable(){ + public void run() { + File file = site.backup(); + Template template = site.getTemplate( "backup email", + BasicNamespace.class, NabbleNamespace.class + ); + Map<String,Object> params = new HashMap<String,Object>(); + params.put("email", email); + params.put("file", file.getName()); + template.run( TemplatePrintWriter.NULL, params, + new BasicNamespace(template), + new NabbleNamespace(site) + ); + sitesRunningBackup.remove(site.getId()); + } + }); + } + } + + @Command public void server_url(IPrintWriter out,Interpreter interp) { + out.print( interp.encode( Jtp.defaultContextUrl() ) ); + } + + @Command public void javascript_version(IPrintWriter out,Interpreter interp) { + out.print(Shared.javascriptVersion); + } + + @Command public void css_version(IPrintWriter out,Interpreter interp) { + out.print(Shared.cssVersion); + } + +}