Skip to content

Commit

Permalink
Merge pull request #448 from impresso/develop
Browse files Browse the repository at this point in the history
Release v3.0.4
  • Loading branch information
theorm authored Oct 22, 2024
2 parents b8d64a3 + 4f61fd7 commit 34873da
Show file tree
Hide file tree
Showing 18 changed files with 736 additions and 599 deletions.
711 changes: 402 additions & 309 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
"moment": "^2.24.0",
"multer": "^1.4.5-lts.1",
"mustache": "^2.3.2",
"mysql2": "^2.3.3",
"mysql2": "^3.11.3",
"nanoid": "^2.0.1",
"neo4j-driver": "^1.7.2",
"node-eta": "^0.9.0",
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/access-rights.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const obfuscate = () => context => {
}
break
case 'articles.get':
case 'content-items.get':
if (shouldBeObfuscated(context.result.issue.accessRights)) {
debug(
`${prefix} issue obfuscated due to context.result.issue.accessRights: ${context.result.issue.accessRights}`
Expand All @@ -86,6 +87,7 @@ const obfuscate = () => context => {
}
break
case 'articles.find':
case 'content-items.find':
case 'articles-suggestions.get':
debug(`${prefix} verify accessRights per article issue`)
for (let i = 0, l = context.result.data.length; i < l; i += 1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Article",
"description": "A journal/magazine article",
"title": "ContentItem",
"description": "A journal/magazine content item (article, advertisement, etc.)",
"type": "object",
"additionalProperties": false,
"properties": {
"uid": {
"type": "string",
"description": "The unique identifier of the article"
"description": "The unique identifier of the content item"
},
"type": {
"type": "string",
"description": "The type of the article. NOTE: may be empty."
"description": "The type of the content item. NOTE: may be empty."
},
"title": {
"type": "string",
"description": "The title of the article"
"description": "The title of the content item"
},
"size": {
"type": "integer",
"description": "The size of the article in characters"
"description": "The size of the content item in characters"
},
"nbPages": {
"type": "integer",
"description": "The number of pages in this article"
"description": "The number of pages in this content item"
},
"pages": {
"type": "array",
Expand All @@ -37,7 +37,7 @@
},
"excerpt": {
"type": "string",
"description": "The excerpt of the article"
"description": "The excerpt of the content item"
},
"locations": {
"type": "array",
Expand All @@ -53,21 +53,21 @@
},
"language": {
"type": "string",
"description": "The language code of the article"
"description": "The language code of the content item"
},
"issue": {
"$ref": "./NewspaperIssue.json"
},
"matches": {
"type": "array",
"items": {
"$ref": "./ArticleMatch.json"
"$ref": "./ContentItemMatch.json"
}
},
"regions": {
"type": "array",
"items": {
"$ref": "./ArticleRegion.json"
"$ref": "./ContentItemRegion.json"
}
},
"regionBreaks": {
Expand All @@ -93,17 +93,17 @@
},
"date": {
"oneOf": [
{ "type": "string", "description": "The date of the article", "format": "date-time" },
{ "type": "string", "description": "The date of the content item", "format": "date-time" },
{ "type": "null" }
]
},
"year": {
"type": "integer",
"description": "The year of the article"
"description": "The year of the content item"
},
"country": {
"type": "string",
"description": "The country code of the article"
"description": "The country code of the content item"
},
"tags": {
"type": "array",
Expand All @@ -119,15 +119,15 @@
"$ref": "./Newspaper.json"
},
"dataProvider": {
"oneOf": [{ "type": "string", "description": "The provider article" }, { "type": "null" }]
"oneOf": [{ "type": "string", "description": "The provider of the content item" }, { "type": "null" }]
},
"topics": {
"type": "array",
"items": { "$ref": "./ArticleTopic.json" }
"items": { "$ref": "./ContentItemTopic.json" }
},
"content": {
"type": "string",
"description": "The content of the article"
"description": "The content of the content item"
},
"mentions": {
"type": "array",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ArticleMatch",
"title": "ContentItemMatch",
"description": "TODO",
"type": "object",
"additionalProperties": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ArticleRegion",
"title": "ContentItemRegion",
"description": "TODO",
"type": "object",
"additionalProperties": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ArticleTopic",
"title": "ContentItemTopic",
"description": "TODO",
"type": "object",
"additionalProperties": false,
Expand Down
2 changes: 1 addition & 1 deletion src/services/articles-search/articles-search.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ArticlesSearch {
this.options = options || {}
/** @type {import('../../cachedSolr').CachedSolrClient} */
this.solr = app.service('cachedSolr')
this.articlesService = app.service('articles')
this.articlesService = app.service('content-items')
}

/**
Expand Down
16 changes: 8 additions & 8 deletions src/services/articles/articles.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ const findParameters: MethodParameter[] = [
* NOTE: Keep this in sync with validators in search.hooks.ts
*/
export const docs: ServiceSwaggerOptions = {
description: 'Articles',
description: 'Content items',
securities: ['find', 'get'],
operations: {
find: {
operationId: 'findArticles',
description: 'Find articles that match the given query',
operationId: 'findContentItem',
description: 'Find content items that match the given query',
parameters: findParameters,
responses: getStandardResponses({
method: 'find',
schema: 'Article',
schema: 'ContentItem',
}),
},
get: {
operationId: 'getArticle',
description: 'Get an article by its UID',
operationId: 'getContentItem',
description: 'Get a content item by its UID',
parameters: [
{
in: 'path',
Expand All @@ -53,12 +53,12 @@ export const docs: ServiceSwaggerOptions = {
schema: {
type: 'string',
},
description: 'UID of the article',
description: 'UID of the content item',
},
],
responses: getStandardResponses({
method: 'get',
schema: 'Article',
schema: 'ContentItem',
}),
},
},
Expand Down
29 changes: 0 additions & 29 deletions src/services/articles/articles.service.js

This file was deleted.

43 changes: 43 additions & 0 deletions src/services/articles/articles.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ServiceOptions } from '@feathersjs/feathers'
import { createSwaggerServiceOptions } from 'feathers-swagger'
import { ImpressoApplication } from '../../types'
import { docs } from './articles.schema'

// Initializes the `articles` service on path `/articles`
const createService = require('./articles.class')
const hooks = require('./articles.hooks')

export default function (app: ImpressoApplication) {
const paginate = app.get('paginate')

/**
* Even though the service is historically called 'articles'
* it technically deals with content items. We keep the original prefix
* for the internal use (web app), but expose it as 'content-items' for the public API.
*/
const prefix = app.get('isPublicApi') ? '/content-items' : '/articles'

const options = {
name: 'articles',
paginate,
app,
}

const svc = createService(options)

// Initialize our service with any options it requires
app.use('/content-items', svc, {
events: [],
docs: createSwaggerServiceOptions({ schemas: {}, docs }),
} as ServiceOptions)

// Get our initialized service so that we can register hooks and filters
const service = app.service('content-items')

service.hooks(hooks)

if (!app.get('isPublicApi')) {
// Expose the service as 'articles' for the web app
app.use('/articles', service)
}
}
91 changes: 49 additions & 42 deletions src/services/search-exporter/search-exporter.class.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,66 @@
/* eslint-disable no-unused-vars */
const debug = require('debug')('impresso/services:search');
const { NotFound, NotImplemented } = require('@feathersjs/errors');
const { protobuf } = require('impresso-jscommons');
const solr = require('../../solr');
const article = require('../../models/articles.model');
const debug = require('debug')('impresso/services:search-exporter')
const { NotFound, NotImplemented } = require('@feathersjs/errors')
const { protobuf } = require('impresso-jscommons')
const solr = require('../../solr')
const article = require('../../models/articles.model')

class Service {
constructor (options) {
this.solr = solr.client(options.app.get('solr'), options.app.get('solrConnectionPool'));
this.name = options.name;
this.options = options || {};
this.app = options.app;
constructor(options) {
this.solr = solr.client(options.app.get('solr'), options.app.get('solrConnectionPool'))
this.name = options.name
this.options = options || {}
this.app = options.app
debug('Service created')
}

async create (data, params) {
const client = this.app.get('celeryClient');
async create(data, params) {
const client = this.app.get('celeryClient')
if (!client) {
return {};
return {}
}

const q = params.sanitized.sq;
debug('[create] from solr query:', q, 'filters:', params.sanitized.filters);
const q = params.sanitized.sq
debug('[create] from solr query:', q, 'filters:', params.sanitized.filters)

const pq = protobuf.searchQuery.serialize({
filters: params.sanitized.filters,
});
debug('[create] protobuffered:', pq);
})
debug('[create] protobuffered:', pq)

return client.run({
task: 'impresso.tasks.export_query_as_csv',
args: [
// user id
params.user.id,
// query
q,
// description
data.sanitized.description || '',
// query_hash
pq,
],
}).catch((err) => {
if (err.result.exc_type === 'DoesNotExist') {
throw new NotFound(err.result.exc_message);
} else if (err.result.exc_type === 'OperationalError') {
// probably db is not availabe
throw new NotImplemented();
}
console.error(err);
throw new NotImplemented();
});
return client
.run({
task: 'impresso.tasks.export_query_as_csv',
args: [
// user id
params.user.id,
// query
q,
// description
data.sanitized.description || '',
// query_hash
pq,
],
})
.then(result => {
debug('[create] result:', result)
return { taskId: result.taskId }
})
.catch(err => {
if (err.result.exc_type === 'DoesNotExist') {
throw new NotFound(err.result.exc_message)
} else if (err.result.exc_type === 'OperationalError') {
// probably db is not availabe
throw new NotImplemented()
}
console.error(err)
throw new NotImplemented()
})
}
}

module.exports = function (options) {
return new Service(options);
};
return new Service(options)
}

module.exports.Service = Service;
module.exports.Service = Service
Loading

0 comments on commit 34873da

Please sign in to comment.