diff --git a/lib/v2/mymusicsheet/maintainer.js b/lib/v2/mymusicsheet/maintainer.js
new file mode 100644
index 000000000..a9837cb94
--- /dev/null
+++ b/lib/v2/mymusicsheet/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/user/sheets/:username/:iso?': ['Freddd13'],
+};
diff --git a/lib/v2/mymusicsheet/radar.js b/lib/v2/mymusicsheet/radar.js
new file mode 100644
index 000000000..f6a9154b3
--- /dev/null
+++ b/lib/v2/mymusicsheet/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'mymusicsheet.com': {
+ _name: 'MyMusicSheet',
+ '.': [
+ {
+ title: 'User Sheets',
+ docs: 'https://docs.rsshub.app/routes/shopping#mymusicsheet-user-sheets',
+ source: [':username/*', '/:username'],
+ target: '/mymusicsheet/user/sheets/:username',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/mymusicsheet/router.js b/lib/v2/mymusicsheet/router.js
new file mode 100644
index 000000000..74a760bcc
--- /dev/null
+++ b/lib/v2/mymusicsheet/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/user/sheets/:username/:iso?', require('./usersheets'));
+};
diff --git a/lib/v2/mymusicsheet/templates/description.art b/lib/v2/mymusicsheet/templates/description.art
new file mode 100644
index 000000000..48d5ab5f6
--- /dev/null
+++ b/lib/v2/mymusicsheet/templates/description.art
@@ -0,0 +1,41 @@
+
+ {{if youtubeId}}
+
+ {{/if}}
+
+ {{if content.musicName}}
+
Music Name: {{content.musicName}}
+ {{/if}}
+
+ {{if content.musicMemo}}
+
Music Memo: {{content.musicMemo}}
+ {{/if}}
+
+ {{if content.musicianName}}
+
Musician Name: {{content.musicianName}}
+ {{/if}}
+
+ {{if content.author}}
+
Author: {{content.author}}
+ {{/if}}
+
+ {{if content.instruments && content.instruments.length}}
+
Instruments:
+ {{each content.instruments}}{{$value}} {{/each}}
+
+ {{/if}}
+
+ {{if content.status}}
+
Status: {{content.status}}
+ {{/if}}
+
+ {{if content.price}}
+
Price: {{content.price}}
+ {{/if}}
+
diff --git a/lib/v2/mymusicsheet/usersheets.js b/lib/v2/mymusicsheet/usersheets.js
new file mode 100644
index 000000000..ce4ea7e4b
--- /dev/null
+++ b/lib/v2/mymusicsheet/usersheets.js
@@ -0,0 +1,120 @@
+const got = require('@/utils/got');
+const { art } = require('@/utils/render');
+const path = require('path');
+
+module.exports = async (ctx) => {
+ const baseUrl = 'https://www.mymusicsheet.com';
+ const graphqlUrl = 'https://mms.pd.mapia.io/mms/graphql';
+ const exchangeRateUrl = 'https://payport.pd.mapia.io/v2/currency';
+ const { username, iso = 'CNY' } = ctx.params;
+
+ const exchangeRateResponse = await got(exchangeRateUrl, {
+ searchParams: {
+ serviceProvider: 'mms',
+ 'ngsw-bypass': true,
+ 'no-cache': Date.now(),
+ skipHeaders: true,
+ },
+ responseType: 'json',
+ });
+ const rates = exchangeRateResponse.data;
+
+ const response = await got.post(graphqlUrl, {
+ json: {
+ operationName: 'loadArtistSheets',
+ query: `
+ query loadArtistSheets($data: SheetSearchInput!) {
+ sheetSearch(data: $data) {
+ list {
+ productId
+ productType
+ metaSong
+ metaMaker
+ metaMusician
+ metaMemo
+ instruments
+ level
+ price
+ sheetId
+ status
+ author {
+ name
+ artistUrl
+ profileUrl
+ }
+ youtubeId
+ title
+ supportCountry
+ excludeCountries
+ __typename
+ }
+ total
+ current
+ listNum
+ }
+ }`,
+ variables: {
+ data: {
+ listNum: 10,
+ paginate: 'page',
+ includeChord: null,
+ includeLyrics: null,
+ page: 1,
+ level: null,
+ instruments: [],
+ orderBy: {
+ createdAt: 'DESC',
+ },
+ isFree: null,
+ category: null,
+ artistUrl: username,
+ aggregationKeywords: ['PACKAGE_IDS', 'TAG_IDS', 'INSTRUMENTS', 'SHEET_TYPE', 'INCLUDE_CHORD', 'INCLUDE_LYRICS', 'INSTRUMENTATION', 'LEVEL', 'CATEGORY'],
+ aggregationKeySize: 20,
+ },
+ },
+ },
+ responseType: 'json',
+ });
+
+ const sheetSearch = response.data.data.sheetSearch.list;
+ const items = sheetSearch.map((item) => {
+ let finalPrice = 'Unknown';
+ const price = parseFloat(item.price);
+
+ if (item.price === 0) {
+ finalPrice = 'Free';
+ } else if (!isNaN(price) && isFinite(price)) {
+ const rate = rates[iso];
+ if (rate) {
+ finalPrice = `${(price * rate).toFixed(2)} ${iso}`;
+ }
+ }
+
+ const youtubeId = item.youtubeId;
+ const content = {
+ musicName: item.metaSong,
+ musicMemo: item.metaMemo,
+ musicianName: item.metaMusician,
+ author: item.author.name,
+ instruments: item.instruments,
+ status: item.status,
+ price: finalPrice,
+ };
+
+ return {
+ title: `${item.author.name} | ${item.title} | ${finalPrice}`,
+ link: `${baseUrl}/${username}/${item.sheetId}`,
+ itunes_item_image: item.author.profileUrl,
+ description: art(path.join(__dirname, 'templates/description.art'), {
+ youtubeId,
+ content,
+ }),
+ };
+ });
+
+ ctx.state.data = {
+ title: `${username}'s sheets`,
+ link: `https://www.mymusicsheet.com/${username}?viewType=sheet&orderBy=createdAt`,
+ item: items,
+ };
+};
diff --git a/website/docs/routes/shopping.md b/website/docs/routes/shopping.md
index 27ef53ed1..284a0fa6d 100644
--- a/website/docs/routes/shopping.md
+++ b/website/docs/routes/shopping.md
@@ -268,6 +268,14 @@ Language
+## MyMusicSheet {#mymusicsheet}
+
+### User Sheets {#mymusicsheet-user-sheets}
+
+
+
+关于ISO 4217,请参考[维基百科](https://zh.wikipedia.org/zh-cn/ISO_4217#%E7%8E%B0%E8%A1%8C%E4%BB%A3%E7%A0%81)
+
## Patagonia {#patagonia}
### New Arrivals {#patagonia-new-arrivals}