R/accounts.R

# Copyright (c) 2015, Brandseye PTY (LTD) 
# 
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#     
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#' Provides access to a BrandsEye account
#' 
#' @details
#' Creates an object representing a BrandsEye account. It can be used to easily perform
#' various queries on the account. 
#' 
#' \code{summary} can be used to briefly summarise an account.
#' 
#' @section Querying an account:
#' 
#' \code{\link{account_count}} allows you to pull statistics from your account 
#' matching a filter. For example,
#' 
#' \verb{
#'  ac <- account("QUIR01BA")
#'  account_count(ac, "published inthelast week", groupby="country")
#' }
#' 
#' The above sums the number of mentions per country in the given account.
#' 
#' @seealso \code{\link{list_accounts}} to see the accounts that you have access to.
#' @seealso \code{\link{list_account_codes}} for a vector of account codes that you have
#' @seealso \code{\link{account_brands}} for listing the brands in an account.
#' @seealso \code{\link{account_phrases}} for listing the phrases used in an account.
#' @seealso \code{\link{account_tags}} for listing the tags used in an account.
#' @seealso \code{\link{client_service}} for the details of the client service
#'   person related to the account.
#' 
#' @examples
#' \dontrun{
#' ac <- account("QUIR01BA", user = "connie@@brandseye.com", 
#'               password = "This is not my real password")
#' account("QUIR01BA", key="<api key here>")        
#' 
#' # Have a brief summary of an account
#' summary(ac)      
#' }
#' @export
#' @author Constance Neeser
account <- function (code, key = NULL, user = NULL, password = NULL,
                     auth = pkg.env$defaultAuthentication) {        
    if (is.null(auth)) auth <- authentication(user = user, password = password, key = key)
    
    if (length(code) > 1) {
        return(lapply(code, function(c) account(c, auth = auth)))
    }
    
    ac <- structure(list(
        code = code,
        auth = auth
    ), class = "brandseye.account")
    
    ac <- account.load(ac)
    ac
}

#' Print's details of a brandseye account.
#' @export
#' @author Constance Neeser
print.brandseye.account <- function(account, ...) {
    output <- matrix(c(account$code, account_name(account), account$auth$user), ncol = 1)
    colnames(output) <- ""
    rownames(output) <- c("Code", "Name", "Login")    
    print(output, quote=F)
}

#' Summarising accounts
#' 
#' \code{summary} method for class "\code{brandseye.account}".
#' @export
#' @author Constance Neeser
summary.brandseye.account <- function(account, ...) {
    lastMonthVolume <- account_count(account, "published inthelast month", groupby="relevancy")
    total <- sum(lastMonthVolume$count)
    irrelevant <- filter(lastMonthVolume, relevancy == 'IRRELEVANT')$count
    relevant <- total - irrelevant
    
    counts <- matrix(c(total, relevant, irrelevant), ncol = 1)    
    rownames(counts) <- c("Total", "Relevant", "Irrelevant")
    colnames(counts) <- c("Mentions")  
    
    published <- account_count(account, "published inthelast month", groupby="published", 
                               include="engagement")
    averages <- matrix(c(mean(published$count), 
                         sd(published$count),
                         mean(published$engagement),
                         sd(published$engagement)), 
                       ncol = 1)
    rownames(averages) <- c("Count mean", "Count SD", "Engagement mean", "Engagement SD")
    colnames(averages) <- ""
    
    structure(list(
        account = account,
        counts = counts,
        averages = averages
    ), 
    class = "summary.brandseye.account"
    )
}

#' Prints a summary of a BrandsEye \code{\link{account}}
#' @export
#' @author Constance Neeser
print.summary.brandseye.account <- function(s.ac, ...) {
    cat("BrandsEye Account:\n")
    print(s.ac$account)
    cat("\n")
    cat("Summary of the last month:\n")
    print(s.ac$counts)
    cat("\nDaily averages:\n")
    print(round(s.ac$averages, 2))
}

#' Loads an account's details.
account.load <- function(account) {
    if (is.null(account$data)) {
        url = paste0("https://mash.brandseye.com/rest/accounts/", account$code)
        query <- list(include="tags,brands")
        data <- httr::GET(url, httr::authenticate(account$auth$user, account$auth$password), query = query)    
        check_errors(data)
        account$data <- httr::content(data)        
        account_name(account) <- account$data$name
        
        add_class <- paste0("brandseye.account.", stringr::str_to_lower(account$data$storage))
        class(account) <-  c(add_class, class(account))
    }
    account
}

#' Returns a BrandsEye \code{\link{account}}'s code. 
#' @export
#' @author Constance Neeser
account_code <- function(account) {
    UseMethod("account_code", account)
}

#' @describeIn account_code Returns the code from an \code{\link{account}} object.
#' @export
account_code.brandseye.account <- function(account) {
    account$code
}

#' @describeIn account_code Returns the code from a list of objects.
#' @export
account_code.list <- function(accounts) {
    sapply(accounts, function(ac) account_code(ac))
}

#' Returns the human readable name of an account
#' @export
#' @author Constance Neeser
account_name <- function(account) {
    UseMethod("account_name", account)
}

#' @describeIn account_name Returns the name from an \code{\link{account}} object.
#' @export
account_name.brandseye.account <- function(account) {    
    account$name
}

#' @describeIn account_name Returns the name from a vector of account codes.
#' @export
account_name.character <- function(accounts) {
    sapply(accounts, function(ac) {
        account_name(account(ac))
    })
}

#' @describeIn account_name Returns the name of an account given by a factor of the account code.
#' @export
account_name.factor <- function(accounts) {
    account_name(as.character(accounts))
}

'account_name<-' <- function(account, value) {
    UseMethod('account_name<-', account)
}

'account_name<-.brandseye.account' <- function(account, value) {
    account$name <- value
    account
}

#' Indicates the api version the account is available through.
#' 
#' Indicates the api version used by the account, such as whether it's V4 or the older V3.
#' @export
#' @author Constance Neeser
account_api_version <- function(account) {
    UseMethod("account_api_version", account)
}

#' @describeIn account_api_version Returns the api version from an \code{\link{account}} object.
#' @export
account_api_version.brandseye.account <- function(account) {    
    account$data$storage
}

#' @describeIn account_api_version Returns the api version from a vector of account codes.
#' @export
account_api_version.character <- function(accounts) {
    sapply(accounts, function(ac) {
        account_api_version(account(ac))
    })
}

#' @describeIn account_api_version Returns the api version of an account given by a factor of the account code.
#' @export
account_api_version.factor <- function(accounts) {
    account_api_version(as.character(accounts))
}

#' Gives the timezone that the account is in.
#' 
#' @export
#' @author Constance Neeser
account_timezone <- function(account) {
    UseMethod("account_timezone", account)
}

#' @describeIn account_timezone Returns the timezone from an \code{\link{account}} object.
#' @export
account_timezone.brandseye.account <- function(account) {    
    account$data$timezone
}

#' @describeIn account_timezone Returns the timezone from a vector of account codes.
#' @export
account_timezone.character <- function(accounts) {
    sapply(accounts, function(ac) {
        account_timezone(account(ac))
    })
}

#' @describeIn account_timezone Returns the timezone of an account given by a factor of the account code.
#' @export
account_timezone.factor <- function(accounts) {
    account_timezone(as.character(accounts))
}    


#' Client service details
#' 
#' Find out the details for the client service person to contact
#' for queries related to your account.
#' 
#' @return Returns a structure holding information about the 
#'  account's client service person, with \code{name} and
#'  \code{email} fields.
#' @export
#' @author Constance Neeser 
client_service <- function(account) {
    UseMethod("client_service", account)
}

#' @describeIn client_service
#' 
#' Returns client service details for an account object
#' 
#' @examples
#' \dontrun{
#' 
#' details <- client_service(account("QUIR01BA"))
#' details$name
#' details$email
#' 
#' }
#' @export
client_service.brandseye.account <- function(account) {
    structure(
        list(name = account$data$clientService$name,
             email = account$data$clientService$email),
        class = "brandseye.clientService"        
    )    
}

#' @describeIn client_service
#' 
#' Returns client service information for an account code.
#' 
#' @examples
#' \dontrun{
#' 
#' client_service("QUIR01BA")
#' 
#' }
#' @export
client_service.character <- function(code) {
    client_service(account(code))
}

#' @describeIn client_service
#' 
#' Returns the client service information for an account represented by a factor object.
#' 
#' @export
client_service.factor <- function(code) {
    client_service(account(code))
}

#' @describeIn client_service
#' 
#' Returns client service information for a vector of \code{\link{account}} objects.
#' 
#' @return As a special case, when given a vector of accounts, 
#'   this function returns a data frame with name and email columns,
#'   and a row per account.
#'   
#' @examples 
#' \dontrun{
#' 
#' client_service(c("QUIR01BA", "BEAD33AA"))
#' client_service(list_account_codes())
#' 
#' }
#' @export
client_service.list <- function(accounts) {
    purrr::map_df(accounts, function(ac) {
        cs <- client_service(ac)
        tibble(name = ifelse(is.null(cs$name), NA, cs$name),
               email = cs$email)
    })
}
    

#' Prints a client service S3 class.
#' @export
#' @author Constance Neeser
print.brandseye.clientService <- function(client_service) {
    display <- matrix(c(client_service$name, client_service$email), 2, 1)
    rownames(display) <- c("name", "email")
    colnames(display) <- ""
    print(display, quote = FALSE)
}

#' Listing brands in an account
#' 
#' This returns a \code{tibble} containing brand IDs, their names,
#' whether they've been deleted or not, and the ID of the parent brand.
#' @export
#' @author Constance Neeser
account_brands <- function(account, ...) {
    UseMethod("account_brands", account)
}

#' @describeIn account_brands
#' 
#' Returns brand information for a particular \code{\link{account}} object.
#' 
#' @examples
#' \dontrun{
#' # Fetch brands for an \code{\link{account}} object.
#' ac <- account("QUIR01BA")
#' account_brands(ac)
#' }
#' @export
account_brands.brandseye.account <- function(account, .process = FALSE) {
    id <- integer()
    name <- character()
    deleted <- logical()
    parents <- integer()
    tier <- character()
    topic_tree_id <- integer()
    
    recurse <- function(brand, parent = NA) {    
        id <<- c(id, brand$id)
        name <<- c(name, brand$name)
        deleted <<- c(deleted, ifelse(is.null(brand$deleted) || brand$deleted == FALSE, FALSE, TRUE))
        parents <<- c(parents, parent)
        tier <<- c(tier, ifelse(is.null(brand$tier), NA, brand$tier))
        topic_tree_id <<- c(topic_tree_id, ifelse(is.null(brand$topicTreeId), NA, brand$topicTreeId))
        
        if (length(brand$children)) {
            for (b in brand$children) {
                recurse(b, parent = brand$id)
            }
        }
    }
    
    for (b in account$data$brands) {
        recurse(b)
    }
    
    
    tibble(id = if(.process) factor(id) else id, 
           name = name, 
           deleted = deleted, 
           parent = if(.process) factor(parents) else parents,
           tier = tier,
           topic_tree_id = topic_tree_id)
}

#' @describeIn account_brands
#' 
#' Returns brand information for a list of accounts
#' 
#' @examples
#' \dontrun{
#' # Returns a tibble containing brand information for two accounts
#' account_brands(c("QUIR01BA", "BEAD33AA"))
#' 
#' # Return brand information for all accounts that you have access to
#' account_brands(list_account_codes())
#' }
#' @export
account_brands.list <- function(accounts) {
    accounts %>% 
        purrr::map_df(function(ac) {
            account_brands(ac) %>% 
                mutate(code = account_code(ac))
        }) %>% 
        select(code, everything())
}

#' @describeIn account_brands
#' 
#' Returns brand information for an account identified by an account code.
#' 
#' @examples
#' \dontrun{
#' # Fetching brands for a particular account
#' account_brands("QUIR01BA")
#' }
#' 
#' @export
account_brands.character <- function(account) {
    account_brands(account(account))
}

#' @describeIn account_brands
#' 
#' Returns brand information for an account identified by a factor of its account code.
#' 
#' @export
account_brands.factor <- function(account) {
    account_brands(account(account))
}

#' List phrases in an account
#' 
#' The returns a \code{tibble} listing the phrases in an
#' account, their IDs, the IDs of the brands that the phrase is associated
#' with, and a flag indicating whether the phrase is inactive or deleted.
#' @export
#' @author Constance Neeser
account_phrases <- function(account, ...) {
    UseMethod("account_phrases", account)
}

#' @describeIn account_phrases
#' 
#' Returns phrase information for a particular account object.
#' 
#' @examples
#' \dontrun{
#' # Returns account information for an account object
#' ac <- account("QUIR01BA")
#' account_phrases(ac)
#' }
#' @export
account_phrases.brandseye.account <- function(account, .process = FALSE) {
    id <- integer()
    brand.id <- character()
    phrase <- character()
    inactive <- logical()
    deleted <- logical()
    
    recurse <- function(brand) {    
        
        for (p in brand$phrases) {
            id <<- c(id, p$id)
            brand.id <<- c(brand.id, brand$id)
            phrase <<- c(phrase, p$q)
            deleted <<- c(deleted, ifelse(is.null(p$deleted) || p$deleted == FALSE, FALSE, TRUE))
            inactive <<- c(inactive, ifelse(is.null(p$inactive) || p$inactive == FALSE, FALSE, TRUE))
        }
        
        if (length(brand$children)) {
            for (b in brand$children) {
                recurse(b)
            }
        }
    }
    
    for (b in account$data$brands) {
        recurse(b)
    }
    
    
    tibble(id = if(.process) factor(id) else id, 
           brand.id = if(.process) factor(brand.id) else brand.id, 
           phrase = phrase, 
           inactive = inactive, 
           deleted = deleted)
}

#' @describeIn account_phrases
#' 
#' Returns account phrase information for an account identified using an account code
#' 
#' @examples
#' \dontrun{
#' account_phrases("QUIR01BA")
#' }
#' @export
account_phrases.character <- function(account) {
    account_phrases(account(account))
}

#' @describeIn account_phrases
#' 
#' Returns account phrase information for an account identified by a factor of 
#' its account code.
#' 
#' @export
account_phrases.factor <- function(account) {
    account_phrases(account(account))
}

#' @describeIn account_phrases
#' 
#' Given a list of \code{account} objects, this will return
#' a combined \code{tibble} for the phrases in all of those accounts.
#' 
#' @examples
#' \dontrun{
#' account_phrases(c("QUIR01BA", "BEAD33AA"))
#' }
#' @export
account_phrases.list <- function(accounts) {
    accounts %>% 
        purrr::map_df(function(ac) {
            account_phrases(ac, .process = FALSE) %>% 
                mutate(code = account_code(ac))
        }) %>% 
        select(code, everything())
}

#' List tags in an account
#' 
#' This returns a data frame of tags available in an account, along with the 
#' IDs of those tags.
#' @export
#' @author Constance Neeser
account_tags <- function(account, ...) {
    UseMethod("account_tags", account)
}

#' @describeIn account_tags
#' 
#' Returns tag information for \code{\link{account}} objects.
#' 
#' @param .process Set to \code{TRUE} if you do not want IDs set as factors.
#' @export
account_tags.brandseye.account <- function(account, .process = FALSE) {
    tags <- account$data$tags %>% 
        purrr::map_df(function(d) {
            tibble(id = d$id,
                   name = d$name,
                   namespace = d$namespace,
                   description = ifelse(is.null(d$description) || nchar(d$description) == 0, NA, d$description),
                   deleted = ifelse(is.null(d$deleted), FALSE, d$deleted)
            )
        }) %>% 
        mutate(children = purrr::map(account$data$tags, "children"),
               is_parent = purrr::map(children, function(d) length(d) > 0)) %>% 
        tidyr::unnest(is_parent)
    
    if (.process) tags$id <- factor(tags$id)
    
    tags
}

#' @describeIn account_tags
#' 
#' Returns tag information an account identified using an account code
#' 
#' @examples
#' \dontrun{
#' account_tags("QUIR01BA")
#' account_tags(c("QUIR01BA", "BEAD33AA")
#' }
#' @export
account_tags.character <- function(account) {
    account_tags(account(account))
}

#' @describeIn account_tags
#' 
#' Returns tag information for an account represented by a factor of its account code.
#' 
#' @export
account_tags.factor <- function(account) {
    account_tags(account(account))
}

#' @describeIn account_tags
#' 
#' Returns tag information for a list of \code{\link{account}} objects
#' @export
account_tags.list <- function(accounts) {
    accounts %>% 
        purrr::map_df(function(ac) {
            account_tags(ac) %>% 
                mutate(code = account_code(ac))
        }) %>% 
        select(code, everything())
}


#' List accounts you have access to
#' 
#' This returns a data frame listing the accounts that you have access to,
#' along with their name and status.
#' 
#' @examples
#' \dontrun{
#' 
#' list_accounts(key = "my api key")
#' 
#' list_accounts(user = "connie@@brandseye.com", 
#'               password = "my brandseye password")
#' 
#' auth <- authentication(user = "connie@@brandseye.com", 
#'                        password = "my brandseye password")
#' list_accounts(auth)
#' 
#' }
#' @export
#' @author Constance Neeser
list_accounts <- function(auth = pkg.env$defaultAuthentication, key = NULL, user = NULL, password = NULL) {
    if (is.null(auth)) auth <- authentication(key = key, user = user, password = password)
    url <- paste0("https://api.brandseye.com/rest/accounts/")
    data <- httr::GET(url, httr::authenticate(auth$user, auth$password))
    results <- jsonlite::fromJSON(httr::content(data, "text"))
    results
}

#' @describeIn list_accounts
#' 
#' Returns a character vector of account codes that you have access to.
#'
#' @examples
#' \dontrun{
#' # Get the number of mentions published in the last day across all 
#' # of your accounts.
#' account_count(list_account_codes(), "published inthelast day")
#' }
#' @export
list_account_codes <- function(auth = pkg.env$defaultAuthentication, key = NULL, user = NULL, password = NULL) {
    list_accounts(auth, key, user, password)$code
}
brandseye/brandseyer documentation built on May 13, 2019, 2:30 a.m.