mirror of
https://github.com/nkanaev/yarr.git
synced 2025-11-05 09:10:38 +00:00
Compare commits
39 Commits
4983e18e23
...
gh-actions
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
348693fa95 | ||
|
|
b40c6fc9e4 | ||
|
|
73fd637b23 | ||
|
|
b8afa82a81 | ||
|
|
097a2da5cb | ||
|
|
e6d32946c1 | ||
|
|
fe4eaa4b8d | ||
|
|
48a671b285 | ||
|
|
011c9c7668 | ||
|
|
f06fc1f750 | ||
|
|
0e88d4284d | ||
|
|
1615c6869f | ||
|
|
800f43b299 | ||
|
|
15bff0a0c4 | ||
|
|
e1481f4aac | ||
|
|
7ef97ee6db | ||
|
|
d785fe4c5a | ||
|
|
5254df53dc | ||
|
|
7301eab99c | ||
|
|
ad138c3017 | ||
|
|
b09c95d7ea | ||
|
|
64611a0dd3 | ||
|
|
321ad7608f | ||
|
|
2a8b6ea935 | ||
|
|
e9cbea500b | ||
|
|
223039b2c6 | ||
|
|
7402dfc4e6 | ||
|
|
6b12715506 | ||
|
|
2dc58c5c8e | ||
|
|
0cef51c6ac | ||
|
|
2a4d974965 | ||
|
|
f71792d6a5 | ||
|
|
b571042c5d | ||
|
|
349c966c63 | ||
|
|
4a42b239cc | ||
|
|
b9b3d2350c | ||
|
|
b13cd85f0b | ||
|
|
daffd721eb | ||
|
|
24232d72e9 |
157
.github/workflows/build.yml
vendored
157
.github/workflows/build.yml
vendored
@@ -1,8 +1,14 @@
|
|||||||
name: build
|
name: Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags: ['v*', 'test*']
|
tags:
|
||||||
|
- v*
|
||||||
|
workflow_dispatch:
|
||||||
|
workflow_run:
|
||||||
|
workflows: [Test]
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_macos:
|
build_macos:
|
||||||
@@ -18,7 +24,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '^1.17'
|
go-version: '^1.17'
|
||||||
- name: Cache Go Modules
|
- name: Cache Go Modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
@@ -27,7 +33,7 @@ jobs:
|
|||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: make build_macos
|
run: make build_macos
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: macos
|
name: macos
|
||||||
path: _output/macos/yarr.app
|
path: _output/macos/yarr.app
|
||||||
@@ -45,7 +51,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '^1.17'
|
go-version: '^1.17'
|
||||||
- name: Cache Go Modules
|
- name: Cache Go Modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
@@ -54,7 +60,7 @@ jobs:
|
|||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: make build_windows
|
run: make build_windows
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: windows
|
name: windows
|
||||||
path: _output/windows/yarr.exe
|
path: _output/windows/yarr.exe
|
||||||
@@ -72,38 +78,99 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '^1.17'
|
go-version: '^1.17'
|
||||||
- name: Cache Go Modules
|
- name: Cache Go Modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-amd64-go-${{ hashFiles('**/go.sum') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-amd64
|
||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: make build_linux
|
run: make build_linux
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: linux
|
name: linux
|
||||||
path: _output/linux/yarr
|
path: _output/linux/yarr
|
||||||
|
|
||||||
|
build_linux-arm:
|
||||||
|
name: Build for Linux ARM
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: >
|
||||||
|
sudo apt-get install -y
|
||||||
|
gcc-arm-linux-gnueabihf
|
||||||
|
libc6-dev-armhf-cross
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
|
- name: "Setup Go"
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: '^1.17'
|
||||||
|
- name: Cache Go Modules
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-armv7-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-armv7
|
||||||
|
- name: "Build"
|
||||||
|
env:
|
||||||
|
CC: arm-linux-gnueabihf-gcc
|
||||||
|
GOARCH: arm
|
||||||
|
GOARM: 7
|
||||||
|
run: make build_linux
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: linux_arm
|
||||||
|
path: _output/linux/yarr
|
||||||
|
|
||||||
|
build_linux-arm64:
|
||||||
|
name: Build for Linux ARM64
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: >
|
||||||
|
sudo apt-get install -y
|
||||||
|
gcc-aarch64-linux-gnu
|
||||||
|
libc6-dev-arm64-cross
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
|
- name: "Setup Go"
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: '^1.17'
|
||||||
|
- name: Cache Go Modules
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-arm64-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-arm64
|
||||||
|
- name: "Build"
|
||||||
|
env:
|
||||||
|
CC: aarch64-linux-gnu-gcc
|
||||||
|
GOARCH: arm64
|
||||||
|
run: make build_linux
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: linux_arm64
|
||||||
|
path: _output/linux/yarr
|
||||||
|
|
||||||
create_release:
|
create_release:
|
||||||
name: Create Release
|
name: Create Release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ !contains(github.ref, 'test') }}
|
if: ${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'test') }}
|
||||||
needs: [build_macos, build_windows, build_linux]
|
needs: [build_macos, build_windows, build_linux, build_linux-arm, build_linux-arm64]
|
||||||
steps:
|
steps:
|
||||||
- name: Create Release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
id: create_release
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: ${{ github.ref }}
|
|
||||||
draft: true
|
|
||||||
prerelease: true
|
|
||||||
- name: Download Artifacts
|
- name: Download Artifacts
|
||||||
uses: actions/download-artifact@v2
|
uses: actions/download-artifact@v4.1.7
|
||||||
with:
|
with:
|
||||||
path: .
|
path: .
|
||||||
- name: Preparation
|
- name: Preparation
|
||||||
@@ -111,34 +178,24 @@ jobs:
|
|||||||
ls -R
|
ls -R
|
||||||
chmod u+x macos/Contents/MacOS/yarr
|
chmod u+x macos/Contents/MacOS/yarr
|
||||||
chmod u+x linux/yarr
|
chmod u+x linux/yarr
|
||||||
|
chmod u+x linux_arm/yarr
|
||||||
|
chmod u+x linux_arm64/yarr
|
||||||
|
|
||||||
mv macos yarr.app && zip -r yarr-macos.zip yarr.app
|
mv macos yarr.app && zip -r yarr-${GITHUB_REF_NAME}-macos64.zip yarr.app
|
||||||
mv windows/yarr.exe . && zip yarr-windows.zip yarr.exe
|
( cd windows && zip ../yarr-${GITHUB_REF_NAME}-windows64.zip yarr.exe )
|
||||||
mv linux/yarr . && zip yarr-linux.zip yarr
|
( cd linux && zip ../yarr-${GITHUB_REF_NAME}-linux64.zip yarr )
|
||||||
- name: Upload MacOS
|
( cd linux_arm && zip ../yarr-${GITHUB_REF_NAME}-linux_arm.zip yarr )
|
||||||
uses: actions/upload-release-asset@v1
|
( cd linux_arm64 && zip ../yarr-${GITHUB_REF_NAME}-linux_arm64.zip yarr )
|
||||||
|
- name: Upload Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
draft: true
|
||||||
asset_path: ./yarr-macos.zip
|
prerelease: true
|
||||||
asset_name: yarr-${{ github.ref }}-macos64.zip
|
files: |
|
||||||
asset_content_type: application/zip
|
yarr-${{ github.ref_name }}-macos64.zip
|
||||||
- name: Upload Windows
|
yarr-${{ github.ref_name }}-windows64.zip
|
||||||
uses: actions/upload-release-asset@v1
|
yarr-${{ github.ref_name }}-linux64.zip
|
||||||
env:
|
yarr-${{ github.ref_name }}-linux_arm.zip
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
yarr-${{ github.ref_name }}-linux_arm64.zip
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./yarr-windows.zip
|
|
||||||
asset_name: yarr-${{ github.ref }}-windows64.zip
|
|
||||||
asset_content_type: application/zip
|
|
||||||
- name: Upload Linux
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./yarr-linux.zip
|
|
||||||
asset_name: yarr-${{ github.ref }}-linux64.zip
|
|
||||||
asset_content_type: application/zip
|
|
||||||
|
|||||||
19
.github/workflows/test.yml
vendored
Normal file
19
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: Test
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '^1.18'
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: make test
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,7 @@
|
|||||||
/_output
|
/_output
|
||||||
/yarr
|
/yarr
|
||||||
*.db
|
*.db
|
||||||
|
*.db-shm
|
||||||
|
*.db-wal
|
||||||
*.syso
|
*.syso
|
||||||
versioninfo.rc
|
versioninfo.rc
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/nkanaev/yarr/src/platform"
|
"github.com/nkanaev/yarr/src/platform"
|
||||||
"github.com/nkanaev/yarr/src/server"
|
"github.com/nkanaev/yarr/src/server"
|
||||||
"github.com/nkanaev/yarr/src/storage"
|
"github.com/nkanaev/yarr/src/storage"
|
||||||
|
"github.com/nkanaev/yarr/src/worker"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version string = "0.0"
|
var Version string = "0.0"
|
||||||
@@ -89,12 +90,12 @@ func main() {
|
|||||||
log.SetOutput(os.Stdout)
|
log.SetOutput(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if db == "" {
|
||||||
configPath, err := os.UserConfigDir()
|
configPath, err := os.UserConfigDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to get config dir: ", err)
|
log.Fatal("Failed to get config dir: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if db == "" {
|
|
||||||
storagePath := filepath.Join(configPath, "yarr")
|
storagePath := filepath.Join(configPath, "yarr")
|
||||||
if err := os.MkdirAll(storagePath, 0755); err != nil {
|
if err := os.MkdirAll(storagePath, 0755); err != nil {
|
||||||
log.Fatal("Failed to create app config dir: ", err)
|
log.Fatal("Failed to create app config dir: ", err)
|
||||||
@@ -105,6 +106,7 @@ func main() {
|
|||||||
log.Printf("using db file %s", db)
|
log.Printf("using db file %s", db)
|
||||||
|
|
||||||
var username, password string
|
var username, password string
|
||||||
|
var err error
|
||||||
if authfile != "" {
|
if authfile != "" {
|
||||||
f, err := os.Open(authfile)
|
f, err := os.Open(authfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -131,6 +133,7 @@ func main() {
|
|||||||
log.Fatal("Failed to initialise database: ", err)
|
log.Fatal("Failed to initialise database: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
worker.SetVersion(Version)
|
||||||
srv := server.NewServer(store, addr)
|
srv := server.NewServer(store, addr)
|
||||||
|
|
||||||
if basepath != "" {
|
if basepath != "" {
|
||||||
|
|||||||
@@ -2,12 +2,21 @@
|
|||||||
|
|
||||||
- (new) Fever API support (thanks to @icefed)
|
- (new) Fever API support (thanks to @icefed)
|
||||||
- (new) editable feed link (thanks to @adaszko)
|
- (new) editable feed link (thanks to @adaszko)
|
||||||
|
- (new) switch to feed by clicking the title in the article page (thanks to @tarasglek for suggestion)
|
||||||
|
- (new) support multiple media links
|
||||||
- (fix) duplicate articles caused by the same feed addition (thanks to @adaszko)
|
- (fix) duplicate articles caused by the same feed addition (thanks to @adaszko)
|
||||||
- (fix) relative article links (thanks to @adazsko for the report)
|
- (fix) relative article links (thanks to @adazsko for the report)
|
||||||
- (fix) atom article links stored in id element (thanks to @adazsko for the report)
|
- (fix) atom article links stored in id element (thanks to @adazsko for the report)
|
||||||
- (fix) parsing atom feed titles (thanks to @wnh)
|
- (fix) parsing atom feed titles (thanks to @wnh)
|
||||||
- (fix) sorting same-day batch articles (thanks to @lamescholar for the report)
|
- (fix) sorting same-day batch articles (thanks to @lamescholar for the report)
|
||||||
- (fix) showing login page in the selected theme (thanks to @feddiriko for the report)
|
- (fix) showing login page in the selected theme (thanks to @feddiriko for the report)
|
||||||
|
- (fix) parsing atom feeds with html elements (thanks to @tillcash & @toBeOfUse for the report, @krkk for the fix)
|
||||||
|
- (fix) parsing feeds with missing guids (thanks to @hoyii for the report)
|
||||||
|
- (fix) sending actual client version to servers (thanks to @aidanholm)
|
||||||
|
- (fix) error caused by missing config dir (thanks to @timster)
|
||||||
|
- (etc) load external images with no-referrer policy (thanks to @tillcash for the report)
|
||||||
|
- (etc) open external links with no-referrer policy (thanks to @donovanglover)
|
||||||
|
- (etc) show article content in the list if title is missing (thanks to @asimpson for suggestion)
|
||||||
|
|
||||||
# v2.4 (2023-08-15)
|
# v2.4 (2023-08-15)
|
||||||
|
|
||||||
|
|||||||
68
doc/samples.yml
Normal file
68
doc/samples.yml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
- site: https://vimeo.com/channels/staffpicks/videos
|
||||||
|
feed: https://vimeo.com/channels/staffpicks/videos/rss
|
||||||
|
tags: [vimeo, image]
|
||||||
|
|
||||||
|
- site: https://www.youtube.com/@everyframeapainting/videos
|
||||||
|
feed: https://www.youtube.com/feeds/videos.xml?channel_id=UCjFqcJQXGZ6T6sxyFB-5i6A"
|
||||||
|
tags: [youtube, image]
|
||||||
|
|
||||||
|
- site: https://iwdrm.tumblr.com/
|
||||||
|
feed: https://iwdrm.tumblr.com/rss
|
||||||
|
tags: [tumblr, image]
|
||||||
|
|
||||||
|
- site: https://falseknees.tumblr.com/
|
||||||
|
feed: https://falseknees.tumblr.com/rss
|
||||||
|
tags: [tumblr, image]
|
||||||
|
|
||||||
|
- site: https://accidentallyquadratic.tumblr.com/
|
||||||
|
feed: https://accidentallyquadratic.tumblr.com/rss
|
||||||
|
info: text blog with code sections
|
||||||
|
tags: [tumblr, text, code]
|
||||||
|
|
||||||
|
- site: https://www.flickr.com/photos/maratsafin/
|
||||||
|
feed: https://www.flickr.com/services/feeds/photos_public.gne?id=59021497@N07&lang=en-us&format=atom
|
||||||
|
tags: [flickr, image]
|
||||||
|
|
||||||
|
- site: https://www.reddit.com/r/comics
|
||||||
|
feed: https://www.reddit.com/r/comics.rss
|
||||||
|
tags: [reddit, image]
|
||||||
|
|
||||||
|
- site: https://www.reddit.com/r/AITAH
|
||||||
|
feed: https://www.reddit.com/r/AITAH.rss
|
||||||
|
tags: [reddit, text]
|
||||||
|
|
||||||
|
- site: https://idothei.wordpress.com/
|
||||||
|
feed: https://idothei.wordpress.com/feed/
|
||||||
|
tags: [wordpress, text]
|
||||||
|
|
||||||
|
- site: https://www.vidarholen.net/contents/blog/
|
||||||
|
feed: https://www.vidarholen.net/contents/blog/?feed=rss2
|
||||||
|
tags: [wordpress, text]
|
||||||
|
|
||||||
|
- site: https://blog.posthaven.com/
|
||||||
|
feed: https://blog.posthaven.com/posts.atom
|
||||||
|
tags: [posthaven, text]
|
||||||
|
|
||||||
|
- site: https://medium.com/@dailynewsletter
|
||||||
|
feed: https://medium.com/feed/@dailynewsletter
|
||||||
|
tags: [medium, text]
|
||||||
|
|
||||||
|
- site: https://thereveal.substack.com/
|
||||||
|
feed: https://thereveal.substack.com/feed
|
||||||
|
tags: [substack, text]
|
||||||
|
|
||||||
|
- site: https://tema.livejournal.com/
|
||||||
|
feed: https://tema.livejournal.com/data/rss
|
||||||
|
tags: [livejournal, text]
|
||||||
|
|
||||||
|
- site: https://mametter.hatenablog.com/
|
||||||
|
feed: https://mametter.hatenablog.com/feed
|
||||||
|
tags: [hatena, text]
|
||||||
|
|
||||||
|
- site: https://juliepowell.blogspot.com/
|
||||||
|
feed: https://juliepowell.blogspot.com/feeds/posts/default
|
||||||
|
tags: [blogger, text]
|
||||||
|
|
||||||
|
- site: https://micro.blog/val
|
||||||
|
feed: https://micro.blog/posts/val
|
||||||
|
tags: [json, microblog]
|
||||||
@@ -2,7 +2,8 @@ FROM golang:alpine3.18 AS build
|
|||||||
RUN apk add build-base git
|
RUN apk add build-base git
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN make build_linux
|
RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/root/go/pkg \
|
||||||
|
make build_linux
|
||||||
|
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
RUN apk add --no-cache ca-certificates && \
|
RUN apk add --no-cache ca-certificates && \
|
||||||
|
|||||||
8
go.mod
8
go.mod
@@ -1,11 +1,11 @@
|
|||||||
module github.com/nkanaev/yarr
|
module github.com/nkanaev/yarr
|
||||||
|
|
||||||
go 1.17
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/mattn/go-sqlite3 v1.14.7
|
github.com/mattn/go-sqlite3 v1.14.7
|
||||||
golang.org/x/net v0.17.0
|
golang.org/x/net v0.33.0
|
||||||
golang.org/x/sys v0.13.0
|
golang.org/x/sys v0.28.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require golang.org/x/text v0.13.0 // indirect
|
require golang.org/x/text v0.21.0 // indirect
|
||||||
|
|||||||
49
go.sum
49
go.sum
@@ -1,45 +1,70 @@
|
|||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
|
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
|
||||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
|
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||||
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||||
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
|
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|
||||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
19
makefile
19
makefile
@@ -1,33 +1,34 @@
|
|||||||
VERSION=2.4
|
VERSION=2.4
|
||||||
GITHASH=$(shell git rev-parse --short=8 HEAD)
|
GITHASH=$(shell git rev-parse --short=8 HEAD)
|
||||||
|
|
||||||
CGO_ENABLED=1
|
GO_TAGS = sqlite_foreign_keys sqlite_json
|
||||||
|
GO_LDFLAGS = -s -w -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)'
|
||||||
|
|
||||||
GO_LDFLAGS = -s -w
|
export GOARCH ?= amd64
|
||||||
GO_LDFLAGS := $(GO_LDFLAGS) -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)'
|
export CGO_ENABLED = 1
|
||||||
|
|
||||||
build_default:
|
build_default:
|
||||||
mkdir -p _output
|
mkdir -p _output
|
||||||
go build -tags "sqlite_foreign_keys" -ldflags="$(GO_LDFLAGS)" -o _output/yarr ./cmd/yarr
|
go build -tags "$(GO_TAGS)" -ldflags="$(GO_LDFLAGS)" -o _output/yarr ./cmd/yarr
|
||||||
|
|
||||||
build_macos:
|
build_macos:
|
||||||
mkdir -p _output/macos
|
mkdir -p _output/macos
|
||||||
GOOS=darwin GOARCH=amd64 go build -tags "sqlite_foreign_keys macos" -ldflags="$(GO_LDFLAGS)" -o _output/macos/yarr ./cmd/yarr
|
GOOS=darwin go build -tags "$(GO_TAGS) macos" -ldflags="$(GO_LDFLAGS)" -o _output/macos/yarr ./cmd/yarr
|
||||||
cp src/platform/icon.png _output/macos/icon.png
|
cp src/platform/icon.png _output/macos/icon.png
|
||||||
go run ./cmd/package_macos -outdir _output/macos -version "$(VERSION)"
|
go run ./cmd/package_macos -outdir _output/macos -version "$(VERSION)"
|
||||||
|
|
||||||
build_linux:
|
build_linux:
|
||||||
mkdir -p _output/linux
|
mkdir -p _output/linux
|
||||||
GOOS=linux GOARCH=amd64 go build -tags "sqlite_foreign_keys linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr ./cmd/yarr
|
GOOS=linux go build -tags "$(GO_TAGS) linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr ./cmd/yarr
|
||||||
|
|
||||||
build_windows:
|
build_windows:
|
||||||
mkdir -p _output/windows
|
mkdir -p _output/windows
|
||||||
go run ./cmd/generate_versioninfo -version "$(VERSION)" -outfile src/platform/versioninfo.rc
|
go run ./cmd/generate_versioninfo -version "$(VERSION)" -outfile src/platform/versioninfo.rc
|
||||||
windres -i src/platform/versioninfo.rc -O coff -o src/platform/versioninfo.syso
|
windres -i src/platform/versioninfo.rc -O coff -o src/platform/versioninfo.syso
|
||||||
GOOS=windows GOARCH=amd64 go build -tags "sqlite_foreign_keys windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr
|
GOOS=windows go build -tags "$(GO_TAGS) windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr
|
||||||
|
|
||||||
serve:
|
serve:
|
||||||
go run -tags "sqlite_foreign_keys" ./cmd/yarr -db local.db
|
go run -tags "$(GO_TAGS)" ./cmd/yarr -db local.db
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -tags "sqlite_foreign_keys" ./...
|
go test -tags "$(GO_TAGS)" ./...
|
||||||
|
|||||||
@@ -25,18 +25,21 @@
|
|||||||
<div class="flex-grow-1"></div>
|
<div class="flex-grow-1"></div>
|
||||||
<button class="toolbar-item"
|
<button class="toolbar-item"
|
||||||
:class="{active: filterSelected == 'unread'}"
|
:class="{active: filterSelected == 'unread'}"
|
||||||
|
:aria-pressed="filterSelected == 'unread'"
|
||||||
title="Unread"
|
title="Unread"
|
||||||
@click="filterSelected = 'unread'">
|
@click="filterSelected = 'unread'">
|
||||||
<span class="icon">{% inline "circle-full.svg" %}</span>
|
<span class="icon">{% inline "circle-full.svg" %}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="toolbar-item"
|
<button class="toolbar-item"
|
||||||
:class="{active: filterSelected == 'starred'}"
|
:class="{active: filterSelected == 'starred'}"
|
||||||
|
:aria-pressed="filterSelected == 'starred'"
|
||||||
title="Starred"
|
title="Starred"
|
||||||
@click="filterSelected = 'starred'">
|
@click="filterSelected = 'starred'">
|
||||||
<span class="icon">{% inline "star-full.svg" %}</span>
|
<span class="icon">{% inline "star-full.svg" %}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="toolbar-item"
|
<button class="toolbar-item"
|
||||||
:class="{active: filterSelected == ''}"
|
:class="{active: filterSelected == ''}"
|
||||||
|
:aria-pressed="filterSelected == ''"
|
||||||
title="All"
|
title="All"
|
||||||
@click="filterSelected = ''">
|
@click="filterSelected = ''">
|
||||||
<span class="icon">{% inline "assorted.svg" %}</span>
|
<span class="icon">{% inline "assorted.svg" %}</span>
|
||||||
@@ -59,10 +62,12 @@
|
|||||||
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|
||||||
<header class="dropdown-header">Theme</header>
|
<header class="dropdown-header" role="heading" aria-level="2">Theme</header>
|
||||||
<div class="row text-center m-0">
|
<div class="row text-center m-0">
|
||||||
<button class="btn btn-link col-4 px-0 rounded-0"
|
<button class="btn btn-link col-4 px-0 rounded-0"
|
||||||
:class="'theme-'+t"
|
:class="'theme-'+t"
|
||||||
|
:aria-label="t"
|
||||||
|
:aria-pressed="theme.name == t"
|
||||||
@click.stop="theme.name = t"
|
@click.stop="theme.name = t"
|
||||||
v-for="t in ['light', 'sepia', 'night']">
|
v-for="t in ['light', 'sepia', 'night']">
|
||||||
<span class="icon" v-if="theme.name == t">{% inline "check.svg" %}</span>
|
<span class="icon" v-if="theme.name == t">{% inline "check.svg" %}</span>
|
||||||
@@ -71,25 +76,25 @@
|
|||||||
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|
||||||
<header class="dropdown-header">Auto Refresh</header>
|
<header class="dropdown-header" role="heading" aria-level="2">Auto Refresh</header>
|
||||||
<div class="row text-center m-0">
|
<div class="row text-center m-0">
|
||||||
<button class="dropdown-item col-4 px-0" :class="{active: !refreshRate}" @click.stop="refreshRate = 0">0</button>
|
<button class="dropdown-item col-4 px-0" :aria-pressed="!refreshRate" :class="{active: !refreshRate}" @click.stop="refreshRate = 0">0</button>
|
||||||
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 10}" @click.stop="refreshRate = 10">10m</button>
|
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 10" :class="{active: refreshRate == 10}" @click.stop="refreshRate = 10">10m</button>
|
||||||
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 30}" @click.stop="refreshRate = 30">30m</button>
|
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 30" :class="{active: refreshRate == 30}" @click.stop="refreshRate = 30">30m</button>
|
||||||
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 60}" @click.stop="refreshRate = 60">1h</button>
|
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 60" :class="{active: refreshRate == 60}" @click.stop="refreshRate = 60">1h</button>
|
||||||
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 120}" @click.stop="refreshRate = 120">2h</button>
|
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 120" :class="{active: refreshRate == 120}" @click.stop="refreshRate = 120">2h</button>
|
||||||
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 240}" @click.stop="refreshRate = 240">4h</button>
|
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 240" :class="{active: refreshRate == 240}" @click.stop="refreshRate = 240">4h</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|
||||||
<header class="dropdown-header">Show first</header>
|
<header class="dropdown-header" role="heading" aria-level="2">Show first</header>
|
||||||
<div class="d-flex text-center">
|
<div class="d-flex text-center">
|
||||||
<button class="dropdown-item px-0" :class="{active: itemSortNewestFirst}" @click.stop="itemSortNewestFirst=true">New</button>
|
<button class="dropdown-item px-0" :aria-pressed="itemSortNewestFirst" :class="{active: itemSortNewestFirst}" @click.stop="itemSortNewestFirst=true">New</button>
|
||||||
<button class="dropdown-item px-0" :class="{active: !itemSortNewestFirst}" @click.stop="itemSortNewestFirst=false">Old</button>
|
<button class="dropdown-item px-0" :aria-pressed="!itemSortNewestFirst" :class="{active: !itemSortNewestFirst}" @click.stop="itemSortNewestFirst=false">Old</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<header class="dropdown-header">Subscriptions</header>
|
<header class="dropdown-header" role="heading" aria-level="2">Subscriptions</header>
|
||||||
<form id="opml-import-form" enctype="multipart/form-data" tabindex="-1">
|
<form id="opml-import-form" enctype="multipart/form-data" tabindex="-1">
|
||||||
<input type="file"
|
<input type="file"
|
||||||
id="opml-import"
|
id="opml-import"
|
||||||
@@ -206,12 +211,12 @@
|
|||||||
<template v-slot:button>
|
<template v-slot:button>
|
||||||
<span class="icon">{% inline "more-horizontal.svg" %}</span>
|
<span class="icon">{% inline "more-horizontal.svg" %}</span>
|
||||||
</template>
|
</template>
|
||||||
<header class="dropdown-header">{{ current.feed.title }}</header>
|
<header class="dropdown-header" role="heading" aria-level="2">{{ current.feed.title }}</header>
|
||||||
<a class="dropdown-item" :href="current.feed.link" target="_blank" v-if="current.feed.link">
|
<a class="dropdown-item" :href="current.feed.link" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" v-if="current.feed.link">
|
||||||
<span class="icon mr-1">{% inline "globe.svg" %}</span>
|
<span class="icon mr-1">{% inline "globe.svg" %}</span>
|
||||||
Website
|
Website
|
||||||
</a>
|
</a>
|
||||||
<a class="dropdown-item" :href="current.feed.feed_link" target="_blank" v-if="current.feed.feed_link">
|
<a class="dropdown-item" :href="current.feed.feed_link" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" v-if="current.feed.feed_link">
|
||||||
<span class="icon mr-1">{% inline "rss.svg" %}</span>
|
<span class="icon mr-1">{% inline "rss.svg" %}</span>
|
||||||
Feed Link
|
Feed Link
|
||||||
</a>
|
</a>
|
||||||
@@ -225,7 +230,7 @@
|
|||||||
Change Link
|
Change Link
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<header class="dropdown-header">Move to...</header>
|
<header class="dropdown-header" role="heading" aria-level="2">Move to...</header>
|
||||||
<button class="dropdown-item"
|
<button class="dropdown-item"
|
||||||
v-if="folder.id != current.feed.folder_id"
|
v-if="folder.id != current.feed.folder_id"
|
||||||
v-for="folder in folders"
|
v-for="folder in folders"
|
||||||
@@ -255,7 +260,7 @@
|
|||||||
<template v-slot:button>
|
<template v-slot:button>
|
||||||
<span class="icon">{% inline "more-horizontal.svg" %}</span>
|
<span class="icon">{% inline "more-horizontal.svg" %}</span>
|
||||||
</template>
|
</template>
|
||||||
<header class="dropdown-header">{{ current.folder.title }}</header>
|
<header class="dropdown-header" role="heading" aria-level="2">{{ current.folder.title }}</header>
|
||||||
<button class="dropdown-item" @click="renameFolder(current.folder)">
|
<button class="dropdown-item" @click="renameFolder(current.folder)">
|
||||||
<span class="icon mr-1">{% inline "edit.svg" %}</span>
|
<span class="icon mr-1">{% inline "edit.svg" %}</span>
|
||||||
Rename
|
Rename
|
||||||
@@ -326,10 +331,16 @@
|
|||||||
title="Read Here">
|
title="Read Here">
|
||||||
<span class="icon" :class="{'icon-loading': loading.readability}">{% inline "book-open.svg" %}</span>
|
<span class="icon" :class="{'icon-loading': loading.readability}">{% inline "book-open.svg" %}</span>
|
||||||
</button>
|
</button>
|
||||||
<a class="toolbar-item" :href="itemSelectedDetails.link" target="_blank" title="Open Link">
|
<a class="toolbar-item" :href="itemSelectedDetails.link" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" title="Open Link">
|
||||||
<span class="icon">{% inline "external-link.svg" %}</span>
|
<span class="icon">{% inline "external-link.svg" %}</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="flex-grow-1"></div>
|
<div class="flex-grow-1"></div>
|
||||||
|
<button class="toolbar-item" @click="navigateToItem(-1)" title="Previous Article" :disabled="itemSelected == items[0].id">
|
||||||
|
<span class="icon">{% inline "chevron-left.svg" %}</span>
|
||||||
|
</button>
|
||||||
|
<button class="toolbar-item" @click="navigateToItem(+1)" title="Next Article" :disabled="itemSelected == items[items.length - 1].id">
|
||||||
|
<span class="icon">{% inline "chevron-right.svg" %}</span>
|
||||||
|
</button>
|
||||||
<button class="toolbar-item" @click="itemSelected=null" title="Close Article">
|
<button class="toolbar-item" @click="itemSelected=null" title="Close Article">
|
||||||
<span class="icon">{% inline "x.svg" %}</span>
|
<span class="icon">{% inline "x.svg" %}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -351,8 +362,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div v-if="!itemSelectedReadability">
|
<div v-if="!itemSelectedReadability">
|
||||||
<img :src="itemSelectedDetails.image" v-if="itemSelectedDetails.image" class="mb-3">
|
<div v-if="contentImages.length">
|
||||||
<audio class="w-100" controls v-if="itemSelectedDetails.podcast_url" :src="itemSelectedDetails.podcast_url"></audio>
|
<figure v-for="media in contentImages">
|
||||||
|
<img :src="media.url" loading="lazy">
|
||||||
|
<figcaption v-if="media.description" v-html="media.description"></figcaption>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<audio class="w-100" controls v-for="media in contentAudios" :src="media.url"></audio>
|
||||||
|
<video class="w-100" controls v-for="media in contentVideos" :src="media.url"></video>
|
||||||
</div>
|
</div>
|
||||||
<div v-html="itemSelectedContent"></div>
|
<div v-html="itemSelectedContent"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,26 @@
|
|||||||
|
|
||||||
var TITLE = document.title
|
var TITLE = document.title
|
||||||
|
|
||||||
|
function scrollto(target, scroll) {
|
||||||
|
var padding = 10
|
||||||
|
var targetRect = target.getBoundingClientRect()
|
||||||
|
var scrollRect = scroll.getBoundingClientRect()
|
||||||
|
|
||||||
|
// target
|
||||||
|
var relativeOffset = targetRect.y - scrollRect.y
|
||||||
|
var absoluteOffset = relativeOffset + scroll.scrollTop
|
||||||
|
|
||||||
|
if (padding <= relativeOffset && relativeOffset + targetRect.height <= scrollRect.height - padding) return
|
||||||
|
|
||||||
|
var newPos = scroll.scrollTop
|
||||||
|
if (relativeOffset < padding) {
|
||||||
|
newPos = absoluteOffset - padding
|
||||||
|
} else {
|
||||||
|
newPos = absoluteOffset - scrollRect.height + targetRect.height + padding
|
||||||
|
}
|
||||||
|
scroll.scrollTop = Math.round(newPos)
|
||||||
|
}
|
||||||
|
|
||||||
var debounce = function(callback, wait) {
|
var debounce = function(callback, wait) {
|
||||||
var timeout
|
var timeout
|
||||||
return function() {
|
return function() {
|
||||||
@@ -278,6 +298,18 @@ var vm = new Vue({
|
|||||||
|
|
||||||
return this.itemSelectedDetails.content || ''
|
return this.itemSelectedDetails.content || ''
|
||||||
},
|
},
|
||||||
|
contentImages: function() {
|
||||||
|
if (!this.itemSelectedDetails) return []
|
||||||
|
return (this.itemSelectedDetails.media_links || []).filter(l => l.type === 'image')
|
||||||
|
},
|
||||||
|
contentAudios: function() {
|
||||||
|
if (!this.itemSelectedDetails) return []
|
||||||
|
return (this.itemSelectedDetails.media_links || []).filter(l => l.type === 'audio')
|
||||||
|
},
|
||||||
|
contentVideos: function() {
|
||||||
|
if (!this.itemSelectedDetails) return []
|
||||||
|
return (this.itemSelectedDetails.media_links || []).filter(l => l.type === 'video')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'theme': {
|
'theme': {
|
||||||
@@ -407,7 +439,7 @@ var vm = new Vue({
|
|||||||
vm.feeds = values[1]
|
vm.feeds = values[1]
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
refreshItems: function(loadMore) {
|
refreshItems: function(loadMore = false) {
|
||||||
if (this.feedSelected === null) {
|
if (this.feedSelected === null) {
|
||||||
vm.items = []
|
vm.items = []
|
||||||
vm.itemsHasMore = false
|
vm.itemsHasMore = false
|
||||||
@@ -420,7 +452,7 @@ var vm = new Vue({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.loading.items = true
|
this.loading.items = true
|
||||||
api.items.list(query).then(function(data) {
|
return api.items.list(query).then(function(data) {
|
||||||
if (loadMore) {
|
if (loadMore) {
|
||||||
vm.items = vm.items.concat(data.list)
|
vm.items = vm.items.concat(data.list)
|
||||||
} else {
|
} else {
|
||||||
@@ -443,13 +475,17 @@ var vm = new Vue({
|
|||||||
var scale = (parseFloat(getComputedStyle(document.documentElement).fontSize) || 16) / 16
|
var scale = (parseFloat(getComputedStyle(document.documentElement).fontSize) || 16) / 16
|
||||||
|
|
||||||
var el = this.$refs.itemlist
|
var el = this.$refs.itemlist
|
||||||
|
|
||||||
|
if (el.scrollHeight === 0) return false // element is invisible (responsive design)
|
||||||
|
|
||||||
var closeToBottom = (el.scrollHeight - el.scrollTop - el.offsetHeight) < bottomSpace * scale
|
var closeToBottom = (el.scrollHeight - el.scrollTop - el.offsetHeight) < bottomSpace * scale
|
||||||
return closeToBottom
|
return closeToBottom
|
||||||
},
|
},
|
||||||
loadMoreItems: function(event, el) {
|
loadMoreItems: function(event, el) {
|
||||||
if (!this.itemsHasMore) return
|
if (!this.itemsHasMore) return
|
||||||
if (this.loading.items) return
|
if (this.loading.items) return
|
||||||
if (this.itemListCloseToBottom()) this.refreshItems(true)
|
if (this.itemListCloseToBottom()) return this.refreshItems(true)
|
||||||
|
if (this.itemSelected && this.itemSelected === this.items[this.items.length - 1].id) return this.refreshItems(true)
|
||||||
},
|
},
|
||||||
markItemsRead: function() {
|
markItemsRead: function() {
|
||||||
var query = this.getItemsQuery()
|
var query = this.getItemsQuery()
|
||||||
@@ -683,6 +719,65 @@ var vm = new Vue({
|
|||||||
this.filteredFolderStats = statsFolders
|
this.filteredFolderStats = statsFolders
|
||||||
this.filteredTotalStats = statsTotal
|
this.filteredTotalStats = statsTotal
|
||||||
},
|
},
|
||||||
|
// navigation helper, navigate relative to selected item
|
||||||
|
navigateToItem: function(relativePosition) {
|
||||||
|
let vm = this
|
||||||
|
if (vm.itemSelected == null) {
|
||||||
|
// if no item is selected, select first
|
||||||
|
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemPosition = vm.items.findIndex(function(x) { return x.id === vm.itemSelected })
|
||||||
|
if (itemPosition === -1) {
|
||||||
|
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var newPosition = itemPosition + relativePosition
|
||||||
|
if (newPosition < 0 || newPosition >= vm.items.length) return
|
||||||
|
|
||||||
|
vm.itemSelected = vm.items[newPosition].id
|
||||||
|
|
||||||
|
vm.$nextTick(function() {
|
||||||
|
var scroll = document.querySelector('#item-list-scroll')
|
||||||
|
|
||||||
|
var handle = scroll.querySelector('input[type=radio]:checked')
|
||||||
|
var target = handle && handle.parentElement
|
||||||
|
|
||||||
|
if (target && scroll) scrollto(target, scroll)
|
||||||
|
|
||||||
|
vm.loadMoreItems()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// navigation helper, navigate relative to selected feed
|
||||||
|
navigateToFeed: function(relativePosition) {
|
||||||
|
let vm = this
|
||||||
|
var navigationList = Array.from(document.querySelectorAll('#col-feed-list input[name=feed]'))
|
||||||
|
.filter(function(r) { return r.offsetParent !== null && r.value !== 'folder:null' })
|
||||||
|
.map(function(r) { return r.value })
|
||||||
|
|
||||||
|
var currentFeedPosition = navigationList.indexOf(vm.feedSelected)
|
||||||
|
|
||||||
|
if (currentFeedPosition == -1) {
|
||||||
|
vm.feedSelected = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var newPosition = currentFeedPosition+relativePosition
|
||||||
|
if (newPosition < 0 || newPosition >= navigationList.length) return
|
||||||
|
|
||||||
|
vm.feedSelected = navigationList[newPosition]
|
||||||
|
|
||||||
|
vm.$nextTick(function() {
|
||||||
|
var scroll = document.querySelector('#feed-list-scroll')
|
||||||
|
|
||||||
|
var handle = scroll.querySelector('input[type=radio]:checked')
|
||||||
|
var target = handle && handle.parentElement
|
||||||
|
|
||||||
|
if (target && scroll) scrollto(target, scroll)
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,79 +1,4 @@
|
|||||||
function scrollto(target, scroll) {
|
|
||||||
var padding = 10
|
|
||||||
var targetRect = target.getBoundingClientRect()
|
|
||||||
var scrollRect = scroll.getBoundingClientRect()
|
|
||||||
|
|
||||||
// target
|
|
||||||
var relativeOffset = targetRect.y - scrollRect.y
|
|
||||||
var absoluteOffset = relativeOffset + scroll.scrollTop
|
|
||||||
|
|
||||||
if (padding <= relativeOffset && relativeOffset + targetRect.height <= scrollRect.height - padding) return
|
|
||||||
|
|
||||||
var newPos = scroll.scrollTop
|
|
||||||
if (relativeOffset < padding) {
|
|
||||||
newPos = absoluteOffset - padding
|
|
||||||
} else {
|
|
||||||
newPos = absoluteOffset - scrollRect.height + targetRect.height + padding
|
|
||||||
}
|
|
||||||
scroll.scrollTop = Math.round(newPos)
|
|
||||||
}
|
|
||||||
|
|
||||||
var helperFunctions = {
|
var helperFunctions = {
|
||||||
// navigation helper, navigate relative to selected item
|
|
||||||
navigateToItem: function(relativePosition) {
|
|
||||||
if (vm.itemSelected == null) {
|
|
||||||
// if no item is selected, select first
|
|
||||||
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var itemPosition = vm.items.findIndex(function(x) { return x.id === vm.itemSelected })
|
|
||||||
if (itemPosition === -1) {
|
|
||||||
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var newPosition = itemPosition + relativePosition
|
|
||||||
if (newPosition < 0 || newPosition >= vm.items.length) return
|
|
||||||
|
|
||||||
vm.itemSelected = vm.items[newPosition].id
|
|
||||||
|
|
||||||
vm.$nextTick(function() {
|
|
||||||
var scroll = document.querySelector('#item-list-scroll')
|
|
||||||
|
|
||||||
var handle = scroll.querySelector('input[type=radio]:checked')
|
|
||||||
var target = handle && handle.parentElement
|
|
||||||
|
|
||||||
if (target && scroll) scrollto(target, scroll)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// navigation helper, navigate relative to selected feed
|
|
||||||
navigateToFeed: function(relativePosition) {
|
|
||||||
var navigationList = Array.from(document.querySelectorAll('#col-feed-list input[name=feed]'))
|
|
||||||
.filter(function(r) { return r.offsetParent !== null && r.value !== 'folder:null' })
|
|
||||||
.map(function(r) { return r.value })
|
|
||||||
|
|
||||||
var currentFeedPosition = navigationList.indexOf(vm.feedSelected)
|
|
||||||
|
|
||||||
if (currentFeedPosition == -1) {
|
|
||||||
vm.feedSelected = ''
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var newPosition = currentFeedPosition+relativePosition
|
|
||||||
if (newPosition < 0 || newPosition >= navigationList.length) return
|
|
||||||
|
|
||||||
vm.feedSelected = navigationList[newPosition]
|
|
||||||
|
|
||||||
vm.$nextTick(function() {
|
|
||||||
var scroll = document.querySelector('#feed-list-scroll')
|
|
||||||
|
|
||||||
var handle = scroll.querySelector('input[type=radio]:checked')
|
|
||||||
var target = handle && handle.parentElement
|
|
||||||
|
|
||||||
if (target && scroll) scrollto(target, scroll)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
scrollContent: function(direction) {
|
scrollContent: function(direction) {
|
||||||
var padding = 40
|
var padding = 40
|
||||||
var scroll = document.querySelector('.content')
|
var scroll = document.querySelector('.content')
|
||||||
@@ -92,7 +17,7 @@ var helperFunctions = {
|
|||||||
var shortcutFunctions = {
|
var shortcutFunctions = {
|
||||||
openItemLink: function() {
|
openItemLink: function() {
|
||||||
if (vm.itemSelectedDetails && vm.itemSelectedDetails.link) {
|
if (vm.itemSelectedDetails && vm.itemSelectedDetails.link) {
|
||||||
window.open(vm.itemSelectedDetails.link, '_blank')
|
window.open(vm.itemSelectedDetails.link, '_blank', 'noopener,noreferrer')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleReadability: function() {
|
toggleReadability: function() {
|
||||||
@@ -118,16 +43,16 @@ var shortcutFunctions = {
|
|||||||
document.getElementById("searchbar").focus()
|
document.getElementById("searchbar").focus()
|
||||||
},
|
},
|
||||||
nextItem(){
|
nextItem(){
|
||||||
helperFunctions.navigateToItem(+1)
|
vm.navigateToItem(+1)
|
||||||
},
|
},
|
||||||
previousItem() {
|
previousItem() {
|
||||||
helperFunctions.navigateToItem(-1)
|
vm.navigateToItem(-1)
|
||||||
},
|
},
|
||||||
nextFeed(){
|
nextFeed(){
|
||||||
helperFunctions.navigateToFeed(+1)
|
vm.navigateToFeed(+1)
|
||||||
},
|
},
|
||||||
previousFeed() {
|
previousFeed() {
|
||||||
helperFunctions.navigateToFeed(-1)
|
vm.navigateToFeed(-1)
|
||||||
},
|
},
|
||||||
scrollForward: function() {
|
scrollForward: function() {
|
||||||
helperFunctions.scrollContent(+1)
|
helperFunctions.scrollContent(+1)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
)
|
)
|
||||||
@@ -61,3 +62,16 @@ func ExtractText(content string) string {
|
|||||||
text = whitespaceRegex.ReplaceAllLiteralString(text, " ")
|
text = whitespaceRegex.ReplaceAllLiteralString(text, " ")
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TruncateText(input string, size int) string {
|
||||||
|
runes := []rune(input)
|
||||||
|
if len(runes) <= size {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
for i := size - 1; i > 0; i-- {
|
||||||
|
if unicode.IsSpace(runes[i]) {
|
||||||
|
return string(runes[:i]) + " ..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,3 +24,21 @@ func TestExtractText(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTruncateText(t *testing.T) {
|
||||||
|
input := "Lorem ipsum — классический текст-«рыба»"
|
||||||
|
|
||||||
|
size := 30
|
||||||
|
want := "Lorem ipsum — классический ..."
|
||||||
|
have := TruncateText(input, size)
|
||||||
|
if want != have {
|
||||||
|
t.Errorf("\nsize: %d\nwant: %#v\nhave: %#v", size, want, have)
|
||||||
|
}
|
||||||
|
|
||||||
|
size = 1000
|
||||||
|
want = input
|
||||||
|
have = TruncateText(input, size)
|
||||||
|
if want != have {
|
||||||
|
t.Errorf("\nsize: %d\nwant: %#v\nhave: %#v", size, want, have)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ func getExtraAttributes(tagName string) ([]string, []string) {
|
|||||||
case "iframe":
|
case "iframe":
|
||||||
return []string{"sandbox", "loading"}, []string{`sandbox="allow-scripts allow-same-origin allow-popups"`, `loading="lazy"`}
|
return []string{"sandbox", "loading"}, []string{`sandbox="allow-scripts allow-same-origin allow-popups"`, `loading="lazy"`}
|
||||||
case "img":
|
case "img":
|
||||||
return []string{"loading"}, []string{`loading="lazy"`}
|
return []string{"loading"}, []string{`loading="lazy"`, `referrerpolicy="no-referrer"`}
|
||||||
default:
|
default:
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ import "testing"
|
|||||||
|
|
||||||
func TestValidInput(t *testing.T) {
|
func TestValidInput(t *testing.T) {
|
||||||
input := `<p>This is a <strong>text</strong> with an image: <img src="http://example.org/" alt="Test" loading="lazy">.</p>`
|
input := `<p>This is a <strong>text</strong> with an image: <img src="http://example.org/" alt="Test" loading="lazy">.</p>`
|
||||||
output := Sanitize("http://example.org/", input)
|
want := `<p>This is a <strong>text</strong> with an image: <img src="http://example.org/" alt="Test" loading="lazy" referrerpolicy="no-referrer">.</p>`
|
||||||
|
have := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if input != output {
|
if have != want {
|
||||||
t.Errorf(`Wrong output: "%s" != "%s"`, input, output)
|
t.Errorf("Wrong output: \nwant: %#v\nhave: %#v", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,31 +28,31 @@ func TestImgWithTextDataURL(t *testing.T) {
|
|||||||
|
|
||||||
func TestImgWithDataURL(t *testing.T) {
|
func TestImgWithDataURL(t *testing.T) {
|
||||||
input := `<img src="data:image/gif;base64,test" alt="Example">`
|
input := `<img src="data:image/gif;base64,test" alt="Example">`
|
||||||
expected := `<img src="data:image/gif;base64,test" alt="Example" loading="lazy">`
|
want := `<img src="data:image/gif;base64,test" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
|
||||||
output := Sanitize("http://example.org/", input)
|
have := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if output != expected {
|
if have != want {
|
||||||
t.Errorf(`Wrong output: %s`, output)
|
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImgWithSrcset(t *testing.T) {
|
func TestImgWithSrcset(t *testing.T) {
|
||||||
input := `<img srcset="example-320w.jpg, example-480w.jpg 1.5x, example-640w.jpg 2x, example-640w.jpg 640w" src="example-640w.jpg" alt="Example">`
|
input := `<img srcset="example-320w.jpg, example-480w.jpg 1.5x, example-640w.jpg 2x, example-640w.jpg 640w" src="example-640w.jpg" alt="Example">`
|
||||||
expected := `<img srcset="http://example.org/example-320w.jpg, http://example.org/example-480w.jpg 1.5x, http://example.org/example-640w.jpg 2x, http://example.org/example-640w.jpg 640w" src="http://example.org/example-640w.jpg" alt="Example" loading="lazy">`
|
want := `<img srcset="http://example.org/example-320w.jpg, http://example.org/example-480w.jpg 1.5x, http://example.org/example-640w.jpg 2x, http://example.org/example-640w.jpg 640w" src="http://example.org/example-640w.jpg" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
|
||||||
output := Sanitize("http://example.org/", input)
|
have := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if output != expected {
|
if have != want {
|
||||||
t.Errorf(`Wrong output: %s`, output)
|
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImgWithSrcsetAndDataURL(t *testing.T) {
|
func TestImgWithSrcsetAndDataURL(t *testing.T) {
|
||||||
input := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example">`
|
input := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example">`
|
||||||
expected := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example" loading="lazy">`
|
want := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
|
||||||
output := Sanitize("http://example.org/", input)
|
have := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if output != expected {
|
if have != want {
|
||||||
t.Errorf(`Wrong output: %s`, output)
|
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,16 +68,16 @@ func TestSourceWithSrcsetAndMedia(t *testing.T) {
|
|||||||
|
|
||||||
func TestMediumImgWithSrcset(t *testing.T) {
|
func TestMediumImgWithSrcset(t *testing.T) {
|
||||||
input := `<img alt="Image for post" class="t u v ef aj" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" width="2730" height="3407">`
|
input := `<img alt="Image for post" class="t u v ef aj" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" width="2730" height="3407">`
|
||||||
expected := `<img alt="Image for post" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" loading="lazy">`
|
want := `<img alt="Image for post" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" loading="lazy" referrerpolicy="no-referrer">`
|
||||||
output := Sanitize("http://example.org/", input)
|
have := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if output != expected {
|
if have != want {
|
||||||
t.Errorf(`Wrong output: %s`, output)
|
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelfClosingTags(t *testing.T) {
|
func TestSelfClosingTags(t *testing.T) {
|
||||||
input := `<p>This <br> is a <strong>text</strong> <br/>with an image: <img src="http://example.org/" alt="Test" loading="lazy"/>.</p>`
|
input := `<p>This <br> is a <strong>text</strong><br/>.</p>`
|
||||||
output := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if input != output {
|
if input != output {
|
||||||
@@ -95,11 +96,11 @@ func TestTable(t *testing.T) {
|
|||||||
|
|
||||||
func TestRelativeURL(t *testing.T) {
|
func TestRelativeURL(t *testing.T) {
|
||||||
input := `This <a href="/test.html">link is relative</a> and this image: <img src="../folder/image.png"/>`
|
input := `This <a href="/test.html">link is relative</a> and this image: <img src="../folder/image.png"/>`
|
||||||
expected := `This <a href="http://example.org/test.html" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer">link is relative</a> and this image: <img src="http://example.org/folder/image.png" loading="lazy"/>`
|
want := `This <a href="http://example.org/test.html" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer">link is relative</a> and this image: <img src="http://example.org/folder/image.png" loading="lazy" referrerpolicy="no-referrer"/>`
|
||||||
output := Sanitize("http://example.org/", input)
|
have := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if expected != output {
|
if want != have {
|
||||||
t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
|
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,11 +166,11 @@ func TestInvalidNestedTag(t *testing.T) {
|
|||||||
|
|
||||||
func TestValidIFrame(t *testing.T) {
|
func TestValidIFrame(t *testing.T) {
|
||||||
input := `<iframe src="http://example.org/"></iframe>`
|
input := `<iframe src="http://example.org/"></iframe>`
|
||||||
expected := `<iframe src="http://example.org/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
|
want := `<iframe src="http://example.org/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
|
||||||
output := Sanitize("http://example.org/", input)
|
have := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if expected != output {
|
if want != have {
|
||||||
t.Errorf("Wrong output:\nwant: %s\nhave: %s", expected, output)
|
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package scraper
|
package scraper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/nkanaev/yarr/src/content/htmlutil"
|
"github.com/nkanaev/yarr/src/content/htmlutil"
|
||||||
@@ -35,6 +36,18 @@ func FindFeeds(body string, base string) map[string]string {
|
|||||||
link := htmlutil.AbsoluteUrl(href, base)
|
link := htmlutil.AbsoluteUrl(href, base)
|
||||||
if link != "" {
|
if link != "" {
|
||||||
candidates[link] = name
|
candidates[link] = name
|
||||||
|
|
||||||
|
l, err := url.Parse(link)
|
||||||
|
if err == nil && l.Host == "www.youtube.com" && l.Path == "/feeds/videos.xml" {
|
||||||
|
// https://wiki.archiveteam.org/index.php/YouTube/Technical_details#Playlists
|
||||||
|
channelID, found := strings.CutPrefix(l.Query().Get("channel_id"), "UC")
|
||||||
|
if found {
|
||||||
|
const url string = "https://www.youtube.com/feeds/videos.xml?playlist_id="
|
||||||
|
candidates[url+"UULF"+channelID] = name + " - Videos"
|
||||||
|
candidates[url+"UULV"+channelID] = name + " - Live Streams"
|
||||||
|
candidates[url+"UUSH"+channelID] = name + " - Short videos"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"html"
|
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -58,7 +57,7 @@ func (a *atomText) String() string {
|
|||||||
if a.Type == "xhtml" {
|
if a.Type == "xhtml" {
|
||||||
data = a.XML
|
data = a.XML
|
||||||
}
|
}
|
||||||
return html.UnescapeString(strings.TrimSpace(data))
|
return strings.TrimSpace(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (links atomLinks) First(rel string) string {
|
func (links atomLinks) First(rel string) string {
|
||||||
@@ -90,6 +89,8 @@ func ParseAtom(r io.Reader) (*Feed, error) {
|
|||||||
guidFromID = srcitem.ID + "::" + srcitem.Updated
|
guidFromID = srcitem.ID + "::" + srcitem.Updated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mediaLinks := srcitem.mediaLinks()
|
||||||
|
|
||||||
link := firstNonEmpty(srcitem.OrigLink, srcitem.Links.First("alternate"), srcitem.Links.First(""), linkFromID)
|
link := firstNonEmpty(srcitem.OrigLink, srcitem.Links.First("alternate"), srcitem.Links.First(""), linkFromID)
|
||||||
dstfeed.Items = append(dstfeed.Items, Item{
|
dstfeed.Items = append(dstfeed.Items, Item{
|
||||||
GUID: firstNonEmpty(guidFromID, srcitem.ID, link),
|
GUID: firstNonEmpty(guidFromID, srcitem.ID, link),
|
||||||
@@ -97,8 +98,7 @@ func ParseAtom(r io.Reader) (*Feed, error) {
|
|||||||
URL: link,
|
URL: link,
|
||||||
Title: srcitem.Title.Text(),
|
Title: srcitem.Title.Text(),
|
||||||
Content: firstNonEmpty(srcitem.Content.String(), srcitem.Summary.String(), srcitem.firstMediaDescription()),
|
Content: firstNonEmpty(srcitem.Content.String(), srcitem.Summary.String(), srcitem.firstMediaDescription()),
|
||||||
ImageURL: srcitem.firstMediaThumbnail(),
|
MediaLinks: mediaLinks,
|
||||||
AudioURL: "",
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return dstfeed, nil
|
return dstfeed, nil
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ func TestAtom(t *testing.T) {
|
|||||||
URL: "http://example.org/2003/12/13/atom03.html",
|
URL: "http://example.org/2003/12/13/atom03.html",
|
||||||
Title: "Atom-Powered Robots Run Amok",
|
Title: "Atom-Powered Robots Run Amok",
|
||||||
Content: `<div xmlns="http://www.w3.org/1999/xhtml"><p>This is the entry content.</p></div>`,
|
Content: `<div xmlns="http://www.w3.org/1999/xhtml"><p>This is the entry content.</p></div>`,
|
||||||
ImageURL: "",
|
|
||||||
AudioURL: "",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -141,9 +139,15 @@ func TestAtomImageLink(t *testing.T) {
|
|||||||
</entry>
|
</entry>
|
||||||
</feed>
|
</feed>
|
||||||
`))
|
`))
|
||||||
have := feed.Items[0].ImageURL
|
if len(feed.Items[0].MediaLinks) != 1 {
|
||||||
want := `https://example.com/image.png?width=100&height=100`
|
t.Fatalf("Expected 1 media link, got: %#v", feed.Items[0].MediaLinks)
|
||||||
if want != have {
|
}
|
||||||
|
have := feed.Items[0].MediaLinks[0]
|
||||||
|
want := MediaLink{
|
||||||
|
URL: `https://example.com/image.png?width=100&height=100`,
|
||||||
|
Type: "image",
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, have) {
|
||||||
t.Fatalf("item.image_url doesn't match\nwant: %#v\nhave: %#v\n", want, have)
|
t.Fatalf("item.image_url doesn't match\nwant: %#v\nhave: %#v\n", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,8 +169,8 @@ func TestAtomImageLinkDuplicated(t *testing.T) {
|
|||||||
if want != have {
|
if want != have {
|
||||||
t.Fatalf("want: %#v\nhave: %#v\n", want, have)
|
t.Fatalf("want: %#v\nhave: %#v\n", want, have)
|
||||||
}
|
}
|
||||||
if feed.Items[0].ImageURL != "" {
|
if len(feed.Items[0].MediaLinks) != 0 {
|
||||||
t.Fatal("item.image_url must be unset if present in the content")
|
t.Fatal("item media link must be excluded if present in the content")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,3 +218,19 @@ func TestAtomLinkInID(t *testing.T) {
|
|||||||
t.Fatalf("\nwant: %#v\nhave: %#v\n", want, have)
|
t.Fatalf("\nwant: %#v\nhave: %#v\n", want, have)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAtomDoesntEscapeHTMLTags(t *testing.T) {
|
||||||
|
feed, _ := Parse(strings.NewReader(`
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
<entry><summary type="html">&lt;script&gt;alert(1);&lt;/script&gt;</summary></entry>
|
||||||
|
</feed>
|
||||||
|
`))
|
||||||
|
have := feed.Items[0].Content
|
||||||
|
want := "<script>alert(1);</script>"
|
||||||
|
if !reflect.DeepEqual(want, have) {
|
||||||
|
t.Logf("want: %#v", want)
|
||||||
|
t.Logf("have: %#v", have)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -119,6 +120,7 @@ func ParseAndFix(r io.Reader, baseURL, fallbackEncoding string) (*Feed, error) {
|
|||||||
}
|
}
|
||||||
feed.TranslateURLs(baseURL)
|
feed.TranslateURLs(baseURL)
|
||||||
feed.SetMissingDatesTo(time.Now())
|
feed.SetMissingDatesTo(time.Now())
|
||||||
|
feed.SetMissingGUIDs()
|
||||||
return feed, nil
|
return feed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,11 +134,14 @@ func (feed *Feed) cleanup() {
|
|||||||
feed.Items[i].Title = strings.TrimSpace(htmlutil.ExtractText(item.Title))
|
feed.Items[i].Title = strings.TrimSpace(htmlutil.ExtractText(item.Title))
|
||||||
feed.Items[i].Content = strings.TrimSpace(item.Content)
|
feed.Items[i].Content = strings.TrimSpace(item.Content)
|
||||||
|
|
||||||
if item.ImageURL != "" && strings.Contains(item.Content, item.ImageURL) {
|
if len(feed.Items[i].MediaLinks) > 0 {
|
||||||
feed.Items[i].ImageURL = ""
|
mediaLinks := make([]MediaLink, 0)
|
||||||
|
for _, link := range item.MediaLinks {
|
||||||
|
if !strings.Contains(item.Content, link.URL) {
|
||||||
|
mediaLinks = append(mediaLinks, link)
|
||||||
}
|
}
|
||||||
if item.AudioURL != "" && strings.Contains(item.Content, item.AudioURL) {
|
}
|
||||||
feed.Items[i].AudioURL = ""
|
feed.Items[i].MediaLinks = mediaLinks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,3 +173,12 @@ func (feed *Feed) TranslateURLs(base string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (feed *Feed) SetMissingGUIDs() {
|
||||||
|
for i, item := range feed.Items {
|
||||||
|
if item.GUID == "" {
|
||||||
|
id := strings.Join([]string{item.Title, item.Date.Format(time.RFC3339), item.URL}, ";;")
|
||||||
|
feed.Items[i].GUID = fmt.Sprintf("%x", sha256.Sum256([]byte(id)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -150,3 +150,32 @@ func TestParseCleanIllegalCharsInNonUTF8(t *testing.T) {
|
|||||||
t.Fatalf("invalid feed, got: %v", feed)
|
t.Fatalf("invalid feed, got: %v", feed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseMissingGUID(t *testing.T) {
|
||||||
|
data := `
|
||||||
|
<?xml version="1.0" encoding="windows-1251"?>
|
||||||
|
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
|
||||||
|
<channel>
|
||||||
|
<item>
|
||||||
|
<title>foo</title>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title>bar</title>
|
||||||
|
</item>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
|
`
|
||||||
|
feed, err := ParseAndFix(strings.NewReader(data), "", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(feed.Items) != 2 {
|
||||||
|
t.Fatalf("expected 2 items, got %d", len(feed.Items))
|
||||||
|
}
|
||||||
|
if feed.Items[0].GUID == "" || feed.Items[1].GUID == "" {
|
||||||
|
t.Fatalf("item GUIDs are missing, got %#v", feed.Items)
|
||||||
|
}
|
||||||
|
if feed.Items[0].GUID == feed.Items[1].GUID {
|
||||||
|
t.Fatalf("item GUIDs are not unique, got %#v", feed.Items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package parser
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
type media struct {
|
type media struct {
|
||||||
MediaGroups []mediaGroup `xml:"http://search.yahoo.com/mrss/ group"`
|
MediaGroups []mediaGroup `xml:"http://search.yahoo.com/mrss/ group"`
|
||||||
MediaContents []mediaContent `xml:"http://search.yahoo.com/mrss/ content"`
|
MediaContents []mediaContent `xml:"http://search.yahoo.com/mrss/ content"`
|
||||||
@@ -8,12 +12,17 @@ type media struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mediaGroup struct {
|
type mediaGroup struct {
|
||||||
|
MediaContent []mediaContent `xml:"http://search.yahoo.com/mrss/ content"`
|
||||||
MediaThumbnails []mediaThumbnail `xml:"http://search.yahoo.com/mrss/ thumbnail"`
|
MediaThumbnails []mediaThumbnail `xml:"http://search.yahoo.com/mrss/ thumbnail"`
|
||||||
MediaDescriptions []mediaDescription `xml:"http://search.yahoo.com/mrss/ description"`
|
MediaDescriptions []mediaDescription `xml:"http://search.yahoo.com/mrss/ description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type mediaContent struct {
|
type mediaContent struct {
|
||||||
MediaThumbnails []mediaThumbnail `xml:"http://search.yahoo.com/mrss/ thumbnail"`
|
MediaThumbnails []mediaThumbnail `xml:"http://search.yahoo.com/mrss/ thumbnail"`
|
||||||
|
MediaType string `xml:"type,attr"`
|
||||||
|
MediaMedium string `xml:"medium,attr"`
|
||||||
|
MediaURL string `xml:"url,attr"`
|
||||||
|
MediaDescription mediaDescription `xml:"http://search.yahoo.com/mrss/ description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type mediaThumbnail struct {
|
type mediaThumbnail struct {
|
||||||
@@ -22,7 +31,7 @@ type mediaThumbnail struct {
|
|||||||
|
|
||||||
type mediaDescription struct {
|
type mediaDescription struct {
|
||||||
Type string `xml:"type,attr"`
|
Type string `xml:"type,attr"`
|
||||||
Description string `xml:",chardata"`
|
Text string `xml:",chardata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *media) firstMediaThumbnail() string {
|
func (m *media) firstMediaThumbnail() string {
|
||||||
@@ -44,12 +53,59 @@ func (m *media) firstMediaThumbnail() string {
|
|||||||
|
|
||||||
func (m *media) firstMediaDescription() string {
|
func (m *media) firstMediaDescription() string {
|
||||||
for _, d := range m.MediaDescriptions {
|
for _, d := range m.MediaDescriptions {
|
||||||
return plain2html(d.Description)
|
return plain2html(d.Text)
|
||||||
}
|
}
|
||||||
for _, g := range m.MediaGroups {
|
for _, g := range m.MediaGroups {
|
||||||
for _, d := range g.MediaDescriptions {
|
for _, d := range g.MediaDescriptions {
|
||||||
return plain2html(d.Description)
|
return plain2html(d.Text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *media) mediaLinks() []MediaLink {
|
||||||
|
links := make([]MediaLink, 0)
|
||||||
|
for _, thumbnail := range m.MediaThumbnails {
|
||||||
|
links = append(links, MediaLink{URL: thumbnail.URL, Type: "image"})
|
||||||
|
}
|
||||||
|
for _, group := range m.MediaGroups {
|
||||||
|
for _, thumbnail := range group.MediaThumbnails {
|
||||||
|
links = append(links, MediaLink{
|
||||||
|
URL: thumbnail.URL,
|
||||||
|
Type: "image",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, content := range m.MediaContents {
|
||||||
|
if content.MediaURL != "" {
|
||||||
|
url := content.MediaURL
|
||||||
|
description := content.MediaDescription.Text
|
||||||
|
if strings.HasPrefix(content.MediaType, "image/") {
|
||||||
|
links = append(links, MediaLink{URL: url, Type: "image", Description: description})
|
||||||
|
} else if strings.HasPrefix(content.MediaType, "audio/") {
|
||||||
|
links = append(links, MediaLink{URL: url, Type: "audio", Description: description})
|
||||||
|
} else if strings.HasPrefix(content.MediaType, "video/") {
|
||||||
|
links = append(links, MediaLink{URL: url, Type: "video", Description: description})
|
||||||
|
} else if content.MediaMedium == "image" || content.MediaMedium == "audio" || content.MediaMedium == "video" {
|
||||||
|
links = append(links, MediaLink{URL: url, Type: content.MediaMedium, Description: description})
|
||||||
|
} else {
|
||||||
|
if len(content.MediaThumbnails) > 0 {
|
||||||
|
links = append(links, MediaLink{
|
||||||
|
URL: content.MediaThumbnails[0].URL,
|
||||||
|
Type: "image",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, thumbnail := range content.MediaThumbnails {
|
||||||
|
links = append(links, MediaLink{
|
||||||
|
URL: thumbnail.URL,
|
||||||
|
Type: "image",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(links) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return links
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ type Item struct {
|
|||||||
Title string
|
Title string
|
||||||
|
|
||||||
Content string
|
Content string
|
||||||
ImageURL string
|
MediaLinks []MediaLink
|
||||||
AudioURL string
|
}
|
||||||
|
|
||||||
|
type MediaLink struct {
|
||||||
|
URL string
|
||||||
|
Type string
|
||||||
|
Description string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ func ParseRSS(r io.Reader) (*Feed, error) {
|
|||||||
SiteURL: srcfeed.Link,
|
SiteURL: srcfeed.Link,
|
||||||
}
|
}
|
||||||
for _, srcitem := range srcfeed.Items {
|
for _, srcitem := range srcfeed.Items {
|
||||||
podcastURL := ""
|
mediaLinks := srcitem.mediaLinks()
|
||||||
for _, e := range srcitem.Enclosures {
|
for _, e := range srcitem.Enclosures {
|
||||||
if strings.HasPrefix(e.Type, "audio/") {
|
if strings.HasPrefix(e.Type, "audio/") {
|
||||||
podcastURL = e.URL
|
podcastURL := e.URL
|
||||||
|
|
||||||
if srcitem.OrigEnclosureLink != "" && strings.Contains(podcastURL, path.Base(srcitem.OrigEnclosureLink)) {
|
if srcitem.OrigEnclosureLink != "" && strings.Contains(podcastURL, path.Base(srcitem.OrigEnclosureLink)) {
|
||||||
podcastURL = srcitem.OrigEnclosureLink
|
podcastURL = srcitem.OrigEnclosureLink
|
||||||
}
|
}
|
||||||
|
mediaLinks = append(mediaLinks, MediaLink{URL: podcastURL, Type: "audio"})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,9 +96,8 @@ func ParseRSS(r io.Reader) (*Feed, error) {
|
|||||||
Date: dateParse(firstNonEmpty(srcitem.DublinCoreDate, srcitem.PubDate)),
|
Date: dateParse(firstNonEmpty(srcitem.DublinCoreDate, srcitem.PubDate)),
|
||||||
URL: firstNonEmpty(srcitem.OrigLink, srcitem.Link, permalink),
|
URL: firstNonEmpty(srcitem.OrigLink, srcitem.Link, permalink),
|
||||||
Title: srcitem.Title,
|
Title: srcitem.Title,
|
||||||
Content: firstNonEmpty(srcitem.ContentEncoded, srcitem.Description),
|
Content: firstNonEmpty(srcitem.ContentEncoded, srcitem.Description, srcitem.firstMediaDescription()),
|
||||||
AudioURL: podcastURL,
|
MediaLinks: mediaLinks,
|
||||||
ImageURL: srcitem.firstMediaThumbnail(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return dstfeed, nil
|
return dstfeed, nil
|
||||||
|
|||||||
@@ -75,9 +75,15 @@ func TestRSSMediaContentThumbnail(t *testing.T) {
|
|||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
`))
|
`))
|
||||||
have := feed.Items[0].ImageURL
|
if len(feed.Items[0].MediaLinks) != 1 {
|
||||||
want := "https://i.vimeocdn.com/video/1092705247_960.jpg"
|
t.Fatalf("Expected 1 media link, got %#v", feed.Items[0].MediaLinks)
|
||||||
if have != want {
|
}
|
||||||
|
have := feed.Items[0].MediaLinks[0]
|
||||||
|
want := MediaLink{
|
||||||
|
URL: "https://i.vimeocdn.com/video/1092705247_960.jpg",
|
||||||
|
Type: "image",
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, have) {
|
||||||
t.Logf("want: %#v", want)
|
t.Logf("want: %#v", want)
|
||||||
t.Logf("have: %#v", have)
|
t.Logf("have: %#v", have)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -127,9 +133,15 @@ func TestRSSPodcast(t *testing.T) {
|
|||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
`))
|
`))
|
||||||
have := feed.Items[0].AudioURL
|
if len(feed.Items[0].MediaLinks) != 1 {
|
||||||
want := "http://example.com/audio.ext"
|
t.Fatal("Invalid media links")
|
||||||
if want != have {
|
}
|
||||||
|
have := feed.Items[0].MediaLinks[0]
|
||||||
|
want := MediaLink{
|
||||||
|
URL: "http://example.com/audio.ext",
|
||||||
|
Type: "audio",
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, have) {
|
||||||
t.Logf("want: %#v", want)
|
t.Logf("want: %#v", want)
|
||||||
t.Logf("have: %#v", have)
|
t.Logf("have: %#v", have)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -147,9 +159,15 @@ func TestRSSOpusPodcast(t *testing.T) {
|
|||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
`))
|
`))
|
||||||
have := feed.Items[0].AudioURL
|
if len(feed.Items[0].MediaLinks) != 1 {
|
||||||
want := "http://example.com/audio.ext"
|
t.Fatal("Invalid media links")
|
||||||
if want != have {
|
}
|
||||||
|
have := feed.Items[0].MediaLinks[0]
|
||||||
|
want := MediaLink{
|
||||||
|
URL: "http://example.com/audio.ext",
|
||||||
|
Type: "audio",
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, have) {
|
||||||
t.Logf("want: %#v", want)
|
t.Logf("want: %#v", want)
|
||||||
t.Logf("have: %#v", have)
|
t.Logf("have: %#v", have)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -176,8 +194,9 @@ func TestRSSPodcastDuplicated(t *testing.T) {
|
|||||||
if want != have {
|
if want != have {
|
||||||
t.Fatalf("content doesn't match\nwant: %#v\nhave: %#v\n", want, have)
|
t.Fatalf("content doesn't match\nwant: %#v\nhave: %#v\n", want, have)
|
||||||
}
|
}
|
||||||
if feed.Items[0].AudioURL != "" {
|
|
||||||
t.Fatal("item.audio_url must be unset if present in the content")
|
if len(feed.Items[0].MediaLinks) != 0 {
|
||||||
|
t.Fatal("item media must be excluded if present in the content")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,8 +242,47 @@ func TestRSSIsPermalink(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := 0; i < len(want); i++ {
|
for i := 0; i < len(want); i++ {
|
||||||
if want[i] != have[i] {
|
if !reflect.DeepEqual(want, have) {
|
||||||
t.Errorf("Failed to handle isPermalink\nwant: %#v\nhave: %#v\n", want[i], have[i])
|
t.Errorf("Failed to handle isPermalink\nwant: %#v\nhave: %#v\n", want[i], have[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRSSMultipleMedia(t *testing.T) {
|
||||||
|
feed, _ := Parse(strings.NewReader(`
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
|
||||||
|
<channel>
|
||||||
|
<item>
|
||||||
|
<guid isPermaLink="true">http://example.com/posts/1</guid>
|
||||||
|
<media:content url="https://example.com/path/to/image1.png" type="image/png" fileSize="1000" medium="image">
|
||||||
|
<media:description type="plain">description 1</media:description>
|
||||||
|
</media:content>
|
||||||
|
<media:content url="https://example.com/path/to/image2.png" type="image/png" fileSize="2000" medium="image">
|
||||||
|
<media:description type="plain">description 2</media:description>
|
||||||
|
</media:content>
|
||||||
|
<media:content url="https://example.com/path/to/video1.mp4" type="video/mp4" fileSize="2000" medium="image">
|
||||||
|
<media:description type="plain">video description</media:description>
|
||||||
|
</media:content>
|
||||||
|
</item>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
|
`))
|
||||||
|
have := feed.Items
|
||||||
|
want := []Item{
|
||||||
|
{
|
||||||
|
GUID: "http://example.com/posts/1",
|
||||||
|
URL: "http://example.com/posts/1",
|
||||||
|
MediaLinks: []MediaLink{
|
||||||
|
{URL:"https://example.com/path/to/image1.png", Type:"image", Description:"description 1"},
|
||||||
|
{URL:"https://example.com/path/to/image2.png", Type:"image", Description:"description 2"},
|
||||||
|
{URL:"https://example.com/path/to/video1.mp4", Type:"video", Description:"video description"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, have) {
|
||||||
|
t.Logf("want: %#v", want)
|
||||||
|
t.Logf("have: %#v", have)
|
||||||
|
t.Fatal("invalid rss")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
func Start(s *server.Server) {
|
func Start(s *server.Server) {
|
||||||
systrayOnReady := func() {
|
systrayOnReady := func() {
|
||||||
systray.SetIcon(Icon)
|
systray.SetIcon(Icon)
|
||||||
|
systray.SetTooltip("yarr")
|
||||||
|
|
||||||
menuOpen := systray.AddMenuItem("Open", "")
|
menuOpen := systray.AddMenuItem("Open", "")
|
||||||
systray.AddSeparator()
|
systray.AddSeparator()
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ func (s *Server) handleManifest(c *router.Context) {
|
|||||||
"short_name": "yarr",
|
"short_name": "yarr",
|
||||||
"description": "yet another rss reader",
|
"description": "yet another rss reader",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"start_url": s.BasePath,
|
"start_url": "/" + strings.TrimPrefix(s.BasePath, "/"),
|
||||||
"icons": []map[string]interface{}{
|
"icons": []map[string]interface{}{
|
||||||
{
|
{
|
||||||
"src": s.BasePath + "/static/graphicarts/favicon.png",
|
"src": s.BasePath + "/static/graphicarts/favicon.png",
|
||||||
@@ -329,6 +329,9 @@ func (s *Server) handleItem(c *router.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
item.Content = sanitizer.Sanitize(item.Link, item.Content)
|
item.Content = sanitizer.Sanitize(item.Link, item.Content)
|
||||||
|
for i, link := range item.MediaLinks {
|
||||||
|
item.MediaLinks[i].Description = sanitizer.Sanitize(item.Link, link.Description)
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, item)
|
c.JSON(http.StatusOK, item)
|
||||||
} else if c.Req.Method == "PUT" {
|
} else if c.Req.Method == "PUT" {
|
||||||
@@ -371,12 +374,19 @@ func (s *Server) handleItemList(c *router.Context) {
|
|||||||
}
|
}
|
||||||
newestFirst := query.Get("oldest_first") != "true"
|
newestFirst := query.Get("oldest_first") != "true"
|
||||||
|
|
||||||
items := s.db.ListItems(filter, perPage+1, newestFirst, false)
|
items := s.db.ListItems(filter, perPage+1, newestFirst, true)
|
||||||
hasMore := false
|
hasMore := false
|
||||||
if len(items) == perPage+1 {
|
if len(items) == perPage+1 {
|
||||||
hasMore = true
|
hasMore = true
|
||||||
items = items[:perPage]
|
items = items[:perPage]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i, item := range items {
|
||||||
|
if item.Title == "" {
|
||||||
|
text := htmlutil.ExtractText(item.Content)
|
||||||
|
items[i].Title = htmlutil.TruncateText(text, 140)
|
||||||
|
}
|
||||||
|
}
|
||||||
c.JSON(http.StatusOK, map[string]interface{}{
|
c.JSON(http.StatusOK, map[string]interface{}{
|
||||||
"list": items,
|
"list": items,
|
||||||
"has_more": hasMore,
|
"has_more": hasMore,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -44,6 +45,25 @@ func (s *ItemStatus) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MediaLink struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaLinks []MediaLink
|
||||||
|
|
||||||
|
func (m *MediaLinks) Scan(src any) error {
|
||||||
|
if data, ok := src.([]byte); ok {
|
||||||
|
return json.Unmarshal(data, m)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MediaLinks) Value() (driver.Value, error) {
|
||||||
|
return json.Marshal(m)
|
||||||
|
}
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
GUID string `json:"guid"`
|
GUID string `json:"guid"`
|
||||||
@@ -53,8 +73,7 @@ type Item struct {
|
|||||||
Content string `json:"content,omitempty"`
|
Content string `json:"content,omitempty"`
|
||||||
Date time.Time `json:"date"`
|
Date time.Time `json:"date"`
|
||||||
Status ItemStatus `json:"status"`
|
Status ItemStatus `json:"status"`
|
||||||
ImageURL *string `json:"image"`
|
MediaLinks MediaLinks `json:"media_links"`
|
||||||
AudioURL *string `json:"podcast_url"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemFilter struct {
|
type ItemFilter struct {
|
||||||
@@ -94,7 +113,6 @@ func (list ItemList) Swap(i, j int) {
|
|||||||
list[i], list[j] = list[j], list[i]
|
list[i], list[j] = list[j], list[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (s *Storage) CreateItems(items []Item) bool {
|
func (s *Storage) CreateItems(items []Item) bool {
|
||||||
tx, err := s.db.Begin()
|
tx, err := s.db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -111,13 +129,17 @@ func (s *Storage) CreateItems(items []Item) bool {
|
|||||||
_, err = tx.Exec(`
|
_, err = tx.Exec(`
|
||||||
insert into items (
|
insert into items (
|
||||||
guid, feed_id, title, link, date,
|
guid, feed_id, title, link, date,
|
||||||
content, image, podcast_url,
|
content, media_links,
|
||||||
date_arrived, status
|
date_arrived, status
|
||||||
)
|
)
|
||||||
values (?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%f', ?), ?, ?, ?, ?, ?)
|
values (
|
||||||
|
?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%f', ?),
|
||||||
|
?, ?,
|
||||||
|
?, ?
|
||||||
|
)
|
||||||
on conflict (feed_id, guid) do nothing`,
|
on conflict (feed_id, guid) do nothing`,
|
||||||
item.GUID, item.FeedId, item.Title, item.Link, item.Date,
|
item.GUID, item.FeedId, item.Title, item.Link, item.Date,
|
||||||
item.Content, item.ImageURL, item.AudioURL,
|
item.Content, item.MediaLinks,
|
||||||
now, UNREAD,
|
now, UNREAD,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -232,7 +254,7 @@ func (s *Storage) ListItems(filter ItemFilter, limit int, newestFirst bool, with
|
|||||||
order = "i.id desc"
|
order = "i.id desc"
|
||||||
}
|
}
|
||||||
|
|
||||||
selectCols := "i.id, i.guid, i.feed_id, i.title, i.link, i.date, i.status, i.image, i.podcast_url"
|
selectCols := "i.id, i.guid, i.feed_id, i.title, i.link, i.date, i.status, i.media_links"
|
||||||
if withContent {
|
if withContent {
|
||||||
selectCols += ", i.content"
|
selectCols += ", i.content"
|
||||||
} else {
|
} else {
|
||||||
@@ -255,7 +277,7 @@ func (s *Storage) ListItems(filter ItemFilter, limit int, newestFirst bool, with
|
|||||||
err = rows.Scan(
|
err = rows.Scan(
|
||||||
&x.Id, &x.GUID, &x.FeedId,
|
&x.Id, &x.GUID, &x.FeedId,
|
||||||
&x.Title, &x.Link, &x.Date,
|
&x.Title, &x.Link, &x.Date,
|
||||||
&x.Status, &x.ImageURL, &x.AudioURL, &x.Content,
|
&x.Status, &x.MediaLinks, &x.Content,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
@@ -271,12 +293,12 @@ func (s *Storage) GetItem(id int64) *Item {
|
|||||||
err := s.db.QueryRow(`
|
err := s.db.QueryRow(`
|
||||||
select
|
select
|
||||||
i.id, i.guid, i.feed_id, i.title, i.link, i.content,
|
i.id, i.guid, i.feed_id, i.title, i.link, i.content,
|
||||||
i.date, i.status, i.image, i.podcast_url
|
i.date, i.status, i.media_links
|
||||||
from items i
|
from items i
|
||||||
where i.id = ?
|
where i.id = ?
|
||||||
`, id).Scan(
|
`, id).Scan(
|
||||||
&i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content,
|
&i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content,
|
||||||
&i.Date, &i.Status, &i.ImageURL, &i.AudioURL,
|
&i.Date, &i.Status, &i.MediaLinks,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
|||||||
@@ -77,12 +77,12 @@ func getItem(db *Storage, guid string) *Item {
|
|||||||
err := db.db.QueryRow(`
|
err := db.db.QueryRow(`
|
||||||
select
|
select
|
||||||
i.id, i.guid, i.feed_id, i.title, i.link, i.content,
|
i.id, i.guid, i.feed_id, i.title, i.link, i.content,
|
||||||
i.date, i.status, i.image, i.podcast_url
|
i.date, i.status, i.media_links
|
||||||
from items i
|
from items i
|
||||||
where i.guid = ?
|
where i.guid = ?
|
||||||
`, guid).Scan(
|
`, guid).Scan(
|
||||||
&i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content,
|
&i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content,
|
||||||
&i.Date, &i.Status, &i.ImageURL, &i.AudioURL,
|
&i.Date, &i.Status, &i.MediaLinks,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|||||||
@@ -16,13 +16,17 @@ var migrations = []func(*sql.Tx) error{
|
|||||||
m06_fill_missing_dates,
|
m06_fill_missing_dates,
|
||||||
m07_add_feed_size,
|
m07_add_feed_size,
|
||||||
m08_normalize_datetime,
|
m08_normalize_datetime,
|
||||||
|
m09_change_item_index,
|
||||||
|
m10_add_item_medialinks,
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxVersion = int64(len(migrations))
|
var maxVersion = int64(len(migrations))
|
||||||
|
|
||||||
func migrate(db *sql.DB) error {
|
func migrate(db *sql.DB) error {
|
||||||
var version int64
|
var version int64
|
||||||
db.QueryRow("pragma user_version").Scan(&version)
|
if err := db.QueryRow("pragma user_version").Scan(&version); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if version >= maxVersion {
|
if version >= maxVersion {
|
||||||
return nil
|
return nil
|
||||||
@@ -294,3 +298,37 @@ func m08_normalize_datetime(tx *sql.Tx) error {
|
|||||||
_, err = tx.Exec(`update items set date = strftime('%Y-%m-%d %H:%M:%f', date);`)
|
_, err = tx.Exec(`update items set date = strftime('%Y-%m-%d %H:%M:%f', date);`)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func m09_change_item_index(tx *sql.Tx) error {
|
||||||
|
sql := `
|
||||||
|
drop index if exists idx_item_status;
|
||||||
|
create index if not exists idx_item__date_id_status on items(date,id,status);
|
||||||
|
`
|
||||||
|
_, err := tx.Exec(sql)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func m10_add_item_medialinks(tx *sql.Tx) error {
|
||||||
|
sql := `
|
||||||
|
alter table items add column media_links blob;
|
||||||
|
update items set media_links =
|
||||||
|
iif(
|
||||||
|
coalesce(image, '') != '' and coalesce(podcast_url, '') != '',
|
||||||
|
json_array(json_object('type', 'image', 'url', image), json_object('type', 'audio', 'url', podcast_url)),
|
||||||
|
iif(
|
||||||
|
coalesce(image, '') != '',
|
||||||
|
json_array(json_object('type', 'image', 'url', image)),
|
||||||
|
iif(
|
||||||
|
coalesce(podcast_url, '') != '',
|
||||||
|
json_array(json_object('type', 'audio', 'url', podcast_url)),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table items drop column image;
|
||||||
|
alter table items drop column podcast_url;
|
||||||
|
`
|
||||||
|
_, err := tx.Exec(sql)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -10,14 +13,17 @@ type Storage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(path string) (*Storage, error) {
|
func New(path string) (*Storage, error) {
|
||||||
|
if pos := strings.IndexRune(path, '?'); pos == -1 {
|
||||||
|
params := "_journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared"
|
||||||
|
log.Printf("opening db with params: %s", params)
|
||||||
|
path = path + "?" + params
|
||||||
|
}
|
||||||
|
|
||||||
db, err := sql.Open("sqlite3", path)
|
db, err := sql.Open("sqlite3", path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: https://foxcpp.dev/articles/the-right-way-to-use-go-sqlite3
|
|
||||||
db.SetMaxOpenConns(1)
|
|
||||||
|
|
||||||
if err = migrate(db); err != nil {
|
if err = migrate(db); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build darwin || windows
|
||||||
// +build darwin windows
|
// +build darwin windows
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build never
|
||||||
// +build never
|
// +build never
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build darwin
|
||||||
// +build darwin
|
// +build darwin
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ func (c *Client) getConditional(url, lastModified, etag string) (*http.Response,
|
|||||||
|
|
||||||
var client *Client
|
var client *Client
|
||||||
|
|
||||||
|
func SetVersion(num string) {
|
||||||
|
client.userAgent = "Yarr/" + num
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
|||||||
@@ -143,13 +143,9 @@ func ConvertItems(items []parser.Item, feed storage.Feed) []storage.Item {
|
|||||||
result := make([]storage.Item, len(items))
|
result := make([]storage.Item, len(items))
|
||||||
for i, item := range items {
|
for i, item := range items {
|
||||||
item := item
|
item := item
|
||||||
var audioURL *string = nil
|
mediaLinks := make(storage.MediaLinks, 0)
|
||||||
if item.AudioURL != "" {
|
for _, link := range item.MediaLinks {
|
||||||
audioURL = &item.AudioURL
|
mediaLinks = append(mediaLinks, storage.MediaLink(link))
|
||||||
}
|
|
||||||
var imageURL *string = nil
|
|
||||||
if item.ImageURL != "" {
|
|
||||||
imageURL = &item.ImageURL
|
|
||||||
}
|
}
|
||||||
result[i] = storage.Item{
|
result[i] = storage.Item{
|
||||||
GUID: item.GUID,
|
GUID: item.GUID,
|
||||||
@@ -159,8 +155,7 @@ func ConvertItems(items []parser.Item, feed storage.Feed) []storage.Item {
|
|||||||
Content: item.Content,
|
Content: item.Content,
|
||||||
Date: item.Date,
|
Date: item.Date,
|
||||||
Status: storage.UNREAD,
|
Status: storage.UNREAD,
|
||||||
ImageURL: imageURL,
|
MediaLinks: mediaLinks,
|
||||||
AudioURL: audioURL,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|||||||
4
vendor/golang.org/x/net/LICENSE
generated
vendored
4
vendor/golang.org/x/net/LICENSE
generated
vendored
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
|
|||||||
copyright notice, this list of conditions and the following disclaimer
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
in the documentation and/or other materials provided with the
|
in the documentation and/or other materials provided with the
|
||||||
distribution.
|
distribution.
|
||||||
* Neither the name of Google Inc. nor the names of its
|
* Neither the name of Google LLC nor the names of its
|
||||||
contributors may be used to endorse or promote products derived from
|
contributors may be used to endorse or promote products derived from
|
||||||
this software without specific prior written permission.
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
|||||||
9
vendor/golang.org/x/net/html/doc.go
generated
vendored
9
vendor/golang.org/x/net/html/doc.go
generated
vendored
@@ -78,16 +78,11 @@ example, to process each anchor node in depth-first order:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
var f func(*html.Node)
|
for n := range doc.Descendants() {
|
||||||
f = func(n *html.Node) {
|
|
||||||
if n.Type == html.ElementNode && n.Data == "a" {
|
if n.Type == html.ElementNode && n.Data == "a" {
|
||||||
// Do something with n...
|
// Do something with n...
|
||||||
}
|
}
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
f(c)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
f(doc)
|
|
||||||
|
|
||||||
The relevant specifications include:
|
The relevant specifications include:
|
||||||
https://html.spec.whatwg.org/multipage/syntax.html and
|
https://html.spec.whatwg.org/multipage/syntax.html and
|
||||||
@@ -104,7 +99,7 @@ tokenization, and tokenization and tree construction stages of the WHATWG HTML
|
|||||||
parsing specification respectively. While the tokenizer parses and normalizes
|
parsing specification respectively. While the tokenizer parses and normalizes
|
||||||
individual HTML tokens, only the parser constructs the DOM tree from the
|
individual HTML tokens, only the parser constructs the DOM tree from the
|
||||||
tokenized HTML, as described in the tree construction stage of the
|
tokenized HTML, as described in the tree construction stage of the
|
||||||
specification, dynamically modifying or extending the docuemnt's DOM tree.
|
specification, dynamically modifying or extending the document's DOM tree.
|
||||||
|
|
||||||
If your use case requires semantically well-formed HTML documents, as defined by
|
If your use case requires semantically well-formed HTML documents, as defined by
|
||||||
the WHATWG specification, the parser should be used rather than the tokenizer.
|
the WHATWG specification, the parser should be used rather than the tokenizer.
|
||||||
|
|||||||
2
vendor/golang.org/x/net/html/doctype.go
generated
vendored
2
vendor/golang.org/x/net/html/doctype.go
generated
vendored
@@ -87,7 +87,7 @@ func parseDoctype(s string) (n *Node, quirks bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" &&
|
if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" &&
|
||||||
strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" {
|
strings.EqualFold(lastAttr.Val, "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") {
|
||||||
quirks = true
|
quirks = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
vendor/golang.org/x/net/html/foreign.go
generated
vendored
3
vendor/golang.org/x/net/html/foreign.go
generated
vendored
@@ -40,8 +40,7 @@ func htmlIntegrationPoint(n *Node) bool {
|
|||||||
if n.Data == "annotation-xml" {
|
if n.Data == "annotation-xml" {
|
||||||
for _, a := range n.Attr {
|
for _, a := range n.Attr {
|
||||||
if a.Key == "encoding" {
|
if a.Key == "encoding" {
|
||||||
val := strings.ToLower(a.Val)
|
if strings.EqualFold(a.Val, "text/html") || strings.EqualFold(a.Val, "application/xhtml+xml") {
|
||||||
if val == "text/html" || val == "application/xhtml+xml" {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
vendor/golang.org/x/net/html/iter.go
generated
vendored
Normal file
56
vendor/golang.org/x/net/html/iter.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.23
|
||||||
|
|
||||||
|
package html
|
||||||
|
|
||||||
|
import "iter"
|
||||||
|
|
||||||
|
// Ancestors returns an iterator over the ancestors of n, starting with n.Parent.
|
||||||
|
//
|
||||||
|
// Mutating a Node or its parents while iterating may have unexpected results.
|
||||||
|
func (n *Node) Ancestors() iter.Seq[*Node] {
|
||||||
|
_ = n.Parent // eager nil check
|
||||||
|
|
||||||
|
return func(yield func(*Node) bool) {
|
||||||
|
for p := n.Parent; p != nil && yield(p); p = p.Parent {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChildNodes returns an iterator over the immediate children of n,
|
||||||
|
// starting with n.FirstChild.
|
||||||
|
//
|
||||||
|
// Mutating a Node or its children while iterating may have unexpected results.
|
||||||
|
func (n *Node) ChildNodes() iter.Seq[*Node] {
|
||||||
|
_ = n.FirstChild // eager nil check
|
||||||
|
|
||||||
|
return func(yield func(*Node) bool) {
|
||||||
|
for c := n.FirstChild; c != nil && yield(c); c = c.NextSibling {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Descendants returns an iterator over all nodes recursively beneath
|
||||||
|
// n, excluding n itself. Nodes are visited in depth-first preorder.
|
||||||
|
//
|
||||||
|
// Mutating a Node or its descendants while iterating may have unexpected results.
|
||||||
|
func (n *Node) Descendants() iter.Seq[*Node] {
|
||||||
|
_ = n.FirstChild // eager nil check
|
||||||
|
|
||||||
|
return func(yield func(*Node) bool) {
|
||||||
|
n.descendants(yield)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) descendants(yield func(*Node) bool) bool {
|
||||||
|
for c := range n.ChildNodes() {
|
||||||
|
if !yield(c) || !c.descendants(yield) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
4
vendor/golang.org/x/net/html/node.go
generated
vendored
4
vendor/golang.org/x/net/html/node.go
generated
vendored
@@ -38,6 +38,10 @@ var scopeMarker = Node{Type: scopeMarkerNode}
|
|||||||
// that it looks like "a<b" rather than "a<b". For element nodes, DataAtom
|
// that it looks like "a<b" rather than "a<b". For element nodes, DataAtom
|
||||||
// is the atom for Data, or zero if Data is not a known tag name.
|
// is the atom for Data, or zero if Data is not a known tag name.
|
||||||
//
|
//
|
||||||
|
// Node trees may be navigated using the link fields (Parent,
|
||||||
|
// FirstChild, and so on) or a range loop over iterators such as
|
||||||
|
// [Node.Descendants].
|
||||||
|
//
|
||||||
// An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace.
|
// An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace.
|
||||||
// Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and
|
// Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and
|
||||||
// "svg" is short for "http://www.w3.org/2000/svg".
|
// "svg" is short for "http://www.w3.org/2000/svg".
|
||||||
|
|||||||
8
vendor/golang.org/x/net/html/parse.go
generated
vendored
8
vendor/golang.org/x/net/html/parse.go
generated
vendored
@@ -840,6 +840,10 @@ func afterHeadIM(p *parser) bool {
|
|||||||
|
|
||||||
p.parseImpliedToken(StartTagToken, a.Body, a.Body.String())
|
p.parseImpliedToken(StartTagToken, a.Body, a.Body.String())
|
||||||
p.framesetOK = true
|
p.framesetOK = true
|
||||||
|
if p.tok.Type == ErrorToken {
|
||||||
|
// Stop parsing.
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,7 +1035,7 @@ func inBodyIM(p *parser) bool {
|
|||||||
if p.tok.DataAtom == a.Input {
|
if p.tok.DataAtom == a.Input {
|
||||||
for _, t := range p.tok.Attr {
|
for _, t := range p.tok.Attr {
|
||||||
if t.Key == "type" {
|
if t.Key == "type" {
|
||||||
if strings.ToLower(t.Val) == "hidden" {
|
if strings.EqualFold(t.Val, "hidden") {
|
||||||
// Skip setting framesetOK = false
|
// Skip setting framesetOK = false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -1459,7 +1463,7 @@ func inTableIM(p *parser) bool {
|
|||||||
return inHeadIM(p)
|
return inHeadIM(p)
|
||||||
case a.Input:
|
case a.Input:
|
||||||
for _, t := range p.tok.Attr {
|
for _, t := range p.tok.Attr {
|
||||||
if t.Key == "type" && strings.ToLower(t.Val) == "hidden" {
|
if t.Key == "type" && strings.EqualFold(t.Val, "hidden") {
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.oe.pop()
|
p.oe.pop()
|
||||||
return true
|
return true
|
||||||
|
|||||||
12
vendor/golang.org/x/net/html/token.go
generated
vendored
12
vendor/golang.org/x/net/html/token.go
generated
vendored
@@ -910,9 +910,6 @@ func (z *Tokenizer) readTagAttrKey() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch c {
|
switch c {
|
||||||
case ' ', '\n', '\r', '\t', '\f', '/':
|
|
||||||
z.pendingAttr[0].end = z.raw.end - 1
|
|
||||||
return
|
|
||||||
case '=':
|
case '=':
|
||||||
if z.pendingAttr[0].start+1 == z.raw.end {
|
if z.pendingAttr[0].start+1 == z.raw.end {
|
||||||
// WHATWG 13.2.5.32, if we see an equals sign before the attribute name
|
// WHATWG 13.2.5.32, if we see an equals sign before the attribute name
|
||||||
@@ -920,7 +917,9 @@ func (z *Tokenizer) readTagAttrKey() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case '>':
|
case ' ', '\n', '\r', '\t', '\f', '/', '>':
|
||||||
|
// WHATWG 13.2.5.33 Attribute name state
|
||||||
|
// We need to reconsume the char in the after attribute name state to support the / character
|
||||||
z.raw.end--
|
z.raw.end--
|
||||||
z.pendingAttr[0].end = z.raw.end
|
z.pendingAttr[0].end = z.raw.end
|
||||||
return
|
return
|
||||||
@@ -939,6 +938,11 @@ func (z *Tokenizer) readTagAttrVal() {
|
|||||||
if z.err != nil {
|
if z.err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if c == '/' {
|
||||||
|
// WHATWG 13.2.5.34 After attribute name state
|
||||||
|
// U+002F SOLIDUS (/) - Switch to the self-closing start tag state.
|
||||||
|
return
|
||||||
|
}
|
||||||
if c != '=' {
|
if c != '=' {
|
||||||
z.raw.end--
|
z.raw.end--
|
||||||
return
|
return
|
||||||
|
|||||||
4
vendor/golang.org/x/sys/LICENSE
generated
vendored
4
vendor/golang.org/x/sys/LICENSE
generated
vendored
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
|
|||||||
copyright notice, this list of conditions and the following disclaimer
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
in the documentation and/or other materials provided with the
|
in the documentation and/or other materials provided with the
|
||||||
distribution.
|
distribution.
|
||||||
* Neither the name of Google Inc. nor the names of its
|
* Neither the name of Google LLC nor the names of its
|
||||||
contributors may be used to endorse or promote products derived from
|
contributors may be used to endorse or promote products derived from
|
||||||
this software without specific prior written permission.
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
|||||||
3
vendor/golang.org/x/sys/windows/aliases.go
generated
vendored
3
vendor/golang.org/x/sys/windows/aliases.go
generated
vendored
@@ -2,8 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build windows && go1.9
|
//go:build windows
|
||||||
// +build windows,go1.9
|
|
||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
|||||||
2
vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
2
vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
@@ -65,7 +65,7 @@ func LoadDLL(name string) (dll *DLL, err error) {
|
|||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustLoadDLL is like LoadDLL but panics if load operation failes.
|
// MustLoadDLL is like LoadDLL but panics if load operation fails.
|
||||||
func MustLoadDLL(name string) *DLL {
|
func MustLoadDLL(name string) *DLL {
|
||||||
d, e := LoadDLL(name)
|
d, e := LoadDLL(name)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
|||||||
9
vendor/golang.org/x/sys/windows/empty.s
generated
vendored
9
vendor/golang.org/x/sys/windows/empty.s
generated
vendored
@@ -1,9 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build !go1.12
|
|
||||||
// +build !go1.12
|
|
||||||
|
|
||||||
// This file is here to allow bodyless functions with go:linkname for Go 1.11
|
|
||||||
// and earlier (see https://golang.org/issue/23311).
|
|
||||||
17
vendor/golang.org/x/sys/windows/env_windows.go
generated
vendored
17
vendor/golang.org/x/sys/windows/env_windows.go
generated
vendored
@@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer DestroyEnvironmentBlock(block)
|
defer DestroyEnvironmentBlock(block)
|
||||||
blockp := unsafe.Pointer(block)
|
size := unsafe.Sizeof(*block)
|
||||||
for {
|
for *block != 0 {
|
||||||
entry := UTF16PtrToString((*uint16)(blockp))
|
// find NUL terminator
|
||||||
if len(entry) == 0 {
|
end := unsafe.Pointer(block)
|
||||||
break
|
for *(*uint16)(end) != 0 {
|
||||||
|
end = unsafe.Add(end, size)
|
||||||
}
|
}
|
||||||
env = append(env, entry)
|
|
||||||
blockp = unsafe.Add(blockp, 2*(len(entry)+1))
|
entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size)
|
||||||
|
env = append(env, UTF16ToString(entry))
|
||||||
|
block = (*uint16)(unsafe.Add(end, size))
|
||||||
}
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|||||||
1
vendor/golang.org/x/sys/windows/eventlog.go
generated
vendored
1
vendor/golang.org/x/sys/windows/eventlog.go
generated
vendored
@@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
|||||||
1
vendor/golang.org/x/sys/windows/mksyscall.go
generated
vendored
1
vendor/golang.org/x/sys/windows/mksyscall.go
generated
vendored
@@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build generate
|
//go:build generate
|
||||||
// +build generate
|
|
||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
|||||||
1
vendor/golang.org/x/sys/windows/race.go
generated
vendored
1
vendor/golang.org/x/sys/windows/race.go
generated
vendored
@@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build windows && race
|
//go:build windows && race
|
||||||
// +build windows,race
|
|
||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
|||||||
1
vendor/golang.org/x/sys/windows/race0.go
generated
vendored
1
vendor/golang.org/x/sys/windows/race0.go
generated
vendored
@@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build windows && !race
|
//go:build windows && !race
|
||||||
// +build windows,!race
|
|
||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
|||||||
25
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
25
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
@@ -68,6 +68,7 @@ type UserInfo10 struct {
|
|||||||
//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
|
//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
|
||||||
//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
|
//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
|
||||||
//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
|
//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
|
||||||
|
//sys NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) = netapi32.NetUserEnum
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// do not reorder
|
// do not reorder
|
||||||
@@ -893,7 +894,7 @@ type ACL struct {
|
|||||||
aclRevision byte
|
aclRevision byte
|
||||||
sbz1 byte
|
sbz1 byte
|
||||||
aclSize uint16
|
aclSize uint16
|
||||||
aceCount uint16
|
AceCount uint16
|
||||||
sbz2 uint16
|
sbz2 uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1086,6 +1087,27 @@ type EXPLICIT_ACCESS struct {
|
|||||||
Trustee TRUSTEE
|
Trustee TRUSTEE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
|
||||||
|
type ACE_HEADER struct {
|
||||||
|
AceType uint8
|
||||||
|
AceFlags uint8
|
||||||
|
AceSize uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
|
||||||
|
type ACCESS_ALLOWED_ACE struct {
|
||||||
|
Header ACE_HEADER
|
||||||
|
Mask ACCESS_MASK
|
||||||
|
SidStart uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Constants for AceType
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
|
||||||
|
ACCESS_ALLOWED_ACE_TYPE = 0
|
||||||
|
ACCESS_DENIED_ACE_TYPE = 1
|
||||||
|
)
|
||||||
|
|
||||||
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
|
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
|
||||||
type TrusteeValue uintptr
|
type TrusteeValue uintptr
|
||||||
|
|
||||||
@@ -1157,6 +1179,7 @@ type OBJECTS_AND_NAME struct {
|
|||||||
//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
|
//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
|
||||||
|
|
||||||
//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
|
//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
|
||||||
|
//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) = advapi32.GetAce
|
||||||
|
|
||||||
// Control returns the security descriptor control bits.
|
// Control returns the security descriptor control bits.
|
||||||
func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
|
func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
|
||||||
|
|||||||
1
vendor/golang.org/x/sys/windows/service.go
generated
vendored
1
vendor/golang.org/x/sys/windows/service.go
generated
vendored
@@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
|||||||
1
vendor/golang.org/x/sys/windows/str.go
generated
vendored
1
vendor/golang.org/x/sys/windows/str.go
generated
vendored
@@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
|||||||
1
vendor/golang.org/x/sys/windows/syscall.go
generated
vendored
1
vendor/golang.org/x/sys/windows/syscall.go
generated
vendored
@@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
|
||||||
|
|
||||||
// Package windows contains an interface to the low-level operating system
|
// Package windows contains an interface to the low-level operating system
|
||||||
// primitives. OS details vary depending on the underlying system, and
|
// primitives. OS details vary depending on the underlying system, and
|
||||||
|
|||||||
144
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
144
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
@@ -17,8 +17,10 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handle uintptr
|
type (
|
||||||
type HWND uintptr
|
Handle uintptr
|
||||||
|
HWND uintptr
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
InvalidHandle = ^Handle(0)
|
InvalidHandle = ^Handle(0)
|
||||||
@@ -125,8 +127,7 @@ func UTF16PtrToString(p *uint16) string {
|
|||||||
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
|
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
|
||||||
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
|
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
|
||||||
}
|
}
|
||||||
|
return UTF16ToString(unsafe.Slice(p, n))
|
||||||
return string(utf16.Decode(unsafe.Slice(p, n)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Getpagesize() int { return 4096 }
|
func Getpagesize() int { return 4096 }
|
||||||
@@ -155,6 +156,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
|
//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
|
||||||
//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW
|
//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW
|
||||||
//sys SetDefaultDllDirectories(directoryFlags uint32) (err error)
|
//sys SetDefaultDllDirectories(directoryFlags uint32) (err error)
|
||||||
|
//sys AddDllDirectory(path *uint16) (cookie uintptr, err error) = kernel32.AddDllDirectory
|
||||||
|
//sys RemoveDllDirectory(cookie uintptr) (err error) = kernel32.RemoveDllDirectory
|
||||||
//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW
|
//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW
|
||||||
//sys GetVersion() (ver uint32, err error)
|
//sys GetVersion() (ver uint32, err error)
|
||||||
//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
|
//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
|
||||||
@@ -164,6 +167,9 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
|
//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
|
||||||
//sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW
|
//sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW
|
||||||
//sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error)
|
//sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error)
|
||||||
|
//sys DisconnectNamedPipe(pipe Handle) (err error)
|
||||||
|
//sys GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error)
|
||||||
|
//sys GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error)
|
||||||
//sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error)
|
//sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error)
|
||||||
//sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
//sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||||
//sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState
|
//sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState
|
||||||
@@ -192,6 +198,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
|
//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
|
||||||
//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
|
//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
|
||||||
//sys SetEndOfFile(handle Handle) (err error)
|
//sys SetEndOfFile(handle Handle) (err error)
|
||||||
|
//sys SetFileValidData(handle Handle, validDataLength int64) (err error)
|
||||||
//sys GetSystemTimeAsFileTime(time *Filetime)
|
//sys GetSystemTimeAsFileTime(time *Filetime)
|
||||||
//sys GetSystemTimePreciseAsFileTime(time *Filetime)
|
//sys GetSystemTimePreciseAsFileTime(time *Filetime)
|
||||||
//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
|
//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
|
||||||
@@ -208,6 +215,10 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error)
|
//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error)
|
||||||
//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW
|
//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW
|
||||||
//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId
|
//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId
|
||||||
|
//sys LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) [failretval==0] = user32.LoadKeyboardLayoutW
|
||||||
|
//sys UnloadKeyboardLayout(hkl Handle) (err error) = user32.UnloadKeyboardLayout
|
||||||
|
//sys GetKeyboardLayout(tid uint32) (hkl Handle) = user32.GetKeyboardLayout
|
||||||
|
//sys ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) = user32.ToUnicodeEx
|
||||||
//sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow
|
//sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow
|
||||||
//sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW
|
//sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW
|
||||||
//sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx
|
//sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx
|
||||||
@@ -233,6 +244,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
|
//sys CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
|
||||||
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
|
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
|
||||||
//sys getTickCount64() (ms uint64) = kernel32.GetTickCount64
|
//sys getTickCount64() (ms uint64) = kernel32.GetTickCount64
|
||||||
|
//sys GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
|
||||||
//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
|
//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
|
||||||
//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
|
//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
|
||||||
//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
|
//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
|
||||||
@@ -303,6 +315,10 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
|
//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
|
||||||
//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
|
//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
|
||||||
//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition
|
//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition
|
||||||
|
//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP
|
||||||
|
//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP
|
||||||
|
//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP
|
||||||
|
//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP
|
||||||
//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
|
//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
|
||||||
//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
|
//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
|
||||||
//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
|
//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
|
||||||
@@ -345,8 +361,19 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost
|
//sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost
|
||||||
//sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32)
|
//sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32)
|
||||||
//sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error)
|
//sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error)
|
||||||
|
//sys ClearCommBreak(handle Handle) (err error)
|
||||||
|
//sys ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error)
|
||||||
|
//sys EscapeCommFunction(handle Handle, dwFunc uint32) (err error)
|
||||||
|
//sys GetCommState(handle Handle, lpDCB *DCB) (err error)
|
||||||
|
//sys GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error)
|
||||||
//sys GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
|
//sys GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
|
||||||
|
//sys PurgeComm(handle Handle, dwFlags uint32) (err error)
|
||||||
|
//sys SetCommBreak(handle Handle) (err error)
|
||||||
|
//sys SetCommMask(handle Handle, dwEvtMask uint32) (err error)
|
||||||
|
//sys SetCommState(handle Handle, lpDCB *DCB) (err error)
|
||||||
//sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
|
//sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
|
||||||
|
//sys SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error)
|
||||||
|
//sys WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error)
|
||||||
//sys GetActiveProcessorCount(groupNumber uint16) (ret uint32)
|
//sys GetActiveProcessorCount(groupNumber uint16) (ret uint32)
|
||||||
//sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32)
|
//sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32)
|
||||||
//sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows
|
//sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows
|
||||||
@@ -700,20 +727,12 @@ func DurationSinceBoot() time.Duration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Ftruncate(fd Handle, length int64) (err error) {
|
func Ftruncate(fd Handle, length int64) (err error) {
|
||||||
curoffset, e := Seek(fd, 0, 1)
|
type _FILE_END_OF_FILE_INFO struct {
|
||||||
if e != nil {
|
EndOfFile int64
|
||||||
return e
|
|
||||||
}
|
}
|
||||||
defer Seek(fd, curoffset, 0)
|
var info _FILE_END_OF_FILE_INFO
|
||||||
_, e = Seek(fd, length, 0)
|
info.EndOfFile = length
|
||||||
if e != nil {
|
return SetFileInformationByHandle(fd, FileEndOfFileInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info)))
|
||||||
return e
|
|
||||||
}
|
|
||||||
e = SetEndOfFile(fd)
|
|
||||||
if e != nil {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Gettimeofday(tv *Timeval) (err error) {
|
func Gettimeofday(tv *Timeval) (err error) {
|
||||||
@@ -869,6 +888,11 @@ const socket_error = uintptr(^uint32(0))
|
|||||||
//sys GetACP() (acp uint32) = kernel32.GetACP
|
//sys GetACP() (acp uint32) = kernel32.GetACP
|
||||||
//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
|
//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
|
||||||
//sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx
|
//sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx
|
||||||
|
//sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex
|
||||||
|
//sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry
|
||||||
|
//sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange
|
||||||
|
//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange
|
||||||
|
//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2
|
||||||
|
|
||||||
// For testing: clients can set this flag to force
|
// For testing: clients can set this flag to force
|
||||||
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
||||||
@@ -969,7 +993,8 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
|
|||||||
if n > 0 {
|
if n > 0 {
|
||||||
sl += int32(n) + 1
|
sl += int32(n) + 1
|
||||||
}
|
}
|
||||||
if sa.raw.Path[0] == '@' {
|
if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
|
||||||
|
// Check sl > 3 so we don't change unnamed socket behavior.
|
||||||
sa.raw.Path[0] = 0
|
sa.raw.Path[0] = 0
|
||||||
// Don't count trailing NUL for abstract address.
|
// Don't count trailing NUL for abstract address.
|
||||||
sl--
|
sl--
|
||||||
@@ -1352,9 +1377,11 @@ func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
|
|||||||
func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
|
func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
|
||||||
return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
|
return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
|
func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
|
||||||
return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
|
return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
|
func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
|
||||||
return syscall.EWINDOWS
|
return syscall.EWINDOWS
|
||||||
}
|
}
|
||||||
@@ -1657,13 +1684,16 @@ func (s NTStatus) Error() string {
|
|||||||
// do not use NTUnicodeString, and instead UTF16PtrFromString should be used for
|
// do not use NTUnicodeString, and instead UTF16PtrFromString should be used for
|
||||||
// the more common *uint16 string type.
|
// the more common *uint16 string type.
|
||||||
func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
|
func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
|
||||||
var u NTUnicodeString
|
s16, err := UTF16FromString(s)
|
||||||
s16, err := UTF16PtrFromString(s)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
RtlInitUnicodeString(&u, s16)
|
n := uint16(len(s16) * 2)
|
||||||
return &u, nil
|
return &NTUnicodeString{
|
||||||
|
Length: n - 2, // subtract 2 bytes for the NULL terminator
|
||||||
|
MaximumLength: n,
|
||||||
|
Buffer: &s16[0],
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
|
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
|
||||||
@@ -1830,3 +1860,73 @@ func ResizePseudoConsole(pconsole Handle, size Coord) error {
|
|||||||
// accept arguments that can be casted to uintptr, and Coord can't.
|
// accept arguments that can be casted to uintptr, and Coord can't.
|
||||||
return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size))))
|
return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DCB constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb.
|
||||||
|
const (
|
||||||
|
CBR_110 = 110
|
||||||
|
CBR_300 = 300
|
||||||
|
CBR_600 = 600
|
||||||
|
CBR_1200 = 1200
|
||||||
|
CBR_2400 = 2400
|
||||||
|
CBR_4800 = 4800
|
||||||
|
CBR_9600 = 9600
|
||||||
|
CBR_14400 = 14400
|
||||||
|
CBR_19200 = 19200
|
||||||
|
CBR_38400 = 38400
|
||||||
|
CBR_57600 = 57600
|
||||||
|
CBR_115200 = 115200
|
||||||
|
CBR_128000 = 128000
|
||||||
|
CBR_256000 = 256000
|
||||||
|
|
||||||
|
DTR_CONTROL_DISABLE = 0x00000000
|
||||||
|
DTR_CONTROL_ENABLE = 0x00000010
|
||||||
|
DTR_CONTROL_HANDSHAKE = 0x00000020
|
||||||
|
|
||||||
|
RTS_CONTROL_DISABLE = 0x00000000
|
||||||
|
RTS_CONTROL_ENABLE = 0x00001000
|
||||||
|
RTS_CONTROL_HANDSHAKE = 0x00002000
|
||||||
|
RTS_CONTROL_TOGGLE = 0x00003000
|
||||||
|
|
||||||
|
NOPARITY = 0
|
||||||
|
ODDPARITY = 1
|
||||||
|
EVENPARITY = 2
|
||||||
|
MARKPARITY = 3
|
||||||
|
SPACEPARITY = 4
|
||||||
|
|
||||||
|
ONESTOPBIT = 0
|
||||||
|
ONE5STOPBITS = 1
|
||||||
|
TWOSTOPBITS = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// EscapeCommFunction constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-escapecommfunction.
|
||||||
|
const (
|
||||||
|
SETXOFF = 1
|
||||||
|
SETXON = 2
|
||||||
|
SETRTS = 3
|
||||||
|
CLRRTS = 4
|
||||||
|
SETDTR = 5
|
||||||
|
CLRDTR = 6
|
||||||
|
SETBREAK = 8
|
||||||
|
CLRBREAK = 9
|
||||||
|
)
|
||||||
|
|
||||||
|
// PurgeComm constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-purgecomm.
|
||||||
|
const (
|
||||||
|
PURGE_TXABORT = 0x0001
|
||||||
|
PURGE_RXABORT = 0x0002
|
||||||
|
PURGE_TXCLEAR = 0x0004
|
||||||
|
PURGE_RXCLEAR = 0x0008
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetCommMask constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcommmask.
|
||||||
|
const (
|
||||||
|
EV_RXCHAR = 0x0001
|
||||||
|
EV_RXFLAG = 0x0002
|
||||||
|
EV_TXEMPTY = 0x0004
|
||||||
|
EV_CTS = 0x0008
|
||||||
|
EV_DSR = 0x0010
|
||||||
|
EV_RLSD = 0x0020
|
||||||
|
EV_BREAK = 0x0040
|
||||||
|
EV_ERR = 0x0080
|
||||||
|
EV_RING = 0x0100
|
||||||
|
)
|
||||||
|
|||||||
249
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
249
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
@@ -176,6 +176,7 @@ const (
|
|||||||
WAIT_FAILED = 0xFFFFFFFF
|
WAIT_FAILED = 0xFFFFFFFF
|
||||||
|
|
||||||
// Access rights for process.
|
// Access rights for process.
|
||||||
|
PROCESS_ALL_ACCESS = 0xFFFF
|
||||||
PROCESS_CREATE_PROCESS = 0x0080
|
PROCESS_CREATE_PROCESS = 0x0080
|
||||||
PROCESS_CREATE_THREAD = 0x0002
|
PROCESS_CREATE_THREAD = 0x0002
|
||||||
PROCESS_DUP_HANDLE = 0x0040
|
PROCESS_DUP_HANDLE = 0x0040
|
||||||
@@ -1060,6 +1061,7 @@ const (
|
|||||||
SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
|
SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
|
||||||
SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4
|
SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4
|
||||||
SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
|
SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
|
||||||
|
SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15
|
||||||
|
|
||||||
// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
|
// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
|
||||||
|
|
||||||
@@ -1095,6 +1097,32 @@ const (
|
|||||||
SOMAXCONN = 0x7fffffff
|
SOMAXCONN = 0x7fffffff
|
||||||
|
|
||||||
TCP_NODELAY = 1
|
TCP_NODELAY = 1
|
||||||
|
TCP_EXPEDITED_1122 = 2
|
||||||
|
TCP_KEEPALIVE = 3
|
||||||
|
TCP_MAXSEG = 4
|
||||||
|
TCP_MAXRT = 5
|
||||||
|
TCP_STDURG = 6
|
||||||
|
TCP_NOURG = 7
|
||||||
|
TCP_ATMARK = 8
|
||||||
|
TCP_NOSYNRETRIES = 9
|
||||||
|
TCP_TIMESTAMPS = 10
|
||||||
|
TCP_OFFLOAD_PREFERENCE = 11
|
||||||
|
TCP_CONGESTION_ALGORITHM = 12
|
||||||
|
TCP_DELAY_FIN_ACK = 13
|
||||||
|
TCP_MAXRTMS = 14
|
||||||
|
TCP_FASTOPEN = 15
|
||||||
|
TCP_KEEPCNT = 16
|
||||||
|
TCP_KEEPIDLE = TCP_KEEPALIVE
|
||||||
|
TCP_KEEPINTVL = 17
|
||||||
|
TCP_FAIL_CONNECT_ON_ICMP_ERROR = 18
|
||||||
|
TCP_ICMP_ERROR_INFO = 19
|
||||||
|
|
||||||
|
UDP_NOCHECKSUM = 1
|
||||||
|
UDP_SEND_MSG_SIZE = 2
|
||||||
|
UDP_RECV_MAX_COALESCED_SIZE = 3
|
||||||
|
UDP_CHECKSUM_COVERAGE = 20
|
||||||
|
|
||||||
|
UDP_COALESCED_INFO = 3
|
||||||
|
|
||||||
SHUT_RD = 0
|
SHUT_RD = 0
|
||||||
SHUT_WR = 1
|
SHUT_WR = 1
|
||||||
@@ -1977,7 +2005,21 @@ const (
|
|||||||
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
|
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
|
||||||
)
|
)
|
||||||
|
|
||||||
const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
|
// Flags for GetAdaptersAddresses, see
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses.
|
||||||
|
const (
|
||||||
|
GAA_FLAG_SKIP_UNICAST = 0x1
|
||||||
|
GAA_FLAG_SKIP_ANYCAST = 0x2
|
||||||
|
GAA_FLAG_SKIP_MULTICAST = 0x4
|
||||||
|
GAA_FLAG_SKIP_DNS_SERVER = 0x8
|
||||||
|
GAA_FLAG_INCLUDE_PREFIX = 0x10
|
||||||
|
GAA_FLAG_SKIP_FRIENDLY_NAME = 0x20
|
||||||
|
GAA_FLAG_INCLUDE_WINS_INFO = 0x40
|
||||||
|
GAA_FLAG_INCLUDE_GATEWAYS = 0x80
|
||||||
|
GAA_FLAG_INCLUDE_ALL_INTERFACES = 0x100
|
||||||
|
GAA_FLAG_INCLUDE_ALL_COMPARTMENTS = 0x200
|
||||||
|
GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER = 0x400
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IF_TYPE_OTHER = 1
|
IF_TYPE_OTHER = 1
|
||||||
@@ -1991,6 +2033,50 @@ const (
|
|||||||
IF_TYPE_IEEE1394 = 144
|
IF_TYPE_IEEE1394 = 144
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Enum NL_PREFIX_ORIGIN for [IpAdapterUnicastAddress], see
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_prefix_origin
|
||||||
|
const (
|
||||||
|
IpPrefixOriginOther = 0
|
||||||
|
IpPrefixOriginManual = 1
|
||||||
|
IpPrefixOriginWellKnown = 2
|
||||||
|
IpPrefixOriginDhcp = 3
|
||||||
|
IpPrefixOriginRouterAdvertisement = 4
|
||||||
|
IpPrefixOriginUnchanged = 1 << 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum NL_SUFFIX_ORIGIN for [IpAdapterUnicastAddress], see
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_suffix_origin
|
||||||
|
const (
|
||||||
|
NlsoOther = 0
|
||||||
|
NlsoManual = 1
|
||||||
|
NlsoWellKnown = 2
|
||||||
|
NlsoDhcp = 3
|
||||||
|
NlsoLinkLayerAddress = 4
|
||||||
|
NlsoRandom = 5
|
||||||
|
IpSuffixOriginOther = 0
|
||||||
|
IpSuffixOriginManual = 1
|
||||||
|
IpSuffixOriginWellKnown = 2
|
||||||
|
IpSuffixOriginDhcp = 3
|
||||||
|
IpSuffixOriginLinkLayerAddress = 4
|
||||||
|
IpSuffixOriginRandom = 5
|
||||||
|
IpSuffixOriginUnchanged = 1 << 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum NL_DAD_STATE for [IpAdapterUnicastAddress], see
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_dad_state
|
||||||
|
const (
|
||||||
|
NldsInvalid = 0
|
||||||
|
NldsTentative = 1
|
||||||
|
NldsDuplicate = 2
|
||||||
|
NldsDeprecated = 3
|
||||||
|
NldsPreferred = 4
|
||||||
|
IpDadStateInvalid = 0
|
||||||
|
IpDadStateTentative = 1
|
||||||
|
IpDadStateDuplicate = 2
|
||||||
|
IpDadStateDeprecated = 3
|
||||||
|
IpDadStatePreferred = 4
|
||||||
|
)
|
||||||
|
|
||||||
type SocketAddress struct {
|
type SocketAddress struct {
|
||||||
Sockaddr *syscall.RawSockaddrAny
|
Sockaddr *syscall.RawSockaddrAny
|
||||||
SockaddrLength int32
|
SockaddrLength int32
|
||||||
@@ -2118,6 +2204,132 @@ const (
|
|||||||
IfOperStatusLowerLayerDown = 7
|
IfOperStatusLowerLayerDown = 7
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
IF_MAX_PHYS_ADDRESS_LENGTH = 32
|
||||||
|
IF_MAX_STRING_SIZE = 256
|
||||||
|
)
|
||||||
|
|
||||||
|
// MIB_IF_ENTRY_LEVEL enumeration from netioapi.h or
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2ex.
|
||||||
|
const (
|
||||||
|
MibIfEntryNormal = 0
|
||||||
|
MibIfEntryNormalWithoutStatistics = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// MIB_NOTIFICATION_TYPE enumeration from netioapi.h or
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ne-netioapi-mib_notification_type.
|
||||||
|
const (
|
||||||
|
MibParameterNotification = 0
|
||||||
|
MibAddInstance = 1
|
||||||
|
MibDeleteInstance = 2
|
||||||
|
MibInitialNotification = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// MibIfRow2 stores information about a particular interface. See
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2.
|
||||||
|
type MibIfRow2 struct {
|
||||||
|
InterfaceLuid uint64
|
||||||
|
InterfaceIndex uint32
|
||||||
|
InterfaceGuid GUID
|
||||||
|
Alias [IF_MAX_STRING_SIZE + 1]uint16
|
||||||
|
Description [IF_MAX_STRING_SIZE + 1]uint16
|
||||||
|
PhysicalAddressLength uint32
|
||||||
|
PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
||||||
|
PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
||||||
|
Mtu uint32
|
||||||
|
Type uint32
|
||||||
|
TunnelType uint32
|
||||||
|
MediaType uint32
|
||||||
|
PhysicalMediumType uint32
|
||||||
|
AccessType uint32
|
||||||
|
DirectionType uint32
|
||||||
|
InterfaceAndOperStatusFlags uint8
|
||||||
|
OperStatus uint32
|
||||||
|
AdminStatus uint32
|
||||||
|
MediaConnectState uint32
|
||||||
|
NetworkGuid GUID
|
||||||
|
ConnectionType uint32
|
||||||
|
TransmitLinkSpeed uint64
|
||||||
|
ReceiveLinkSpeed uint64
|
||||||
|
InOctets uint64
|
||||||
|
InUcastPkts uint64
|
||||||
|
InNUcastPkts uint64
|
||||||
|
InDiscards uint64
|
||||||
|
InErrors uint64
|
||||||
|
InUnknownProtos uint64
|
||||||
|
InUcastOctets uint64
|
||||||
|
InMulticastOctets uint64
|
||||||
|
InBroadcastOctets uint64
|
||||||
|
OutOctets uint64
|
||||||
|
OutUcastPkts uint64
|
||||||
|
OutNUcastPkts uint64
|
||||||
|
OutDiscards uint64
|
||||||
|
OutErrors uint64
|
||||||
|
OutUcastOctets uint64
|
||||||
|
OutMulticastOctets uint64
|
||||||
|
OutBroadcastOctets uint64
|
||||||
|
OutQLen uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row.
|
||||||
|
type MibUnicastIpAddressRow struct {
|
||||||
|
Address RawSockaddrInet6 // SOCKADDR_INET union
|
||||||
|
InterfaceLuid uint64
|
||||||
|
InterfaceIndex uint32
|
||||||
|
PrefixOrigin uint32
|
||||||
|
SuffixOrigin uint32
|
||||||
|
ValidLifetime uint32
|
||||||
|
PreferredLifetime uint32
|
||||||
|
OnLinkPrefixLength uint8
|
||||||
|
SkipAsSource uint8
|
||||||
|
DadState uint32
|
||||||
|
ScopeId uint32
|
||||||
|
CreationTimeStamp Filetime
|
||||||
|
}
|
||||||
|
|
||||||
|
const ScopeLevelCount = 16
|
||||||
|
|
||||||
|
// MIB_IPINTERFACE_ROW stores interface management information for a particular IP address family on a network interface.
|
||||||
|
// See https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_row.
|
||||||
|
type MibIpInterfaceRow struct {
|
||||||
|
Family uint16
|
||||||
|
InterfaceLuid uint64
|
||||||
|
InterfaceIndex uint32
|
||||||
|
MaxReassemblySize uint32
|
||||||
|
InterfaceIdentifier uint64
|
||||||
|
MinRouterAdvertisementInterval uint32
|
||||||
|
MaxRouterAdvertisementInterval uint32
|
||||||
|
AdvertisingEnabled uint8
|
||||||
|
ForwardingEnabled uint8
|
||||||
|
WeakHostSend uint8
|
||||||
|
WeakHostReceive uint8
|
||||||
|
UseAutomaticMetric uint8
|
||||||
|
UseNeighborUnreachabilityDetection uint8
|
||||||
|
ManagedAddressConfigurationSupported uint8
|
||||||
|
OtherStatefulConfigurationSupported uint8
|
||||||
|
AdvertiseDefaultRoute uint8
|
||||||
|
RouterDiscoveryBehavior uint32
|
||||||
|
DadTransmits uint32
|
||||||
|
BaseReachableTime uint32
|
||||||
|
RetransmitTime uint32
|
||||||
|
PathMtuDiscoveryTimeout uint32
|
||||||
|
LinkLocalAddressBehavior uint32
|
||||||
|
LinkLocalAddressTimeout uint32
|
||||||
|
ZoneIndices [ScopeLevelCount]uint32
|
||||||
|
SitePrefixLength uint32
|
||||||
|
Metric uint32
|
||||||
|
NlMtu uint32
|
||||||
|
Connected uint8
|
||||||
|
SupportsWakeUpPatterns uint8
|
||||||
|
SupportsNeighborDiscovery uint8
|
||||||
|
SupportsRouterDiscovery uint8
|
||||||
|
ReachableTime uint32
|
||||||
|
TransmitOffload uint32
|
||||||
|
ReceiveOffload uint32
|
||||||
|
DisableDefaultRoutes uint8
|
||||||
|
}
|
||||||
|
|
||||||
// Console related constants used for the mode parameter to SetConsoleMode. See
|
// Console related constants used for the mode parameter to SetConsoleMode. See
|
||||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details.
|
// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details.
|
||||||
|
|
||||||
@@ -3354,3 +3566,38 @@ type BLOB struct {
|
|||||||
Size uint32
|
Size uint32
|
||||||
BlobData *byte
|
BlobData *byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ComStat struct {
|
||||||
|
Flags uint32
|
||||||
|
CBInQue uint32
|
||||||
|
CBOutQue uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type DCB struct {
|
||||||
|
DCBlength uint32
|
||||||
|
BaudRate uint32
|
||||||
|
Flags uint32
|
||||||
|
wReserved uint16
|
||||||
|
XonLim uint16
|
||||||
|
XoffLim uint16
|
||||||
|
ByteSize uint8
|
||||||
|
Parity uint8
|
||||||
|
StopBits uint8
|
||||||
|
XonChar byte
|
||||||
|
XoffChar byte
|
||||||
|
ErrorChar byte
|
||||||
|
EofChar byte
|
||||||
|
EvtChar byte
|
||||||
|
wReserved1 uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard Layout Flags.
|
||||||
|
// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadkeyboardlayoutw
|
||||||
|
const (
|
||||||
|
KLF_ACTIVATE = 0x00000001
|
||||||
|
KLF_SUBSTITUTE_OK = 0x00000002
|
||||||
|
KLF_REORDER = 0x00000008
|
||||||
|
KLF_REPLACELANG = 0x00000010
|
||||||
|
KLF_NOTELLSHELL = 0x00000080
|
||||||
|
KLF_SETFORPROCESS = 0x00000100
|
||||||
|
)
|
||||||
|
|||||||
305
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
305
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
@@ -91,6 +91,7 @@ var (
|
|||||||
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
|
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
|
||||||
procEqualSid = modadvapi32.NewProc("EqualSid")
|
procEqualSid = modadvapi32.NewProc("EqualSid")
|
||||||
procFreeSid = modadvapi32.NewProc("FreeSid")
|
procFreeSid = modadvapi32.NewProc("FreeSid")
|
||||||
|
procGetAce = modadvapi32.NewProc("GetAce")
|
||||||
procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
|
procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
|
||||||
procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW")
|
procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW")
|
||||||
procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl")
|
procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl")
|
||||||
@@ -180,13 +181,21 @@ var (
|
|||||||
procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree")
|
procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree")
|
||||||
procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
|
procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
|
||||||
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
|
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
|
||||||
|
procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2")
|
||||||
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
|
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
|
||||||
procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
|
procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
|
||||||
procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx")
|
procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx")
|
||||||
procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
|
procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
|
||||||
|
procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex")
|
||||||
|
procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry")
|
||||||
|
procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange")
|
||||||
|
procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange")
|
||||||
|
procAddDllDirectory = modkernel32.NewProc("AddDllDirectory")
|
||||||
procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject")
|
procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject")
|
||||||
procCancelIo = modkernel32.NewProc("CancelIo")
|
procCancelIo = modkernel32.NewProc("CancelIo")
|
||||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||||
|
procClearCommBreak = modkernel32.NewProc("ClearCommBreak")
|
||||||
|
procClearCommError = modkernel32.NewProc("ClearCommError")
|
||||||
procCloseHandle = modkernel32.NewProc("CloseHandle")
|
procCloseHandle = modkernel32.NewProc("CloseHandle")
|
||||||
procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole")
|
procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole")
|
||||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||||
@@ -211,7 +220,9 @@ var (
|
|||||||
procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList")
|
procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList")
|
||||||
procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW")
|
procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW")
|
||||||
procDeviceIoControl = modkernel32.NewProc("DeviceIoControl")
|
procDeviceIoControl = modkernel32.NewProc("DeviceIoControl")
|
||||||
|
procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe")
|
||||||
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
|
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
|
||||||
|
procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction")
|
||||||
procExitProcess = modkernel32.NewProc("ExitProcess")
|
procExitProcess = modkernel32.NewProc("ExitProcess")
|
||||||
procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
|
procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
|
||||||
procFindClose = modkernel32.NewProc("FindClose")
|
procFindClose = modkernel32.NewProc("FindClose")
|
||||||
@@ -235,11 +246,15 @@ var (
|
|||||||
procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent")
|
procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent")
|
||||||
procGetACP = modkernel32.NewProc("GetACP")
|
procGetACP = modkernel32.NewProc("GetACP")
|
||||||
procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
|
procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
|
||||||
|
procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus")
|
||||||
|
procGetCommState = modkernel32.NewProc("GetCommState")
|
||||||
procGetCommTimeouts = modkernel32.NewProc("GetCommTimeouts")
|
procGetCommTimeouts = modkernel32.NewProc("GetCommTimeouts")
|
||||||
procGetCommandLineW = modkernel32.NewProc("GetCommandLineW")
|
procGetCommandLineW = modkernel32.NewProc("GetCommandLineW")
|
||||||
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
|
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
|
||||||
procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
|
procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
|
||||||
|
procGetConsoleCP = modkernel32.NewProc("GetConsoleCP")
|
||||||
procGetConsoleMode = modkernel32.NewProc("GetConsoleMode")
|
procGetConsoleMode = modkernel32.NewProc("GetConsoleMode")
|
||||||
|
procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP")
|
||||||
procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
|
procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||||
procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW")
|
procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW")
|
||||||
procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId")
|
procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId")
|
||||||
@@ -253,6 +268,7 @@ var (
|
|||||||
procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW")
|
procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW")
|
||||||
procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle")
|
procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle")
|
||||||
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
|
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
|
||||||
|
procGetFileTime = modkernel32.NewProc("GetFileTime")
|
||||||
procGetFileType = modkernel32.NewProc("GetFileType")
|
procGetFileType = modkernel32.NewProc("GetFileType")
|
||||||
procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
|
procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
|
||||||
procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
|
procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
|
||||||
@@ -264,8 +280,10 @@ var (
|
|||||||
procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount")
|
procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount")
|
||||||
procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW")
|
procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW")
|
||||||
procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW")
|
procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW")
|
||||||
|
procGetNamedPipeClientProcessId = modkernel32.NewProc("GetNamedPipeClientProcessId")
|
||||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||||
|
procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId")
|
||||||
procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult")
|
procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult")
|
||||||
procGetPriorityClass = modkernel32.NewProc("GetPriorityClass")
|
procGetPriorityClass = modkernel32.NewProc("GetPriorityClass")
|
||||||
procGetProcAddress = modkernel32.NewProc("GetProcAddress")
|
procGetProcAddress = modkernel32.NewProc("GetProcAddress")
|
||||||
@@ -320,6 +338,7 @@ var (
|
|||||||
procProcess32NextW = modkernel32.NewProc("Process32NextW")
|
procProcess32NextW = modkernel32.NewProc("Process32NextW")
|
||||||
procProcessIdToSessionId = modkernel32.NewProc("ProcessIdToSessionId")
|
procProcessIdToSessionId = modkernel32.NewProc("ProcessIdToSessionId")
|
||||||
procPulseEvent = modkernel32.NewProc("PulseEvent")
|
procPulseEvent = modkernel32.NewProc("PulseEvent")
|
||||||
|
procPurgeComm = modkernel32.NewProc("PurgeComm")
|
||||||
procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW")
|
procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW")
|
||||||
procQueryFullProcessImageNameW = modkernel32.NewProc("QueryFullProcessImageNameW")
|
procQueryFullProcessImageNameW = modkernel32.NewProc("QueryFullProcessImageNameW")
|
||||||
procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
|
procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
|
||||||
@@ -329,12 +348,18 @@ var (
|
|||||||
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory")
|
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory")
|
||||||
procReleaseMutex = modkernel32.NewProc("ReleaseMutex")
|
procReleaseMutex = modkernel32.NewProc("ReleaseMutex")
|
||||||
procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
|
procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
|
||||||
|
procRemoveDllDirectory = modkernel32.NewProc("RemoveDllDirectory")
|
||||||
procResetEvent = modkernel32.NewProc("ResetEvent")
|
procResetEvent = modkernel32.NewProc("ResetEvent")
|
||||||
procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole")
|
procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole")
|
||||||
procResumeThread = modkernel32.NewProc("ResumeThread")
|
procResumeThread = modkernel32.NewProc("ResumeThread")
|
||||||
|
procSetCommBreak = modkernel32.NewProc("SetCommBreak")
|
||||||
|
procSetCommMask = modkernel32.NewProc("SetCommMask")
|
||||||
|
procSetCommState = modkernel32.NewProc("SetCommState")
|
||||||
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
|
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
|
||||||
|
procSetConsoleCP = modkernel32.NewProc("SetConsoleCP")
|
||||||
procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition")
|
procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition")
|
||||||
procSetConsoleMode = modkernel32.NewProc("SetConsoleMode")
|
procSetConsoleMode = modkernel32.NewProc("SetConsoleMode")
|
||||||
|
procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP")
|
||||||
procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW")
|
procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW")
|
||||||
procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories")
|
procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories")
|
||||||
procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW")
|
procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW")
|
||||||
@@ -347,6 +372,7 @@ var (
|
|||||||
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
|
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
|
||||||
procSetFilePointer = modkernel32.NewProc("SetFilePointer")
|
procSetFilePointer = modkernel32.NewProc("SetFilePointer")
|
||||||
procSetFileTime = modkernel32.NewProc("SetFileTime")
|
procSetFileTime = modkernel32.NewProc("SetFileTime")
|
||||||
|
procSetFileValidData = modkernel32.NewProc("SetFileValidData")
|
||||||
procSetHandleInformation = modkernel32.NewProc("SetHandleInformation")
|
procSetHandleInformation = modkernel32.NewProc("SetHandleInformation")
|
||||||
procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject")
|
procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject")
|
||||||
procSetNamedPipeHandleState = modkernel32.NewProc("SetNamedPipeHandleState")
|
procSetNamedPipeHandleState = modkernel32.NewProc("SetNamedPipeHandleState")
|
||||||
@@ -357,6 +383,7 @@ var (
|
|||||||
procSetStdHandle = modkernel32.NewProc("SetStdHandle")
|
procSetStdHandle = modkernel32.NewProc("SetStdHandle")
|
||||||
procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW")
|
procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW")
|
||||||
procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW")
|
procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW")
|
||||||
|
procSetupComm = modkernel32.NewProc("SetupComm")
|
||||||
procSizeofResource = modkernel32.NewProc("SizeofResource")
|
procSizeofResource = modkernel32.NewProc("SizeofResource")
|
||||||
procSleepEx = modkernel32.NewProc("SleepEx")
|
procSleepEx = modkernel32.NewProc("SleepEx")
|
||||||
procTerminateJobObject = modkernel32.NewProc("TerminateJobObject")
|
procTerminateJobObject = modkernel32.NewProc("TerminateJobObject")
|
||||||
@@ -375,6 +402,7 @@ var (
|
|||||||
procVirtualQueryEx = modkernel32.NewProc("VirtualQueryEx")
|
procVirtualQueryEx = modkernel32.NewProc("VirtualQueryEx")
|
||||||
procVirtualUnlock = modkernel32.NewProc("VirtualUnlock")
|
procVirtualUnlock = modkernel32.NewProc("VirtualUnlock")
|
||||||
procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId")
|
procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId")
|
||||||
|
procWaitCommEvent = modkernel32.NewProc("WaitCommEvent")
|
||||||
procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects")
|
procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects")
|
||||||
procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
|
procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
|
||||||
procWriteConsoleW = modkernel32.NewProc("WriteConsoleW")
|
procWriteConsoleW = modkernel32.NewProc("WriteConsoleW")
|
||||||
@@ -385,6 +413,7 @@ var (
|
|||||||
procTransmitFile = modmswsock.NewProc("TransmitFile")
|
procTransmitFile = modmswsock.NewProc("TransmitFile")
|
||||||
procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree")
|
procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree")
|
||||||
procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
|
procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
|
||||||
|
procNetUserEnum = modnetapi32.NewProc("NetUserEnum")
|
||||||
procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
|
procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
|
||||||
procNtCreateFile = modntdll.NewProc("NtCreateFile")
|
procNtCreateFile = modntdll.NewProc("NtCreateFile")
|
||||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||||
@@ -460,12 +489,16 @@ var (
|
|||||||
procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow")
|
procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow")
|
||||||
procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow")
|
procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow")
|
||||||
procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo")
|
procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo")
|
||||||
|
procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout")
|
||||||
procGetShellWindow = moduser32.NewProc("GetShellWindow")
|
procGetShellWindow = moduser32.NewProc("GetShellWindow")
|
||||||
procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId")
|
procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId")
|
||||||
procIsWindow = moduser32.NewProc("IsWindow")
|
procIsWindow = moduser32.NewProc("IsWindow")
|
||||||
procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode")
|
procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode")
|
||||||
procIsWindowVisible = moduser32.NewProc("IsWindowVisible")
|
procIsWindowVisible = moduser32.NewProc("IsWindowVisible")
|
||||||
|
procLoadKeyboardLayoutW = moduser32.NewProc("LoadKeyboardLayoutW")
|
||||||
procMessageBoxW = moduser32.NewProc("MessageBoxW")
|
procMessageBoxW = moduser32.NewProc("MessageBoxW")
|
||||||
|
procToUnicodeEx = moduser32.NewProc("ToUnicodeEx")
|
||||||
|
procUnloadKeyboardLayout = moduser32.NewProc("UnloadKeyboardLayout")
|
||||||
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
|
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
|
||||||
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
|
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
|
||||||
procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
|
procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
|
||||||
@@ -771,6 +804,14 @@ func FreeSid(sid *SID) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce)))
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetLengthSid(sid *SID) (len uint32) {
|
func GetLengthSid(sid *SID) (len uint32) {
|
||||||
r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
|
r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
|
||||||
len = uint32(r0)
|
len = uint32(r0)
|
||||||
@@ -1572,6 +1613,14 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
errcode = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
|
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
|
||||||
r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
|
r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
|
||||||
if r0 != 0 {
|
if r0 != 0 {
|
||||||
@@ -1604,6 +1653,55 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
errcode = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
errcode = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
|
||||||
|
var _p0 uint32
|
||||||
|
if initialNotification {
|
||||||
|
_p0 = 1
|
||||||
|
}
|
||||||
|
r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
errcode = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
|
||||||
|
var _p0 uint32
|
||||||
|
if initialNotification {
|
||||||
|
_p0 = 1
|
||||||
|
}
|
||||||
|
r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
errcode = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddDllDirectory(path *uint16) (cookie uintptr, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
|
||||||
|
cookie = uintptr(r0)
|
||||||
|
if cookie == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func AssignProcessToJobObject(job Handle, process Handle) (err error) {
|
func AssignProcessToJobObject(job Handle, process Handle) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0)
|
r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -1628,6 +1726,22 @@ func CancelIoEx(s Handle, o *Overlapped) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ClearCommBreak(handle Handle) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procClearCommError.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat)))
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func CloseHandle(handle Handle) (err error) {
|
func CloseHandle(handle Handle) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
|
r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -1832,6 +1946,14 @@ func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBuff
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DisconnectNamedPipe(pipe Handle) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(pipe), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
|
func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
|
||||||
var _p0 uint32
|
var _p0 uint32
|
||||||
if bInheritHandle {
|
if bInheritHandle {
|
||||||
@@ -1844,6 +1966,14 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(dwFunc), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func ExitProcess(exitcode uint32) {
|
func ExitProcess(exitcode uint32) {
|
||||||
syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
|
syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
|
||||||
return
|
return
|
||||||
@@ -2045,6 +2175,22 @@ func GetActiveProcessorCount(groupNumber uint16) (ret uint32) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpModemStat)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCommState(handle Handle, lpDCB *DCB) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
|
func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
|
r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2075,6 +2221,15 @@ func GetComputerName(buf *uint16, n *uint32) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetConsoleCP() (cp uint32, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0)
|
||||||
|
cp = uint32(r0)
|
||||||
|
if cp == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetConsoleMode(console Handle, mode *uint32) (err error) {
|
func GetConsoleMode(console Handle, mode *uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
|
r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2083,6 +2238,15 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetConsoleOutputCP() (cp uint32, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0)
|
||||||
|
cp = uint32(r0)
|
||||||
|
if cp == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) {
|
func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0)
|
r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2185,6 +2349,14 @@ func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procGetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetFileType(filehandle Handle) (n uint32, err error) {
|
func GetFileType(filehandle Handle) (n uint32, err error) {
|
||||||
r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
|
r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
|
||||||
n = uint32(r0)
|
n = uint32(r0)
|
||||||
@@ -2276,6 +2448,14 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2292,6 +2472,14 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) {
|
func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) {
|
||||||
var _p0 uint32
|
var _p0 uint32
|
||||||
if wait {
|
if wait {
|
||||||
@@ -2789,6 +2977,14 @@ func PulseEvent(event Handle) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PurgeComm(handle Handle, dwFlags uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(dwFlags), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) {
|
func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) {
|
||||||
r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max))
|
r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max))
|
||||||
n = uint32(r0)
|
n = uint32(r0)
|
||||||
@@ -2870,6 +3066,14 @@ func RemoveDirectory(path *uint16) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RemoveDllDirectory(cookie uintptr) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procRemoveDllDirectory.Addr(), 1, uintptr(cookie), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func ResetEvent(event Handle) (err error) {
|
func ResetEvent(event Handle) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0)
|
r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2895,6 +3099,30 @@ func ResumeThread(thread Handle) (ret uint32, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetCommBreak(handle Handle) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetCommMask(handle Handle, dwEvtMask uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetCommMask.Addr(), 2, uintptr(handle), uintptr(dwEvtMask), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetCommState(handle Handle, lpDCB *DCB) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
|
func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
|
r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2903,6 +3131,14 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetConsoleCP(cp uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func setConsoleCursorPosition(console Handle, position uint32) (err error) {
|
func setConsoleCursorPosition(console Handle, position uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0)
|
r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2919,6 +3155,14 @@ func SetConsoleMode(console Handle, mode uint32) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetConsoleOutputCP(cp uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func SetCurrentDirectory(path *uint16) (err error) {
|
func SetCurrentDirectory(path *uint16) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
|
r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -3023,6 +3267,14 @@ func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetFileValidData(handle Handle, validDataLength int64) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
|
func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
|
r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -3108,6 +3360,14 @@ func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetupComm.Addr(), 3, uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue))
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) {
|
func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) {
|
||||||
r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0)
|
r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0)
|
||||||
size = uint32(r0)
|
size = uint32(r0)
|
||||||
@@ -3254,6 +3514,14 @@ func WTSGetActiveConsoleSessionId() (sessionID uint32) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procWaitCommEvent.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped)))
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) {
|
func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) {
|
||||||
var _p0 uint32
|
var _p0 uint32
|
||||||
if waitAll {
|
if waitAll {
|
||||||
@@ -3341,6 +3609,14 @@ func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (nete
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) {
|
||||||
|
r0, _, _ := syscall.Syscall9(procNetUserEnum.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
neterr = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
|
func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
|
||||||
r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
|
r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
|
||||||
if r0 != 0 {
|
if r0 != 0 {
|
||||||
@@ -3919,6 +4195,12 @@ func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetKeyboardLayout(tid uint32) (hkl Handle) {
|
||||||
|
r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(tid), 0, 0)
|
||||||
|
hkl = Handle(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetShellWindow() (shellWindow HWND) {
|
func GetShellWindow() (shellWindow HWND) {
|
||||||
r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0)
|
r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0)
|
||||||
shellWindow = HWND(r0)
|
shellWindow = HWND(r0)
|
||||||
@@ -3952,6 +4234,15 @@ func IsWindowVisible(hwnd HWND) (isVisible bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall(procLoadKeyboardLayoutW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(flags), 0)
|
||||||
|
hkl = Handle(r0)
|
||||||
|
if hkl == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
|
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
|
||||||
r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0)
|
r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0)
|
||||||
ret = int32(r0)
|
ret = int32(r0)
|
||||||
@@ -3961,6 +4252,20 @@ func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret i
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) {
|
||||||
|
r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0)
|
||||||
|
ret = int32(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnloadKeyboardLayout(hkl Handle) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procUnloadKeyboardLayout.Addr(), 1, uintptr(hkl), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) {
|
func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) {
|
||||||
var _p0 uint32
|
var _p0 uint32
|
||||||
if inheritExisting {
|
if inheritExisting {
|
||||||
|
|||||||
4
vendor/golang.org/x/text/LICENSE
generated
vendored
4
vendor/golang.org/x/text/LICENSE
generated
vendored
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
|
|||||||
copyright notice, this list of conditions and the following disclaimer
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
in the documentation and/or other materials provided with the
|
in the documentation and/or other materials provided with the
|
||||||
distribution.
|
distribution.
|
||||||
* Neither the name of Google Inc. nor the names of its
|
* Neither the name of Google LLC nor the names of its
|
||||||
contributors may be used to endorse or promote products derived from
|
contributors may be used to endorse or promote products derived from
|
||||||
this software without specific prior written permission.
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
|||||||
12
vendor/modules.txt
vendored
12
vendor/modules.txt
vendored
@@ -1,16 +1,16 @@
|
|||||||
# github.com/mattn/go-sqlite3 v1.14.7
|
# github.com/mattn/go-sqlite3 v1.14.7
|
||||||
## explicit; go 1.12
|
## explicit; go 1.12
|
||||||
github.com/mattn/go-sqlite3
|
github.com/mattn/go-sqlite3
|
||||||
# golang.org/x/net v0.17.0
|
# golang.org/x/net v0.33.0
|
||||||
## explicit; go 1.17
|
## explicit; go 1.18
|
||||||
golang.org/x/net/html
|
golang.org/x/net/html
|
||||||
golang.org/x/net/html/atom
|
golang.org/x/net/html/atom
|
||||||
golang.org/x/net/html/charset
|
golang.org/x/net/html/charset
|
||||||
# golang.org/x/sys v0.13.0
|
# golang.org/x/sys v0.28.0
|
||||||
## explicit; go 1.17
|
## explicit; go 1.18
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/text v0.13.0
|
# golang.org/x/text v0.21.0
|
||||||
## explicit; go 1.17
|
## explicit; go 1.18
|
||||||
golang.org/x/text/encoding
|
golang.org/x/text/encoding
|
||||||
golang.org/x/text/encoding/charmap
|
golang.org/x/text/encoding/charmap
|
||||||
golang.org/x/text/encoding/htmlindex
|
golang.org/x/text/encoding/htmlindex
|
||||||
|
|||||||
Reference in New Issue
Block a user