Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bda014a
comments for changes
RWParsons Nov 21, 2025
36554cb
add refactored handle & fetch fncs
cynthiahqy Nov 21, 2025
14ededa
fix typo in fetch_response call
cynthiahqy Nov 21, 2025
ef3bd37
remove unused libraries_count line
cynthiahqy Nov 21, 2025
8e6a167
match language names draft
smwindecker Nov 21, 2025
02eb395
draft get_auth_handle function
smwindecker Nov 21, 2025
3dcb441
Merge remote-tracking branch 'origin/refactor-recent-stats' into refa…
smwindecker Nov 21, 2025
1492b55
add documentation to get_auth_handle and remove unneeded version of f…
smwindecker Nov 21, 2025
303fe65
add fncs to fetch all pages from endpoint
cynthiahqy Nov 21, 2025
48dd8d9
fetch pages as list in Recent Changes
cynthiahqy Nov 21, 2025
9aecf5d
move function to correct R folder.
smwindecker Nov 21, 2025
a0c8c89
implement the match language functions
smwindecker Nov 21, 2025
c6b930d
Merge remote-tracking branch 'origin/refactor-recent-stats' into refa…
smwindecker Nov 21, 2025
7dfd8d0
Merge remote-tracking branch 'origin/refactor-recent-stats' into refa…
cynthiahqy Nov 21, 2025
80089f0
process page response as function
RWParsons Nov 21, 2025
cf40b34
cut down on for loop to process changes pages
RWParsons Nov 21, 2025
f566ded
revise example in documentation to use file object name
smwindecker Nov 21, 2025
bfe5923
refactor plural to singular in process_page_response()
RWParsons Nov 21, 2025
cc92225
create function to replace the loop over pages in edit_url
smwindecker Nov 21, 2025
722bcf4
source directory before using functions
smwindecker Nov 21, 2025
10ac50f
commit merge
smwindecker Nov 21, 2025
5d17d94
change name of file to match name of function
smwindecker Nov 21, 2025
c63ee65
styling mark_page
RWParsons Nov 21, 2025
b496f34
wrap process_page_response in collect_page_changes that returns data.…
RWParsons Nov 21, 2025
aedf99f
remove stringr dependency
RWParsons Nov 21, 2025
4f8f790
remove redundant code and run styler
RWParsons Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions weblate/R/collect_page_changes.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
collect_page_changes <- function(
changes_page,
language_file = NULL,
slugs = NULL,
name_of_libraries = NULL
) {
stopifnot(
"language_file must be provided" = !is.null(language_file),
"slugs must be provided" = !is.null(slugs),
"name_of_libraries must be provided" = !is.null(name_of_libraries)
)
page_data <- process_page_response(changes_page)

languages <- match_language_names(
page_data$extracted_lang,
language_file
)

extracted_lib <- numeric(length(page_data$extracted_slug))
k <- 1
for (s in page_data$extracted_slug) {
index <- which(s == slugs)
extracted_lib[k] <- name_of_libraries[index]
print(k)
k <- k + 1
}

data.frame(
user = page_data$extracted_users,
language = languages,
library = extracted_lib,
units = page_data$extracted_units,
date = as.integer(page_data$date),
time = page_data$time
)
}
28 changes: 28 additions & 0 deletions weblate/R/fetch_responses.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
fetch_response_content <- function(endpoint, handle) {
print(paste("Querying endpoint", endpoint))

response <- curl_fetch_memory(endpoint, handle = h)
response_content <- rawToChar(response$content)
fromJSON(response_content)
}

calculate_n_pages <- function(count, page_size = 50) {
remain <- count %% page_size

if (remain == 0) {
pages <- count / page_size
} else {
pages <- ceiling(count / page_size)
}

return(pages)
}

fetch_pages_content <- function(n_pages, endpoint, handle) {
pages <- vector("list", n_pages)
for (i in 1:n_pages) {
url <- paste0(endpoint, "&page=", i)
pages[[i]] <- fetch_response_content(url, handle)
}
pages
}
19 changes: 19 additions & 0 deletions weblate/R/get_auth_handle.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#' Get authorisation handle for data fetching
#'
#' @param API_TOKEN access credential
#'
#' @returns handle for fetching
#' @export
#'
#' @examples
#' \dontrun{
#' API_TOKEN <- Sys.getenv("WEBLATE_TOKEN")
#' h <- get_auth_handle()
#' }
get_auth_handle <- function(API_TOKEN) {
h <- new_handle()
handle_setopt(h, ssl_verifyhost = 0L, ssl_verifypeer = 0L)
handle_setopt(h, customrequest = "GET")
handle_setopt(h, httpheader = c(paste0("Authorization: Token ", API_TOKEN)))
return(h)
}
53 changes: 53 additions & 0 deletions weblate/R/mark_page.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#' Extract information from newly edited records on a given page
#'
#' @param page_no page of edited changes to be fetched
#' @param edit_url url to access edited changes page
#' @param language_file reference file containing the link between language
#' code and language full name
#'
#' @returns dataframe containing language, library, string, id, and url for
#' the edited records on this given page
#' @export
#'
#' @examples
#' \dontrun{
#' mark_page(1,
#' "https://translate.rx.studio/api/units/?q=project:r-project%20AND%20state:needs-editing",
#' Language_Statistics)
#' }
mark_page <- function(page_no, edit_url, language_file = NULL) {
# input checking
stopifnot(
"page should be greater than 0" = page_no > 0,
"edit_url should not be empty" = nzchar(edit_url),
"language_file must be provided" = !is.null(language_file)
)

mark_url <- paste0(edit_url, "&page=", page_no)
mark_changes <- fetch_response_content(endpoint = mark_url, handle = h)
# each row is a unit: https://docs.weblate.org/en/latest/api.html#units

mark_lang <- match_language_names(
mark_changes$results$language_code,
language_file
)

mark_lib_id <- match(
basename(dirname(mark_changes$results$translation)),
slugs
)
mark_lib <- name_of_libraries[mark_lib_id]

# where there are multiple messages due to plurals, use the first
mark_string <- vapply(mark_changes$results$source, "[", character(1), 1)
mark_units <- mark_changes$results$id
mark_web_url <- mark_changes$results$web_url

data.frame(
language = mark_lang,
library = mark_lib,
string = mark_string,
id = mark_units,
url = mark_web_url
)
}
20 changes: 20 additions & 0 deletions weblate/R/match_language_names.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#' Match language code page changes to reference list
#'
#' @param extracted_language_codes language code extracted from the
#' page changes objects
#' @param language_file reference file containing the link between language
#' code and language full name
#'
#' @returns vector of language names
#' @export
#'
#' @examples
#' extracted_lang <- c('ar', 'bn', 'ca')
#' languages <- match_language_names(extracted_lang, Language_Statistics)
match_language_names <- function (extracted_language_codes,
language_file) {
lang_codes <- match(extracted_language_codes, language_file$Code)
languages <- language_file$Name[lang_codes]
return(languages)
}

67 changes: 67 additions & 0 deletions weblate/R/process_page_response.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#' Extract and clean data from a page
#'
#' @param pages_changes
#'
#' @returns A list.
#' @export
process_page_response <- function(page) {
component <- extract_str(page$results$component, "components/(.*?)/")
component <- gsub("components/|/", "", component)
extracted_users <- extract_str(page$results$user, "/([^/]+)/$")
extracted_users <- gsub("/", "", extracted_users)
extracted_lang <- extract_str(page$results$translation, "/([^/]+)/$")
extracted_lang <- gsub("/", "", extracted_lang)
extracted_slug <- extract_str(page$results$component, "/([^/]+)/$")
extracted_slug <- gsub("/", "", extracted_slug)
extracted_units <- extract_str(page$results$unit, "/([^/]+)/$")
extracted_units <- gsub("/", "", extracted_units)

datetime <- as.POSIXct(
page$results$timestamp,
format = "%Y-%m-%dT%H:%M:%OSZ"
)
datetime <- strptime(datetime, format = "%Y-%m-%d %H:%M:%S")
date <- as.Date(datetime)
time <- format(datetime, format = "%H:%M:%S")

list(
extracted_users = extracted_users,
extracted_lang = extracted_lang,
extracted_slug = extracted_slug,
extracted_units = extracted_units,
date = date,
time = time
)
}


#' Basically the same as stringr::str_extract()
#'
#' @param x A character vector.
#' @param pattern A regular expression.
#'
#' @returns A character vector.
#'
#' @examples
#' extract_str(c('test1', 'apple'), 'app')
extract_str <- function(x, pattern) {
unname(sapply(x, function(.x) extract_str_or_na(.x, pattern)))
}


#' Extract the string given a pattern and return NA if no match.
#'
#' @param i A character.
#' @param pattern A regular expression.
#'
#' @returns A character.
#'
#' @examples
#' extract_str_or_na('apple', 'app')
extract_str_or_na <- function(i, pattern) {
m <- unlist(regmatches(i, gregexpr(pattern, i)))
if (length(m) == 0) {
return(NA_character_)
}
m
}
Loading