mirror of
https://github.com/simon-ding/polaris.git
synced 2026-05-28 05:27:41 +08:00
chore: update watchlist
This commit is contained in:
@@ -3,17 +3,28 @@ package douban
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"polaris/log"
|
||||||
|
"polaris/pkg/importlist"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DoulistItem struct {
|
const ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
|
||||||
Name string
|
|
||||||
ImdbID string
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseDoulist(doulistUrl string) ([]DoulistItem, error) {
|
func ParseDoulist(doulistUrl string) (*importlist.Response, error) {
|
||||||
res, err := http.Get(doulistUrl)
|
if !strings.Contains(doulistUrl, "doulist") {
|
||||||
|
return nil, fmt.Errorf("not doulist")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", doulistUrl, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("User-Agent", ua)
|
||||||
|
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -26,6 +37,64 @@ func ParseDoulist(doulistUrl string) ([]DoulistItem, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
doc.Find("")
|
doc.Find("div[class=doulist-item]").Each(func(i int, selection *goquery.Selection) {
|
||||||
|
titleDiv := selection.Find("div[class=title]")
|
||||||
|
link := titleDiv.Find("div>a")
|
||||||
|
href, ok := link.Attr("href")
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
abstract := selection.Find("div[class=abstract]")
|
||||||
|
|
||||||
|
lines := strings.Split(abstract.Text(), "\n")
|
||||||
|
year := 0
|
||||||
|
for _, l := range lines {
|
||||||
|
if strings.Contains(l, "年份") {
|
||||||
|
ppp := strings.Split(l, ":")
|
||||||
|
if len(ppp) < 2 {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
n := ppp[1]
|
||||||
|
n1, err := strconv.Atoi(n)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("convert year number %s to int error: %v", n, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
year = n1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item := importlist.Item{
|
||||||
|
Title: strings.TrimSpace(link.Text()),
|
||||||
|
Year: year,
|
||||||
|
}
|
||||||
|
_ = item
|
||||||
|
println(link.Text(), href)
|
||||||
|
})
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseDetailPage(url string) (string, error) {
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req.Header.Set("User-Agent", ua)
|
||||||
|
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
if res.StatusCode != 200 {
|
||||||
|
return "", fmt.Errorf("status code error: %d %s", res.StatusCode, res.Status)
|
||||||
|
|
||||||
|
}
|
||||||
|
doc, err := goquery.NewDocumentFromReader(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
_ = doc
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|||||||
11
pkg/importlist/douban/douban_test.go
Normal file
11
pkg/importlist/douban/douban_test.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package douban
|
||||||
|
|
||||||
|
import (
|
||||||
|
"polaris/log"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseDoulist(t *testing.T) {
|
||||||
|
r, err := ParseDoulist("https://www.douban.com/doulist/166422/")
|
||||||
|
log.Info(r, err)
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package importlist
|
|||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
Title string
|
Title string
|
||||||
|
Year int
|
||||||
ImdbID string
|
ImdbID string
|
||||||
TvdbID string
|
TvdbID string
|
||||||
TmdbID string
|
TmdbID string
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Future<void> showSettingDialog(
|
|||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 400,
|
width: 400,
|
||||||
child: body,
|
child: SelectionArea(child: body),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class Importlist extends ConsumerStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ImportlistState extends ConsumerState<Importlist> {
|
class _ImportlistState extends ConsumerState<Importlist> {
|
||||||
|
String? _selectedType;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var importlists = ref.watch(importlistProvider);
|
var importlists = ref.watch(importlistProvider);
|
||||||
@@ -42,16 +43,39 @@ class _ImportlistState extends ConsumerState<Importlist> {
|
|||||||
Future<void> showImportlistDetails(ImportList list) {
|
Future<void> showImportlistDetails(ImportList list) {
|
||||||
final _formKey = GlobalKey<FormBuilderState>();
|
final _formKey = GlobalKey<FormBuilderState>();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_selectedType = list.type;
|
||||||
|
});
|
||||||
var body = FormBuilder(
|
var body = FormBuilder(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
initialValue: {
|
initialValue: {
|
||||||
"name": list.name,
|
"name": list.name,
|
||||||
"url": list.url,
|
"url": list.url,
|
||||||
"qulity": list.qulity,
|
"qulity": list.qulity,
|
||||||
|
"type": list.type,
|
||||||
"storage_id": list.storageId
|
"storage_id": list.storageId
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
FormBuilderDropdown(
|
||||||
|
name: "type",
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "类型",
|
||||||
|
hintText:
|
||||||
|
"Plex Watchlist: https://support.plex.tv/articles/universal-watchlist/"),
|
||||||
|
items: const [
|
||||||
|
DropdownMenuItem(value: "plex", child: Text("Plex Watchlist")),
|
||||||
|
],
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_selectedType = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
_selectedType == "plex"
|
||||||
|
? const Text(
|
||||||
|
"Plex Watchlist: https://support.plex.tv/articles/universal-watchlist/")
|
||||||
|
: const Text(""),
|
||||||
FormBuilderTextField(
|
FormBuilderTextField(
|
||||||
name: "name",
|
name: "name",
|
||||||
decoration: Commons.requiredTextFieldStyle(text: "名称"),
|
decoration: Commons.requiredTextFieldStyle(text: "名称"),
|
||||||
@@ -103,12 +127,12 @@ class _ImportlistState extends ConsumerState<Importlist> {
|
|||||||
onSubmit() async {
|
onSubmit() async {
|
||||||
if (_formKey.currentState!.saveAndValidate()) {
|
if (_formKey.currentState!.saveAndValidate()) {
|
||||||
var values = _formKey.currentState!.value;
|
var values = _formKey.currentState!.value;
|
||||||
|
|
||||||
return ref.read(importlistProvider.notifier).addImportlist(ImportList(
|
return ref.read(importlistProvider.notifier).addImportlist(ImportList(
|
||||||
id: list.id,
|
id: list.id,
|
||||||
name: values["name"],
|
name: values["name"],
|
||||||
url: values["url"],
|
url: values["url"],
|
||||||
type: "plex",
|
type: values["type"],
|
||||||
qulity: values["qulity"],
|
qulity: values["qulity"],
|
||||||
storageId: values["storage_id"],
|
storageId: values["storage_id"],
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user