Skip to content

Commit 6a8aa0a

Browse files
authored
Merge pull request #570 from EstrellaXD/3.1-dev
3.1.10
2 parents a544ef1 + a81d93f commit 6a8aa0a

File tree

8 files changed

+249
-35
lines changed

8 files changed

+249
-35
lines changed

.github/workflows/build.yml

+6
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ jobs:
247247
run: |
248248
echo ${{ needs.version-info.outputs.version }}
249249
echo "VERSION='${{ needs.version-info.outputs.version }}'" >> module/__version__.py
250+
251+
- name: Copy requirements.txt
252+
working-directory: ./backend
253+
run:
254+
cp requirements.txt src/requirements.txt
250255

251256
- name: Zip app
252257
run: |
@@ -262,6 +267,7 @@ jobs:
262267
echo "version=🌟${{ needs.version-info.outputs.version }}" >> $GITHUB_OUTPUT
263268
echo "pre_release=false" >> $GITHUB_OUTPUT
264269
fi
270+
265271
- name: Release
266272
id: release
267273
uses: softprops/action-gh-release@v1

backend/src/module/api/bangumi.py

+10
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ async def refresh_poster():
116116
resp = manager.refresh_poster()
117117
return u_response(resp)
118118

119+
@router.get(
120+
path="/refresh/poster/{bangumi_id}",
121+
response_model=APIResponse,
122+
dependencies=[Depends(get_current_user)],
123+
)
124+
async def refresh_poster(bangumi_id: int):
125+
with TorrentManager() as manager:
126+
resp = manager.refind_poster(bangumi_id)
127+
return u_response(resp)
128+
119129

120130
@router.get(
121131
"/reset/all", response_model=APIResponse, dependencies=[Depends(get_current_user)]

backend/src/module/manager/torrent.py

+11
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,17 @@ def refresh_poster(self):
143143
msg_zh="刷新海报链接成功。",
144144
)
145145

146+
def refind_poster(self, bangumi_id: int):
147+
bangumi = self.bangumi.search_id(bangumi_id)
148+
TitleParser().tmdb_poster_parser(bangumi)
149+
self.bangumi.update(bangumi)
150+
return ResponseModel(
151+
status_code=200,
152+
status=True,
153+
msg_en="Refresh poster link successfully.",
154+
msg_zh="刷新海报链接成功。",
155+
)
156+
146157
def search_all_bangumi(self):
147158
datas = self.bangumi.search_all()
148159
if not datas:

backend/src/module/parser/analyser/mikan_parser.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def mikan_parser(homepage: str):
1616
official_title = soup.select_one(
1717
'p.bangumi-title a[href^="/Home/Bangumi/"]'
1818
).text
19-
official_title = re.sub(r"第.*季", "", official_title)
19+
official_title = re.sub(r"第.*季", "", official_title).strip()
2020
if poster_div:
2121
poster_path = poster_div.split("url('")[1].split("')")[0]
2222
img = req.get_content(f"https://{root_path}{poster_path}")

webui/src/components/ab-edit-rule.vue

+38-34
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<script lang="ts" setup>
2-
import type { BangumiRule } from '#/bangumi';
2+
import type {BangumiRule} from '#/bangumi';
33
44
const emit = defineEmits<{
55
(e: 'apply', rule: BangumiRule): void;
66
(e: 'enable', id: number): void;
77
(
8-
e: 'deleteFile',
9-
type: 'disable' | 'delete',
10-
opts: { id: number; deleteFile: boolean }
8+
e: 'deleteFile',
9+
type: 'disable' | 'delete',
10+
opts: { id: number; deleteFile: boolean }
1111
): void;
1212
}>();
1313
14-
const { t } = useMyI18n();
14+
const {t} = useMyI18n();
1515
16-
const show = defineModel('show', { default: false });
16+
const show = defineModel('show', {default: false});
1717
const rule = defineModel<BangumiRule>('rule', {
1818
required: true,
1919
});
@@ -31,9 +31,13 @@ watch(show, (val) => {
3131
}
3232
});
3333
34-
function showDeleteFileDialog(type: 'disable' | 'delete') {
34+
function showDeleteFileDialog(type: String) {
3535
deleteFileDialog.show = true;
36-
deleteFileDialog.type = type;
36+
if (type === 'disable' || type === '禁用') {
37+
deleteFileDialog.type = 'disable';
38+
} else {
39+
deleteFileDialog.type = 'delete';
40+
}
3741
}
3842
3943
const close = () => (show.value = false);
@@ -44,6 +48,7 @@ function emitdeleteFile(deleteFile: boolean) {
4448
deleteFile,
4549
});
4650
}
51+
4752
function emitApply() {
4853
emit('apply', rule.value);
4954
}
@@ -78,53 +83,52 @@ const boxSize = computed(() => {
7883

7984
<div fx-cer justify-center space-x-10px>
8085
<ab-button size="small" type="warn" @click="() => emitEnable()">{{
81-
$t('homepage.rule.yes_btn')
82-
}}</ab-button>
86+
$t('homepage.rule.yes_btn')
87+
}}
88+
</ab-button>
8389
<ab-button size="small" @click="() => close()">{{
84-
$t('homepage.rule.no_btn')
85-
}}</ab-button>
90+
$t('homepage.rule.no_btn')
91+
}}
92+
</ab-button>
8693
</div>
8794
</div>
8895

8996
<div v-else space-y-12px>
9097
<ab-rule v-model:rule="rule"></ab-rule>
9198

9299
<div fx-cer justify-end space-x-10px>
93-
<ab-button
94-
size="small"
95-
type="warn"
96-
@click="() => showDeleteFileDialog('disable')"
97-
>{{ $t('homepage.rule.disable') }}</ab-button
98-
>
99-
<ab-button
100-
size="small"
101-
type="warn"
102-
@click="() => showDeleteFileDialog('delete')"
103-
>{{ $t('homepage.rule.delete') }}</ab-button
104-
>
100+
<ab-button-multi
101+
size="small"
102+
type="warn"
103+
:selections="[t('homepage.rule.delete'), t('homepage.rule.disable')]"
104+
@click="showDeleteFileDialog"
105+
/>
105106
<ab-button size="small" @click="emitApply">{{
106-
$t('homepage.rule.apply')
107-
}}</ab-button>
107+
$t('homepage.rule.apply')
108+
}}
109+
</ab-button>
108110
</div>
109111
</div>
110112

111113
<ab-popup
112-
v-model:show="deleteFileDialog.show"
113-
:title="$t('homepage.rule.delete')"
114+
v-model:show="deleteFileDialog.show"
115+
:title="$t('homepage.rule.delete')"
114116
>
115117
<div>{{ $t('homepage.rule.delete_hit') }}</div>
116118
<div line my-8px></div>
117119

118120
<div fx-cer justify-center space-x-10px>
119121
<ab-button
120-
size="small"
121-
type="warn"
122-
@click="() => emitdeleteFile(true)"
123-
>{{ $t('homepage.rule.yes_btn') }}</ab-button
122+
size="small"
123+
type="warn"
124+
@click="() => emitdeleteFile(true)"
125+
>{{ $t('homepage.rule.yes_btn') }}
126+
</ab-button
124127
>
125128
<ab-button size="small" @click="() => emitdeleteFile(false)">{{
126-
$t('homepage.rule.no_btn')
127-
}}</ab-button>
129+
$t('homepage.rule.no_btn')
130+
}}
131+
</ab-button>
128132
</div>
129133
</ab-popup>
130134
</ab-popup>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type {Meta, StoryObj} from '@storybook/vue3';
2+
3+
import AbButtonMulti from './ab-button-multi.vue';
4+
5+
const meta: Meta<typeof AbButtonMulti> = {
6+
title: 'basic/ab-button-multi',
7+
component: AbButtonMulti,
8+
tags: ['autodocs'],
9+
argTypes: {
10+
type: {
11+
control: {type: 'select'},
12+
options: ['primary', 'warn'],
13+
},
14+
size: {
15+
control: {type: 'select'},
16+
options: ['big', 'normal', 'small'],
17+
},
18+
},
19+
};
20+
21+
export default meta;
22+
type Story = StoryObj<typeof AbButtonMulti>;
23+
24+
export const Template: Story = {
25+
render: (args) => ({
26+
components: {AbButtonMulti},
27+
setup() {
28+
return {args};
29+
},
30+
template: '<ab-button-multi v-bind="args">button</ab-button-multi>',
31+
}),
32+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<script lang="ts" setup xmlns="http://www.w3.org/1999/html">
2+
3+
import {NSpin} from 'naive-ui';
4+
import {Down} from "@icon-park/vue-next";
5+
import {computed} from "vue";
6+
7+
const props = withDefaults(
8+
defineProps<{
9+
type?: 'primary' | 'warn';
10+
size?: 'big' | 'normal' | 'small';
11+
link?: string | null;
12+
loading?: boolean;
13+
selections: string[];
14+
}>(),
15+
{
16+
type: 'primary',
17+
size: 'normal',
18+
link: null,
19+
loading: false,
20+
}
21+
);
22+
23+
defineEmits(['click']);
24+
25+
const selected = ref<string>(
26+
props.selections[0]
27+
);
28+
const showSelections = ref<boolean>(false);
29+
30+
31+
const buttonSize = computed(() => {
32+
switch (props.size) {
33+
case 'big':
34+
return 'rounded-10px text-h1 w-276px h-55px text-h1';
35+
case 'normal':
36+
return 'rounded-6px w-170px h-36px';
37+
case 'small':
38+
return 'rounded-6px w-86px h-28px text-main';
39+
}
40+
});
41+
42+
const selectboxSize = computed(() => {
43+
switch (props.size) {
44+
case 'big':
45+
return 'w-276px rounded-10px text-h1';
46+
case 'normal':
47+
return 'w-170px rounded-6px';
48+
case 'small':
49+
return 'w-86px rounded-6px text-main';
50+
}
51+
});
52+
53+
const loadingSize = computed(() => {
54+
switch (props.size) {
55+
case 'big':
56+
return 'large';
57+
case 'normal':
58+
return 'small';
59+
case 'small':
60+
return 18;
61+
}
62+
});
63+
64+
function onSelect(selection: string) {
65+
selected.value = selection;
66+
showSelections.value = false;
67+
console.log(selected.value);
68+
}
69+
70+
</script>
71+
72+
<template>
73+
<div
74+
:class="buttonSize"
75+
f-cer
76+
overflow-hidden
77+
>
78+
<Component
79+
:is="link !== null ? 'a' : 'button'"
80+
:href="link"
81+
text-white
82+
outline-none
83+
wh-full
84+
pl-12px
85+
:class="[`type-${type}`]"
86+
@click="$emit('click', selected)"
87+
>
88+
<NSpin :show="loading" :size="loadingSize">
89+
<div text-main>{{ selected }}</div>
90+
</NSpin>
91+
</Component>
92+
<div
93+
is-btn
94+
px-12px
95+
h-full
96+
f-cer
97+
:class="[`selector-${type}`]"
98+
@click="() => showSelections = !showSelections"
99+
>
100+
<Down fill="white"/>
101+
</div>
102+
</div>
103+
<div
104+
v-if="showSelections"
105+
abs
106+
z-70
107+
:class="selectboxSize"
108+
overflow-hidden
109+
class="select-box"
110+
>
111+
<div
112+
v-for="selection in selections"
113+
:key="selection"
114+
is-btn
115+
wh-full
116+
f-cer
117+
text-main
118+
py-8px
119+
text-white
120+
:class="[`type-${type}`]"
121+
@click="onSelect(selection)"
122+
>
123+
{{ selection }}
124+
</div>
125+
</div>
126+
</template>
127+
128+
<style lang="scss" scoped>
129+
.type {
130+
&-primary {
131+
@include bg-mouse-event(#4e3c94, #281e52, #8e8a9c);
132+
}
133+
134+
&-warn {
135+
@include bg-mouse-event(#943c61, #521e2a, #9c8a93);
136+
}
137+
}
138+
.selector {
139+
&-primary {
140+
@include bg-mouse-event(#4e3c94, #281e52, #8e8a9c);
141+
}
142+
&-warn {
143+
@include bg-mouse-event(#943c61, #521e2a, #9c8a93);
144+
}
145+
}
146+
147+
.select-box {
148+
transform: TranslateY(80%) TranslateX(-111%);
149+
}
150+
</style>

webui/types/dts/components.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ declare module '@vue/runtime-core' {
1313
AbAddRss: typeof import('./../../src/components/ab-add-rss.vue')['default']
1414
AbBangumiCard: typeof import('./../../src/components/ab-bangumi-card.vue')['default']
1515
AbButton: typeof import('./../../src/components/basic/ab-button.vue')['default']
16+
AbButtonMulti: typeof import('./../../src/components/basic/ab-button-multi.vue')['default']
1617
AbChangeAccount: typeof import('./../../src/components/ab-change-account.vue')['default']
1718
AbCheckbox: typeof import('./../../src/components/basic/ab-checkbox.vue')['default']
1819
AbContainer: typeof import('./../../src/components/ab-container.vue')['default']

0 commit comments

Comments
 (0)