diff --git a/_schema.graphql b/_schema.graphql
index 7e54f8d7..5673637b 100644
--- a/_schema.graphql
+++ b/_schema.graphql
@@ -33,6 +33,9 @@ type Collection {
# Collection can be surfaced on editorial pages
show_on_editorial: Boolean!
+
+ # Collection has prioritized connection to artist
+ is_featured_artist_content: Boolean!
}
type CollectionCategory {
@@ -78,8 +81,9 @@ scalar DateTime
type Query {
collections(
- randomize: Boolean
+ randomizationSeed: String
size: Int
+ isFeaturedArtistContent: Boolean
showOnEditorial: Boolean
artistID: String
): [Collection!]!
diff --git a/fixtures/collections_test.csv b/fixtures/collections_test.csv
index 8d3874a4..ffdeca05 100644
--- a/fixtures/collections_test.csv
+++ b/fixtures/collections_test.csv
@@ -1,3 +1,3 @@
-title,slug,category,description,headerImage,credit,artist_ids,gene_ids,tag_id,keyword,price_guidance,show_on_editorial
-Alexander Calder: Lithographs,alexander-calder-lithographs ,Modern,"
Although Alexander Calder might be best known for his wire mobiles, the artist was also an avid printmaker at the end of his career. Featuring primary colors, geometric lines and spirals, and flattened biomorphic shapes, the imagery in Calder’s lithographs is often reminiscent of his sculptural work. While many of Calder’s prints may initially appear abstract, a closer look will reveal symbols of people, plants, and animals. Calder even used his prints for political activism—in 1967 and 1969, Calder produced posters protesting the Vietnam War.
",http://files.artsy.net/images/alexandercalderlithographs.png,"© Alexander Calder / Artist Rights Society (ARS), New York, NY.
",4dde70a1306f6800010036ef,lithograph-1,,,1000,true
+title,slug,category,description,headerImage,credit,artist_ids,gene_ids,tag_id,keyword,price_guidance,show_on_editorial,is_featured_artist_content
+Alexander Calder: Lithographs,alexander-calder-lithographs ,Modern,"Although Alexander Calder might be best known for his wire mobiles, the artist was also an avid printmaker at the end of his career. Featuring primary colors, geometric lines and spirals, and flattened biomorphic shapes, the imagery in Calder’s lithographs is often reminiscent of his sculptural work. While many of Calder’s prints may initially appear abstract, a closer look will reveal symbols of people, plants, and animals. Calder even used his prints for political activism—in 1967 and 1969, Calder produced posters protesting the Vietnam War.
",http://files.artsy.net/images/alexandercalderlithographs.png,"© Alexander Calder / Artist Rights Society (ARS), New York, NY.
",4dde70a1306f6800010036ef,lithograph-1,,,1000,true,true
Andy Warhol: Bananas,andy-warhol-bananas/,Pop Art,"In 1967, Andy Warhol designed one of the most iconic album covers of all time, featuring a simple yellow banana on the sleeve of The Velvet Underground’s debut record. Warhol, undeterred by his lack of experience in the music industry, had become the band’s manager two years prior and even introduced the German vocalist Nico to the group. Early editions of the record cover featured removable stickers, allowing music fans to peel the banana’s yellow skin to reveal a pink fruit underneath. These early covers, now a rare collector’s item, also included the titillating suggestion, “Peel Slowly and See.” Though Warhol cut ties with The Velvet Underground in 1968, he continued experimenting with the banana motif in silkscreens and polaroids, favoring the fruit for its phallic shape and ubiquity in American daily life.
",http://files.artsy.net/images/andywarholbanana.png,"© Andy Warhol / Artist Rights Society (ARS), New York, NY.
",4d8b92b34eb68a1b2c0003f4,,,Banana
\ No newline at end of file
diff --git a/src/Entities/Collection.ts b/src/Entities/Collection.ts
index beb46c5e..ec7c9209 100644
--- a/src/Entities/Collection.ts
+++ b/src/Entities/Collection.ts
@@ -79,4 +79,10 @@ export class Collection {
})
@Column({ default: false })
show_on_editorial: boolean = false
+
+ @Field(type => Boolean, {
+ description: "Collection has prioritized connection to artist",
+ })
+ @Column({ default: false })
+ is_featured_artist_content: boolean = false
}
diff --git a/src/Resolvers/Collections.ts b/src/Resolvers/Collections.ts
index b215b12e..12a0937b 100644
--- a/src/Resolvers/Collections.ts
+++ b/src/Resolvers/Collections.ts
@@ -12,24 +12,29 @@ export class CollectionsResolver {
async collections(
@Arg("artistID", { nullable: true }) artistID: string,
@Arg("showOnEditorial", { nullable: true }) showOnEditorial: boolean,
+ @Arg("isFeaturedArtistContent", { nullable: true })
+ isFeaturedArtistContent: boolean,
@Arg("size", () => Int, { nullable: true }) size: number,
- @Arg("randomize", { nullable: true }) randomize: boolean
+ @Arg("randomizationSeed", { nullable: true }) randomizationSeed: string
): Promise {
const hasArguments =
[].filter.call(arguments, arg => arg !== undefined).length > 0
const query: any = hasArguments ? { where: {} } : {}
+ if (isFeaturedArtistContent !== undefined) {
+ query.where.is_featured_artist_content = isFeaturedArtistContent
+ }
if (showOnEditorial !== undefined) {
query.where.show_on_editorial = showOnEditorial
}
if (artistID) {
query.where["query.artist_ids"] = { $in: [artistID] }
}
- if (!randomize && size) {
+ if (!randomizationSeed && size) {
query.take = size
}
- if (randomize) {
+ if (randomizationSeed) {
const aggregatePipeline: any = []
if (!isEmpty(query.where)) {
aggregatePipeline.push({ $match: query.where })
diff --git a/src/Resolvers/__tests__/collection_resolvers.test.ts b/src/Resolvers/__tests__/collection_resolvers.test.ts
index 4559124f..b2c19bbc 100644
--- a/src/Resolvers/__tests__/collection_resolvers.test.ts
+++ b/src/Resolvers/__tests__/collection_resolvers.test.ts
@@ -58,6 +58,7 @@ describe("Collections", () => {
}
price_guidance
show_on_editorial
+ is_featured_artist_content
}
}
`
@@ -79,6 +80,7 @@ describe("Collections", () => {
},
price_guidance: null,
show_on_editorial: false,
+ is_featured_artist_content: true,
},
{
id: "2",
@@ -92,6 +94,7 @@ describe("Collections", () => {
},
price_guidance: 1000,
show_on_editorial: true,
+ is_featured_artist_content: false,
},
{
id: "3",
@@ -105,6 +108,7 @@ describe("Collections", () => {
},
price_guidance: 1000,
show_on_editorial: false,
+ is_featured_artist_content: true,
},
],
})
@@ -112,6 +116,23 @@ describe("Collections", () => {
})
describe("queries", () => {
+ it("can construct queries with isFeaturedArtistContent", () => {
+ const query = `
+ {
+ collections(isFeaturedArtistContent: true) {
+ id
+ }
+ }
+ `
+
+ return runQuery(query, {}, createMockSchema).then(data => {
+ expect(find).toBeCalledWith({
+ where: { is_featured_artist_content: true },
+ })
+ expect((data as any).collections.length).toBeTruthy()
+ })
+ })
+
it("can construct queries with showOnEditorial", () => {
const query = `
{
@@ -185,7 +206,7 @@ describe("Collections", () => {
it("can return collections in random order via randomize", () => {
const query = `
{
- collections(randomize: true) {
+ collections(randomizationSeed: "123") {
id
}
}
@@ -200,7 +221,7 @@ describe("Collections", () => {
it("can return collections in random order via randomize with query", () => {
const query = `
{
- collections(randomize: true, size: 2, showOnEditorial: true) {
+ collections(randomizationSeed: "1234", size: 2, showOnEditorial: true) {
id
}
}
diff --git a/src/Resolvers/__tests__/fixtures/data.ts b/src/Resolvers/__tests__/fixtures/data.ts
index 15480813..f8deee20 100644
--- a/src/Resolvers/__tests__/fixtures/data.ts
+++ b/src/Resolvers/__tests__/fixtures/data.ts
@@ -17,6 +17,8 @@ export const mockCollectionRepository = plainToClass(Collection, [
createdAt: Date.now(),
updatedAt: Date.now(),
show_on_editorial: false,
+ price_guidance: null,
+ is_featured_artist_content: true,
},
{
id: 2,
@@ -34,6 +36,7 @@ export const mockCollectionRepository = plainToClass(Collection, [
},
show_on_editorial: true,
price_guidance: 1000,
+ is_featured_artist_content: false,
},
{
id: 3,
@@ -50,5 +53,6 @@ export const mockCollectionRepository = plainToClass(Collection, [
},
show_on_editorial: false,
price_guidance: 1000,
+ is_featured_artist_content: true,
},
])
diff --git a/src/utils/__tests__/__snapshots__/createSchema.test.ts.snap b/src/utils/__tests__/__snapshots__/createSchema.test.ts.snap
index 55160a19..531c4991 100644
--- a/src/utils/__tests__/__snapshots__/createSchema.test.ts.snap
+++ b/src/utils/__tests__/__snapshots__/createSchema.test.ts.snap
@@ -36,6 +36,9 @@ type Collection {
# Collection can be surfaced on editorial pages
show_on_editorial: Boolean!
+
+ # Collection has prioritized connection to artist
+ is_featured_artist_content: Boolean!
}
type CollectionCategory {
@@ -80,7 +83,7 @@ type CollectionQuery {
scalar DateTime
type Query {
- collections(randomize: Boolean, size: Int, showOnEditorial: Boolean, artistID: String): [Collection!]!
+ collections(randomizationSeed: String, size: Int, isFeaturedArtistContent: Boolean, showOnEditorial: Boolean, artistID: String): [Collection!]!
categories: [CollectionCategory!]!
collection(slug: String!): Collection
}
diff --git a/src/utils/__tests__/updateSailthru.test.ts b/src/utils/__tests__/updateSailthru.test.ts
index 52a1f4f9..98a7c5a1 100644
--- a/src/utils/__tests__/updateSailthru.test.ts
+++ b/src/utils/__tests__/updateSailthru.test.ts
@@ -2,8 +2,9 @@ jest.mock("../../Entities", () => ({ Collection: jest.fn() }))
jest.mock("../../config/database", () => ({ databaseConfig: jest.fn() }))
const pushContent = jest.fn()
-jest.mock("../getArtists", () => ({ getArtists: jest.fn() }))
-jest.mock("../getArtworks", () => ({ getArtworks: jest.fn() }))
+jest.mock("../getArtworks", () => ({
+ getArtworks: jest.fn().mockReturnValue([[], []]),
+}))
jest.mock("sailthru-client", () => ({
createSailthruClient: jest.fn().mockReturnValue({
@@ -68,6 +69,7 @@ describe("pushContentToSailthru", () => {
// 2nd argument: tags, vars, and images being passed to Sailthru
expect(argumentsForPushToSailthru[2].tags[0]).toEqual("collection")
expect(argumentsForPushToSailthru[2].vars).toEqual({
+ artworks_slugs: [],
slug: "cat-pictures",
collection_category: "Contemporary",
description: "Wow! Look at those cats!",
diff --git a/src/utils/convertCSVToJSON.ts b/src/utils/convertCSVToJSON.ts
index e1cc0abf..95d34259 100644
--- a/src/utils/convertCSVToJSON.ts
+++ b/src/utils/convertCSVToJSON.ts
@@ -31,6 +31,7 @@ export const convertCSVToJSON: (string) => Promise = (
keyword,
price_guidance,
show_on_editorial = false,
+ is_featured_artist_content = false,
}) =>
({
title,
@@ -41,6 +42,7 @@ export const convertCSVToJSON: (string) => Promise = (
credit,
price_guidance: price_guidance ? Number(price_guidance) : null,
show_on_editorial: Boolean(show_on_editorial),
+ is_featured_artist_content: Boolean(is_featured_artist_content),
query: (artist_ids || gene_ids || tag_id || keyword) && {
artist_ids: artist_ids
? artist_ids.split(",").map(a => a.trim())
diff --git a/src/utils/getArtists.ts b/src/utils/getArtists.ts
deleted file mode 100644
index 97e2b14a..00000000
--- a/src/utils/getArtists.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import metaphysics from "../lib/metaphysics"
-
-export const getArtists = async (query: string) => {
- const results: any = await metaphysics(`${query}`)
- let artistArray
- try {
- artistArray = results.marketingCollection.artworks.hits.map(
- x => x.artist.id
- )
- } catch (error) {
- throw error
- }
- const seen = {}
- return artistArray.filter(item => {
- return seen.hasOwnProperty(item) ? false : (seen[item] = true)
- })
-}
diff --git a/src/utils/getArtworks.ts b/src/utils/getArtworks.ts
index e6d5f95f..949c77ef 100644
--- a/src/utils/getArtworks.ts
+++ b/src/utils/getArtworks.ts
@@ -3,10 +3,14 @@ import metaphysics from "../lib/metaphysics"
export const getArtworks = async (query: string) => {
const results: any = await metaphysics(`${query}`)
let artworkArray
+ let artistArray
try {
artworkArray = results.marketingCollection.artworks.hits.map(x => x.id)
+ artistArray = results.marketingCollection.artworks.hits.map(
+ x => x.artist.id
+ )
} catch (error) {
throw error
}
- return artworkArray
+ return [artworkArray, artistArray]
}
diff --git a/src/utils/updateSailthru.ts b/src/utils/updateSailthru.ts
index 148d6451..270fc8bf 100644
--- a/src/utils/updateSailthru.ts
+++ b/src/utils/updateSailthru.ts
@@ -3,7 +3,6 @@ import * as SailthruAPI from "sailthru-client"
import { Connection, createConnection, getMongoRepository } from "typeorm"
import { databaseConfig } from "../config/database"
import { Collection } from "../Entities"
-import { getArtists } from "./getArtists"
import { getArtworks } from "./getArtworks"
const { SAILTHRU_KEY, SAILTHRU_SECRET } = process.env
@@ -27,51 +26,46 @@ export const pushContentToSailthru = async () => {
const image = collection.headerImage
const body_text = collection.description
const full_url = `https://www.artsy.net/collection/${collection_slug}`
- const all_artworks = await getArtworks(
- `{marketingCollection(slug: "${collection.slug}") {
- artworks {
- hits {
- id
+ try {
+ const [all_artworks, all_artists] = await getArtworks(
+ `{
+ marketingCollection(slug: "${collection.slug}") {
+ artworks {
+ hits {
+ id
+ artist {
+ id
+ }
+ }
+ }
}
- }
- }
- }`
- )
- const all_artists = await getArtists(`
- {
- marketingCollection(slug: "${collection.slug}") {
- artworks {
- hits {
- artist {
- id
- }
- }
- }
- }
- }
- `)
+ }`
+ )
- const options = {
- tags: ["collection"].concat(all_artists),
- vars: {
- slug: collection_slug,
- collection_category: featured_names,
- description: body_text,
- artworks_slugs: all_artworks,
- },
- images: {
- full: {
- url: image,
+ const options = {
+ tags: ["collection"].concat(all_artists),
+ vars: {
+ slug: collection_slug,
+ collection_category: featured_names,
+ description: body_text,
+ artworks_slugs: all_artworks,
+ },
+ images: {
+ full: {
+ url: image,
+ },
},
- },
- }
- sailthru.pushContent(name, full_url, options, (err, response) => {
- if (err) {
- console.log(`Error: ${err}`)
- return
}
- console.log(`Success: collection ${name} posted`)
- })
+ sailthru.pushContent(name, full_url, options, (err, response) => {
+ if (err) {
+ console.log(`Error: ${err}`)
+ return
+ }
+ console.log(`Success: collection ${name} posted`)
+ })
+ } catch (e) {
+ console.log(e)
+ }
}
} else {
throw new Error("Could not connect to database")