Skip to content

Commit

Permalink
Merge pull request #53 from CMU-313/bc/translate
Browse files Browse the repository at this point in the history
Adding backend components to integrate translation service
  • Loading branch information
bencondemi authored Nov 12, 2024
2 parents 9c71d2f + e855951 commit c02b742
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 10 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ logs/
.eslintrc
test/files
*.min.js
install/docker/
install/docker/
src/translate/index.js
13 changes: 12 additions & 1 deletion .github/workflows/azure-deploy-f24.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,20 @@ jobs:
uses:
./.github/workflows/test.yaml

deepscan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run DeepScan
uses: deepscan/gh-action@v1
with:
token: ${{ secrets.DEEPSCAN_API_KEY }}


build-and-deploy:
if: github.repository == 'cmu-313/nodebb-f24-d-buggers'
needs: lint-and-test
needs: [lint-and-test, deepscan]

runs-on: ubuntu-latest

Expand Down
5 changes: 5 additions & 0 deletions public/openapi/components/schemas/CategoryObject.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ CategoryObject:
subCategoriesPerPage:
type: number
description: The number of subcategories to display on the categories and category page
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
- type: object
description: Optional properties that may or may not be present (except for `cid`, which is always present, and is only here as a hack to pass validation)
properties:
Expand Down
17 changes: 16 additions & 1 deletion public/openapi/components/schemas/PostObject.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ PostObject:
`icon:text` for the user's auto-generated
icon
example: "#f44336"
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
topic:
type: object
properties:
Expand Down Expand Up @@ -105,6 +110,11 @@ PostObject:
type: array
items:
$ref: ../../components/schemas/TagObject.yaml#/TagObject
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
required:
- uid
- tid
Expand Down Expand Up @@ -139,4 +149,9 @@ PostObject:
isMainPost:
type: boolean
replies:
type: number
type: number
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
40 changes: 40 additions & 0 deletions public/openapi/read/categories.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ get:
allOf:
- type: object
properties:
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
title:
description: The page title
type: string
Expand All @@ -34,6 +39,11 @@ get:
- $ref: ../components/schemas/CategoryObject.yaml#/CategoryObject
- type: object
properties:
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
tagWhitelist:
type: array
items:
Expand All @@ -50,6 +60,11 @@ get:
- $ref: ../components/schemas/CategoryObject.yaml#/CategoryObject
- type: object
properties:
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
tagWhitelist:
type: array
items:
Expand Down Expand Up @@ -113,6 +128,11 @@ get:
with `icon:text` for the user's
auto-generated icon
example: "#f44336"
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
index:
type: number
cid:
Expand Down Expand Up @@ -145,6 +165,11 @@ get:
timestampISO:
type: string
description: An ISO 8601 formatted date string (complementing `timestamp`)
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
user:
type: object
properties:
Expand Down Expand Up @@ -176,6 +201,11 @@ get:
`icon:text` for the user's
auto-generated icon
example: "#f44336"
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
index:
type: number
cid:
Expand All @@ -190,6 +220,11 @@ get:
type: string
title:
type: string
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
teaser:
type: object
properties:
Expand Down Expand Up @@ -240,6 +275,11 @@ get:
'icon:bgColor':
type: string
example: '#9c27b0'
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
imageClass:
type: string
- $ref: ../components/schemas/Pagination.yaml#/Pagination
Expand Down
10 changes: 10 additions & 0 deletions public/openapi/read/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ get:
type: number
content:
type: string
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
timestampISO:
type: string
description: An ISO 8601 formatted date string (complementing `timestamp`)
Expand Down Expand Up @@ -144,6 +149,11 @@ get:
type: number
content:
type: string
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
timestampISO:
type: string
description: An ISO 8601 formatted date string (complementing `timestamp`)
Expand Down
11 changes: 7 additions & 4 deletions public/openapi/read/search.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,24 @@ get:
type: boolean
search:tags:
type: boolean
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
required:
- posts
- matchCount
- pageCount
- time
- multiplePages
- search_query
- allCategories
- allCategoriesCount
- expandSearch
- showAsPosts
- showAsTopics
- title
- searchDefaultSortBy
- permissions
- privileges
- isEnglish
- $ref: ../components/schemas/Pagination.yaml#/Pagination
- $ref: ../components/schemas/Breadcrumbs.yaml#/Breadcrumbs
- $ref: ../components/schemas/CommonProps.yaml#/CommonProps
9 changes: 9 additions & 0 deletions public/openapi/read/topic/topic_id.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ get:
description: A topic identifier
content:
type: string
translatedContent:
type: string
description: Translated text, if applicable
nullable: true
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
timestamp:
type: number
votes:
Expand Down
9 changes: 9 additions & 0 deletions public/openapi/write/posts/pid.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ get:
description: A topic identifier
content:
type: string
translatedContent:
type: string
description: Translated text, if applicable
nullable: true
isEnglish:
type: boolean
description: Indicator about whether the text is English or not
default: false
nullable: true
timestamp:
type: number
flagId:
Expand Down
15 changes: 15 additions & 0 deletions public/src/client/topic.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,27 @@ define('forum/topic', [
handleThumbs();

$(window).on('scroll', utils.debounce(updateTopicTitle, 250));
configurePostToggle();

handleTopicSearch();

hooks.fire('action:topic.loaded', ajaxify.data);
};

function configurePostToggle() {
$('.topic').on('click', '.view-translated-btn', function () {
// Toggle the visibility of the next .translated-content div
$(this).closest('.sensitive-content-message').next('.translated-content').toggle();
// Optionally, change the button text based on visibility
var isVisible = $(this).closest('.sensitive-content-message').next('.translated-content').is(':visible');
if (isVisible) {
$(this).text('Hide the translated message.');
} else {
$(this).text('Click here to view the translated message.');
}
});
}

function handleTopicSearch() {
require(['mousetrap'], (mousetrap) => {
if (config.topicSearchEnabled) {
Expand Down
4 changes: 4 additions & 0 deletions src/posts/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const topics = require('../topics');
const categories = require('../categories');
const groups = require('../groups');
const privileges = require('../privileges');
const translate = require('../translate');

module.exports = function (Posts) {
Posts.create = async function (data) {
Expand All @@ -19,6 +20,7 @@ module.exports = function (Posts) {
const content = data.content.toString();
const timestamp = data.timestamp || Date.now();
const isMain = data.isMain || false;
const [isEnglish, translatedContent] = await translate.translate(data);

if (!uid && parseInt(uid, 10) !== 0) {
throw new Error('[[error:invalid-uid]]');
Expand All @@ -35,6 +37,8 @@ module.exports = function (Posts) {
tid: tid,
content: content,
timestamp: timestamp,
translatedContent: translatedContent,
isEnglish: isEnglish,
};

if (data.toPid) {
Expand Down
2 changes: 2 additions & 0 deletions src/posts/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,7 @@ function modifyPost(post, fields) {
if (post.hasOwnProperty('edited')) {
post.editedISO = post.edited !== 0 ? utils.toISOString(post.edited) : '';
}
// Mark post as "English" if decided by translator service or if it has no info
post.isEnglish = post.isEnglish === 'true' || post.isEnglish === undefined;
}
}
24 changes: 24 additions & 0 deletions src/translate/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

const translatorApi = module.exports;

translatorApi.translate = async function (postData) {
const TRANSLATOR_API = 'https://d-buggers-translate-hmfmgsg4cpa5fcfp.canadacentral-01.azurewebsites.net';
const response = await fetch(`${TRANSLATOR_API}/?content=${postData.content}`);
const data = await response.json();
return [data.is_english, data.translated_content];
};


// var request = require('request');

// const translatorApi = module.exports;

// translatorApi.translate = async function (postData) {
// // Edit the translator URL below
// const TRANSLATOR_API = "https://nodebb-f24-translator.azurewebsites.net/"
// const response = await fetch(TRANSLATOR_API+'/?content='+postData.content);
// const data = await response.json();
// return [data["is_english"], data["translated_content"]]
// }

5 changes: 2 additions & 3 deletions test/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -615,12 +615,11 @@ describe('API', async () => {
// Compare the schema to the response
required.forEach((prop) => {
if (schema.hasOwnProperty(prop)) {
assert(response.hasOwnProperty(prop), `"${prop}" is a required property (path: ${method} ${path}, context: ${context})`);

// Don't proceed with type-check if the value could possibly be unset (nullable: true, in spec)
if (response[prop] === null && schema[prop].nullable === true) {
if (response[prop] === null || schema[prop].nullable === true) {
return;
}
assert(response.hasOwnProperty(prop), `"${prop}" is a required property (path: ${method} ${path}, context: ${context})`);

// Therefore, if the value is actually null, that's a problem (nullable is probably missing)
assert(response[prop] !== null, `"${prop}" was null, but schema does not specify it to be a nullable property (path: ${method} ${path}, context: ${context})`);
Expand Down

0 comments on commit c02b742

Please sign in to comment.