send recsys powered-by #6875

Merged
jessopb merged 4 commits from recsys-sendPoweredBy into master 2021-08-17 16:03:25 +02:00
6 changed files with 62 additions and 19 deletions
Showing only changes of commit 4cd6dc01ef - Show all commits

View file

@ -28,7 +28,7 @@ declare type SearchOptions = {
declare type SearchState = {
options: SearchOptions,
urisByQuery: {},
resultsByQuery: {},
hasReachedMaxResultsLength: {},
searching: boolean,
};
@ -40,6 +40,7 @@ declare type SearchSuccess = {
from: number,
size: number,
uris: Array<string>,
recsys: string,
},
};

View file

@ -6,6 +6,7 @@ import {
makeSelectRecommendedClaimIds,
makeSelectRecommendationClicks,
} from 'redux/selectors/content';
import { makeSelectRecommendedRecsysIdForClaimId } from 'redux/selectors/search';
const VERSION = '0.0.1';
@ -36,7 +37,7 @@ function createRecsys(claimId, userId, events, loadedAt, isEmbed) {
claimId: claimId,
pageLoadedAt: pageLoadedAt,
pageExitedAt: pageExitedAt,
recsysId: recsysId,
recsysId: makeSelectRecommendedRecsysIdForClaimId(claimId)(state) || recsysId,
recClaimIds: makeSelectRecommendedClaimIds(claimId)(state),
recClickedVideoIdx: makeSelectRecommendationClicks(claimId)(state),
events: events,

View file

@ -61,13 +61,14 @@ export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => (
lighthouse
.search(queryWithOptions)
.then((data: Array<{ name: string, claimId: string }>) => {
.then((data: { body: Array<{ name: string, claimId: string }>, poweredBy: string }) => {
const { body: result, poweredBy } = data;
const uris = [];
const actions = [];
data.forEach((result) => {
if (result) {
const { name, claimId } = result;
result.forEach((item) => {
if (item) {
const { name, claimId } = item;
const urlObj: LbryUrlObj = {};
if (name.startsWith('@')) {
@ -94,6 +95,7 @@ export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => (
from: from,
size: size,
uris,
recsys: poweredBy,
},
});
dispatch(batchActions(...actions));

View file

@ -17,7 +17,7 @@ const defaultState: SearchState = {
[SEARCH_OPTIONS.MEDIA_IMAGE]: defaultSearchTypes.includes(SEARCH_OPTIONS.MEDIA_IMAGE),
[SEARCH_OPTIONS.MEDIA_APPLICATION]: defaultSearchTypes.includes(SEARCH_OPTIONS.MEDIA_APPLICATION),
},
urisByQuery: {},
resultsByQuery: {},
hasReachedMaxResultsLength: {},
searching: false,
};
@ -29,21 +29,23 @@ export default handleActions(
searching: true,
}),
[ACTIONS.SEARCH_SUCCESS]: (state: SearchState, action: SearchSuccess): SearchState => {
const { query, uris, from, size } = action.data;
const { query, uris, from, size, recsys } = action.data;
const normalizedQuery = createNormalizedSearchKey(query);
const urisForQuery = state.resultsByQuery[normalizedQuery] && state.resultsByQuery[normalizedQuery]['uris'];
let newUris = uris;
if (from !== 0 && state.urisByQuery[normalizedQuery]) {
newUris = Array.from(new Set(state.urisByQuery[normalizedQuery].concat(uris)));
if (from !== 0 && urisForQuery) {
newUris = Array.from(new Set(urisForQuery.concat(uris)));
}
// The returned number of urls is less than the page size, so we're on the last page
const noMoreResults = size && uris.length < size;
const results = { uris: newUris, recsys };
return {
...state,
searching: false,
urisByQuery: Object.assign({}, state.urisByQuery, { [normalizedQuery]: newUris }),
resultsByQuery: Object.assign({}, state.resultsByQuery, { [normalizedQuery]: results }),
hasReachedMaxResultsLength: Object.assign({}, state.hasReachedMaxResultsLength, {
[normalizedQuery]: noMoreResults,
}),

View file

@ -4,6 +4,7 @@ import { selectShowMatureContent } from 'redux/selectors/settings';
import {
parseURI,
makeSelectClaimForUri,
makeSelectClaimForClaimId,
makeSelectClaimIsNsfw,
buildURI,
isClaimNsfw,
@ -28,7 +29,7 @@ export const selectIsSearching: (state: State) => boolean = createSelector(selec
export const selectSearchUrisByQuery: (state: State) => { [string]: Array<string> } = createSelector(
selectState,
(state) => state.urisByQuery
(state) => state.resultsByQuery
);
export const selectHasReachedMaxResultsLength: (state: State) => { [boolean]: Array<boolean> } = createSelector(
@ -42,9 +43,9 @@ export const makeSelectSearchUris = (query: string): ((state: State) => Array<st
if (query) {
query = query.replace(/^lbry:\/\//i, '').replace(/\//, ' ');
const normalizedQuery = createNormalizedSearchKey(query);
return byQuery[normalizedQuery];
return byQuery[normalizedQuery] && byQuery[normalizedQuery]['uris'];
}
return byQuery[query];
return byQuery[query] && byQuery[query]['uris'];
});
export const makeSelectHasReachedMaxResultsLength = (query: string): ((state: State) => boolean) =>
@ -84,16 +85,47 @@ export const makeSelectRecommendedContentForUri = (uri: string) =>
const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options);
const normalizedSearchQuery = createNormalizedSearchKey(searchQuery);
let searchUris = searchUrisByQuery[normalizedSearchQuery];
if (searchUris) {
searchUris = searchUris.filter((searchUri) => searchUri !== currentUri);
recommendedContent = searchUris;
let searchResult = searchUrisByQuery[normalizedSearchQuery];
if (searchResult) {
recommendedContent = searchResult['uris'].filter((searchUri) => searchUri !== currentUri);
}
}
return recommendedContent;
}
);
export const makeSelectRecommendedRecsysIdForClaimId = (claimId: string) =>
createSelector(makeSelectClaimForClaimId(claimId), selectSearchUrisByQuery, (claim, searchUrisByQuery) => {
// TODO: DRY this out.
let poweredBy;
if (claim) {
const isMature = isClaimNsfw(claim);
const { title } = claim.value;
if (!title) {
return;
}
const options: {
related_to?: string,
nsfw?: boolean,
isBackgroundSearch?: boolean,
} = { related_to: claim.claim_id, isBackgroundSearch: true };
options['nsfw'] = isMature;
const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options);
const normalizedSearchQuery = createNormalizedSearchKey(searchQuery);
let searchResult = searchUrisByQuery[normalizedSearchQuery];
if (searchResult) {
poweredBy = searchResult.recsys;
} else {
return normalizedSearchQuery;
}
}
return poweredBy;
});
export const makeSelectWinningUriForQuery = (query: string) => {
const uriFromQuery = `lbry://${query}`;

View file

@ -1,4 +1,9 @@
// @flow
export default function handleFetchResponse(response: Response): Promise<any> {
return response.status === 200 ? Promise.resolve(response.json()) : Promise.reject(new Error(response.statusText));
const headers = response.headers;
const poweredBy = headers.get('x-powered-by');
return response.status === 200
? response.json().then((body) => ({ body, poweredBy }))
: Promise.reject(new Error(response.statusText));
}