From 0e402651c2c88fe4bf6311433cc3ff1a7335933d Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Sat, 23 Apr 2016 15:18:28 -0400 Subject: [PATCH] Improve testing tools and update README Signed-off-by: Walker Crouse --- .gitignore | 3 + OreTestPlugin/build.gradle | 18 ++ OreTestPlugin/gradlew | 164 ++++++++++++++++++ OreTestPlugin/gradlew.bat | 90 ++++++++++ OreTestPlugin/settings.gradle | 2 + .../org/spongepowered/ore/OreTestPlugin.java | 18 ++ README.md | 28 ++- app/controllers/Application.scala | 26 +-- app/controllers/BaseController.scala | 8 +- app/controllers/project/Channels.scala | 2 +- app/controllers/project/Pages.scala | 2 +- app/controllers/project/Projects.scala | 2 +- app/controllers/project/Versions.scala | 2 +- app/models/project/Channel.scala | 2 - app/models/project/Page.scala | 1 - app/models/project/Project.scala | 8 +- app/models/project/Version.scala | 4 +- app/ore/permission/Permission.scala | 1 + app/util/DataUtils.scala | 57 ++++++ app/util/form/Forms.scala | 2 +- app/util/forums/SpongeForums.scala | 12 +- conf/application.conf.template | 2 + conf/routes | 1 + scripts/generate_seed_script.sh | 15 -- 24 files changed, 406 insertions(+), 64 deletions(-) create mode 100644 OreTestPlugin/build.gradle create mode 100755 OreTestPlugin/gradlew create mode 100644 OreTestPlugin/gradlew.bat create mode 100644 OreTestPlugin/settings.gradle create mode 100644 OreTestPlugin/src/main/java/org/spongepowered/ore/OreTestPlugin.java create mode 100644 app/util/DataUtils.scala delete mode 100755 scripts/generate_seed_script.sh diff --git a/.gitignore b/.gitignore index 799bedaeb..088adff17 100644 --- a/.gitignore +++ b/.gitignore @@ -186,3 +186,6 @@ local.properties /project/project/target uploads RUNNING_PID +gradle +.gradle +build diff --git a/OreTestPlugin/build.gradle b/OreTestPlugin/build.gradle new file mode 100644 index 000000000..8d954850e --- /dev/null +++ b/OreTestPlugin/build.gradle @@ -0,0 +1,18 @@ +group 'org.spongepowered' +version 'dev-SNAPSHOT' + +apply plugin: 'java' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() + maven { + name 'sponge' + url 'http://repo.spongepowered.org/maven' + } +} + +dependencies { + compile 'org.spongepowered:spongeapi:4.1.0-SNAPSHOT' +} diff --git a/OreTestPlugin/gradlew b/OreTestPlugin/gradlew new file mode 100755 index 000000000..91a7e269e --- /dev/null +++ b/OreTestPlugin/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/OreTestPlugin/gradlew.bat b/OreTestPlugin/gradlew.bat new file mode 100644 index 000000000..aec99730b --- /dev/null +++ b/OreTestPlugin/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/OreTestPlugin/settings.gradle b/OreTestPlugin/settings.gradle new file mode 100644 index 000000000..57b401bac --- /dev/null +++ b/OreTestPlugin/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'ore-test-plugin' + diff --git a/OreTestPlugin/src/main/java/org/spongepowered/ore/OreTestPlugin.java b/OreTestPlugin/src/main/java/org/spongepowered/ore/OreTestPlugin.java new file mode 100644 index 000000000..d3c583202 --- /dev/null +++ b/OreTestPlugin/src/main/java/org/spongepowered/ore/OreTestPlugin.java @@ -0,0 +1,18 @@ +package org.spongepowered.ore; + +import org.spongepowered.api.plugin.Dependency; +import org.spongepowered.api.plugin.Plugin; + +@Plugin(id = "ore-test", + name = "Ore Test Plugin", + version = "1.0.0", + dependencies = { + @Dependency(id = "ore-test", version = "1.0.0"), + @Dependency(id = "worldedit", version = "1.0.0"), + @Dependency(id = "bookotd", version = "1.0.0") + }, + description = "Plugin for testing Ore functionality.", + url = "https://ore-staging.spongepowered.org", + authors = { "SpongePowered", "windy", "Zidane", "gabizou" } +) +public class OreTestPlugin {} diff --git a/README.md b/README.md index 5badc523d..aa9f633ea 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Ore === -*Catchy tagline here* +Repository software for Sponge plugins and Forge mods https://ore-staging.spongepowered.org/ Ore is written in Scala using the [Play](https://www.playframework.com/) framework. @@ -24,20 +24,12 @@ Namely, the differences include: ### Setup -In production, Ore currently requires the `DISCOURSE_SSO_SECRET` and `DISCOURSE_SSO_URL` environment variables to be set. -If you don't have access to these, you can bypass the standard authentication method by setting the -`application.fakeUser` setting to `true` in `conf/application.conf`. This will allow you to work with Ore in a -development environment without requiring authentication to Sponge services. - -You must also set some other environment variables: - -| Variable | Description | Typical Value | Required | -| ---------------------- | ---------------------------------------------------- | ------------------------------- | -------- | -| BASE_URL | The full root URL of the instance | http://localhost:9000 | Yes | -| JDBC_DATABASE_URL | PostgreSQL JDBC Database URL | jdbc:postgresql://localhost/ore | Yes | -| JDBC_DATABASE_USERNAME | PostgreSQL Database username | root | Yes | -| JDBC_DATABASE_PASSWORD | PostgreSQL Database password | hunter2 | No | -| FAKE_USER | Whether a "fake" user should be used for auth | true | No | -| APPLICATION_SECRET | The application secret for cryptography | `REDACTED` | No | -| DISCOURSE_SSO_SECRET | The secret key for authentication against the forums | `REDACTED` | No | -| DISCOURSE_SSO_URL | The URL to redirect to for authentication | `REDACTED` | No | +After cloning Ore, the first thing you will want to do is create a new PostgreSQL database for the application to user. +This is required in order for Ore to run. Learn more about PostgreSQL [here](http://www.postgresql.org/). + +After setting up a database, create a copy of `conf/application.conf.template` named `conf/application.conf` and +configure the application. This file is in the `.gitignore` so it will not appear in your commits. In a typical +development environment, most of the defaults will do except you must set `application.fakeUser` to `true` to disable +authentication to the Sponge forums. In addition, the SSL certification authority of https://forums.spongepowered.org is +not typically recognized by the JVM so you will either have to manually add the cert to your JVM or set +`discourse.api.enabled` to `false` in the configuration file. diff --git a/app/controllers/Application.scala b/app/controllers/Application.scala index ad8c2d7a0..fd38f040e 100644 --- a/app/controllers/Application.scala +++ b/app/controllers/Application.scala @@ -4,20 +4,19 @@ import javax.inject.Inject import controllers.routes.{Application => self} import db.OrePostgresDriver.api._ +import db.ProjectTable import db.query.Queries import db.query.Queries.now -import db.{ProjectTable, UserTable} import models.project.Project._ import models.user.{FakeUser, User} -import ore.permission.ResetOre +import ore.permission.{ResetOre, SeedOre} import ore.project.Categories import ore.project.Categories.Category -import org.apache.commons.io.FileUtils import play.api.Play.{configuration => config, current} import play.api.i18n.MessagesApi import play.api.libs.ws.WSClient import play.api.mvc._ -import util.P +import util.DataUtils import util.form.Forms import util.forums.SpongeForums._ import views.{html => views} @@ -27,7 +26,7 @@ import scala.concurrent.ExecutionContext.Implicits.global /** * Main entry point for application. */ -class Application @Inject()(override val messagesApi: MessagesApi, ws: WSClient) extends BaseController(ws) { +class Application @Inject()(override val messagesApi: MessagesApi, implicit val ws: WSClient) extends BaseController { /** * Display the home page. @@ -38,7 +37,7 @@ class Application @Inject()(override val messagesApi: MessagesApi, ws: WSClient) val categoryArray: Array[Category] = if (categories.isDefined) Categories.fromString(categories.get) else null val filter: ProjectTable => Rep[Boolean] = if (query.isDefined) { val q = '%' + query.get.toLowerCase + '%' - p => (p.name.toLowerCase like q) || (p.description like q) || (p.ownerName like q) + p => (p.name.toLowerCase like q) || (p.description.toLowerCase like q) || (p.ownerName.toLowerCase like q) } else null val projects = now(Queries.Projects.collect(filter, categoryArray, InitialLoad)).get Ok(views.home(projects, Option(categoryArray))) @@ -127,10 +126,17 @@ class Application @Inject()(override val messagesApi: MessagesApi, ws: WSClient) * TODO: REMOVE BEFORE PRODUCTION */ def reset = (Authenticated andThen PermissionAction[AuthRequest](ResetOre)) { implicit request => - for (project <- now(Queries.Projects.collect()).get) project.delete - val query: Query[UserTable, User, Seq] = Queries.Users.models - now(Queries.DB.run(query.delete)).get - FileUtils.deleteDirectory(P.UploadsDir.toFile) + DataUtils.reset() + Redirect(self.showHome(None, None)).withNewSession + } + + /** + * Fills Ore with some dummy data. + * + * @return Redirect home + */ + def seed = (Authenticated andThen PermissionAction[AuthRequest](SeedOre)) { implicit request => + DataUtils.seed() Redirect(self.showHome(None, None)).withNewSession } diff --git a/app/controllers/BaseController.scala b/app/controllers/BaseController.scala index 6a01284d6..337b7395f 100644 --- a/app/controllers/BaseController.scala +++ b/app/controllers/BaseController.scala @@ -5,16 +5,18 @@ import ore.Statistics import play.api.i18n.I18nSupport import play.api.libs.ws.WSClient import play.api.mvc._ -import util.forums.SpongeForums._ +import util.DataUtils +import util.forums.SpongeForums import scala.concurrent.Future /** * Represents a Secured base Controller for this application. */ -abstract class BaseController(ws: WSClient) extends Controller with I18nSupport with Secured { +abstract class BaseController(implicit ws: WSClient) extends Controller with I18nSupport with Secured { - if (Users == null) init(ws) + SpongeForums.apply + DataUtils.apply protected[controllers] def withProject(author: String, slug: String)(f: Project => Result) (implicit request: RequestHeader): Result = { diff --git a/app/controllers/project/Channels.scala b/app/controllers/project/Channels.scala index ad7effa64..6ee3cad47 100644 --- a/app/controllers/project/Channels.scala +++ b/app/controllers/project/Channels.scala @@ -13,7 +13,7 @@ import views.html.projects.{channels => views} /** * Controller for handling Channel related actions. */ -class Channels @Inject()(override val messagesApi: MessagesApi, ws: WSClient) extends BaseController(ws) { +class Channels @Inject()(override val messagesApi: MessagesApi, implicit val ws: WSClient) extends BaseController { private def ChannelEditAction(author: String, slug: String) = { AuthedProjectAction(author, slug) andThen ProjectPermissionAction(EditChannels) diff --git a/app/controllers/project/Pages.scala b/app/controllers/project/Pages.scala index a2fdb20ed..e352750c4 100644 --- a/app/controllers/project/Pages.scala +++ b/app/controllers/project/Pages.scala @@ -13,7 +13,7 @@ import views.html.projects.{pages => views} /** * Controller for handling Page related actions. */ -class Pages @Inject()(override val messagesApi: MessagesApi, ws: WSClient) extends BaseController(ws) { +class Pages @Inject()(override val messagesApi: MessagesApi, implicit val ws: WSClient) extends BaseController { private def PageEditAction(author: String, slug: String) = { AuthedProjectAction(author, slug) andThen ProjectPermissionAction(EditPages) diff --git a/app/controllers/project/Projects.scala b/app/controllers/project/Projects.scala index 11b828577..580cf13bc 100644 --- a/app/controllers/project/Projects.scala +++ b/app/controllers/project/Projects.scala @@ -24,7 +24,7 @@ import scala.util.{Failure, Success} * TODO: Replace NotFounds, BadRequests, etc with pretty views * TODO: Localize */ -class Projects @Inject()(override val messagesApi: MessagesApi, ws: WSClient) extends BaseController(ws) { +class Projects @Inject()(override val messagesApi: MessagesApi, implicit val ws: WSClient) extends BaseController { private def SettingsEditAction(author: String, slug: String) = { AuthedProjectAction(author, slug) andThen ProjectPermissionAction(EditSettings) diff --git a/app/controllers/project/Versions.scala b/app/controllers/project/Versions.scala index 2328d19a3..82df7aadf 100644 --- a/app/controllers/project/Versions.scala +++ b/app/controllers/project/Versions.scala @@ -19,7 +19,7 @@ import scala.util.{Failure, Success} /** * Controller for handling Version related actions. */ -class Versions @Inject()(override val messagesApi: MessagesApi, ws: WSClient) extends BaseController(ws) { +class Versions @Inject()(override val messagesApi: MessagesApi, implicit val ws: WSClient) extends BaseController { private def VersionEditAction(author: String, slug: String) = { AuthedProjectAction(author, slug) andThen ProjectPermissionAction(EditVersions) diff --git a/app/models/project/Channel.scala b/app/models/project/Channel.scala index 452997e29..a9c5873ef 100644 --- a/app/models/project/Channel.scala +++ b/app/models/project/Channel.scala @@ -18,8 +18,6 @@ import org.spongepowered.plugin.meta.version.ComparableVersion import org.spongepowered.plugin.meta.version.ComparableVersion.{ListItem, StringItem} import play.api.Play.{configuration => config, current} -import scala.util.Try - /** * Represents a release channel for Project Versions. Each project gets it's * own set of channels. diff --git a/app/models/project/Page.scala b/app/models/project/Page.scala index 42305ea28..7c68da39a 100644 --- a/app/models/project/Page.scala +++ b/app/models/project/Page.scala @@ -2,7 +2,6 @@ package models.project import java.sql.Timestamp -import com.google.common.base.Objects import com.google.common.base.Preconditions._ import db.orm.dao.ModelDAO import db.orm.model.ModelKeys._ diff --git a/app/models/project/Project.scala b/app/models/project/Project.scala index 3d0c5547d..58653fde3 100644 --- a/app/models/project/Project.scala +++ b/app/models/project/Project.scala @@ -458,7 +458,7 @@ case class Project(override val id: Option[Int] = None, def delete = assertDefined { now(Queries.Projects delete this).get FileUtils.deleteDirectory(ProjectFiles.projectDir(this.ownerName, this._name).toFile) - SpongeForums.Embed.deleteTopic(this) + if (this.topicId.isDefined) SpongeForums.Embed.deleteTopic(this) } override def projectId = assertDefined(this.id.get) @@ -638,8 +638,10 @@ object Project extends ModelDAO[Project] { * @param project Project that is pending * @param firstVersion Uploaded plugin */ - def setPending(project: Project, firstVersion: PluginFile) = { - PendingProject(project, firstVersion).cache() + def setPending(project: Project, firstVersion: PluginFile): PendingProject = { + val pendingProject = PendingProject(project, firstVersion) + pendingProject.cache() + pendingProject } /** diff --git a/app/models/project/Version.scala b/app/models/project/Version.scala index cacd46bff..ac72eb2b8 100644 --- a/app/models/project/Version.scala +++ b/app/models/project/Version.scala @@ -168,8 +168,8 @@ object Version extends ModelDAO[Version] { */ case class PendingVersion(val owner: String, val projectSlug: String, - var channelName: String, - var channelColor: Color, + var channelName: String = Channel.DefaultName, + var channelColor: Color = Channel.DefaultColor, val version: Version, val plugin: PluginFile) extends PendingAction[Version] diff --git a/app/ore/permission/Permission.scala b/app/ore/permission/Permission.scala index da65947b3..2040a943a 100644 --- a/app/ore/permission/Permission.scala +++ b/app/ore/permission/Permission.scala @@ -11,3 +11,4 @@ case object EditPages extends Permission { val trust = Limited } case object EditSettings extends Permission { val trust = Absolute } case object EditVersions extends Permission { val trust = Standard } case object ResetOre extends Permission { val trust = Absolute } +case object SeedOre extends Permission { val trust = Absolute } diff --git a/app/util/DataUtils.scala b/app/util/DataUtils.scala new file mode 100644 index 000000000..4bf3daf58 --- /dev/null +++ b/app/util/DataUtils.scala @@ -0,0 +1,57 @@ +package util + +import java.nio.file.Files + +import db.OrePostgresDriver.api._ +import db.query.Queries +import db.query.Queries.DB._ +import db.query.Queries.now +import models.project.Project +import models.user.User +import ore.project.ProjectFactory +import org.apache.commons.io.FileUtils +import play.api.Play.{configuration => config, current} +import play.api.libs.Files.TemporaryFile +import play.api.libs.ws.WSClient +import util.P._ +import util.forums.SpongeForums + +/** + * Utility class for performing some bulk actions on the application data. + * Typically for testing. + */ +object DataUtils { + + implicit private var ws: WSClient = null + + def apply(implicit ws: WSClient) = this.ws = ws + + /** + * Resets the application to factory defaults. + */ + def reset() = { + for (project <- now(Queries.Projects.collect()).get) project.delete + now(run(Queries.Users.models.delete)).get + FileUtils.deleteDirectory(UploadsDir.toFile) + } + + /** + * Fills the application with some dummy data. + * + * @param users Amount of users to create + */ + def seed(users: Int = 200) = { + SpongeForums.disable() + this.reset() + val pluginPath = RootDir.resolve(config.getString("ore.test-plugin").get) + for (i <- 0 until users) { + val pluginFile = Files.copy(pluginPath, pluginPath.getParent.resolve("plugin.jar")).toFile + val user = now(Queries.Users.getOrInsert(new User(i, null, "User-" + i, null))).get + val plugin = ProjectFactory.initUpload(TemporaryFile(pluginFile), pluginFile.getName, user).get + val project = Project.fromMeta(user, plugin.meta.get).copy(pluginId = "pluginId." + i) + Project.setPending(project, plugin).complete.get + } + SpongeForums.apply + } + +} diff --git a/app/util/form/Forms.scala b/app/util/form/Forms.scala index df529ee8f..60044d3d4 100644 --- a/app/util/form/Forms.scala +++ b/app/util/form/Forms.scala @@ -1,7 +1,7 @@ package util.form +import models.project.Channel import models.project.Page._ -import models.project.{Page, Channel} import play.api.data.Form import play.api.data.Forms._ diff --git a/app/util/forums/SpongeForums.scala b/app/util/forums/SpongeForums.scala index 85ddddd94..6d40add56 100644 --- a/app/util/forums/SpongeForums.scala +++ b/app/util/forums/SpongeForums.scala @@ -23,17 +23,19 @@ object SpongeForums { * * @param ws HTTP request client */ - def init(ws: WSClient) = { + def apply(implicit ws: WSClient) = { if (config.getBoolean("discourse.api.enabled").get) { val baseUrl = config.getString("discourse.baseUrl").get val apiKey = config.getString("discourse.api.key").get val categoryId = config.getInt("discourse.embed.categoryId").get this.users = new DiscourseUsers(baseUrl, ws) this.embed = new DiscourseEmbed(baseUrl, apiKey, categoryId, ws) - } else { - this.users = DiscourseUsers.Disabled - this.embed = DiscourseEmbed.Disabled - } + } else disable() + } + + def disable() = { + this.users = DiscourseUsers.Disabled + this.embed = DiscourseEmbed.Disabled } protected[forums] def validate[A](response: WSResponse)(f: JsObject => A): Option[A] = try { diff --git a/conf/application.conf.template b/conf/application.conf.template index 6dd9f0ae3..da4a9d3dd 100644 --- a/conf/application.conf.template +++ b/conf/application.conf.template @@ -50,6 +50,8 @@ ore.git.url = "https://github.com/SpongePowered/Ore" ore.git.ref = ".git/refs/heads/master" ore.git.ref-len = 7 +ore.test-plugin = "OreTestPlugin/build/libs/ore-test-plugin-dev-SNAPSHOT.jar" + # Slick configuration slick.dbs.default.driver = "slick.driver.PostgresDriver$" diff --git a/conf/routes b/conf/routes index ac129c574..530b83b63 100644 --- a/conf/routes +++ b/conf/routes @@ -4,6 +4,7 @@ GET /*path/ @controllers.Application.removeTrail(path) GET /admin/reset @controllers.Application.reset +GET /admin/seed @controllers.Application.seed # ---------- API (v1) ---------- GET /api/projects @controllers.Api.projects(version = "v1", categories: Option[String], limit: Option[Int], offset: Option[Int]) diff --git a/scripts/generate_seed_script.sh b/scripts/generate_seed_script.sh deleted file mode 100755 index d71216401..000000000 --- a/scripts/generate_seed_script.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -time="TIMESTAMP '2016-04-06 19:24:15.394'" - -for i in $(seq 0 200); do - user="'User-$i'" - echo "INSERT INTO users (external_id, created_at, username, email) VALUES ($i, $time, $user, 'spongie@spongepowered.org');" \ - "INSERT INTO projects (id, created_at, plugin_id, name, slug, owner_name, owner_id, authors, " \ - "recommended_version_id, category_id, views, downloads, stars) " \ - "VALUES ($i, $time, 'pluginId.$i', 'Project $i', 'Project-$i', $user, $i, '{}', $i, 0, 0, 0, 0);" \ - "INSERT INTO channels (id, created_at, name, color_id, project_id) " \ - "VALUES ($i, $time, 'Release', 7, $i);" \ - "INSERT INTO versions (id, created_at, version_string, dependencies, downloads, project_id, channel_id) " \ - "VALUES ($i, $time, '1.0.0', '{}', 0, $i, $i);" -done