DATAGRAPH-540 Update SDN examples to 3.2.1.RELEASE
* Cineasts, added profiles for REST/Advanced, removed the separate projects * Todos * Hello World * My-Restaurants * removed IMDB
3
pom.xml
@@ -63,10 +63,7 @@
|
||||
<modules>
|
||||
<module>spring-data-neo4j-examples/hello-worlds</module>
|
||||
<module>spring-data-neo4j-examples/hello-worlds-aspects</module>
|
||||
<module>spring-data-neo4j-examples/imdb</module>
|
||||
<module>spring-data-neo4j-examples/cineasts</module>
|
||||
<module>spring-data-neo4j-examples/cineasts-aspects</module>
|
||||
<module>spring-data-neo4j-examples/cineasts-rest</module>
|
||||
<module>spring-data-neo4j-examples/myrestaurants-social</module>
|
||||
<module>spring-data-neo4j-examples/todos</module>
|
||||
<module>spring-data-neo4j-examples/backwardscompatibility</module>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
.DS_Store
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
*.zip
|
||||
data
|
||||
target
|
||||
*.log
|
||||
tmp
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
@@ -1,16 +0,0 @@
|
||||

|
||||
Cineasts.net
|
||||
============
|
||||
|
||||
This project is the demo/tutorial application for the [Spring Data Neo4j](https://github.com/SpringSource/spring-data-neo4j) library which provides convenient access to the [Neo4j](http://neo4j.org) graph database.
|
||||
|
||||
This tutorial creates a complete web application built on top of Spring Data Neo4j.
|
||||
|
||||
It uses a domain that should be familiar to most - movies. So for cineasts.net we decided to add a social
|
||||
touch to the whole movie rating business, allowing friends to share their ratings and get recommendations
|
||||
for new friends and movies.
|
||||
|
||||
The tutorial is presented as a colloquial description of the steps necessary to create the application.
|
||||
It provides the configuration and code examples that are needed to understand what's happening.
|
||||
|
||||
The complete tutorial is contained in this projects [github wiki](https://github.com/jexp/cineasts/wiki).
|
||||
|
Before Width: | Height: | Size: 30 KiB |
@@ -1,356 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.neo4j.examples</groupId>
|
||||
<artifactId>cineasts-aspects</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>Cineasts.net Aspects</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring.version>3.1.0.RELEASE</spring.version>
|
||||
<slf4j.version>1.6.1</slf4j.version>
|
||||
<neo4j.version>1.8.1</neo4j.version>
|
||||
<spring-data-neo4j.version>${project.version}</spring-data-neo4j.version>
|
||||
<aspectj.version>1.6.12</aspectj.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-maven-release</id>
|
||||
<name>Spring Maven Release Repository</name>
|
||||
<url>http://maven.springframework.org/release</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-maven-snapshot</id>
|
||||
<name>Spring Maven Snapshot Repository</name>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<url>http://maven.springframework.org/snapshot</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-maven-milestone</id>
|
||||
<name>Spring Maven Milestone Repository</name>
|
||||
<url>http://maven.springframework.org/milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>neo4j-release-repository</id>
|
||||
<name>Neo4j Maven 2 release repository</name>
|
||||
<url>http://m2.neo4j.org/releases</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>neo4j-snapshot-repository</id>
|
||||
<name>Neo4j Maven 2 snapshot repository</name>
|
||||
<url>http://m2.neo4j.org/snapshots</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jboss-public-repo</id>
|
||||
<url>http://repository.jboss.org/maven2/</url>
|
||||
<name>JBoss public available repo</name>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-maven-release</id>
|
||||
<name>Spring Maven Release Repository</name>
|
||||
<url>http://maven.springframework.org/release</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-maven-milestone</id>
|
||||
<name>Spring Maven Milestone Repository</name>
|
||||
<url>http://maven.springframework.org/milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.16</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-neo4j-aspects</artifactId>
|
||||
<version>${spring-data-neo4j.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>opensymphony</groupId>
|
||||
<artifactId>sitemesh</artifactId>
|
||||
<version>2.4.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>4.0.2.GA</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>jsp-api</artifactId>
|
||||
<version>2.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<version>1.8.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>1.0.0.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Neo4j Libraries -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.neo4j</groupId>
|
||||
<artifactId>neo4j-kernel</artifactId>
|
||||
<version>${neo4j.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.neo4j</groupId>
|
||||
<artifactId>neo4j-cypher</artifactId>
|
||||
<version>${neo4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>7.1.2.v20100523</version>
|
||||
<configuration>
|
||||
<webAppConfig>
|
||||
<contextPath>/</contextPath>
|
||||
</webAppConfig>
|
||||
<!--scanIntervalSeconds>1</scanIntervalSeconds -->
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<!-- Must use java 1.5 or higher for annotations -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<useFile>true</useFile>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/Abstract*.java</exclude>
|
||||
</excludes>
|
||||
<junitArtifactName>junit:junit</junitArtifactName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- the eclipse plugin interacts with the aspectj-maven-plugin
|
||||
BUT ONLY if the ajdtVersion config value is set (remove it and it won't) -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
<configuration>
|
||||
<!-- The ajdtVersion configuration parameter is optional. The valid values are none, 1.4, and 1.5. none indicates that AJDT should not be enabled even though Aspectj is enabled in maven. 1.4 generates the org.eclipse.ajdt.ui.prefs file in the .settings directory. 1.5 (or later) includes the configuration into the .classpath file and is the default value. -->
|
||||
<ajdtVersion>1.5</ajdtVersion>
|
||||
<additionalProjectnatures>
|
||||
<projectnature>org.eclipse.ajdt.ui.ajnature</projectnature>
|
||||
<projectnature>org.eclipse.jdt.core.javanature</projectnature>
|
||||
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
|
||||
</additionalProjectnatures>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<outxml>true</outxml>
|
||||
<aspectLibraries>
|
||||
<aspectLibrary>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
<aspectLibrary>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-neo4j-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
</aspectLibraries>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -1,63 +0,0 @@
|
||||
package org.neo4j.cineasts.controller;
|
||||
|
||||
|
||||
import org.neo4j.cineasts.service.CineastsUserDetailsService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* Handles and retrieves the login or denied page depending on the URI template
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/auth")
|
||||
public class AuthController {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(AuthController.class);
|
||||
|
||||
@Autowired
|
||||
CineastsUserDetailsService userDetailsService;
|
||||
@RequestMapping(value = "/login", method = RequestMethod.GET)
|
||||
public String login(@RequestParam(value = "login_error", required = false) boolean error, Model model) {
|
||||
logger.debug("Received request to show login page, error "+error);
|
||||
if (error) {
|
||||
model.addAttribute("error", "You have entered an invalid username or password!");
|
||||
}
|
||||
return "/auth/loginpage";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/register", method = RequestMethod.POST)
|
||||
public String register(
|
||||
@RequestParam(value = "j_username") String login,
|
||||
@RequestParam(value = "j_displayname") String name,
|
||||
@RequestParam(value = "j_password") String password,
|
||||
Model model) {
|
||||
|
||||
try {
|
||||
userDetailsService.register(login,name,password);
|
||||
return "forward:/user/"+login;
|
||||
} catch(Exception e) {
|
||||
model.addAttribute("j_username",login);
|
||||
model.addAttribute("j_displayname",name);
|
||||
model.addAttribute("error",e.getMessage());
|
||||
return "/auth/registerpage";
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/denied", method = RequestMethod.GET)
|
||||
public String denied() {
|
||||
logger.debug("Received request to show denied page");
|
||||
return "/auth/deniedpage";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/registerpage", method = RequestMethod.GET)
|
||||
public String registerPage() {
|
||||
logger.debug("Received request to show register page");
|
||||
return "/auth/registerpage";
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.neo4j.cineasts.controller;
|
||||
|
||||
import org.neo4j.cineasts.movieimport.MovieDbImportService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@Controller
|
||||
public class ImportController {
|
||||
|
||||
private MovieDbImportService importService;
|
||||
private static final Logger log = LoggerFactory.getLogger(ImportController.class);
|
||||
|
||||
@Autowired
|
||||
public ImportController(MovieDbImportService importService) {
|
||||
this.importService = importService;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/import/{ids}", method = RequestMethod.GET)
|
||||
public String importMovie(@PathVariable String ids, Model model) {
|
||||
long start=System.currentTimeMillis();
|
||||
final Map<Integer, String> movies = importService.importMovies(extractRanges(ids));
|
||||
long duration = (System.currentTimeMillis() - start) / 1000;
|
||||
model.addAttribute("duration", duration);
|
||||
model.addAttribute("ids", ids);
|
||||
model.addAttribute("movies", movies.entrySet());
|
||||
return "import/result";
|
||||
}
|
||||
|
||||
|
||||
private Map<Integer, Integer> extractRanges(String ids) {
|
||||
Map<Integer, Integer> ranges = new LinkedHashMap<Integer, Integer>();
|
||||
StringBuilder errors = new StringBuilder();
|
||||
for (String token : ids.split(",")) {
|
||||
try {
|
||||
if (token.contains("-")) {
|
||||
String[] range = token.split("-");
|
||||
ranges.put(Integer.parseInt(range[0]), Integer.parseInt(range[1]));
|
||||
} else {
|
||||
int id = Integer.parseInt(token);
|
||||
ranges.put(id, id);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errors.append(token).append(": ").append(e.getMessage()).append("\n");
|
||||
}
|
||||
}
|
||||
if (errors.length() > 0) {
|
||||
throw new RuntimeException("Error parsing ids\n" + errors);
|
||||
}
|
||||
return ranges;
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
package org.neo4j.cineasts.controller;
|
||||
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.Person;
|
||||
import org.neo4j.cineasts.domain.Rating;
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.neo4j.cineasts.repository.PersonRepository;
|
||||
import org.neo4j.cineasts.service.CineastsUserDetailsService;
|
||||
import org.neo4j.cineasts.service.DatabasePopulator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@Controller
|
||||
public class MovieController {
|
||||
|
||||
@Autowired
|
||||
private MovieRepository movieRepository;
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
@Autowired
|
||||
private CineastsUserDetailsService userDetailsService;
|
||||
@Autowired
|
||||
private DatabasePopulator populator;
|
||||
private static final Logger log = LoggerFactory.getLogger(MovieController.class);
|
||||
|
||||
/**
|
||||
* Only matches 'GET /movies/{id}}' requests for JSON content; a 404 is sent otherwise.
|
||||
* TODO send a 406 if an unsupported representation, such as XML, is requested. See SPR-7353.
|
||||
*/
|
||||
@RequestMapping(value = "/movies/{id}", method = RequestMethod.GET, headers = "Accept=application/json")
|
||||
public
|
||||
@ResponseBody
|
||||
Movie getMovie(@PathVariable String id) {
|
||||
return movieRepository.findById(id);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/movies/{movieId}", method = RequestMethod.GET, headers = "Accept=text/html")
|
||||
public String singleMovieView(final Model model, @PathVariable String movieId) {
|
||||
User user = addUser(model);
|
||||
Movie movie = movieRepository.findById(movieId);
|
||||
model.addAttribute("id", movieId);
|
||||
if (movie != null) {
|
||||
model.addAttribute("movie", movie);
|
||||
final int stars = movie.getStars();
|
||||
model.addAttribute("stars", stars);
|
||||
Rating rating = null;
|
||||
if (user!=null) rating = movie.getRelationshipTo(user, Rating.class, "RATED");
|
||||
if (rating == null) rating = new Rating().rate(stars, null);
|
||||
model.addAttribute("userRating",rating);
|
||||
}
|
||||
return "/movies/show";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/movies/{movieId}", method = RequestMethod.POST, headers = "Accept=text/html")
|
||||
public String updateMovie(Model model, @PathVariable String movieId, @RequestParam(value = "rated",required = false) Integer stars, @RequestParam(value = "comment",required = false) String comment) {
|
||||
Movie movie = movieRepository.findById(movieId);
|
||||
User user = userDetailsService.getUserFromSession();
|
||||
userDetailsService.rate(user, movie, stars, comment);
|
||||
return singleMovieView(model,movieId);
|
||||
}
|
||||
|
||||
private User addUser(Model model) {
|
||||
User user = userDetailsService.getUserFromSession();
|
||||
model.addAttribute("user", user);
|
||||
return user;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/movies", method = RequestMethod.GET, headers = "Accept=text/html")
|
||||
public String findMovies(Model model, @RequestParam("q") String query) {
|
||||
if (query!=null && !query.isEmpty()) {
|
||||
Page<Movie> movies = movieRepository.findByTitleLike(query, new PageRequest(0, 20));
|
||||
model.addAttribute("movies", movies.getContent());
|
||||
} else {
|
||||
model.addAttribute("movies", Collections.emptyList());
|
||||
}
|
||||
model.addAttribute("query", query);
|
||||
addUser(model);
|
||||
return "/movies/list";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/actors/{id}", method = RequestMethod.GET, headers = "Accept=text/html")
|
||||
public String singleActorView(Model model, @PathVariable String id) {
|
||||
Person person = personRepository.findById(id);
|
||||
model.addAttribute("actor", person);
|
||||
model.addAttribute("id", id);
|
||||
model.addAttribute("roles", person.getRoles());
|
||||
addUser(model);
|
||||
return "/actors/show";
|
||||
}
|
||||
|
||||
//@RequestMapping(value = "/admin/populate", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "/populate", method = RequestMethod.GET)
|
||||
public String populateDatabase(Model model) {
|
||||
Collection<Movie> movies=populator.populateDatabase();
|
||||
model.addAttribute("movies",movies);
|
||||
addUser(model);
|
||||
return "/movies/list";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/admin/clean", method = RequestMethod.GET)
|
||||
public String clean(Model model) {
|
||||
populator.cleanDb();
|
||||
return "movies/list";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/", method = RequestMethod.GET)
|
||||
public String index(Model model) {
|
||||
addUser(model);
|
||||
return "index";
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.neo4j.cineasts.controller;
|
||||
|
||||
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.neo4j.cineasts.service.CineastsUserDetailsService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
/**
|
||||
* Handles and retrieves the login or denied page depending on the URI template
|
||||
*/
|
||||
@Controller
|
||||
public class UserController {
|
||||
|
||||
@Autowired CineastsUserDetailsService userDetailsService;
|
||||
@Autowired
|
||||
MovieRepository movieRepository;
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(UserController.class);
|
||||
|
||||
@RequestMapping(value = "/user", method = RequestMethod.GET)
|
||||
public String profile(Model model) {
|
||||
final User user = userDetailsService.getUserFromSession();
|
||||
model.addAttribute("user", user);
|
||||
if (user!=null) {
|
||||
model.addAttribute("recommendations", movieRepository.getRecommendations(user));
|
||||
}
|
||||
return "/user/index";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/user/{login}/friends", method = RequestMethod.POST)
|
||||
public String addFriend(Model model, @PathVariable("login") String login) {
|
||||
userDetailsService.addFriend(login);
|
||||
return "forward:/user/"+login;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/user/{login}")
|
||||
public String publicProfile(Model model, @PathVariable("login") String login) {
|
||||
User profiled = userDetailsService.findUser(login);
|
||||
User user = userDetailsService.getUserFromSession();
|
||||
|
||||
return publicProfile(model, profiled, user);
|
||||
}
|
||||
|
||||
private String publicProfile(Model model, User profiled, User user) {
|
||||
if (profiled.equals(user)) return profile(model);
|
||||
|
||||
model.addAttribute("profiled", profiled);
|
||||
model.addAttribute("user", user);
|
||||
model.addAttribute("isFriend", areFriends(profiled, user));
|
||||
return "/user/public";
|
||||
}
|
||||
|
||||
private boolean areFriends(User user, User loggedIn) {
|
||||
return user!=null && user.isFriend(loggedIn);
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.springframework.data.neo4j.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.annotation.RelatedTo;
|
||||
import org.springframework.data.neo4j.annotation.RelatedToVia;
|
||||
import org.springframework.data.neo4j.annotation.Indexed;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.neo4j.graphdb.Direction.INCOMING;
|
||||
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@NodeEntity
|
||||
public class Movie {
|
||||
|
||||
@Indexed
|
||||
String id;
|
||||
|
||||
@Indexed(indexType=IndexType.FULLTEXT, indexName = "search")
|
||||
String title;
|
||||
|
||||
String description;
|
||||
|
||||
@RelatedTo(type="DIRECTED", direction = INCOMING)
|
||||
Person director;
|
||||
|
||||
@RelatedTo(type = "ACTS_IN", direction = INCOMING)
|
||||
Set<Person> actors;
|
||||
|
||||
@RelatedToVia(elementClass = Role.class, type = "ACTS_IN", direction = INCOMING)
|
||||
Iterable<Role> roles;
|
||||
|
||||
@RelatedToVia(elementClass = Rating.class, type = "RATED", direction = INCOMING)
|
||||
Iterable<Rating> ratings;
|
||||
private String language;
|
||||
private String imdbId;
|
||||
private String tagline;
|
||||
private Date releaseDate;
|
||||
private Integer runtime;
|
||||
private String homepage;
|
||||
private String trailer;
|
||||
private String genre;
|
||||
private String studio;
|
||||
private Integer version;
|
||||
private Date lastModified;
|
||||
private String imageUrl;
|
||||
|
||||
public Movie() {
|
||||
}
|
||||
|
||||
public Movie(String id, String title) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Collection<Person> getActors() {
|
||||
return actors;
|
||||
}
|
||||
|
||||
public Collection<Role> getRoles() {
|
||||
return IteratorUtil.asCollection(roles);
|
||||
}
|
||||
|
||||
public int getYear() {
|
||||
if (releaseDate==null) return 0;
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(releaseDate);
|
||||
return cal.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s (%s) [%s]", title, releaseDate, id);
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getStars() {
|
||||
Iterable<Rating> allRatings = ratings;
|
||||
|
||||
if (allRatings == null) return 0;
|
||||
int stars=0, count=0;
|
||||
for (Rating rating : allRatings) {
|
||||
stars += rating.getStars();
|
||||
count++;
|
||||
}
|
||||
return count==0 ? 0 : stars / count;
|
||||
}
|
||||
|
||||
public Collection<Rating> getRatings() {
|
||||
Iterable<Rating> allRatings = ratings;
|
||||
return allRatings == null ? Collections.<Rating>emptyList() : IteratorUtil.asCollection(allRatings);
|
||||
}
|
||||
|
||||
public Person getDirector() {
|
||||
return director;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title=title;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public void setImdbId(String imdbId) {
|
||||
this.imdbId = imdbId;
|
||||
}
|
||||
|
||||
public void setTagline(String tagline) {
|
||||
this.tagline = tagline;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setReleaseDate(Date releaseDate) {
|
||||
this.releaseDate = releaseDate;
|
||||
}
|
||||
|
||||
public void setRuntime(Integer runtime) {
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
public void setHomepage(String homepage) {
|
||||
this.homepage = homepage;
|
||||
}
|
||||
|
||||
public void setTrailer(String trailer) {
|
||||
this.trailer = trailer;
|
||||
}
|
||||
|
||||
public void setGenre(String genre) {
|
||||
this.genre = genre;
|
||||
}
|
||||
|
||||
public void setStudio(String studio) {
|
||||
this.studio = studio;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public void setLastModified(Date lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public String getImdbId() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public String getTagline() {
|
||||
return tagline;
|
||||
}
|
||||
|
||||
public Date getReleaseDate() {
|
||||
return releaseDate;
|
||||
}
|
||||
|
||||
public Integer getRuntime() {
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public String getHomepage() {
|
||||
return homepage;
|
||||
}
|
||||
|
||||
public String getTrailer() {
|
||||
return trailer;
|
||||
}
|
||||
|
||||
public String getGenre() {
|
||||
return genre;
|
||||
}
|
||||
|
||||
public String getStudio() {
|
||||
return studio;
|
||||
}
|
||||
|
||||
public Integer getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public Date getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public String getYoutubeId() {
|
||||
String trailerUrl = trailer;
|
||||
if (trailerUrl==null || !trailerUrl.contains("youtu")) return null;
|
||||
String[] parts = trailerUrl.split("[=/]");
|
||||
int numberOfParts = parts.length;
|
||||
return numberOfParts > 0 ? parts[numberOfParts-1] : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
import org.springframework.data.neo4j.annotation.MapResult;
|
||||
import org.springframework.data.neo4j.annotation.ResultColumn;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.11.11
|
||||
*/
|
||||
@MapResult
|
||||
public interface MovieRecommendation {
|
||||
@ResultColumn("otherMovie")
|
||||
Movie getMovie();
|
||||
|
||||
@ResultColumn("rating")
|
||||
int getRating();
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
import org.springframework.data.neo4j.annotation.Indexed;
|
||||
import org.springframework.data.neo4j.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.annotation.RelatedTo;
|
||||
import org.springframework.data.neo4j.annotation.RelatedToVia;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 12.03.11
|
||||
*/
|
||||
@NodeEntity
|
||||
public class Person {
|
||||
@Indexed(unique=true)
|
||||
String id;
|
||||
@Indexed(indexType=IndexType.FULLTEXT, indexName = "people")
|
||||
String name;
|
||||
private Date birthday;
|
||||
private String birthplace;
|
||||
private String biography;
|
||||
private Integer version;
|
||||
private Date lastModified;
|
||||
private String profileImageUrl;
|
||||
|
||||
public Person(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s [%s]", name, id);
|
||||
}
|
||||
|
||||
public void setBirthday(Date birthday) {
|
||||
this.birthday = birthday;
|
||||
}
|
||||
|
||||
public void setBirthplace(String birthplace) {
|
||||
this.birthplace = birthplace;
|
||||
}
|
||||
|
||||
public void setBiography(String biography) {
|
||||
this.biography = biography;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public void setLastModified(Date lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public Date getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public String getBirthplace() {
|
||||
return birthplace;
|
||||
}
|
||||
|
||||
public String getBiography() {
|
||||
return biography;
|
||||
}
|
||||
|
||||
public Integer getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public Date getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
public void setProfileImageUrl(String profileImageUrl) {
|
||||
this.profileImageUrl = profileImageUrl;
|
||||
}
|
||||
|
||||
public String getProfileImageUrl() {
|
||||
return profileImageUrl;
|
||||
}
|
||||
|
||||
@RelatedTo(elementClass = Movie.class, type = "DIRECTED")
|
||||
private Set<Movie> directedMovies;
|
||||
|
||||
public Set<Movie> getDirectedMovies() {
|
||||
return directedMovies;
|
||||
}
|
||||
|
||||
public void directed(Movie movie) {
|
||||
this.directedMovies.add(movie);
|
||||
}
|
||||
|
||||
@RelatedToVia
|
||||
Set<Role> roles;
|
||||
|
||||
public Set<Role> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public Role playedIn(Movie movie, String roleName) {
|
||||
final Role role = new Role(movie,this,roleName);
|
||||
getRoles().add(role);
|
||||
return role;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
import org.springframework.data.neo4j.annotation.EndNode;
|
||||
import org.springframework.data.neo4j.annotation.RelationshipEntity;
|
||||
import org.springframework.data.neo4j.annotation.StartNode;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@RelationshipEntity
|
||||
public class Rating {
|
||||
private static final int MAX_STARS = 5;
|
||||
private static final int MIN_STARS = 0;
|
||||
|
||||
@StartNode
|
||||
User user;
|
||||
@EndNode Movie movie;
|
||||
|
||||
int stars;
|
||||
String comment;
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public Movie getMovie() {
|
||||
return movie;
|
||||
}
|
||||
|
||||
public int getStars() {
|
||||
return stars;
|
||||
}
|
||||
|
||||
public void setStars(int stars) {
|
||||
this.stars = stars;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public Rating rate(int stars, String comment) {
|
||||
if (stars>= MIN_STARS && stars <= MAX_STARS) this.stars=stars;
|
||||
if (comment!=null && !comment.isEmpty()) this.comment = comment;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
import org.springframework.data.neo4j.annotation.EndNode;
|
||||
import org.springframework.data.neo4j.annotation.RelationshipEntity;
|
||||
import org.springframework.data.neo4j.annotation.StartNode;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@RelationshipEntity(type = "ACTS_IN")
|
||||
public class Role {
|
||||
@EndNode Movie movie;
|
||||
@StartNode Person actor;
|
||||
|
||||
String name;
|
||||
|
||||
public Role() {
|
||||
}
|
||||
|
||||
public Role(Movie movie, Person actor, String roleName) {
|
||||
this.movie = movie;
|
||||
this.actor = actor;
|
||||
this.name = roleName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Movie getMovie() {
|
||||
return movie;
|
||||
}
|
||||
|
||||
public Person getActor() {
|
||||
return actor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s acts as %s in %s", actor, name, movie);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 12.03.11
|
||||
*/
|
||||
public enum Roles {
|
||||
ACTS_IN, DIRECTED
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.springframework.data.neo4j.annotation.Indexed;
|
||||
import org.springframework.data.neo4j.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.annotation.RelatedTo;
|
||||
import org.springframework.data.neo4j.annotation.RelatedToVia;
|
||||
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
@NodeEntity
|
||||
public class User {
|
||||
private static final String SALT = "cewuiqwzie";
|
||||
public static final String FRIEND = "FRIEND";
|
||||
public static final String RATED = "RATED";
|
||||
@Indexed
|
||||
String login;
|
||||
String name;
|
||||
String password;
|
||||
String info;
|
||||
private Roles[] roles;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String login, String name, String password, Roles... roles) {
|
||||
this.login = login;
|
||||
this.name = name;
|
||||
this.password = encode(password);
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
private String encode(String password) {
|
||||
return new Md5PasswordEncoder().encodePassword(password, SALT);
|
||||
}
|
||||
|
||||
@RelatedToVia(elementClass = Rating.class, type = RATED)
|
||||
Iterable<Rating> ratings;
|
||||
|
||||
@RelatedTo(elementClass = Movie.class, type = RATED)
|
||||
Set<Movie> favorites;
|
||||
|
||||
|
||||
@RelatedTo(elementClass = User.class, type = FRIEND, direction = Direction.BOTH)
|
||||
Set<User> friends;
|
||||
|
||||
public void addFriend(User friend) {
|
||||
this.friends.add(friend);
|
||||
}
|
||||
|
||||
public Rating rate(Movie movie, int stars, String comment) {
|
||||
return relateTo(movie, Rating.class, RATED).rate(stars, comment);
|
||||
}
|
||||
|
||||
public Collection<Rating> getRatings() {
|
||||
return IteratorUtil.asCollection(ratings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s (%s)", name, login);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Set<User> getFriends() {
|
||||
return friends;
|
||||
}
|
||||
|
||||
public Roles[] getRole() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
public void updatePassword(String old, String newPass1, String newPass2) {
|
||||
if (!password.equals(encode(old))) throw new IllegalArgumentException("Existing Password invalid");
|
||||
if (!newPass1.equals(newPass2)) throw new IllegalArgumentException("New Passwords don't match");
|
||||
this.password = encode(newPass1);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isFriend(User other) {
|
||||
return other!=null && getFriends().contains(other);
|
||||
}
|
||||
|
||||
public enum Roles implements GrantedAuthority {
|
||||
ROLE_USER, ROLE_ADMIN;
|
||||
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MovieDbApiClient {
|
||||
|
||||
private final String baseUrl = "http://api.themoviedb.org/";
|
||||
private final String apiKey;
|
||||
protected final ObjectMapper mapper;
|
||||
|
||||
public MovieDbApiClient(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
mapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
public Map getMovie(String id) {
|
||||
return loadJsonData(id, buildMovieUrl(id));
|
||||
}
|
||||
|
||||
private Map loadJsonData(String id, String url) {
|
||||
try {
|
||||
List value = mapper.readValue(new URL(url), List.class);
|
||||
if (value.isEmpty() || value.get(0).equals("Nothing found.")) return Collections.singletonMap("not_found",System.currentTimeMillis());
|
||||
return (Map) value.get(0);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get data from " + url, e);
|
||||
}
|
||||
}
|
||||
|
||||
private String buildMovieUrl(String movieId) {
|
||||
return String.format("%s2.1/Movie.getInfo/en/json/%s/%s", baseUrl, apiKey, movieId);
|
||||
}
|
||||
|
||||
public Map getPerson(String id) {
|
||||
return loadJsonData(id, buildPersonUrl(id));
|
||||
}
|
||||
|
||||
private String buildPersonUrl(String personId) {
|
||||
return String.format("%s2.1/Person.getInfo/en/json/%s/%s", baseUrl, apiKey, personId);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
public class MovieDbException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MovieDbException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MovieDbException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
import org.neo4j.cineasts.domain.*;
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.neo4j.cineasts.repository.PersonRepository;
|
||||
import org.neo4j.cineasts.service.CineastsRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class MovieDbImportService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MovieDbImportService.class);
|
||||
MovieDbJsonMapper movieDbJsonMapper = new MovieDbJsonMapper();
|
||||
|
||||
@Autowired
|
||||
MovieRepository movieRepository;
|
||||
@Autowired
|
||||
PersonRepository personRepository;
|
||||
|
||||
@Autowired
|
||||
MovieDbApiClient client;
|
||||
|
||||
@Autowired
|
||||
MovieDbLocalStorage localStorage;
|
||||
|
||||
@Transactional
|
||||
public Map<Integer, String> importMovies(Map<Integer, Integer> ranges) {
|
||||
final Map<Integer,String> movies=new LinkedHashMap<Integer, String>();
|
||||
for (Map.Entry<Integer, Integer> entry : ranges.entrySet()) {
|
||||
for (int id = entry.getKey(); id <= entry.getValue(); id++) {
|
||||
String result = importMovieFailsafe(id);
|
||||
movies.put(id, result);
|
||||
}
|
||||
}
|
||||
return movies;
|
||||
}
|
||||
|
||||
private String importMovieFailsafe(Integer id) {
|
||||
try {
|
||||
Movie movie = doImportMovie(String.valueOf(id));
|
||||
return movie.getTitle();
|
||||
} catch (Exception e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Movie importMovie(String movieId) {
|
||||
return doImportMovie(movieId);
|
||||
}
|
||||
|
||||
private Movie doImportMovie(String movieId) {
|
||||
logger.debug("Importing movie " + movieId);
|
||||
|
||||
Movie movie = movieRepository.findById(movieId);
|
||||
if (movie == null) { // Not found: Create fresh
|
||||
movie = new Movie(movieId,null);
|
||||
}
|
||||
|
||||
Map data = loadMovieData(movieId);
|
||||
if (data.containsKey("not_found")) throw new RuntimeException("Data for Movie "+movieId+" not found.");
|
||||
movieDbJsonMapper.mapToMovie(data, movie);
|
||||
movie.persist();
|
||||
relatePersonsToMovie(movie, data);
|
||||
return movie;
|
||||
}
|
||||
|
||||
private Map loadMovieData(String movieId) {
|
||||
if (localStorage.hasMovie(movieId)) {
|
||||
return localStorage.loadMovie(movieId);
|
||||
}
|
||||
|
||||
Map data = client.getMovie(movieId);
|
||||
localStorage.storeMovie(movieId, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void relatePersonsToMovie(Movie movie, Map data) {
|
||||
Collection<Map> cast = (Collection<Map>) data.get("cast");
|
||||
for (Map entry : cast) {
|
||||
String id = "" + entry.get("id");
|
||||
String jobName = (String) entry.get("job");
|
||||
Roles job = movieDbJsonMapper.mapToRole(jobName);
|
||||
if (job==null) {
|
||||
if (logger.isInfoEnabled()) logger.info("Could not add person with job "+jobName+" "+entry);
|
||||
continue;
|
||||
}
|
||||
Person person = doImportPerson(id);
|
||||
switch (job) {
|
||||
case DIRECTED:
|
||||
person.directed(movie);
|
||||
break;
|
||||
case ACTS_IN:
|
||||
person.playedIn(movie, (String) entry.get("character"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Person importPerson(String personId) {
|
||||
return doImportPerson(personId);
|
||||
}
|
||||
|
||||
private Person doImportPerson(String personId) {
|
||||
logger.debug("Importing person " + personId);
|
||||
Person person = personRepository.findById(personId);
|
||||
if (person!=null) return person;
|
||||
Map data = loadPersonData(personId);
|
||||
if (data.containsKey("not_found")) throw new RuntimeException("Data for Person "+personId+" not found.");
|
||||
Person newPerson=new Person(personId,null);
|
||||
movieDbJsonMapper.mapToPerson(data, newPerson);
|
||||
return newPerson.persist();
|
||||
}
|
||||
|
||||
private Map loadPersonData(String personId) {
|
||||
if (localStorage.hasPerson(personId)) {
|
||||
return localStorage.loadPerson(personId);
|
||||
}
|
||||
Map data = client.getPerson(personId);
|
||||
localStorage.storePerson(personId, data);
|
||||
return localStorage.loadPerson(personId);
|
||||
}
|
||||
}
|
||||
@@ -1,708 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.Person;
|
||||
import org.neo4j.cineasts.domain.Roles;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class MovieDbJsonMapper {
|
||||
|
||||
public void mapToMovie(Map data, Movie movie) {
|
||||
try {
|
||||
movie.setTitle((String) data.get("name"));
|
||||
movie.setLanguage((String) data.get("language"));
|
||||
movie.setImdbId((String) data.get("imdb_id"));
|
||||
movie.setTagline((String) data.get("tagline"));
|
||||
movie.setDescription(limit((String) data.get("overview"), 500));
|
||||
movie.setReleaseDate(toDate(data, "released", "yyyy-MM-dd"));
|
||||
movie.setRuntime((Integer) data.get("runtime"));
|
||||
movie.setHomepage((String) data.get("homepage"));
|
||||
movie.setTrailer((String) data.get("trailer"));
|
||||
movie.setGenre(extractFirst(data, "genres", "name"));
|
||||
movie.setStudio(extractFirst(data,"studios", "name"));
|
||||
movie.setVersion((Integer)data.get("version"));
|
||||
movie.setLastModified(toDate(data,"last_modified_at","yyyy-MM-dd HH:mm:ss"));
|
||||
movie.setImageUrl(selectImageUrl((List<Map>) data.get("posters"), "poster", "mid"));
|
||||
} catch (Exception e) {
|
||||
throw new MovieDbException("Failed to map json for movie", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String selectImageUrl(List<Map> data, final String type, final String size) {
|
||||
if (data==null) return null;
|
||||
for (Map entry : data) {
|
||||
Map image = (Map) entry.get("image");
|
||||
if (image.get("type").equals(type) && image.get("size").equals(size)) return (String) image.get("url");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private String extractFirst(Map data, String field, String property) {
|
||||
List<Map> inner = (List<Map>) data.get(field);
|
||||
if (inner == null || inner.isEmpty()) return null;
|
||||
return (String) inner.get(0).get(property);
|
||||
}
|
||||
|
||||
private Date toDate(Map data, String field, final String pattern) throws ParseException {
|
||||
try {
|
||||
String dateString = (String) data.get(field);
|
||||
if (dateString == null || dateString.isEmpty()) return null;
|
||||
return new SimpleDateFormat(pattern).parse(dateString);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
[{"popularity":3,
|
||||
"translated":true,
|
||||
"adult":false,
|
||||
"language":"en",
|
||||
"original_name":"[Rec]",
|
||||
"name":"[Rec]",
|
||||
"alternative_name":"[REC]",
|
||||
"movie_type":"movie",
|
||||
"id":8329,
|
||||
"imdb_id":"tt1038988",
|
||||
"url":"http://www.themoviedb.org/movie/8329",
|
||||
"votes":11,
|
||||
"rating":7.2,
|
||||
"status":"Released",
|
||||
"tagline":"One Witness. One Camera",
|
||||
"certification":"R",
|
||||
"overview":"\"REC\" turns on a young TV reporter and her cameraman who cover the night shift at the local fire station. Receiving a call from an old lady trapped in her house,
|
||||
they reach her building to hear horrifying screams -- which begin a long nightmare and a uniquely dramatic TV report.",
|
||||
"keywords":["terror",
|
||||
"lebende leichen",
|
||||
"obsession",
|
||||
"camcorder",
|
||||
"firemen",
|
||||
"reality tv ",
|
||||
"bite",
|
||||
"cinematographer",
|
||||
"attempt to escape",
|
||||
"virus",
|
||||
"lodger",
|
||||
"live-reportage",
|
||||
"schwerverletzt"],
|
||||
"released":"2007-08-29",
|
||||
"runtime":78,
|
||||
"budget":0,
|
||||
"revenue":0,
|
||||
"homepage":"http://www.3l-filmverleih.de/rec",
|
||||
"trailer":"http://www.youtube.com/watch?v=YQUkX_XowqI",
|
||||
"genres":[{"type":"genre",
|
||||
"url":"http://themoviedb.org/genre/horror",
|
||||
"name":"Horror",
|
||||
"id":27}],
|
||||
"studios":[{"url":"http://www.themoviedb.org/company/2270",
|
||||
"name":"Filmax Group",
|
||||
"id":2270}],
|
||||
"languages_spoken":[{"code":"es",
|
||||
"name":"Spanish",
|
||||
"native_name":"Espa\u00f1ol"}],
|
||||
"countries":[{"code":"ES",
|
||||
"name":"Spain",
|
||||
"url":"http://www.themoviedb.org/country/es"}],
|
||||
"posters":[{"image":{"type":"poster",
|
||||
"size":"original",
|
||||
"height":1000,
|
||||
"width":706,
|
||||
"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-original.jpg",
|
||||
"id":"4cc8df415e73d650240003a0"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"mid",
|
||||
"height":708,
|
||||
"width":500,
|
||||
"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-mid.jpg",
|
||||
"id":"4cc8df415e73d650240003a0"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"cover",
|
||||
"height":262,
|
||||
"width":185,
|
||||
"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-cover.jpg",
|
||||
"id":"4cc8df415e73d650240003a0"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"thumb",
|
||||
"height":130,
|
||||
"width":92,
|
||||
"url":"http://cf1.imgobject.com/posters/3a0/4cc8df415e73d650240003a0/rec-thumb.jpg",
|
||||
"id":"4cc8df415e73d650240003a0"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"original",
|
||||
"height":1000,
|
||||
"width":711,
|
||||
"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-original.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1e7"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"mid",
|
||||
"height":703,
|
||||
"width":500,
|
||||
"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-mid.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1e7"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"cover",
|
||||
"height":260,
|
||||
"width":185,
|
||||
"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-cover.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1e7"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"thumb",
|
||||
"height":129,
|
||||
"width":92,
|
||||
"url":"http://cf1.imgobject.com/posters/1e7/4bc92117017a3c57fe00d1e7/rec-thumb.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1e7"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"original",
|
||||
"height":1500,
|
||||
"width":1000,
|
||||
"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-original.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1ec"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"mid",
|
||||
"height":750,
|
||||
"width":500,
|
||||
"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-mid.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1ec"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"cover",
|
||||
"height":278,
|
||||
"width":185,
|
||||
"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-cover.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1ec"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"thumb",
|
||||
"height":138,
|
||||
"width":92,
|
||||
"url":"http://cf1.imgobject.com/posters/1ec/4bc92118017a3c57fe00d1ec/rec-thumb.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1ec"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"original",
|
||||
"height":1429,
|
||||
"width":1000,
|
||||
"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-original.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f1"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"mid",
|
||||
"height":715,
|
||||
"width":500,
|
||||
"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-mid.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f1"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"cover",
|
||||
"height":265,
|
||||
"width":185,
|
||||
"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-cover.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f1"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"thumb",
|
||||
"height":132,
|
||||
"width":92,
|
||||
"url":"http://cf1.imgobject.com/posters/1f1/4bc92118017a3c57fe00d1f1/rec-thumb.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f1"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"original",
|
||||
"height":1125,
|
||||
"width":800,
|
||||
"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-original.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f6"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"mid",
|
||||
"height":703,
|
||||
"width":500,
|
||||
"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-mid.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f6"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"cover",
|
||||
"height":260,
|
||||
"width":185,
|
||||
"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-cover.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f6"}},
|
||||
{"image":{"type":"poster",
|
||||
"size":"thumb",
|
||||
"height":129,
|
||||
"width":92,
|
||||
"url":"http://cf1.imgobject.com/posters/1f6/4bc92118017a3c57fe00d1f6/rec-thumb.jpg",
|
||||
"id":"4bc92118017a3c57fe00d1f6"}}],
|
||||
"backdrops":[{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1df/4bc92117017a3c57fe00d1df/rec-original.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1df"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1df/4bc92117017a3c57fe00d1df/rec-poster.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1df"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1df/4bc92117017a3c57fe00d1df/rec-thumb.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1df"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1d7/4bc92113017a3c57fe00d1d7/rec-original.jpg",
|
||||
"id":"4bc92113017a3c57fe00d1d7"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1d7/4bc92113017a3c57fe00d1d7/rec-poster.jpg",
|
||||
"id":"4bc92113017a3c57fe00d1d7"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1d7/4bc92113017a3c57fe00d1d7/rec-thumb.jpg",
|
||||
"id":"4bc92113017a3c57fe00d1d7"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1e3/4bc92117017a3c57fe00d1e3/rec-original.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1e3"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1e3/4bc92117017a3c57fe00d1e3/rec-poster.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1e3"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1e3/4bc92117017a3c57fe00d1e3/rec-thumb.jpg",
|
||||
"id":"4bc92117017a3c57fe00d1e3"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1d3/4bc92113017a3c57fe00d1d3/rec-original.jpg",
|
||||
"id":"4bc92113017a3c57fe00d1d3"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1d3/4bc92113017a3c57fe00d1d3/rec-poster.jpg",
|
||||
"id":"4bc92113017a3c57fe00d1d3"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1d3/4bc92113017a3c57fe00d1d3/rec-thumb.jpg",
|
||||
"id":"4bc92113017a3c57fe00d1d3"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1db/4bc92114017a3c57fe00d1db/rec-original.jpg",
|
||||
"id":"4bc92114017a3c57fe00d1db"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1db/4bc92114017a3c57fe00d1db/rec-poster.jpg",
|
||||
"id":"4bc92114017a3c57fe00d1db"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/1db/4bc92114017a3c57fe00d1db/rec-thumb.jpg",
|
||||
"id":"4bc92114017a3c57fe00d1db"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/6f4/4d0e39c25e73d637100016f4/rec-original.jpg",
|
||||
"id":"4d0e39c25e73d637100016f4"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/6f4/4d0e39c25e73d637100016f4/rec-poster.jpg",
|
||||
"id":"4d0e39c25e73d637100016f4"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/6f4/4d0e39c25e73d637100016f4/rec-thumb.jpg",
|
||||
"id":"4d0e39c25e73d637100016f4"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/567/4d0e39dd5e73d6370a001567/rec-original.jpg",
|
||||
"id":"4d0e39dd5e73d6370a001567"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/567/4d0e39dd5e73d6370a001567/rec-poster.jpg",
|
||||
"id":"4d0e39dd5e73d6370a001567"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/567/4d0e39dd5e73d6370a001567/rec-thumb.jpg",
|
||||
"id":"4d0e39dd5e73d6370a001567"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/58a/4d0e39fb5e73d6371c00158a/rec-original.jpg",
|
||||
"id":"4d0e39fb5e73d6371c00158a"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/58a/4d0e39fb5e73d6371c00158a/rec-poster.jpg",
|
||||
"id":"4d0e39fb5e73d6371c00158a"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/58a/4d0e39fb5e73d6371c00158a/rec-thumb.jpg",
|
||||
"id":"4d0e39fb5e73d6371c00158a"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/5f4/4d0e3a185e73d6370e0015f4/rec-original.jpg",
|
||||
"id":"4d0e3a185e73d6370e0015f4"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/5f4/4d0e3a185e73d6370e0015f4/rec-poster.jpg",
|
||||
"id":"4d0e3a185e73d6370e0015f4"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/5f4/4d0e3a185e73d6370e0015f4/rec-thumb.jpg",
|
||||
"id":"4d0e3a185e73d6370e0015f4"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"original",
|
||||
"height":1080,
|
||||
"width":1920,
|
||||
"url":"http://cf1.imgobject.com/backdrops/67f/4d0e3a395e73d6371600167f/rec-original.jpg",
|
||||
"id":"4d0e3a395e73d6371600167f"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"poster",
|
||||
"height":439,
|
||||
"width":780,
|
||||
"url":"http://cf1.imgobject.com/backdrops/67f/4d0e3a395e73d6371600167f/rec-poster.jpg",
|
||||
"id":"4d0e3a395e73d6371600167f"}},
|
||||
{"image":{"type":"backdrop",
|
||||
"size":"thumb",
|
||||
"height":169,
|
||||
"width":300,
|
||||
"url":"http://cf1.imgobject.com/backdrops/67f/4d0e3a395e73d6371600167f/rec-thumb.jpg",
|
||||
"id":"4d0e3a395e73d6371600167f"}}],
|
||||
"cast":[{"name":"Manuela Velasco",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Angela Vidal",
|
||||
"id":34793,
|
||||
"order":0,
|
||||
"cast_id":1,
|
||||
"url":"http://www.themoviedb.org/person/34793",
|
||||
"profile":"http://cf1.imgobject.com/profiles/390/4c0157fa017a3c702d001390/manuela-velasco-thumb.jpg"},
|
||||
{"name":"Carlos Lasarte",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"C\u00e9sar",
|
||||
"id":54519,
|
||||
"order":2,
|
||||
"cast_id":3,
|
||||
"url":"http://www.themoviedb.org/person/54519",
|
||||
"profile":"http://cf1.imgobject.com/profiles/ba6/4d27aa297b9aa134d3001ba6/carlos-lasarte-thumb.jpg"},
|
||||
{"name":"Pablo Rosso",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Marcos",
|
||||
"id":54520,
|
||||
"order":3,
|
||||
"cast_id":4,
|
||||
"url":"http://www.themoviedb.org/person/54520",
|
||||
"profile":""},
|
||||
{"name":"David Vert",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Alex",
|
||||
"id":54521,
|
||||
"order":4,
|
||||
"cast_id":5,
|
||||
"url":"http://www.themoviedb.org/person/54521",
|
||||
"profile":"http://cf1.imgobject.com/profiles/c7e/4d27aad57b9aa134cb001c7e/david-vert-thumb.jpg"},
|
||||
{"name":"Vicente Gil",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Polizist",
|
||||
"id":54522,
|
||||
"order":5,
|
||||
"cast_id":6,
|
||||
"url":"http://www.themoviedb.org/person/54522",
|
||||
"profile":"http://cf1.imgobject.com/profiles/c86/4d27ab237b9aa134cb001c86/vicente-gil-thumb.jpg"},
|
||||
{"name":"Martha Carbonell",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Frau Izquierdo",
|
||||
"id":54523,
|
||||
"order":6,
|
||||
"cast_id":7,
|
||||
"url":"http://www.themoviedb.org/person/54523",
|
||||
"profile":"http://cf1.imgobject.com/profiles/c90/4d27ab777b9aa134cb001c90/martha-carbonell-thumb.jpg"},
|
||||
{"name":"Carlos Vicente",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Guillem",
|
||||
"id":54524,
|
||||
"order":7,
|
||||
"cast_id":8,
|
||||
"url":"http://www.themoviedb.org/person/54524",
|
||||
"profile":"http://cf1.imgobject.com/profiles/b0f/4d27abcc7b9aa134cf001b0f/carlos-vicente-thumb.jpg"},
|
||||
{"name":"Ferran Terraza",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Manu",
|
||||
"id":54532,
|
||||
"order":8,
|
||||
"cast_id":22,
|
||||
"url":"http://www.themoviedb.org/person/54532",
|
||||
"profile":"http://cf1.imgobject.com/profiles/129/4c4bfbab7b9aa1237f000129/ferran-terraza-thumb.jpg"},
|
||||
{"name":"Jorge Yamam",
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Sergio",
|
||||
"id":147878,
|
||||
"order":9,
|
||||
"cast_id":23,
|
||||
"url":"http://www.themoviedb.org/person/147878",
|
||||
"profile":"http://cf1.imgobject.com/profiles/cbb/4d27ac677b9aa134dc001cbb/jorge-yamam-thumb.jpg"},
|
||||
{"name":"Jaume Balaguer\u00f3",
|
||||
"job":"Director",
|
||||
"department":"Directing",
|
||||
"character":"",
|
||||
"id":54525,
|
||||
"order":0,
|
||||
"cast_id":9,
|
||||
"url":"http://www.themoviedb.org/person/54525",
|
||||
"profile":""},
|
||||
{"name":"Paco Plaza",
|
||||
"job":"Director",
|
||||
"department":"Directing",
|
||||
"character":"",
|
||||
"id":54526,
|
||||
"order":0,
|
||||
"cast_id":10,
|
||||
"url":"http://www.themoviedb.org/person/54526",
|
||||
"profile":""},
|
||||
{"name":"Jaume Balaguer\u00f3",
|
||||
"job":"Screenplay",
|
||||
"department":"Writing",
|
||||
"character":"",
|
||||
"id":54525,
|
||||
"order":0,
|
||||
"cast_id":11,
|
||||
"url":"http://www.themoviedb.org/person/54525",
|
||||
"profile":""},
|
||||
{"name":"Paco Plaza",
|
||||
"job":"Screenplay",
|
||||
"department":"Writing",
|
||||
"character":"",
|
||||
"id":54526,
|
||||
"order":0,
|
||||
"cast_id":12,
|
||||
"url":"http://www.themoviedb.org/person/54526",
|
||||
"profile":""},
|
||||
{"name":"Luis Berdejo",
|
||||
"job":"Screenplay",
|
||||
"department":"Writing",
|
||||
"character":"",
|
||||
"id":54527,
|
||||
"order":0,
|
||||
"cast_id":13,
|
||||
"url":"http://www.themoviedb.org/person/54527",
|
||||
"profile":""},
|
||||
{"name":"Julio Fern\u00e1ndez",
|
||||
"job":"Producer",
|
||||
"department":"Production",
|
||||
"character":"",
|
||||
"id":17083,
|
||||
"order":0,
|
||||
"cast_id":14,
|
||||
"url":"http://www.themoviedb.org/person/17083",
|
||||
"profile":""},
|
||||
{"name":"Carlos Fern\u00e1ndez",
|
||||
"job":"Executive Producer",
|
||||
"department":"Production",
|
||||
"character":"",
|
||||
"id":37950,
|
||||
"order":0,
|
||||
"cast_id":15,
|
||||
"url":"http://www.themoviedb.org/person/37950",
|
||||
"profile":""},
|
||||
{"name":"Alberto Marini",
|
||||
"job":"Producer",
|
||||
"department":"Production",
|
||||
"character":"",
|
||||
"id":54528,
|
||||
"order":0,
|
||||
"cast_id":16,
|
||||
"url":"http://www.themoviedb.org/person/54528",
|
||||
"profile":""},
|
||||
{"name":"Pablo Rosso",
|
||||
"job":"Director of Photography",
|
||||
"department":"Camera",
|
||||
"character":"",
|
||||
"id":54520,
|
||||
"order":0,
|
||||
"cast_id":17,
|
||||
"url":"http://www.themoviedb.org/person/54520",
|
||||
"profile":""},
|
||||
{"name":"Gemma Fauria",
|
||||
"job":"Set Designer",
|
||||
"department":"Art",
|
||||
"character":"",
|
||||
"id":54529,
|
||||
"order":0,
|
||||
"cast_id":18,
|
||||
"url":"http://www.themoviedb.org/person/54529",
|
||||
"profile":""},
|
||||
{"name":"David Gallart",
|
||||
"job":"Editor",
|
||||
"department":"Editing",
|
||||
"character":"",
|
||||
"id":28500,
|
||||
"order":0,
|
||||
"cast_id":19,
|
||||
"url":"http://www.themoviedb.org/person/28500",
|
||||
"profile":""},
|
||||
{"name":"Xavier Mas",
|
||||
"job":"Sound Designer",
|
||||
"department":"Sound",
|
||||
"character":"",
|
||||
"id":54530,
|
||||
"order":0,
|
||||
"cast_id":20,
|
||||
"url":"http://www.themoviedb.org/person/54530",
|
||||
"profile":""},
|
||||
{"name":"Gl\u00f2ria Viguer",
|
||||
"job":"Costume Design",
|
||||
"department":"Costume \u0026 Make-Up",
|
||||
"character":"",
|
||||
"id":54531,
|
||||
"order":0,
|
||||
"cast_id":21,
|
||||
"url":"http://www.themoviedb.org/person/54531",
|
||||
"profile":""}],
|
||||
"version":150,
|
||||
"last_modified_at":"2011-02-20 23:16:57"}]
|
||||
*/
|
||||
|
||||
public void mapToPerson(Map data, Person person) {
|
||||
try {
|
||||
person.setName((String) data.get("name"));
|
||||
person.setBirthday(toDate(data, "birthday", "yyyy-MM-dd"));
|
||||
person.setBirthplace((String) data.get("birthplace"));
|
||||
String biography = (String) data.get("biography");
|
||||
person.setBiography(limit(biography,500));
|
||||
person.setVersion((Integer) data.get("version"));
|
||||
person.setProfileImageUrl(selectImageUrl((List<Map>) data.get("profile"), "profile", "profile"));
|
||||
person.setLastModified(toDate(data,"last_modified_at","yyyy-MM-dd HH:mm:ss"));
|
||||
} catch (Exception e) {
|
||||
throw new MovieDbException("Failed to map json for person", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String limit(String text, int limit) {
|
||||
if (text==null || text.length() < limit) return text;
|
||||
return text.substring(0,limit);
|
||||
}
|
||||
|
||||
/*
|
||||
[{"popularity":3,
|
||||
"name":"Glenn Strange",
|
||||
"known_as":[{"name":"George Glenn Strange"},
|
||||
{"name":"Glen Strange"},
|
||||
{"name":"Glen 'Peewee' Strange"},
|
||||
{"name":"Peewee Strange"},
|
||||
{"name":"'Peewee' Strange"}],
|
||||
"id":30112,
|
||||
"biography":"",
|
||||
"known_movies":4,
|
||||
"birthday":"1899-08-16",
|
||||
"birthplace":"Weed,
|
||||
New Mexico,
|
||||
USA",
|
||||
"url":"http://www.themoviedb.org/person/30112",
|
||||
"filmography":[{"name":"Bud Abbott Lou Costello Meet Frankenstein",
|
||||
"id":3073,
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"The Frankenstein Monster",
|
||||
"cast_id":23,
|
||||
"url":"http://www.themoviedb.org/movie/3073",
|
||||
"poster":"http://cf1.imgobject.com/posters/4ca/4bc9185d017a3c57fe0094ca/bud-abbott-lou-costello-meet-frankenstein-cover.jpg",
|
||||
"adult":false,
|
||||
"release":"1948-06-15"},
|
||||
{"name":"Arizona Days (1937)",
|
||||
"id":22367,
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Henchman Pete ",
|
||||
"cast_id":12,
|
||||
"url":"http://www.themoviedb.org/movie/22367",
|
||||
"poster":"",
|
||||
"adult":false,
|
||||
"release":"1937-01-30"},
|
||||
{"name":"House of Dracula",
|
||||
"id":30793,
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"The Frankenstein Monster",
|
||||
"cast_id":3,
|
||||
"url":"http://www.themoviedb.org/movie/30793",
|
||||
"poster":"http://cf1.imgobject.com/posters/7cf/4bc97660017a3c57fe0367cf/house-of-dracula-cover.jpg",
|
||||
"adult":false,
|
||||
"release":"1945-01-01"},
|
||||
{"name":"The Fargo Kid",
|
||||
"id":38704,
|
||||
"job":"Actor",
|
||||
"department":"Actors",
|
||||
"character":"Sheriff Dave",
|
||||
"cast_id":24,
|
||||
"url":"http://www.themoviedb.org/movie/38704",
|
||||
"poster":"http://cf1.imgobject.com/posters/04e/4d74018a5e73d6021d00004e/the-fargo-kid-cover.jpg",
|
||||
"adult":false,
|
||||
"release":"1940-12-06"}],
|
||||
"profile":[],
|
||||
"version":19,
|
||||
"last_modified_at":"2011-03-07 13:02:35"}]
|
||||
*/
|
||||
|
||||
|
||||
public Roles mapToRole(String roleString) {
|
||||
if (roleString.equals("Actor")) {
|
||||
return Roles.ACTS_IN;
|
||||
}
|
||||
if (roleString.equals("Director")) {
|
||||
return Roles.DIRECTED;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MovieDbLocalStorage {
|
||||
|
||||
private String storagePath;
|
||||
protected ObjectMapper mapper;
|
||||
|
||||
public MovieDbLocalStorage(String storagePath) {
|
||||
this.storagePath = storagePath;
|
||||
ensureStorageDirectoryExists();
|
||||
mapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
private void ensureStorageDirectoryExists() {
|
||||
File storageDirectory = new File(storagePath);
|
||||
if (!storageDirectory.isDirectory()) {
|
||||
if (!storageDirectory.mkdirs()) {
|
||||
throw new RuntimeException("Failed to create storage dir");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMovie(String movieId) {
|
||||
return fileForMovie(movieId).exists();
|
||||
}
|
||||
|
||||
private File fileForMovie(String movieId) {
|
||||
return new File(storagePath, String.format("movie_%s.json", movieId));
|
||||
}
|
||||
|
||||
public Map loadMovie(String movieId) {
|
||||
File storageFile = fileForMovie(movieId);
|
||||
return loadJsonValue(storageFile);
|
||||
}
|
||||
|
||||
private Map loadJsonValue(File storageFile) {
|
||||
try {
|
||||
final Object value = mapper.readValue(storageFile, Object.class);
|
||||
if (value instanceof List) {
|
||||
List list = (List) value;
|
||||
if (list.isEmpty() || list.get(0).equals("Nothing found.")) return Collections.singletonMap("not_found", System.currentTimeMillis());
|
||||
return asMap(list.get(0));
|
||||
}
|
||||
return asMap(value);
|
||||
} catch (Exception e) {
|
||||
throw new MovieDbException("Failed to load JSON from storage for file " + storageFile.getPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map asMap(Object value) {
|
||||
if (value instanceof Map) {
|
||||
return (Map) value;
|
||||
}
|
||||
final String typeInformation = value == null ? "null" : value.getClass().getSimpleName();
|
||||
throw new MovieDbException("Wrong movie data format, expected Map/JSON-Object but was "+ typeInformation);
|
||||
}
|
||||
|
||||
public void storeMovie(String movieId, Object movieData) {
|
||||
File storageFile = fileForMovie(movieId);
|
||||
storeJsonValue(movieData, storageFile);
|
||||
}
|
||||
|
||||
private void storeJsonValue(Object jsonData, File storageFile) {
|
||||
try {
|
||||
mapper.writeValue(storageFile,jsonData);
|
||||
} catch (Exception e) {
|
||||
throw new MovieDbException("Failed to store JSON to storage for file " + storageFile.getPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPerson(String personId) {
|
||||
return fileForPerson(personId).exists();
|
||||
}
|
||||
|
||||
private File fileForPerson(String personId) {
|
||||
return new File(storagePath, String.format("person_%s.json", personId));
|
||||
}
|
||||
|
||||
public Map loadPerson(String personId) {
|
||||
File storageFile = fileForPerson(personId);
|
||||
return loadJsonValue(storageFile);
|
||||
}
|
||||
|
||||
public void storePerson(String personId, Object personJson) {
|
||||
File storageFile = fileForPerson(personId);
|
||||
storeJsonValue(personJson, storageFile);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
import org.springframework.context.support.FileSystemXmlApplicationContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.10.11
|
||||
*/
|
||||
public class MovieImporter {
|
||||
|
||||
private final MovieDbImportService importer;
|
||||
|
||||
public static void main(String[] args) {
|
||||
final FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("src/main/webapp/WEB-INF/applicationContext.xml");
|
||||
try {
|
||||
final MovieDbImportService importer = ctx.getBean(MovieDbImportService.class);
|
||||
final MovieImporter movieImporter = new MovieImporter(importer);
|
||||
movieImporter.runImport(getMovieIdsToImport(args));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public MovieImporter(MovieDbImportService importer) {
|
||||
this.importer = importer;
|
||||
}
|
||||
|
||||
private void runImport(Map<Integer, Integer> movieIdsToImport) {
|
||||
final long start = System.currentTimeMillis();
|
||||
final Map<Integer, String> result = importer.importMovies(movieIdsToImport);
|
||||
final long time = System.currentTimeMillis() - start;
|
||||
for (Map.Entry<Integer, String> movie : result.entrySet()) {
|
||||
System.out.println(movie.getKey() + "\t" + movie.getValue());
|
||||
}
|
||||
System.out.println("Imported movies took "+ time+" ms.");
|
||||
}
|
||||
|
||||
private static Map<Integer, Integer> getMovieIdsToImport(String[] args) {
|
||||
if (args.length == 0) {
|
||||
throw new IllegalArgumentException("Usage: MovieImporter 1 10000\nWorking Directory should be the cineasts directory with the json files in data/json.");
|
||||
}
|
||||
if (args.length == 1) {
|
||||
return Collections.singletonMap(Integer.valueOf(args[0]), Integer.valueOf(args[0]));
|
||||
}
|
||||
return Collections.singletonMap(Integer.valueOf(args[0]), Integer.valueOf(args[1]));
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package org.neo4j.cineasts.repository;
|
||||
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.MovieRecommendation;
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.neo4j.annotation.MapResult;
|
||||
import org.springframework.data.neo4j.annotation.Query;
|
||||
import org.springframework.data.neo4j.annotation.ResultColumn;
|
||||
import org.springframework.data.neo4j.repository.GraphRepository;
|
||||
import org.springframework.data.neo4j.repository.NamedIndexRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 02.04.11
|
||||
*/
|
||||
public interface MovieRepository extends GraphRepository<Movie>, NamedIndexRepository<Movie> {
|
||||
Movie findById(String id);
|
||||
|
||||
Page<Movie> findByTitleLike(String title, Pageable page);
|
||||
|
||||
@Query( "start user=node({0}) " +
|
||||
" match user-[r:RATED]->movie<-[r2:RATED]-other-[r3:RATED]->otherMovie " +
|
||||
" where r.stars >= 3 and r2.stars >= r.stars and r3.stars >= r.stars " +
|
||||
" return otherMovie, avg(r3.stars) as rating, count(*) as cnt" +
|
||||
" order by rating desc, cnt desc" +
|
||||
" limit 10" )
|
||||
List<MovieRecommendation> getRecommendations( User user );
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package org.neo4j.cineasts.repository;
|
||||
|
||||
import org.neo4j.cineasts.domain.Person;
|
||||
import org.springframework.data.neo4j.repository.GraphRepository;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 02.04.11
|
||||
*/
|
||||
public interface PersonRepository extends GraphRepository<Person> {
|
||||
Person findById(String id);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.neo4j.cineasts.repository;
|
||||
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.springframework.data.neo4j.repository.GraphRepository;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 02.04.11
|
||||
*/
|
||||
public interface UserRepository extends GraphRepository<User> {
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@Repository
|
||||
@Transactional
|
||||
public class CineastsRepository {
|
||||
|
||||
@Autowired private MovieRepository movieRepository;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 07.03.11
|
||||
*/
|
||||
public class CineastsUserDetails implements UserDetails {
|
||||
private final User user;
|
||||
|
||||
public CineastsUserDetails(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GrantedAuthority> getAuthorities() {
|
||||
User.Roles[] roles = user.getRole();
|
||||
if (roles ==null) return Collections.emptyList();
|
||||
return Arrays.<GrantedAuthority>asList(roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return user.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return user.getLogin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.neo4j.cineasts.repository.UserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 06.03.11
|
||||
*/
|
||||
@Service
|
||||
public class CineastsUserDetailsService implements UserDetailsService {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException {
|
||||
final User user = findUser(login);
|
||||
if (user==null) throw new UsernameNotFoundException("Username not found",login);
|
||||
return new CineastsUserDetails(user);
|
||||
}
|
||||
|
||||
public User findUser(String login) {
|
||||
return userRepository.findByPropertyValue("login",login);
|
||||
}
|
||||
|
||||
|
||||
public User getUserFromSession() {
|
||||
SecurityContext context = SecurityContextHolder.getContext();
|
||||
Authentication authentication = context.getAuthentication();
|
||||
Object principal = authentication.getPrincipal();
|
||||
if (principal instanceof CineastsUserDetails) {
|
||||
CineastsUserDetails userDetails = (CineastsUserDetails) principal;
|
||||
return userDetails.getUser();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public User register(String login, String name, String password) {
|
||||
User found = findUser(login);
|
||||
if (found!=null) throw new RuntimeException("Login already taken: "+login);
|
||||
if (name==null || name.isEmpty()) throw new RuntimeException("No name provided.");
|
||||
if (password==null || password.isEmpty()) throw new RuntimeException("No password provided.");
|
||||
User user=userRepository.save(new User(login,name,password,User.Roles.ROLE_USER));
|
||||
setUserInSession(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
private void setUserInSession(User user) {
|
||||
SecurityContext context = SecurityContextHolder.getContext();
|
||||
CineastsUserDetails userDetails = new CineastsUserDetails(user);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, user.getPassword(),userDetails.getAuthorities());
|
||||
context.setAuthentication(authentication);
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void addFriend(String login) {
|
||||
User friend = findUser(login);
|
||||
User user = getUserFromSession();
|
||||
if (!user.equals(friend)) {
|
||||
user.addFriend(friend);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void rate(User user, Movie movie, Integer stars, String comment) {
|
||||
if (user == null || movie == null) return;
|
||||
int stars1 = stars==null ? -1 : stars;
|
||||
String comment1 = comment!=null ? comment.trim() : null;
|
||||
user.rate(movie, stars1, comment1);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.neo4j.kernel.AbstractGraphDatabase;
|
||||
import org.neo4j.cineasts.domain.*;
|
||||
import org.neo4j.cineasts.movieimport.MovieDbImportService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@Service
|
||||
public class DatabasePopulator {
|
||||
|
||||
@Autowired
|
||||
Neo4jTemplate ctx;
|
||||
@Autowired
|
||||
MovieRepository movieRepository;
|
||||
|
||||
@Autowired
|
||||
MovieDbImportService importService;
|
||||
private final static Logger log = LoggerFactory.getLogger(DatabasePopulator.class);
|
||||
|
||||
@Transactional
|
||||
public List<Movie> populateDatabase() {
|
||||
User me = new User("micha", "Micha", "password", User.Roles.ROLE_ADMIN,User.Roles.ROLE_USER).persist();
|
||||
User ollie = new User("ollie", "Olliver", "password",User.Roles.ROLE_USER).persist();
|
||||
me.addFriend(ollie);
|
||||
List<Integer> ids = asList(19995 , 194, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 13, 20526, 11, 1893, 1892, 1894, 168, 193, 200, 157, 152, 201, 154, 12155, 58, 285, 118, 22, 392, 5255, 568, 9800, 497, 101, 120, 121, 122);
|
||||
List<Movie> result=new ArrayList<Movie>(ids.size());
|
||||
for (Integer id : ids) {
|
||||
result.add(importService.importMovie(String.valueOf(id)));
|
||||
}
|
||||
|
||||
//me.rate(repository.getMovie("13"),5,"Inspiring");
|
||||
me.rate(movieRepository.findById("603"),5,"Best of the series");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void cleanDb() {
|
||||
new Neo4jDatabaseCleaner((AbstractGraphDatabase) ctx.getGraphDatabaseService()).cleanDb();
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.Rating;
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.neo4j.graphdb.traversal.Evaluators;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.Uniqueness;
|
||||
import org.springframework.data.neo4j.core.EntityPath;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.neo4j.graphdb.DynamicRelationshipType.withName;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.04.11
|
||||
*/
|
||||
public class FriendsMovieRecommendations {
|
||||
private final Map<Movie, MovieRating> ratings = new HashMap<Movie, MovieRating>();
|
||||
private final int ratingDistance;
|
||||
|
||||
public static class MovieRating {
|
||||
int stars;
|
||||
int count;
|
||||
public void update(Rating rating, int weight) {
|
||||
this.stars += rating.getStars()*weight;
|
||||
this.count += weight;
|
||||
}
|
||||
public int average() {
|
||||
return count == 0 ? 0 : stars / count;
|
||||
}
|
||||
public String toString() {
|
||||
return String.valueOf(average());
|
||||
}
|
||||
|
||||
}
|
||||
public FriendsMovieRecommendations(int ratingDistance) {
|
||||
this.ratingDistance = ratingDistance;
|
||||
}
|
||||
|
||||
public Map<Movie, ?> getRecommendationsFor(User user) {
|
||||
TraversalDescription traversal = Traversal.description().breadthFirst()
|
||||
.uniqueness(Uniqueness.NODE_GLOBAL).relationships(withName(User.FRIEND))
|
||||
.evaluator(Evaluators.toDepth(ratingDistance)).evaluator(Evaluators.excludeStartPosition());
|
||||
|
||||
Iterable result = user.findAllPathsByTraversal(traversal);
|
||||
Iterable<EntityPath<User,User>> friends = (Iterable<EntityPath<User,User>>)result;
|
||||
for (EntityPath<User,User> path : friends) {
|
||||
int weight = ratingDistance - path.length();
|
||||
User friend = path.endEntity();
|
||||
aggregateRatings(friend,weight);
|
||||
}
|
||||
for (Rating rating : user.getRatings()) {
|
||||
ratings.remove(rating.getMovie());
|
||||
}
|
||||
return ratings;
|
||||
}
|
||||
|
||||
private void aggregateRatings(User friend, int weight) {
|
||||
for (Rating rating : friend.getRatings()) {
|
||||
obtainRating(rating.getMovie()).update(rating, weight);
|
||||
}
|
||||
}
|
||||
|
||||
private MovieRating obtainRating(Movie movie) {
|
||||
if (!ratings.containsKey(movie)) {
|
||||
ratings.put(movie, new MovieRating());
|
||||
}
|
||||
return ratings.get(movie);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.neo4j.graphdb.Path;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.graphdb.traversal.Evaluation;
|
||||
import org.neo4j.graphdb.traversal.Evaluator;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.Uniqueness;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.neo4j.graphdb.Direction.OUTGOING;
|
||||
import static org.neo4j.graphdb.DynamicRelationshipType.withName;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.04.11
|
||||
*/
|
||||
class MovieRecommendations implements Evaluator {
|
||||
private final Map<Long,int[]> ratings=new HashMap<Long, int[]>();
|
||||
private final int ratingDistance;
|
||||
private MovieRepository movieRepository;
|
||||
|
||||
public MovieRecommendations(MovieRepository movieRepository, int ratingDistance) {
|
||||
this.movieRepository = movieRepository;
|
||||
this.ratingDistance = ratingDistance;
|
||||
}
|
||||
|
||||
public Map<Movie, ?> getRecommendationsFor(User user) {
|
||||
TraversalDescription traversal= Traversal.description().breadthFirst()
|
||||
.uniqueness(Uniqueness.NODE_PATH)
|
||||
.relationships(withName(User.FRIEND))
|
||||
.relationships(withName(User.RATED), OUTGOING)
|
||||
.evaluator(this);
|
||||
return averageRecommendations(user, traversal);
|
||||
}
|
||||
|
||||
private Map<Movie, Integer> averageRecommendations(User user, TraversalDescription traversal) { // todo sort, limit
|
||||
Map<Movie,Integer> result=new HashMap<Movie, Integer>();
|
||||
for (Movie movie : movieRepository.findAllByTraversal(user, traversal)) {
|
||||
final int[] rating = ratings.get(movie.getNodeId());
|
||||
result.put(movie, rating[1]==0 ? 0 : rating[0]/rating[1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Evaluation evaluate(Path path) {
|
||||
final int distance = path.length() - 1;
|
||||
if (distance > ratingDistance) return Evaluation.EXCLUDE_AND_PRUNE;
|
||||
Relationship rated = path.lastRelationship();
|
||||
if (rated != null && rated.getType().name().equals(User.RATED)) {
|
||||
if (distance == 0) return Evaluation.EXCLUDE_AND_PRUNE; // my rated movies
|
||||
updateRating(rated, distance);
|
||||
return Evaluation.INCLUDE_AND_PRUNE;
|
||||
}
|
||||
System.out.println();
|
||||
return Evaluation.EXCLUDE_AND_CONTINUE;
|
||||
}
|
||||
|
||||
private void updateRating(Relationship rated, int distance) {
|
||||
final long movieId = rated.getEndNode().getId();
|
||||
int[] rating = obtainRating(movieId);
|
||||
|
||||
int weight = ratingDistance - distance;
|
||||
final Integer stars = (Integer) rated.getProperty("stars", 0);
|
||||
rating[0] += weight * stars;
|
||||
rating[1] += weight;
|
||||
}
|
||||
|
||||
private int[] obtainRating(long movieId) {
|
||||
if (!ratings.containsKey(movieId)) {
|
||||
ratings.put(movieId,new int[2]);
|
||||
}
|
||||
return ratings.get(movieId);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.graphdb.Transaction;
|
||||
import org.neo4j.graphdb.index.IndexManager;
|
||||
import org.neo4j.kernel.AbstractGraphDatabase;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 02.03.11
|
||||
*/
|
||||
public class Neo4jDatabaseCleaner {
|
||||
private AbstractGraphDatabase graph;
|
||||
|
||||
public Neo4jDatabaseCleaner(AbstractGraphDatabase graph) {
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
public Map<String, Object> cleanDb() {
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
Transaction tx = graph.beginTx();
|
||||
try {
|
||||
removeNodes(result);
|
||||
clearIndex(result);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void removeNodes(Map<String, Object> result) {
|
||||
Node refNode = graph.getReferenceNode();
|
||||
int nodes = 0, relationships = 0;
|
||||
for (Node node : graph.getAllNodes()) {
|
||||
for (Relationship rel : node.getRelationships(Direction.OUTGOING)) {
|
||||
rel.delete();
|
||||
relationships++;
|
||||
}
|
||||
if (!refNode.equals(node)) {
|
||||
node.delete();
|
||||
nodes++;
|
||||
}
|
||||
}
|
||||
result.put("nodes", nodes);
|
||||
result.put("relationships", relationships);
|
||||
|
||||
}
|
||||
|
||||
private void clearIndex(Map<String, Object> result) {
|
||||
IndexManager indexManager = graph.index();
|
||||
result.put("node-indexes", Arrays.asList(indexManager.nodeIndexNames()));
|
||||
result.put("relationship-indexes", Arrays.asList(indexManager.relationshipIndexNames()));
|
||||
for (String ix : indexManager.nodeIndexNames()) {
|
||||
indexManager.forNodes(ix).delete();
|
||||
}
|
||||
for (String ix : indexManager.relationshipIndexNames()) {
|
||||
indexManager.forRelationships(ix).delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
log4j.rootLogger=warn, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
|
||||
#log4j.category.org.springframework.web=DEBUG
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
|
||||
|
||||
<security:global-method-security secured-annotations="enabled">
|
||||
</security:global-method-security>
|
||||
|
||||
<security:http auto-config="true" access-denied-page="/auth/denied"> <!-- use-expressions="true" -->
|
||||
<security:intercept-url pattern="/admin/*" access="ROLE_ADMIN"/>
|
||||
<security:intercept-url pattern="/import/*" access="ROLE_ADMIN"/>
|
||||
<security:intercept-url pattern="/user/*" access="ROLE_USER"/>
|
||||
<security:intercept-url pattern="/auth/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
|
||||
<security:intercept-url pattern="/auth/register" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
|
||||
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
|
||||
<security:form-login login-page="/auth/login" authentication-failure-url="/auth/login?login_error=true"
|
||||
default-target-url="/user"/>
|
||||
<security:logout logout-url="/auth/logout" logout-success-url="/" invalidate-session="true"/>
|
||||
</security:http>
|
||||
|
||||
<security:authentication-manager>
|
||||
<security:authentication-provider user-service-ref="cineastsUserDetailsService">
|
||||
<security:password-encoder hash="md5">
|
||||
<security:salt-source system-wide="cewuiqwzie"/>
|
||||
</security:password-encoder>
|
||||
</security:authentication-provider>
|
||||
</security:authentication-manager>
|
||||
|
||||
</beans>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
<context:spring-configured/>
|
||||
<context:component-scan base-package="org.neo4j.cineasts">
|
||||
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
|
||||
</context:component-scan>
|
||||
|
||||
<neo4j:config storeDirectory="data/graph.db"/>
|
||||
<neo4j:repositories base-package="org.neo4j.cineasts.repository"/>
|
||||
|
||||
<!--neo4j:config graphDatabaseService="graphDatabaseService"/>
|
||||
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
|
||||
<constructor-arg value="http://localhost:7474"/>
|
||||
</bean-->
|
||||
|
||||
<bean class="org.neo4j.cineasts.movieimport.MovieDbApiClient">
|
||||
<constructor-arg value="926d2a79e82920b62f03b1cb57e532e6"/>
|
||||
</bean>
|
||||
<bean class="org.neo4j.cineasts.movieimport.MovieDbLocalStorage">
|
||||
<constructor-arg value="data/json"/>
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
|
||||
|
||||
<!--import resource="applicatioContext-security.xml"/-->
|
||||
</beans>
|
||||
@@ -1,8 +0,0 @@
|
||||
<decorators defaultdir="/WEB-INF/views/decorators">
|
||||
<decorator name="frontpage" page="frontpage.jsp">
|
||||
<pattern>/</pattern>
|
||||
</decorator>
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/*</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:jee="http://www.springframework.org/schema/jee"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
|
||||
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<mvc:annotation-driven/>
|
||||
<mvc:resources mapping="/images/**" location="/images/"/>
|
||||
<mvc:resources mapping="/resources/**" location="/resources/"/>
|
||||
<context:component-scan base-package="org.neo4j.cineasts.controller"/>
|
||||
|
||||
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp"/>
|
||||
|
||||
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
|
||||
|
||||
</beans>
|
||||
@@ -1,36 +0,0 @@
|
||||
<%@ page session="false" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
|
||||
<%--@elvariable id="actor" type="org.neo4j.cineasts.domain.Actor"--%>
|
||||
<%--@elvariable id="role" type="org.neo4j.cineasts.domain.Role"--%>
|
||||
<c:choose>
|
||||
<c:when test="${actor != null}">
|
||||
<div class="span-4">
|
||||
<div class="actor-framed-image" style="background-image:url(${actor.profileImageUrl})">
|
||||
</div>
|
||||
<div class="actor-sidebar">
|
||||
<h2>${actor.name}</h2>
|
||||
<p>Born <fmt:formatDate value="${actor.birthday}" pattern="yyyy/dd/MM"/> in ${actor.birthplace}.</p>
|
||||
</div>
|
||||
<div class="break"></div>
|
||||
</div>
|
||||
<div class="span-8 last">
|
||||
<h2>Biography</h2>
|
||||
<p>${actor.biography}</p>
|
||||
<h2>Roles</h2>
|
||||
<c:if test="${not empty actor.roles}">
|
||||
<ul>
|
||||
<c:forEach items="${roles}" var="role">
|
||||
<li>
|
||||
<a href="/movies/${role.movie.id}"><c:out value="${role.movie.title}" /> as <c:out value="${role.name}" /> in <c:out value="${role.movie.year}"/></a><br/>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</ul>
|
||||
</c:if>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<h2>Actor cannot be found.</h2>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
@@ -1,7 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Access denied</title>
|
||||
</head> <!-- todo redirect after some seconds -->
|
||||
<body>Unfortunately you are not authorized to see this page.</body>
|
||||
</html>
|
||||
@@ -1,36 +0,0 @@
|
||||
<%@ page import="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Login</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Login</h1>
|
||||
<div class="error">${error}</div>
|
||||
|
||||
<form action="/j_spring_security_check" method="post" >
|
||||
<p>
|
||||
<label for="j_username">Login:</label>
|
||||
<input id="j_username" name="j_username" type="text"
|
||||
value="${not empty param.login_error ? sessionScope['SPRING_SECURITY_LAST_USERNAME'] : '' }" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="j_password">Password:</label>
|
||||
<input id="j_password" name="j_password" type="password" />
|
||||
</p>
|
||||
<p>
|
||||
<input type="checkbox" name="_spring_security_remember_me"/> Remember me
|
||||
</p>
|
||||
<input type="submit" value="Login"/>
|
||||
</form><br/>
|
||||
<a href="/auth/registerpage">Register</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,37 +0,0 @@
|
||||
<%@ page import="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Login</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Login</h1>
|
||||
<div class="error">${error}</div>
|
||||
|
||||
<form action="/auth/register" method="post" >
|
||||
<p>
|
||||
<label for="j_username">Login:</label>
|
||||
<input id="j_username" name="j_username" type="text" value="${j_username}"/>
|
||||
</p>
|
||||
<p>
|
||||
<label for="j_displayname">Name:</label>
|
||||
<input id="j_displayname" name="j_displayname" type="text" value="${j_displayname}"/>
|
||||
</p>
|
||||
<p>
|
||||
<label for="j_password">Password:</label>
|
||||
<input id="j_password" name="j_password" type="password" />
|
||||
</p>
|
||||
<input type="submit" value="Register"/>
|
||||
</form>
|
||||
<br/>
|
||||
<a href="/auth/login">Login</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,30 +0,0 @@
|
||||
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator"
|
||||
prefix="decorator" %>
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>Cineasts.net - <decorator:title default="Welcome" /></title>
|
||||
<decorator:head />
|
||||
<link rel="stylesheet" type="text/css" href="/resources/style.css">
|
||||
<%@ include file="/WEB-INF/views/includes/style.jsp" %>
|
||||
<%@ include file="/WEB-INF/views/includes/js.jsp" %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<div id="header-topbar">
|
||||
<div id="header-menu">
|
||||
<%@ include file="/WEB-INF/views/includes/navigation.jsp" %>
|
||||
</div>
|
||||
</div>
|
||||
<div id="header-splash">
|
||||
<img id="logo-splash" src="<c:url value="/images/logo-splash.png"/>" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<decorator:body />
|
||||
</div>
|
||||
<%@ include file="/WEB-INF/views/includes/footer.jsp" %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,31 +0,0 @@
|
||||
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator"
|
||||
prefix="decorator" %>
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>Cineasts.net - <decorator:title default="Welcome" /></title>
|
||||
<decorator:head />
|
||||
<link rel="stylesheet" type="text/css" href="/resources/style.css">
|
||||
<%@ include file="/WEB-INF/views/includes/style.jsp" %>
|
||||
<%@ include file="/WEB-INF/views/includes/js.jsp" %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<div id="header-topbar">
|
||||
<div id="header-menu">
|
||||
<page:applyDecorator name="header_search">
|
||||
<%@ include file="/WEB-INF/views/includes/search.jsp" %>
|
||||
</page:applyDecorator>
|
||||
<%@ include file="/WEB-INF/views/includes/navigation.jsp" %>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/" id="logo"><img src="<c:url value="/images/logo.png"/>" /></a>
|
||||
</div>
|
||||
<div id="content">
|
||||
<decorator:body />
|
||||
</div>
|
||||
<%@ include file="/WEB-INF/views/includes/footer.jsp" %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,15 +0,0 @@
|
||||
<%@ page session="false" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
|
||||
<h2>Results for importing movies: "${ids}"</h2>
|
||||
|
||||
<p>Imported of ${fn:length(movies)} movies took ${duration} seconds.</p>
|
||||
|
||||
<dl>
|
||||
<c:forEach items="${movies}" var="entry">
|
||||
<dt>${entry.key}</dt>
|
||||
<dd>${entry.value}</dd>
|
||||
</c:forEach>
|
||||
</dl>
|
||||
@@ -1,5 +0,0 @@
|
||||
<div id="footer">
|
||||
This site is running on SpringFramework and Spring Data Neo4j powered by the Neo4j graph database. All movie data is provided by <a href="http://themoviedb.org">themoviedb.org</a>.<br/>
|
||||
<br/>
|
||||
<a href="http://springsource.org"><img src="/images/logo/springsource.png"/></a><a href="http://springsource.org/spring-data"><img src="/images/logo/springdata.jpg"/></a><a href="http://github.com/springsource/spring-data-graph"><img src="/images/logo/springdatagraph.png"/></a><a href="http://neo4j.org"><img src="/images/logo/neo4j.png"/></a>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
|
||||
<div class="navigation">
|
||||
<c:choose>
|
||||
<c:when test="${empty user}">
|
||||
<c:set var="last" value="Login"/>
|
||||
<c:if test="${not empty param.login_error}">
|
||||
<c:set var="last" value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}"/>
|
||||
</c:if>
|
||||
<form action="/j_spring_security_check" method="post" >
|
||||
<input id="j_username" name="j_username" type="text" value="${last}"
|
||||
onfocus="this.value = (this.value=='Login') ? '' : this.value;" onblur="this.value = (this.value=='') ? '${last}' : this.value;"
|
||||
/>
|
||||
<input id="j_password" name="j_password" type="password" onfocus="this.value = (this.value=='*******') ? '' : this.value;" onblur="this.value = (this.value=='') ? '*******' : this.value;" value="*******"/>
|
||||
<input type="image" src="/images/rating-active.png" value="Login" style="max-width:0px;max-height:0px;"/>
|
||||
</form>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<a href="<c:url value="/user" />">${user.name}</a>
|
||||
<a href="<c:url value="/auth/logout" />">Logout</a>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
@@ -1,15 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
|
||||
<div class="navigation">
|
||||
<c:choose>
|
||||
<c:when test="${empty user}">
|
||||
<a href="<c:url value="/auth/login" />">Login</a>
|
||||
<a href="<c:url value="/auth/registerpage" />">Register</a>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<a href="<c:url value="/user" />">${user.name}</a>
|
||||
<a href="<c:url value="/auth/logout" />">Logout</a>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
@@ -1,5 +0,0 @@
|
||||
<div class="search">
|
||||
<form action="/movies" method="get">
|
||||
<input type="text" name="q" value="Find movie" onfocus="this.value='';" onblur="this.value = (this.value=='') ? 'Find movie' : this.value;"/>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
<!-- dynamic, calculated styles -->
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
||||
@@ -1,11 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<div>
|
||||
<h3>Welcome to Cineasts.net</h3>
|
||||
<div id="big-search-wrap">
|
||||
<form action="/movies" method="get">
|
||||
<input type="text" class="big-search" name="q" value="Find movie" onfocus="this.value='';" onblur="this.value = (this.value=='') ? 'Find movie' : this.value;" />
|
||||
<input type="submit" class="big-search-submit" value="Search"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,26 +0,0 @@
|
||||
<%@ page session="false" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
|
||||
<h2>Results for "${query}"</h2>
|
||||
|
||||
<c:choose>
|
||||
<c:when test="${not empty movies}">
|
||||
<ul class="search-results">
|
||||
<c:forEach items="${movies}" var="movie">
|
||||
<li>
|
||||
<div class="search-result-details">
|
||||
<c:set var="image" value="${movie.imageUrl}"/>
|
||||
<c:if test="${empty image}"><c:set var="image" value="/images/movie-placeholder.png"/></c:if>
|
||||
<a class="thumbnail" href="<c:url value="/movies/${movie.id}" />"> <img src="<c:url value="${image}" />" /></a>
|
||||
<a href="/movies/${movie.id}">${movie.title}</a> <img alt="${movie.stars} stars" src="/images/rated_${movie.stars}.png"/>
|
||||
<p><c:out value="${movie.tagline}" escapeXml="true" /></p>
|
||||
</div>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</ul>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<h2>No movies found for query "${query}".</h2>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
@@ -1,170 +0,0 @@
|
||||
<%@ page session="false" %>
|
||||
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
|
||||
<html>
|
||||
<head><title>${movie.title}</title></head>
|
||||
<body>
|
||||
<c:choose>
|
||||
<c:when test="${not empty movie}">
|
||||
<div class="span-5">
|
||||
<div class="profile-header">
|
||||
<%--@elvariable id="movie" type="org.neo4j.cineasts.domain.Movie"--%>
|
||||
<c:set var="image" value="${movie.imageUrl}"/>
|
||||
<c:if test="${empty image}"><c:set var="image" value="/images/movie-placeholder.png"/></c:if>
|
||||
<div class="profile-image"><img src="<c:url value="${image}"/>"/></div>
|
||||
<div class="profile-header-details">
|
||||
<h2>${movie.title} (${movie.year}) <img src="/images/rated_${stars}.png" alt="${stars} stars"/></h2>
|
||||
</div>
|
||||
<h3><${movie.tagline}</h3>
|
||||
<div class="break"></div>
|
||||
</div>
|
||||
|
||||
<div class="span-half">
|
||||
<h3>Movie facts</h3>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Language</th>
|
||||
<td>${movie.language}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Runtime</th>
|
||||
<td>${movie.runtime} Minutes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Genre</th>
|
||||
<td>${movie.genre}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Other sites</th>
|
||||
<td><a target="cineasts_link" href="http://www.themoviedb.org/movie/${movie.id}">TheMovieDb.org</a> |
|
||||
<a target="cineasts_link" href="http://www.imdb.com/title/${movie.imdbId}">IMDb</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Buy DVDs & Books</th>
|
||||
<td><a target="cineasts_link" href="http://www.amazon.com/s/?url=search-alias%3Daps&field-keywords=<c:url value="${movie.title}"/>">Amazon</a> |
|
||||
<a target="cineasts_link" href="http://www.cinebutler.com/search.html?searchBy=title&searchFor=<c:url value="${movie.title}"/>">CineButler</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>In Cinemas</th>
|
||||
<td><a target="cineasts_link" href="http://www.google.com/movies?q=<c:url value="${movie.title}"/>">Google Movies</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="span-half last">
|
||||
<c:if test="${not empty movie.trailer}">
|
||||
<h3>Trailers</h3>
|
||||
<c:set var="youtube" value="movie.youtubeId"/>
|
||||
<c:choose>
|
||||
<c:when test="${not empty youtube}">
|
||||
<iframe title="YouTube video player" width="200" height="143" src="http://www.youtube.com/embed/${movie.youtubeId}?rel=0&controls=0&egm=1&fs=1" frameborder="0" allowfullscreen></iframe>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<ul>
|
||||
<li><a href="${movie.trailer}">Trailer</a></li>
|
||||
</ul>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</c:if>
|
||||
</div>
|
||||
|
||||
<div class="span-half">
|
||||
<h3>Release info</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Released</th>
|
||||
<td><fmt:formatDate value="${movie.releaseDate}" pattern="yyyy/dd/MM"/></td>
|
||||
</tr>
|
||||
<c:if test="${not empty movie.homepage}">
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><a href="${movie.homepage}">Homepage</a></td>
|
||||
</tr>
|
||||
</c:if>
|
||||
<tr>
|
||||
<th>Studio</th>
|
||||
<td>${movie.studio}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="span-7 last">
|
||||
<div class="movie-content-outer">
|
||||
<div class="movie-content">
|
||||
<h2>Overview</h2>
|
||||
<p>${movie.description}</p>
|
||||
|
||||
<h2>Cast</h2>
|
||||
<c:if test="${not empty movie.roles}">
|
||||
<ul class="actors-list">
|
||||
<c:forEach items="${movie.roles}" var="role">
|
||||
<c:set var="actor" value="${role.actor}"/>
|
||||
<li>
|
||||
<c:set var="image" value="${actor.profileImageUrl}"/>
|
||||
<c:if test="${empty image}"><c:set var="image" value="/images/profile-placeholder-small.png"/></c:if>
|
||||
<a class="actor-image" href="<c:url value="/actors/${actor.id}" />"><img alt="${actor.name}" src="<c:url value="${image}" />" /></a>
|
||||
<a href="<c:url value="/actors/${actor.id}" />"><c:out value="${actor.name}" /> as <c:out value="${role.name}" /></a>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</ul>
|
||||
<div class="break"></div>
|
||||
</c:if>
|
||||
|
||||
<h3>Reviews</h3>
|
||||
<c:if test="${not empty user}">
|
||||
<script type="text/javascript">
|
||||
function rate(n) {
|
||||
var hidden = document.getElementById('rated');
|
||||
hidden.value = n;
|
||||
for (i = 1; i <= 5; i++) {
|
||||
document.getElementById("rated_" + i).src = (i <= n ) ? "/images/rating-active.png" : "/images/rating-disabled.png";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<form method="post" action="<c:url value="/movies/${movie.id}" />">
|
||||
<h4>Give
|
||||
<c:forEach begin="1" end="5" var="i">
|
||||
<a href="#" onClick="rate(${i});"><img src="/images/rating-active.png" id="rated_${i}"/></a>
|
||||
</c:forEach>
|
||||
to "${movie.title}" saying:
|
||||
<input type="hidden" value="${userRating.stars}" name="rated" id="rated"/>
|
||||
<input type="text" size="100" name="comment" value="${userRating.comment}"/>
|
||||
<input type="submit" value="Rate!"/>
|
||||
</h4>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
rate(${userRating.stars});
|
||||
</script>
|
||||
</c:if>
|
||||
<c:if test="${not empty movie.ratings}">
|
||||
<ul>
|
||||
<c:forEach items="${movie.ratings}" var="rating">
|
||||
<c:if test="${rating != userRating}">
|
||||
<li><img src="/images/rated_${rating.stars}.png" alt="${rating.stars} stars"/> by <a href="<c:url value="/user/${rating.user.login}" />">${rating.user.name}</a> who says: "${rating.comment}"</li>
|
||||
</c:if>
|
||||
</c:forEach>
|
||||
</ul>
|
||||
</c:if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<h2>No movie found</h2>
|
||||
<p>The movie you were looking for could not be found.</p>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</body></html>
|
||||
@@ -1,104 +0,0 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%--@elvariable id="user" type="org.neo4j.cineasts.domain.User"--%>
|
||||
<%--@elvariable id="recommendations" type="java.util.List<org.neo4j.cineasts.domain.MovieRecommendation>"--%>
|
||||
<%--@elvariable id="recommendation" type="org.neo4j.cineasts.domain.MovieRecommendation"--%>
|
||||
<html>
|
||||
<head>
|
||||
<title>Profile</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="span-5">
|
||||
<div class="profile-header">
|
||||
<div class="profile-image"><img src="<c:url value="/images/profile-placeholder.png" />" /></div>
|
||||
<div class="profile-header-details">
|
||||
<h2>Hi ${user.name}!</h2>
|
||||
<p>${user.info}</p>
|
||||
</div>
|
||||
<div class="break"></div>
|
||||
</div>
|
||||
|
||||
<c:choose>
|
||||
<c:when test="${not empty user.friends}">
|
||||
<h2>Your friends</h2>
|
||||
<ul class="friends-list">
|
||||
<c:forEach items="${user.friends}" var="friend">
|
||||
<li>
|
||||
<a class="friend-image" href="<c:url value="/user/${friend.login}" />"><img src="<c:url value="/images/profile-placeholder-small.png" />" /></a>
|
||||
<div class="friend-info">
|
||||
<h3><a href="<c:url value="/user/${friend.login}" />"><c:out value="${friend.name}"/></a></h3>
|
||||
<p>${friend.info}</p>
|
||||
</div>
|
||||
<div class="break"></div>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</ul>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<h2>You don't have any friends yet</h2>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
<div class="span-7 last">
|
||||
<div class="profile-feed">
|
||||
<div class="span-third">
|
||||
<h2>Your rated movies</h2>
|
||||
</div>
|
||||
<c:set var="ratings" value="${user.ratings}"/>
|
||||
<div class="span-third last">
|
||||
<h2>${fn:length(ratings)}</h2>
|
||||
</div>
|
||||
<ul class="rated-movies-list span-all last">
|
||||
<c:choose>
|
||||
<c:when test="${not empty ratings}">
|
||||
<c:forEach items="${ratings}" var="rating">
|
||||
<c:set var="movie" value="${rating.movie}"/>
|
||||
<c:set var="stars" value="${rating.stars}"/>
|
||||
<li>
|
||||
<h4><a href="<c:url value="/movies/${movie.id}" />"><c:out value="${movie.title}"/>
|
||||
(${movie.year}) - "${rating.comment}"</a>
|
||||
<img class="rating" src="/images/rated_${stars}.png" alt="${stars} stars"/>
|
||||
</h4>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
You have not rated any movies.
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</ul>
|
||||
<div class="break"></div>
|
||||
|
||||
<div class="span-third">
|
||||
<h2>Your recommendations</h2>
|
||||
</div>
|
||||
<div class="span-third last">
|
||||
<h2>${fn:length(recommendations)}</h2>
|
||||
</div>
|
||||
<ul class="rated-movies-list span-all last">
|
||||
<c:choose>
|
||||
<c:when test="${not empty recommendations}">
|
||||
<c:forEach items="${recommendations}" var="recommendation">
|
||||
<c:set var="movie" value="${recommendation.movie}"/>
|
||||
<c:set var="stars" value="${recommendation.rating}"/>
|
||||
<li>
|
||||
<h4><a href="<c:url value="/movies/${movie.id}" />"><c:out value="${movie.title}"/>
|
||||
(${movie.year}) - "${movie.tagline}"</a>
|
||||
<img class="rating" src="/images/rated_${stars}.png" alt="${stars} stars"/>
|
||||
</h4>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
There are no recommendations for you, perhaps you have to add some friends?
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</ul>
|
||||
<div class="break"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,86 +0,0 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%--@elvariable id="user" type="org.neo4j.cineasts.domain.User"--%>
|
||||
<c:set var="name" value="${profiled.name}"/>
|
||||
<html>
|
||||
<head><title>Profile for ${name}</title></head>
|
||||
<body>
|
||||
|
||||
<div class="span-5">
|
||||
<div class="profile-header">
|
||||
<div class="profile-image"><img src="<c:url value="/images/profile-placeholder.png" />" /></div>
|
||||
<div class="profile-header-details">
|
||||
<h2>${name}</h2>
|
||||
<p>${profiled.info}</p>
|
||||
</div>
|
||||
<div class="break"></div>
|
||||
</div>
|
||||
|
||||
<h2>${name}'s friends</h2>
|
||||
<c:choose>
|
||||
<c:when test="${isFriend}">
|
||||
<c:set var="friends" value="${profiled.friends}"/>
|
||||
<c:choose>
|
||||
<c:when test="${not empty friends}">
|
||||
<ul class="friends-list">
|
||||
<c:forEach items="${friends}" var="friend">
|
||||
<li>
|
||||
<a class="friend-image" href="<c:url value="/user/${friend.login}" />"><img src="<c:url value="/images/profile-placeholder-small.png" />" /></a>
|
||||
<div class="friend-info">
|
||||
<h3><a href="<c:url value="/user/${friend.login}" />"><c:out value="${friend.name}"/></a></h3>
|
||||
<p>${friend.info}</p>
|
||||
</div>
|
||||
<div class="break"></div>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</ul>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
${name} has no friends.
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<form id="add_friend" action="/user/${profiled.login}/friends" method="post">
|
||||
<a href="#" onClick="document.getElementById('add_friend').submit();return false;">Add ${name} as a friend.</a>
|
||||
</form>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
<c:set var="ratings" value="${profiled.ratings}"/>
|
||||
<div class="span-7 last">
|
||||
<div class="profile-feed">
|
||||
<div class="span-third">
|
||||
<h2>${name}'s rated movies</h2>
|
||||
</div>
|
||||
<div class="span-third last">
|
||||
<h2>${fn:length(ratings)}</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<ul class="rated-movies-list span-all last">
|
||||
<c:choose>
|
||||
<c:when test="${not empty ratings}">
|
||||
<c:forEach items="${ratings}" var="rating">
|
||||
<c:set var="movie" value="${rating.movie}"/>
|
||||
<c:set var="stars" value="${rating.stars}"/>
|
||||
<li>
|
||||
<h4><a href="<c:url value="/movies/${movie.id}" />"><c:out value="${movie.title}"/>
|
||||
(${movie.year}) - "${rating.comment}"</a>
|
||||
<img class="rating" src="/images/rated_${stars}.png" alt="${stars} stars"/>
|
||||
</h4>
|
||||
</li>
|
||||
</c:forEach>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
${name} has not rated any movies.
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</ul>
|
||||
<div class="break"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
|
||||
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
/WEB-INF/applicatioContext-security.xml
|
||||
/WEB-INF/applicationContext.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<filter>
|
||||
<filter-name>sitemesh</filter-name>
|
||||
<filter-class>
|
||||
com.opensymphony.module.sitemesh.filter.PageFilter
|
||||
</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<filter-name>springSecurityFilterChain</filter-name>
|
||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>springSecurityFilterChain</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>sitemesh</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>dispatcherServlet</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>dispatcherServlet</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<session-config>
|
||||
<session-timeout>60</session-timeout>
|
||||
</session-config>
|
||||
</web-app>
|
||||
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 538 B |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 1023 B |
|
Before Width: | Height: | Size: 588 B |
|
Before Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 214 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
@@ -1,13 +0,0 @@
|
||||
label {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Label for radio buttons, normal buttons and checkboxes.
|
||||
*/
|
||||
label.button-label {
|
||||
display:inline;
|
||||
float:none;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
.span-1 { width: 6.958%; float:left; margin-right:1.5%; }
|
||||
.span-2 { width: 15.416%; float:left; margin-right:1.5%; }
|
||||
.span-3 { width: 23.875%; float:left; margin-right:1.5%; }
|
||||
.span-4 { width: 32.333%; float:left; margin-right:1.5%; }
|
||||
.span-5 { width: 40.791%; float:left; margin-right:1.5%; }
|
||||
.span-6 { width: 49.250%; float:left; margin-right:1.5%; }
|
||||
.span-7 { width: 57.708%; float:left; margin-right:1.5%; }
|
||||
.span-8 { width: 66.166%; float:left; margin-right:1.5%; }
|
||||
.span-9 { width: 74.625%; float:left; margin-right:1.5%; }
|
||||
.span-10 { width: 83.083%; float:left; margin-right:1.5%; }
|
||||
.span-11 { width: 91.541%; float:left; margin-right:1.5%; }
|
||||
.span-12 { width: 100%; float:left; margin-right:0%; }
|
||||
|
||||
.span-third { width: 32%; float:left; margin-right:2%; }
|
||||
.span-half { width: 49%; float:left; margin-right:2%; }
|
||||
.span-all { width: 100%; float:left; clear:right; }
|
||||
|
||||
.last { clear:right; margin-right:0; }
|
||||
@@ -1,328 +0,0 @@
|
||||
|
||||
@import url(typography.css);
|
||||
@import url(forms.css);
|
||||
@import url(grid.css);
|
||||
|
||||
* {
|
||||
outline-style: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
background : #010100;
|
||||
}
|
||||
|
||||
a img { border:0; }
|
||||
|
||||
/**
|
||||
* MAIN COMPONENTS
|
||||
*/
|
||||
|
||||
#header {
|
||||
background: url(../images/header-curtain.png) repeat-y bottom center #010100;
|
||||
border-bottom: 1px solid #5C5C45;
|
||||
}
|
||||
|
||||
#logo img {
|
||||
padding: 10px 10px 0;
|
||||
}
|
||||
|
||||
#header-topbar {
|
||||
height: 49px;
|
||||
padding: 0 0 0 10px;
|
||||
background: url(../images/filmroll-horizontal.png) repeat-x bottom left transparent;
|
||||
}
|
||||
|
||||
#header-splash {
|
||||
text-align:center;
|
||||
background: url(../images/header-splash-bg.png) repeat-x bottom center;
|
||||
}
|
||||
|
||||
#logo-splash {
|
||||
position:relative;
|
||||
top:4px;
|
||||
}
|
||||
|
||||
|
||||
#header-menu {
|
||||
float: right;
|
||||
color: #DDDDDD;
|
||||
height:28px;
|
||||
background:#0b0f07;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.search {
|
||||
float:left;
|
||||
padding:0 10px;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.navigation a {
|
||||
color: #d8d8d8;
|
||||
text-decoration:none;
|
||||
padding: 0 0 0 5px;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
text-align:center;
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
padding: 10px;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
#footer img {
|
||||
padding: 10px;
|
||||
}
|
||||
/**
|
||||
* SEARCH RESULTS
|
||||
*/
|
||||
|
||||
.search-results > li {
|
||||
border-top: 1px solid #666666;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.search-result-details {
|
||||
/* float:left;
|
||||
padding: 0px 10px;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* PROFILE, ACTOR AND MOVIE PAGES
|
||||
*/
|
||||
|
||||
.profile-header {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.profile-image {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.profile-image img {
|
||||
width: 100px;
|
||||
}
|
||||
.actor-image img, .profile-image img, .friend-image img, .thumbnail img {
|
||||
border: 1px solid #4C5C2A !important;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
display:block;
|
||||
/* float:left;*/
|
||||
}
|
||||
.thumbnail img {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.actor-framed-image {
|
||||
background: url(../images/actor-picture-frame.png) no-repeat;
|
||||
width:166px;
|
||||
height:214px;
|
||||
padding: 6px 60px 16px;
|
||||
}
|
||||
|
||||
.actor-sidebar {
|
||||
padding: 0 56px;
|
||||
}
|
||||
|
||||
.profile-header-details {
|
||||
float: left;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.profile-feed {
|
||||
background: none repeat scroll 0 0 #252525;
|
||||
border: 5px solid #CACF81;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.facts {
|
||||
width:50%;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.movie-content-outer, .actor-content-outer {
|
||||
background: url(../images/filmroll-vertical-full.png) no-repeat top right;
|
||||
padding-right: 38px;
|
||||
}
|
||||
|
||||
.movie-content, .actor-content {
|
||||
background: url(../images/filmroll-vertical-full.png) no-repeat top left;
|
||||
padding: 0 10px 0 48px;
|
||||
min-height:690px;
|
||||
}
|
||||
|
||||
.actors-list li {
|
||||
width:100px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.actors-list img {
|
||||
height:92px;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.friends-list li {
|
||||
border-top:1px solid #333;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.friends-list .friend-image {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.friend-image img {
|
||||
height: 64px;
|
||||
}
|
||||
.friends-list .friend-info {
|
||||
float:left;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.friends-list h3, .search-results h3 {
|
||||
border:none;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.friends-list h3 a, .search-results h3 a {
|
||||
text-decoration:none;
|
||||
color: #99CC33;
|
||||
}
|
||||
|
||||
.rated-movies-list h3 {
|
||||
margin: 0;
|
||||
padding: 5px 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.rated-movies-list h3 a {
|
||||
color: #99CC33;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.rated-movies-list li {
|
||||
position:relative;
|
||||
height:20px;
|
||||
padding:8px 0;
|
||||
}
|
||||
|
||||
.rated-movies-list .rating {
|
||||
/* position:absolute;
|
||||
right:0;
|
||||
top:5px;
|
||||
*/
|
||||
float: right;
|
||||
}
|
||||
|
||||
/**
|
||||
* BIG SEARCH
|
||||
*/
|
||||
|
||||
#big-search-wrap {
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.big-search {
|
||||
background: url("../images/searchbar-big.png") no-repeat scroll 0 0 transparent;
|
||||
border: 0 none;
|
||||
height: 50px;
|
||||
width: 480px;
|
||||
font-size: 22px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.big-search-submit {
|
||||
background: url("../images/searchbar-big-searchicon.png") no-repeat scroll 0 0 transparent;
|
||||
border: 0 none;
|
||||
color: transparent;
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
left: -75px;
|
||||
position: relative;
|
||||
width: 41px;
|
||||
}
|
||||
|
||||
/**
|
||||
* RATINGS
|
||||
*/
|
||||
|
||||
.rating-input li, .rating-input lh {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.rating {
|
||||
display: block;
|
||||
height: 20px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.rating li {
|
||||
height: 28px;
|
||||
width: 22px;
|
||||
display:block;
|
||||
float:left;
|
||||
padding:0 2px;
|
||||
}
|
||||
|
||||
.rating li.active {
|
||||
background: url("/images/rating-active.png") no-repeat scroll center 0 transparent;
|
||||
}
|
||||
|
||||
.rating li.disabled {
|
||||
/* background: url("/images/rating-disabled.png") no-repeat scroll center 0 transparent; */
|
||||
}
|
||||
|
||||
/**
|
||||
* TABLES
|
||||
*/
|
||||
|
||||
table th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* LISTS
|
||||
*/
|
||||
|
||||
ul {
|
||||
list-style:none;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
lh {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* UTILS
|
||||
*/
|
||||
|
||||
.break {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ERRORS
|
||||
*/
|
||||
|
||||
.error {
|
||||
color:red;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #99CC33;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
body {
|
||||
font-family:tahoma,verdana,sans-serif,serif;
|
||||
color: #666666;
|
||||
font-size:13px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #314718; /*#99CC33;*/
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #314718; /*#ff6600;*/
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 1px solid #333333;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.tiny-link {
|
||||
color: #222;
|
||||
font-size:12px;
|
||||
text-decoration:none;
|
||||
}
|
||||
.tiny-link:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package org.neo4j.cineasts.domain;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.neo4j.cineasts.repository.UserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({"/movies-test-context.xml"})
|
||||
@Transactional
|
||||
public class DomainTests {
|
||||
|
||||
@Autowired
|
||||
protected MovieRepository movieRepository;
|
||||
@Autowired
|
||||
protected UserRepository userRepository;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actorCanPlayARoleInAMovie() {
|
||||
Person tomHanks = new Person("1","Tom Hanks").persist();
|
||||
Movie forestGump = new Movie("1", "Forrest Gump").persist();
|
||||
|
||||
Role role = tomHanks.playedIn(forestGump, "Forrest");
|
||||
|
||||
Movie foundForestGump = this.movieRepository.findByPropertyValue(null, "id", "1");
|
||||
|
||||
assertEquals("created and looked up movie equal", forestGump, foundForestGump);
|
||||
Role firstRole = foundForestGump.getRoles().iterator().next();
|
||||
assertEquals("role forrest",role, firstRole);
|
||||
assertEquals("role forrest","Forrest", firstRole.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canFindMovieByTitleQuery() {
|
||||
Movie forestGump = new Movie("1", "Forrest Gump").persist();
|
||||
Iterator<Movie> queryResults = movieRepository.findAllByQuery("search", "title", "Forre*").iterator();
|
||||
assertTrue("found movie by query",queryResults.hasNext());
|
||||
Movie foundMovie = queryResults.next();
|
||||
assertEquals("created and looked up movie equal", forestGump, foundMovie);
|
||||
assertFalse("found only one movie by query", queryResults.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userCanRateMovie() {
|
||||
Movie movie= new Movie("1","Forrest Gump").persist();
|
||||
User user = new User("ich","Micha","password").persist();
|
||||
Rating awesome = user.rate(movie, 5, "Awesome");
|
||||
|
||||
User foundUser = userRepository.findByPropertyValue("login", "ich");
|
||||
Rating rating = foundUser.getRatings().iterator().next();
|
||||
assertEquals(awesome,rating);
|
||||
assertEquals("Awesome",rating.getComment());
|
||||
assertEquals(5,rating.getStars());
|
||||
assertEquals(5,movie.getStars(),0);
|
||||
}
|
||||
@Test
|
||||
public void canFindUserByLogin() {
|
||||
User user = new User("ich","Micha","password").persist();
|
||||
User foundUser = userRepository.findByPropertyValue("login", "ich");
|
||||
assertEquals(user, foundUser);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 13.03.11
|
||||
*/
|
||||
@Ignore
|
||||
public class MovieDbApiClientTests {
|
||||
private static final String API_KEY = "926d2a79e82920b62f03b1cb57e532e6";
|
||||
|
||||
@Test
|
||||
public void testGetMovie() throws Exception {
|
||||
Map movie = new MovieDbApiClient(API_KEY).getMovie("2");
|
||||
assertEquals(2,movie.get("id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPerson() throws Exception {
|
||||
Map person = new MovieDbApiClient(API_KEY).getPerson("30112");
|
||||
assertEquals(30112,person.get("id"));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.Person;
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 13.03.11
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({"/movies-test-context.xml"})
|
||||
@Transactional
|
||||
public class MovieDbImportServiceTests {
|
||||
|
||||
@Autowired
|
||||
MovieDbImportService importService;
|
||||
|
||||
@Autowired
|
||||
MovieRepository movieRepository;
|
||||
|
||||
@Test
|
||||
public void testImportMovie() throws Exception {
|
||||
Movie movie = importService.importMovie("2");
|
||||
assertEquals("movie-id","2", movie.getId());
|
||||
assertEquals("movie-title","Ariel", movie.getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportMovieTwice() throws Exception {
|
||||
Movie movie = importService.importMovie("2");
|
||||
Movie movie2 = importService.importMovie("2");
|
||||
final Movie foundMovie = movieRepository.findById("2");
|
||||
assertEquals("movie-id", movie, foundMovie);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportPerson() throws Exception {
|
||||
Person actor = importService.importPerson("105955");
|
||||
assertEquals("movie-id","105955", actor.getId());
|
||||
assertEquals("movie-title","George M. Williamson", actor.getName());
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package org.neo4j.cineasts.movieimport;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 13.03.11
|
||||
*/
|
||||
public class MovieDbLocalStorageTests {
|
||||
|
||||
|
||||
private static final String ID = "111";
|
||||
private static final Map<String,String> DATA = Collections.singletonMap("id", ID);
|
||||
protected MovieDbLocalStorage storage;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
storage = new MovieDbLocalStorage("target/data");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasMovie() throws Exception {
|
||||
storage.storeMovie(ID,DATA);
|
||||
assertEquals(true, storage.hasMovie(ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadMovie() throws Exception {
|
||||
storage.storeMovie(ID,DATA);
|
||||
assertEquals(DATA,storage.loadMovie(ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreMovie() throws Exception {
|
||||
storage.storeMovie(ID,DATA);
|
||||
assertEquals(true, new File("target/data/movie_"+ID+".json").exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasPerson() throws Exception {
|
||||
storage.storePerson(ID,DATA);
|
||||
assertEquals(true, storage.hasPerson(ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadPerson() throws Exception {
|
||||
storage.storePerson(ID,DATA);
|
||||
assertEquals(DATA,storage.loadPerson(ID));
|
||||
}
|
||||
@Test
|
||||
public void testLoadPersonFromList() throws Exception {
|
||||
storage.storePerson(ID,asList(DATA));
|
||||
assertEquals(DATA,storage.loadPerson(ID));
|
||||
}
|
||||
@Test
|
||||
public void testLoadPersonFromInvalidList() throws Exception {
|
||||
storage.storePerson(ID, asList("Nothing found."));
|
||||
final Map personData = storage.loadPerson(ID);
|
||||
assertTrue("person unexpectedly found", personData.containsKey("not_found"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStorePerson() throws Exception {
|
||||
storage.storePerson(ID,DATA);
|
||||
assertEquals(true, new File("target/data/person_"+ID+".json").exists());
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package org.neo4j.cineasts.service;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.cineasts.domain.Movie;
|
||||
import org.neo4j.cineasts.domain.MovieRecommendation;
|
||||
import org.neo4j.cineasts.domain.Rating;
|
||||
import org.neo4j.cineasts.domain.User;
|
||||
import org.neo4j.cineasts.repository.MovieRepository;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.03.11
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({"/movies-test-context.xml"})
|
||||
@Transactional
|
||||
public class MoviesRepositoryTests {
|
||||
@Autowired
|
||||
MovieRepository movieRepository;
|
||||
|
||||
@Test
|
||||
public void testGetMovie() throws Exception {
|
||||
Movie movie = new Movie("1", "Test-Movie").persist();
|
||||
Movie found = movieRepository.findById("1");
|
||||
assertEquals("movie found by id", movie, found);
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testGetMovieRecommendations() throws Exception {
|
||||
Movie movie = new Movie("1", "Test-Movie").persist();
|
||||
Movie movie2 = new Movie("2", "Test-Movie2").persist();
|
||||
User user=new User("me","me","me").persist();
|
||||
user.rate(movie,3,"me");
|
||||
User friend=new User("friend","friend","friend").persist();
|
||||
friend.rate(movie,5,"friend");
|
||||
friend.rate(movie2,3,"friend2");
|
||||
assertEquals(2,movieRepository.count());
|
||||
final List<MovieRecommendation> recommendations = movieRepository.getRecommendations(user);
|
||||
assertEquals("one recommendation", 1, recommendations.size());
|
||||
assertEquals("one recommendation", movie2, recommendations.get(0).getMovie());
|
||||
assertEquals("one recommendation", 3, recommendations.get(0).getRating());
|
||||
}
|
||||
@Test
|
||||
public void testRateMovie() throws Exception {
|
||||
Movie movie = new Movie("1", "Test-Movie").persist();
|
||||
User user=new User("me","me","me").persist();
|
||||
user.rate(movie, 5, "comment");
|
||||
final Rating rating = IteratorUtil.first(movie.getRatings());
|
||||
assertEquals("rating stars", 5, rating.getStars());
|
||||
assertEquals("rating comment", "comment", rating.getComment());
|
||||
assertEquals("rating user", user, rating.getUser());
|
||||
assertEquals("rating movie", movie, rating.getMovie());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindTwoMovies() throws Exception {
|
||||
Movie movie1 = new Movie("1", "Test-Movie1").persist();
|
||||
Movie movie2 = new Movie("2", "Test-Movie2").persist();
|
||||
Movie movie3 = new Movie("3", "Another-Movie3").persist();
|
||||
List<Movie> found = movieRepository.findByTitleLike("Test*", new PageRequest(0, 2)).getContent();
|
||||
assertEquals("2 movies found", 2, found.size());
|
||||
assertEquals("2 correct movies found by query", new HashSet<Movie>(asList(movie1, movie2)), new HashSet<Movie>(found));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindTwoMoviesButRestrictToOne() throws Exception {
|
||||
Movie movie1 = new Movie("1", "Test-Movie1").persist();
|
||||
Movie movie2 = new Movie("2", "Test-Movie2").persist();
|
||||
Movie movie3 = new Movie("3", "Another-Movie3").persist();
|
||||
List<Movie> found = movieRepository.findByTitleLike("Test*", new PageRequest(0, 1)).getContent();
|
||||
assertEquals("1 movie found",1,found.size());
|
||||
assertTrue("1 correct movie found by query", found.get(0).getTitle().startsWith("Test"));
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
<context:spring-configured/>
|
||||
<context:component-scan base-package="org.neo4j.cineasts"/>
|
||||
|
||||
<neo4j:config graphDatabaseService="graphDatabaseService"/>
|
||||
<neo4j:repositories base-package="org.neo4j.cineasts.repository"/>
|
||||
|
||||
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown"/>
|
||||
|
||||
<bean class="org.neo4j.cineasts.movieimport.MovieDbApiClient">
|
||||
<constructor-arg value="926d2a79e82920b62f03b1cb57e532e6"/>
|
||||
</bean>
|
||||
<bean class="org.neo4j.cineasts.movieimport.MovieDbLocalStorage">
|
||||
<constructor-arg value="target/json-data"/>
|
||||
</bean>
|
||||
<tx:annotation-driven mode="aspectj"/>
|
||||
</beans>
|
||||
@@ -1,12 +0,0 @@
|
||||
.DS_Store
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
*.zip
|
||||
data
|
||||
target
|
||||
*.log
|
||||
tmp
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||