package org.grails.plugins.wordpress import groovy.net.xmlrpc.XMLRPCServerProxy import org.codehaus.groovy.grails.commons.ConfigurationHolder import org.hibernate.Session import org.hibernate.criterion.Order import org.hibernate.criterion.Projections import org.hibernate.criterion.Restrictions import org.springframework.transaction.support.TransactionCallback import org.springframework.transaction.support.TransactionTemplate import org.springframework.orm.hibernate3.SessionFactoryUtils import org.grails.plugins.wordpress.model.Category import org.grails.plugins.wordpress.model.Comment import org.grails.plugins.wordpress.model.Page import org.grails.plugins.wordpress.model.Post import org.grails.plugins.wordpress.model.Tag import org.grails.plugins.wordpress.model.User class WordpressService { boolean transactional = false def wordpressTransactionManager def wordpressSessionFactory def cacheService String url = ConfigurationHolder.config.wordpress.url String blogId = ConfigurationHolder.config.wordpress.blogId String username = ConfigurationHolder.config.wordpress.username String password = ConfigurationHolder.config.wordpress.password def withTransaction(Closure callable) { new TransactionTemplate(wordpressTransactionManager).execute({status -> callable.call(status) } as TransactionCallback) } private Tag getTagByName(String tagName) { def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) def results = session.createQuery("from Tag tag where tag.name = :name") .setParameter('name', tagName) .list() return results.size() ? results[0] : null } private Category getCategoryByName(String categoryName) { def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) def results = session.createQuery("from Category cat where cat.name = :name") .setParameter('name', categoryName) .list() return results.size() ? results[0] : null } private Category updateCategory(Map map) { log.trace "Wordpress Category : ${map}" def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) Category category = session.get(Category.class, map.categoryId as Long) ?: new Category(id:map.categoryId as Long) category.name = map.categoryName category.parent = session.get(Category.class, map.parentId as Long) category.htmlUrl = map.htmlUrl category.categoryDescription = map.categoryDescription category.rssUrl = map.rssUrl session.save(category) category } private void updateCategoryParent(Map map) { if (map.parentId) { def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) Category category = session.get(Category.class, map.categoryId as Long) Category parent = session.get(Category.class, map.parentId as Long) category.parent = parent session.save(category) } } private Comment updateComment(Map map) { log.trace "Wordpress Comment : ${map}" def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) Comment comment = session.get(Comment.class, map.comment_id as Long) ?: new Comment(id:map.comment_id as Long) comment.dateCreatedGmt = map.date_created_gmt comment.user = session.get(User.class, map.user_id as Long) comment.parent = session.get(Comment.class, map.parent as Long) comment.status = map.status comment.content = map.content comment.link = map.link comment.post = session.get(Post.class, map.post_id as Long) comment.author = map.author comment.authorUrl = map.author_url comment.authorEmail = map.author_email comment.authorIp = map.author_ip comment.type = map.type session.save(comment) comment } private Page updatePage(Map map) { log.trace "Wordpress Page : ${map}" def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) Page page = session.get(Page.class, map.page_id as Long) ?: new Page(id:map.page_id as Long) page.author = session.get(User.class, map.wp_author_id as Long) page.description = map.description page.title = map.title page.link = map.link page.permaLink = map.permaLink page.excerpt = map.excerpt page.textMore = map.text_more page.allowComments = map.mt_allow_comments page.allowPings = map.mt_allow_pings page.slug = map.wp_slug page.password = map.wp_password page.dateCreated = map.dateCreated page.dateCreatedGmt = map.date_created_gmt page.status = map.page_status page.customFields = map.custom_fields page.pageOrder = map.wp_page_order page.pageTemplate = map.wp_page_template page.parent = session.get(Page.class, map.wp_page_parent_id as Long) session.save(page) page } private void updatePageParent(Map map) { if (map.wp_page_parent_id) { def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) Page page = session.get(Page.class, map.page_id as Long) Page parent = session.get(Page.class, map.wp_page_parent_id as Long) page.parent = parent session.save(page) } } private Post updatePost(Map map) { log.trace "Wordpress Post : ${map}" def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) Post post = session.get(Post.class, map.postid as Long) ?: new Post(id:map.postid as Long) if (post.comments == null) { post.comments = [] } post.categories = [] post.tags = [] post.author = session.get(User.class, map.wp_author_id as Long) post.description = map.description post.title = map.title post.link = map.link post.permaLink = map.permaLink post.mtExcerpt = map.mt_excerpt post.mtTextMore = map.mt_text_more post.mtAllowComments = map.mt_allow_comments post.mtAllowPings = map.mt_allow_pings post.wpSlug = map.wp_slug post.wpPassword = map.wp_password post.dateCreated = map.dateCreated post.dateCreatedGmt = map.date_created_gmt post.status = map.post_status post.customFields = map.custom_fields map.categories.each { Category category = getCategoryByName(it) if (category) { post.categories << category } else { log.error "Could not retrieve Category : ${it}" } } map.keywords.each { Tag tag = getTagByName(it) if (tag) { post.tags << tag } else { log.error "Could not retrieve Tag : ${it}" } } session.save(post) post } private Tag updateTag(Map map) { log.trace "Wordpress Tag : ${map}" def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) Tag tag = session.get(Tag.class, map.tag_id as Long) ?: new Tag(id:map.tag_id as Long) tag.name = map.name tag.count = map.count tag.slug = map.slug tag.htmlUrl = map.htmlUrl tag.rssUrl = map.rssUrl session.save(tag) tag } private User updateUser(Map map) { log.trace "Wordpress User : ${map}" def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) User user = session.get(User.class, map.user_id as Long) ?: new User(id:map.user_id as Long) user.login = map.user_login user.name = map.display_name session.save(user) user } void updateCache() { withTransaction { try { log.info("Starting wordpress cache update") def serverProxy = new XMLRPCServerProxy(url, true) def wpUsers = serverProxy."wp.getAuthors"(blogId, username, password) def wpCategories = serverProxy."wp.getCategories"(blogId, username, password) def wpTags = serverProxy."wp.getTags"(blogId, username, password) def wpPageList = serverProxy."wp.getPageList"(blogId, username, password) def wpPages = serverProxy."wp.getPages"(blogId, username, password, wpPageList.size()) def mostRecentPost = serverProxy."metaWeblog.getRecentPosts"(blogId, username, password, 1) def wpPosts = serverProxy."metaWeblog.getRecentPosts"(blogId, username, password, mostRecentPost[0].postid) wpUsers.each { updateUser(it) } wpCategories.each { updateCategory(it) } wpCategories.each { updateCategoryParent(it) } wpTags.each { updateTag(it) } wpPages.each { updatePage(it) } wpPages.each { updatePageParent(it) } wpPosts.each { updatePost(it) } // getRecentPosts('', [max:wpPosts.size()]).each { Post post -> // def commentCount = serverProxy."wp.getCommentCount"(blogId, username, password, post.id) // def totalComments = commentCount.'total_comments' // log.debug "Update Cache : Post Id ${post.id} : Total Comments : ${totalComments} : Current Comments : ${post.comments.size()}" // if (totalComments > post.comments.size()) { // serverProxy."wp.getComments"(blogId, username, password, [offset:post.comments.size(), max:post.comments.size() - totalComments]).each { wpComment -> // updateComment(wpComment) // } // } // } log.info "Wordpress cache updated : ${wpPosts.size()} posts, ${wpPages.size()} pages" } catch (Exception e) { throw new RuntimeException("An error occurred while updating the wordpress cache", e) } } } def getCategories(Map attrs = [:]) { withTransaction { status -> if (attrs.nocache) { def serverProxy = new XMLRPCServerProxy(url, true) try { serverProxy."wp.getCategories"(blogId, username, password).each { wpCategory -> updateCategory(wpCategory) } } catch (Exception e) { throw new RuntimeException("Unable to update categories", e) } } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) session.createCriteria(Category.class) .addOrder(Order.asc('name')) .list() } } def getComments(Map attrs = [:]) { withTransaction { if (attrs.nocache) { def serverProxy = new XMLRPCServerProxy(url, true) try { serverProxy."wp.getComments"(blogId, username, password, attrs).each { wpComment -> updateComment(wpComment) } } catch (Exception e) { throw new RuntimeException("Unable to update comments", e) } } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) def criteria = session.createCriteria(Comment.class) if (attrs.status) { criteria.add(Restrictions.eq('status', attrs.status)) } if (attrs.postId) { criteria.add(Restrictions.eq('post', session.get(Post.class, attrs.postId as Long))) } if (attrs.offset) { criteria.setFirstResult(attrs.offset as Integer) } criteria.setMaxResults(attrs.max as Integer ?: 100) criteria.list() } } def getPage(Long id, Map attrs = [:]) { withTransaction { if (attrs.nocache) { def serverProxy = new XMLRPCServerProxy(url, true) try { // Get all parents too def wpPages = [] def map for (Long tmpId = id;tmpId;) { map = serverProxy."wp.getPage"(blogId, tmpId, username, password) wpPages << map tmpId = map.wp_page_parent_id as Long } wpPages.reverse().each { updatePage(it) } } catch (Exception e) { throw new RuntimeException("Unable to update page", e) } } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) session.get(Page.class, id) } } def getPost(Long id, Map attrs = [:]) { withTransaction { if (attrs.nocache) { def serverProxy = new XMLRPCServerProxy(url, true) try { updatePost(serverProxy."metaWeblog.getPost"(id, username, password)) } catch (Exception e) { throw new RuntimeException("Unable to update post", e) } } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) session.get(Post.class, id) } } def getRecentPosts(String status = 'publish', Map attrs = [:]) { withTransaction { if (attrs.nocache) { def serverProxy = new XMLRPCServerProxy(url, true) try { def mostRecentPost = serverProxy."metaWeblog.getRecentPosts"(blogId, username, password, 1) serverProxy."metaWeblog.getRecentPosts"(blogId, username, password, mostRecentPost[0].postid).each { post -> log.trace "Wordpress Post : ${post}" updatePost(post) } } catch (Exception e) { throw new RuntimeException("Unable to update recent posts", e) } } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) def criteria = session.createCriteria(Post.class) .addOrder(Order.desc('id')) if (status) { criteria.add(Restrictions.eq('status', status)) } if (attrs.offset) { criteria.setFirstResult(attrs.offset as Integer) } criteria.setMaxResults(attrs.max as Integer ?: 100) criteria.list() } } def getRecentPostsInCategory(String categoryName, String status = 'publish', Map attrs = [:]) { withTransaction { Category category = getCategoryByName(categoryName) if (!category) { throw new RuntimeException("Invalid category : ${categoryName}", e) } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) def criteria = session.createCriteria(Post.class) .addOrder(Order.desc('id')) if (status) { criteria.add(Restrictions.eq('status', status)) } if (attrs.offset) { criteria.setFirstResult(attrs.offset as Integer) } criteria.setMaxResults(attrs.max as Integer ?: 100) criteria.createCriteria('categories') .add(Restrictions.idEq(category.id)) criteria.list() } } def getRecentPostsWithTag(String tagName, String status = 'publish', Map attrs = [:]) { withTransaction { Tag tag = getTagByName(tagName) if (!tag) { throw new RuntimeException("Invalid tag: ${tagName}", e) } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) def criteria = session.createCriteria(Post.class) .addOrder(Order.desc('id')) if (status) { criteria.add(Restrictions.eq('status', status)) } if (attrs.offset) { criteria.setFirstResult(attrs.offset as Integer) } criteria.setMaxResults(attrs.max as Integer ?: 100) criteria.createCriteria('tags') .add(Restrictions.idEq(tag.id)) criteria.list() } } def getPostCount() { withTransaction { def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) def results = session.createCriteria(Post.class) .setProjection(Projections.projectionList().add(Projections.rowCount())) .list() log.trace("Post Count : ${results[0]}") results[0] } } def getTags(Map attrs = [:]) { withTransaction { if (attrs.nocache) { def serverProxy = new XMLRPCServerProxy(url, true) try { serverProxy."wp.getTags"(blogId, username, password).each { wpTag -> updateTag(wpTag) } } catch (Exception e) { throw new RuntimeException("Unable to update tags", e) } } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) session.createCriteria(Tag.class) .addOrder(Order.asc('name')) .list() } } def getUsers(Map attrs = [:]) { withTransaction { if (attrs.nocache) { def serverProxy = new XMLRPCServerProxy(url, true) try { serverProxy."wp.getAuthors"(blogId, username, password).each { wpUser -> updateUser(wpUser) } } catch (Exception e) { throw new RuntimeException("Unable to update users", e) } } def session = SessionFactoryUtils.getSession(wordpressSessionFactory, false) session.createQuery("from User").list() } } }