mirror of
https://github.com/nkanaev/yarr.git
synced 2025-11-08 18:39:36 +00:00
Compare commits
14 Commits
gh-actions
...
ad19ca744b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad19ca744b | ||
|
|
9740e5ee12 | ||
|
|
4bc71acc67 | ||
|
|
183e7cecb0 | ||
|
|
bd6b77bcc2 | ||
|
|
628bde1527 | ||
|
|
976bbfd245 | ||
|
|
b79a542ed7 | ||
|
|
c32bd7e415 | ||
|
|
e9676491ee | ||
|
|
1a545bb2a1 | ||
|
|
1e128a7cd8 | ||
|
|
5dbb6a710c | ||
|
|
dadadeb066 |
157
.github/workflows/build.yml
vendored
157
.github/workflows/build.yml
vendored
@@ -1,14 +1,8 @@
|
|||||||
name: Build
|
name: build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags: ['v*', 'test*']
|
||||||
- v*
|
|
||||||
workflow_dispatch:
|
|
||||||
workflow_run:
|
|
||||||
workflows: [Test]
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_macos:
|
build_macos:
|
||||||
@@ -24,7 +18,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '^1.17'
|
go-version: '^1.17'
|
||||||
- name: Cache Go Modules
|
- name: Cache Go Modules
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
@@ -33,7 +27,7 @@ jobs:
|
|||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: make build_macos
|
run: make build_macos
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: macos
|
name: macos
|
||||||
path: _output/macos/yarr.app
|
path: _output/macos/yarr.app
|
||||||
@@ -51,7 +45,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '^1.17'
|
go-version: '^1.17'
|
||||||
- name: Cache Go Modules
|
- name: Cache Go Modules
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
@@ -60,7 +54,7 @@ jobs:
|
|||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: make build_windows
|
run: make build_windows
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: windows
|
name: windows
|
||||||
path: _output/windows/yarr.exe
|
path: _output/windows/yarr.exe
|
||||||
@@ -78,99 +72,38 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '^1.17'
|
go-version: '^1.17'
|
||||||
- name: Cache Go Modules
|
- name: Cache Go Modules
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-amd64-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-go-amd64
|
${{ runner.os }}-go-
|
||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: make build_linux
|
run: make build_linux
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v2
|
||||||
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: ${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'test') }}
|
if: ${{ !contains(github.ref, 'test') }}
|
||||||
needs: [build_macos, build_windows, build_linux, build_linux-arm, build_linux-arm64]
|
needs: [build_macos, build_windows, build_linux]
|
||||||
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@v4.1.7
|
uses: actions/download-artifact@v2
|
||||||
with:
|
with:
|
||||||
path: .
|
path: .
|
||||||
- name: Preparation
|
- name: Preparation
|
||||||
@@ -178,24 +111,34 @@ 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-${GITHUB_REF_NAME}-macos64.zip yarr.app
|
mv macos yarr.app && zip -r yarr-macos.zip yarr.app
|
||||||
( cd windows && zip ../yarr-${GITHUB_REF_NAME}-windows64.zip yarr.exe )
|
mv windows/yarr.exe . && zip yarr-windows.zip yarr.exe
|
||||||
( cd linux && zip ../yarr-${GITHUB_REF_NAME}-linux64.zip yarr )
|
mv linux/yarr . && zip yarr-linux.zip yarr
|
||||||
( cd linux_arm && zip ../yarr-${GITHUB_REF_NAME}-linux_arm.zip yarr )
|
- name: Upload MacOS
|
||||||
( cd linux_arm64 && zip ../yarr-${GITHUB_REF_NAME}-linux_arm64.zip yarr )
|
uses: actions/upload-release-asset@v1
|
||||||
- name: Upload Release
|
|
||||||
uses: softprops/action-gh-release@v2
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
draft: true
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
prerelease: true
|
asset_path: ./yarr-macos.zip
|
||||||
files: |
|
asset_name: yarr-${{ github.ref }}-macos64.zip
|
||||||
yarr-${{ github.ref_name }}-macos64.zip
|
asset_content_type: application/zip
|
||||||
yarr-${{ github.ref_name }}-windows64.zip
|
- name: Upload Windows
|
||||||
yarr-${{ github.ref_name }}-linux64.zip
|
uses: actions/upload-release-asset@v1
|
||||||
yarr-${{ github.ref_name }}-linux_arm.zip
|
env:
|
||||||
yarr-${{ github.ref_name }}-linux_arm64.zip
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
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
19
.github/workflows/test.yml
vendored
@@ -1,19 +0,0 @@
|
|||||||
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,7 +1,5 @@
|
|||||||
/_output
|
/_output
|
||||||
/yarr
|
/yarr
|
||||||
*.db
|
*.db
|
||||||
*.db-shm
|
|
||||||
*.db-wal
|
|
||||||
*.syso
|
*.syso
|
||||||
versioninfo.rc
|
versioninfo.rc
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ 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"
|
||||||
@@ -90,12 +89,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)
|
||||||
@@ -106,7 +105,6 @@ 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 {
|
||||||
@@ -133,7 +131,6 @@ 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 != "" {
|
||||||
|
|||||||
@@ -1,22 +1,11 @@
|
|||||||
# upcoming
|
# upcoming
|
||||||
|
|
||||||
- (new) Fever API support (thanks to @icefed)
|
- (new) Fever API support (thanks to @icefed)
|
||||||
- (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) 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)
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
- 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,8 +2,7 @@ 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 --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/root/go/pkg \
|
RUN make build_linux
|
||||||
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.18
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/mattn/go-sqlite3 v1.14.7
|
github.com/mattn/go-sqlite3 v1.14.7
|
||||||
golang.org/x/net v0.33.0
|
golang.org/x/net v0.17.0
|
||||||
golang.org/x/sys v0.28.0
|
golang.org/x/sys v0.13.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require golang.org/x/text v0.21.0 // indirect
|
require golang.org/x/text v0.13.0 // indirect
|
||||||
|
|||||||
49
go.sum
49
go.sum
@@ -1,70 +1,45 @@
|
|||||||
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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||||
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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||||
|
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,34 +1,33 @@
|
|||||||
VERSION=2.4
|
VERSION=2.4
|
||||||
GITHASH=$(shell git rev-parse --short=8 HEAD)
|
GITHASH=$(shell git rev-parse --short=8 HEAD)
|
||||||
|
|
||||||
GO_TAGS = sqlite_foreign_keys sqlite_json
|
CGO_ENABLED=1
|
||||||
GO_LDFLAGS = -s -w -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)'
|
|
||||||
|
|
||||||
export GOARCH ?= amd64
|
GO_LDFLAGS = -s -w
|
||||||
export CGO_ENABLED = 1
|
GO_LDFLAGS := $(GO_LDFLAGS) -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)'
|
||||||
|
|
||||||
build_default:
|
build_default:
|
||||||
mkdir -p _output
|
mkdir -p _output
|
||||||
go build -tags "$(GO_TAGS)" -ldflags="$(GO_LDFLAGS)" -o _output/yarr ./cmd/yarr
|
go build -tags "sqlite_foreign_keys" -ldflags="$(GO_LDFLAGS)" -o _output/yarr ./cmd/yarr
|
||||||
|
|
||||||
build_macos:
|
build_macos:
|
||||||
mkdir -p _output/macos
|
mkdir -p _output/macos
|
||||||
GOOS=darwin go build -tags "$(GO_TAGS) macos" -ldflags="$(GO_LDFLAGS)" -o _output/macos/yarr ./cmd/yarr
|
GOOS=darwin GOARCH=amd64 go build -tags "sqlite_foreign_keys 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 go build -tags "$(GO_TAGS) linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr ./cmd/yarr
|
GOOS=linux GOARCH=amd64 go build -tags "sqlite_foreign_keys 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 go build -tags "$(GO_TAGS) windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr
|
GOOS=windows GOARCH=amd64 go build -tags "sqlite_foreign_keys windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr
|
||||||
|
|
||||||
serve:
|
serve:
|
||||||
go run -tags "$(GO_TAGS)" ./cmd/yarr -db local.db
|
go run -tags "sqlite_foreign_keys" ./cmd/yarr -db local.db
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -tags "$(GO_TAGS)" ./...
|
go test -tags "sqlite_foreign_keys" ./...
|
||||||
|
|||||||
BIN
src/assets/graphicarts/favicon-144.png
Normal file
BIN
src/assets/graphicarts/favicon-144.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
@@ -3,16 +3,22 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>yarr!</title>
|
<title>yarr!</title>
|
||||||
<link rel="stylesheet" href="./static/stylesheets/bootstrap.min.css">
|
<link rel="stylesheet" href="./static/stylesheets/bootstrap.min.css" crossorigin="use-credentials">
|
||||||
<link rel="stylesheet" href="./static/stylesheets/app.css">
|
<link rel="stylesheet" href="./static/stylesheets/app.css" crossorigin="use-credentials">
|
||||||
<link rel="icon" href="./static/graphicarts/favicon.svg" type="image/svg+xml">
|
<link rel="icon" href="./static/graphicarts/favicon.svg" type="image/svg+xml" crossorigin="use-credentials">
|
||||||
<link rel="alternate icon" href="./static/graphicarts/favicon.png" type="image/png">
|
<link rel="alternate icon" href="./static/graphicarts/favicon.png" type="image/png" crossorigin="use-credentials">
|
||||||
<link rel="manifest" href="./manifest.json" />
|
<link rel="manifest" href="./manifest.json" crossorigin="use-credentials"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<script>
|
<script>
|
||||||
window.app = window.app || {}
|
window.app = window.app || {}
|
||||||
window.app.settings = {% .settings %}
|
window.app.settings = {% .settings %}
|
||||||
window.app.authenticated = {% .authenticated %}
|
window.app.authenticated = {% .authenticated %}
|
||||||
|
|
||||||
|
if ("serviceWorker" in navigator) {
|
||||||
|
// we use `./sw.js` instead of `./static/javascripts/sw.js` since the latter would not work with
|
||||||
|
// `./manifest.json`, and it leads to uninstallable PWA
|
||||||
|
navigator.serviceWorker.register("./sw.js")
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body class="theme-{% .settings.theme_name %}">
|
<body class="theme-{% .settings.theme_name %}">
|
||||||
@@ -25,21 +31,18 @@
|
|||||||
<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>
|
||||||
@@ -62,12 +65,10 @@
|
|||||||
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|
||||||
<header class="dropdown-header" role="heading" aria-level="2">Theme</header>
|
<header class="dropdown-header">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>
|
||||||
@@ -76,25 +77,25 @@
|
|||||||
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|
||||||
<header class="dropdown-header" role="heading" aria-level="2">Auto Refresh</header>
|
<header class="dropdown-header">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" :aria-pressed="!refreshRate" :class="{active: !refreshRate}" @click.stop="refreshRate = 0">0</button>
|
<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 == 10" :class="{active: refreshRate == 10}" @click.stop="refreshRate = 10">10m</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 == 30" :class="{active: refreshRate == 30}" @click.stop="refreshRate = 30">30m</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 == 60" :class="{active: refreshRate == 60}" @click.stop="refreshRate = 60">1h</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 == 120" :class="{active: refreshRate == 120}" @click.stop="refreshRate = 120">2h</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 == 240" :class="{active: refreshRate == 240}" @click.stop="refreshRate = 240">4h</button>
|
<button class="dropdown-item col-4 px-0" :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" role="heading" aria-level="2">Show first</header>
|
<header class="dropdown-header">Show first</header>
|
||||||
<div class="d-flex text-center">
|
<div class="d-flex text-center">
|
||||||
<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=true">New</button>
|
||||||
<button class="dropdown-item px-0" :aria-pressed="!itemSortNewestFirst" :class="{active: !itemSortNewestFirst}" @click.stop="itemSortNewestFirst=false">Old</button>
|
<button class="dropdown-item px-0" :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" role="heading" aria-level="2">Subscriptions</header>
|
<header class="dropdown-header">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"
|
||||||
@@ -211,12 +212,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" role="heading" aria-level="2">{{ current.feed.title }}</header>
|
<header class="dropdown-header">{{ current.feed.title }}</header>
|
||||||
<a class="dropdown-item" :href="current.feed.link" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" v-if="current.feed.link">
|
<a class="dropdown-item" :href="current.feed.link" target="_blank" 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" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" v-if="current.feed.feed_link">
|
<a class="dropdown-item" :href="current.feed.feed_link" target="_blank" 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,12 +226,8 @@
|
|||||||
<span class="icon mr-1">{% inline "edit.svg" %}</span>
|
<span class="icon mr-1">{% inline "edit.svg" %}</span>
|
||||||
Rename
|
Rename
|
||||||
</button>
|
</button>
|
||||||
<button class="dropdown-item" @click="updateFeedLink(current.feed)" v-if="current.feed.feed_link">
|
|
||||||
<span class="icon mr-1">{% inline "edit.svg" %}</span>
|
|
||||||
Change Link
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<header class="dropdown-header" role="heading" aria-level="2">Move to...</header>
|
<header class="dropdown-header">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"
|
||||||
@@ -260,7 +257,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" role="heading" aria-level="2">{{ current.folder.title }}</header>
|
<header class="dropdown-header">{{ 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
|
||||||
@@ -331,16 +328,10 @@
|
|||||||
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" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" title="Open Link">
|
<a class="toolbar-item" :href="itemSelectedDetails.link" target="_blank" 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>
|
||||||
@@ -353,23 +344,13 @@
|
|||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<h1><b>{{ itemSelectedDetails.title || 'untitled' }}</b></h1>
|
<h1><b>{{ itemSelectedDetails.title || 'untitled' }}</b></h1>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
<div>
|
<div>{{ (feedsById[itemSelectedDetails.feed_id] || {}).title }}</div>
|
||||||
<span class="cursor-pointer" @click="feedSelected = 'feed:'+(feedsById[itemSelectedDetails.feed_id] || {}).id">
|
|
||||||
{{ (feedsById[itemSelectedDetails.feed_id] || {}).title }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<time>{{ formatDate(itemSelectedDetails.date) }}</time>
|
<time>{{ formatDate(itemSelectedDetails.date) }}</time>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div v-if="!itemSelectedReadability">
|
<div v-if="!itemSelectedReadability">
|
||||||
<div v-if="contentImages.length">
|
<img :src="itemSelectedDetails.image" v-if="itemSelectedDetails.image" class="mb-3">
|
||||||
<figure v-for="media in contentImages">
|
<audio class="w-100" controls v-if="itemSelectedDetails.podcast_url" :src="itemSelectedDetails.podcast_url"></audio>
|
||||||
<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,26 +2,6 @@
|
|||||||
|
|
||||||
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() {
|
||||||
@@ -298,18 +278,6 @@ 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': {
|
||||||
@@ -439,7 +407,7 @@ var vm = new Vue({
|
|||||||
vm.feeds = values[1]
|
vm.feeds = values[1]
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
refreshItems: function(loadMore = false) {
|
refreshItems: function(loadMore) {
|
||||||
if (this.feedSelected === null) {
|
if (this.feedSelected === null) {
|
||||||
vm.items = []
|
vm.items = []
|
||||||
vm.itemsHasMore = false
|
vm.itemsHasMore = false
|
||||||
@@ -452,7 +420,7 @@ var vm = new Vue({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.loading.items = true
|
this.loading.items = true
|
||||||
return api.items.list(query).then(function(data) {
|
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 {
|
||||||
@@ -475,17 +443,13 @@ 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()) return this.refreshItems(true)
|
if (this.itemListCloseToBottom()) 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()
|
||||||
@@ -559,14 +523,6 @@ var vm = new Vue({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateFeedLink: function(feed) {
|
|
||||||
var newLink = prompt('Enter feed link', feed.feed_link)
|
|
||||||
if (newLink) {
|
|
||||||
api.feeds.update(feed.id, {feed_link: newLink}).then(function() {
|
|
||||||
feed.feed_link = newLink
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
renameFeed: function(feed) {
|
renameFeed: function(feed) {
|
||||||
var newTitle = prompt('Enter new title', feed.title)
|
var newTitle = prompt('Enter new title', feed.title)
|
||||||
if (newTitle) {
|
if (newTitle) {
|
||||||
@@ -719,65 +675,6 @@ 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,4 +1,79 @@
|
|||||||
|
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')
|
||||||
@@ -17,7 +92,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', 'noopener,noreferrer')
|
window.open(vm.itemSelectedDetails.link, '_blank')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleReadability: function() {
|
toggleReadability: function() {
|
||||||
@@ -43,16 +118,16 @@ var shortcutFunctions = {
|
|||||||
document.getElementById("searchbar").focus()
|
document.getElementById("searchbar").focus()
|
||||||
},
|
},
|
||||||
nextItem(){
|
nextItem(){
|
||||||
vm.navigateToItem(+1)
|
helperFunctions.navigateToItem(+1)
|
||||||
},
|
},
|
||||||
previousItem() {
|
previousItem() {
|
||||||
vm.navigateToItem(-1)
|
helperFunctions.navigateToItem(-1)
|
||||||
},
|
},
|
||||||
nextFeed(){
|
nextFeed(){
|
||||||
vm.navigateToFeed(+1)
|
helperFunctions.navigateToFeed(+1)
|
||||||
},
|
},
|
||||||
previousFeed() {
|
previousFeed() {
|
||||||
vm.navigateToFeed(-1)
|
helperFunctions.navigateToFeed(-1)
|
||||||
},
|
},
|
||||||
scrollForward: function() {
|
scrollForward: function() {
|
||||||
helperFunctions.scrollContent(+1)
|
helperFunctions.scrollContent(+1)
|
||||||
|
|||||||
34
src/assets/javascripts/sw.js
Normal file
34
src/assets/javascripts/sw.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
const VERSION = "v2.4"
|
||||||
|
const APP_STATIC_RESOURCES = [
|
||||||
|
"/",
|
||||||
|
"/static/stylesheets/bootstrap.min.css",
|
||||||
|
"/static/stylesheets/app.css",
|
||||||
|
"/static/graphicarts/favicon.svg",
|
||||||
|
"/static/graphicarts/favicon.png",
|
||||||
|
]
|
||||||
|
const CACHE_NAME = `yarr-${VERSION}`;
|
||||||
|
|
||||||
|
self.addEventListener("install", (e) => {
|
||||||
|
e.waitUntil((async () => {
|
||||||
|
const cache = await caches.open(CACHE_NAME)
|
||||||
|
await cache.addAll(APP_STATIC_RESOURCES)
|
||||||
|
})()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// delete old caches on activate
|
||||||
|
self.addEventListener("activate", (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
(async () => {
|
||||||
|
const names = await caches.keys()
|
||||||
|
await Promise.all(
|
||||||
|
names.map((name) => {
|
||||||
|
if (name !== CACHE_NAME) {
|
||||||
|
return caches.delete(name)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
await clients.claim()
|
||||||
|
})(),
|
||||||
|
)
|
||||||
|
})
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="theme-{% .settings.theme_name %}">
|
<body>
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
<img src="./static/graphicarts/anchor.svg" alt="">
|
<img src="./static/graphicarts/anchor.svg" alt="">
|
||||||
{% if .error %}
|
{% if .error %}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
|
||||||
|
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
)
|
)
|
||||||
@@ -62,16 +61,3 @@ 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,21 +24,3 @@ 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"`, `referrerpolicy="no-referrer"`}
|
return []string{"loading"}, []string{`loading="lazy"`}
|
||||||
default:
|
default:
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,10 @@ 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>`
|
||||||
want := `<p>This is a <strong>text</strong> with an image: <img src="http://example.org/" alt="Test" loading="lazy" referrerpolicy="no-referrer">.</p>`
|
output := Sanitize("http://example.org/", input)
|
||||||
have := Sanitize("http://example.org/", input)
|
|
||||||
|
|
||||||
if have != want {
|
if input != output {
|
||||||
t.Errorf("Wrong output: \nwant: %#v\nhave: %#v", want, have)
|
t.Errorf(`Wrong output: "%s" != "%s"`, input, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,31 +27,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">`
|
||||||
want := `<img src="data:image/gif;base64,test" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
|
expected := `<img src="data:image/gif;base64,test" alt="Example" loading="lazy">`
|
||||||
have := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if have != want {
|
if output != expected {
|
||||||
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
t.Errorf(`Wrong output: %s`, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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">`
|
||||||
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">`
|
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">`
|
||||||
have := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if have != want {
|
if output != expected {
|
||||||
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
t.Errorf(`Wrong output: %s`, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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">`
|
||||||
want := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
|
expected := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example" loading="lazy">`
|
||||||
have := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if have != want {
|
if output != expected {
|
||||||
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
t.Errorf(`Wrong output: %s`, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,16 +67,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">`
|
||||||
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">`
|
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">`
|
||||||
have := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if have != want {
|
if output != expected {
|
||||||
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
t.Errorf(`Wrong output: %s`, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelfClosingTags(t *testing.T) {
|
func TestSelfClosingTags(t *testing.T) {
|
||||||
input := `<p>This <br> is a <strong>text</strong><br/>.</p>`
|
input := `<p>This <br> is a <strong>text</strong> <br/>with an image: <img src="http://example.org/" alt="Test" loading="lazy"/>.</p>`
|
||||||
output := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if input != output {
|
if input != output {
|
||||||
@@ -96,11 +95,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"/>`
|
||||||
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"/>`
|
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"/>`
|
||||||
have := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if want != have {
|
if expected != output {
|
||||||
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,11 +165,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>`
|
||||||
want := `<iframe src="http://example.org/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
|
expected := `<iframe src="http://example.org/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
|
||||||
have := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if want != have {
|
if expected != output {
|
||||||
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
|
t.Errorf("Wrong output:\nwant: %s\nhave: %s", expected, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package scraper
|
package scraper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/nkanaev/yarr/src/content/htmlutil"
|
"github.com/nkanaev/yarr/src/content/htmlutil"
|
||||||
@@ -36,18 +35,6 @@ 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,6 +3,7 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"html"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ func (a *atomText) String() string {
|
|||||||
if a.Type == "xhtml" {
|
if a.Type == "xhtml" {
|
||||||
data = a.XML
|
data = a.XML
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(data)
|
return html.UnescapeString(strings.TrimSpace(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (links atomLinks) First(rel string) string {
|
func (links atomLinks) First(rel string) string {
|
||||||
@@ -89,16 +90,15 @@ 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),
|
||||||
Date: dateParse(firstNonEmpty(srcitem.Published, srcitem.Updated)),
|
Date: dateParse(firstNonEmpty(srcitem.Published, srcitem.Updated)),
|
||||||
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()),
|
||||||
MediaLinks: mediaLinks,
|
ImageURL: srcitem.firstMediaThumbnail(),
|
||||||
|
AudioURL: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return dstfeed, nil
|
return dstfeed, nil
|
||||||
|
|||||||
@@ -40,11 +40,13 @@ func TestAtom(t *testing.T) {
|
|||||||
SiteURL: "http://example.org/",
|
SiteURL: "http://example.org/",
|
||||||
Items: []Item{
|
Items: []Item{
|
||||||
{
|
{
|
||||||
GUID: "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
|
GUID: "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
|
||||||
Date: time.Unix(1071340202, 0).UTC(),
|
Date: time.Unix(1071340202, 0).UTC(),
|
||||||
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: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -139,15 +141,9 @@ func TestAtomImageLink(t *testing.T) {
|
|||||||
</entry>
|
</entry>
|
||||||
</feed>
|
</feed>
|
||||||
`))
|
`))
|
||||||
if len(feed.Items[0].MediaLinks) != 1 {
|
have := feed.Items[0].ImageURL
|
||||||
t.Fatalf("Expected 1 media link, got: %#v", feed.Items[0].MediaLinks)
|
want := `https://example.com/image.png?width=100&height=100`
|
||||||
}
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,8 +165,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 len(feed.Items[0].MediaLinks) != 0 {
|
if feed.Items[0].ImageURL != "" {
|
||||||
t.Fatal("item media link must be excluded if present in the content")
|
t.Fatal("item.image_url must be unset if present in the content")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,41 +192,25 @@ func TestAtomLinkInID(t *testing.T) {
|
|||||||
have := feed.Items
|
have := feed.Items
|
||||||
want := []Item{
|
want := []Item{
|
||||||
Item{
|
Item{
|
||||||
GUID: "https://example.com/posts/1::2003-12-13T09:17:51",
|
GUID: "https://example.com/posts/1::2003-12-13T09:17:51",
|
||||||
Date: time.Date(2003, time.December, 13, 9, 17, 51, 0, time.UTC),
|
Date: time.Date(2003, time.December, 13, 9, 17, 51, 0, time.UTC),
|
||||||
URL: "https://example.com/posts/1",
|
URL: "https://example.com/posts/1",
|
||||||
Title: "one updated",
|
Title: "one updated",
|
||||||
},
|
},
|
||||||
Item{
|
Item{
|
||||||
GUID: "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6",
|
GUID: "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6",
|
||||||
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), URL: "",
|
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), URL: "",
|
||||||
Title: "two",
|
Title: "two",
|
||||||
},
|
},
|
||||||
Item{
|
Item{
|
||||||
GUID: "https://example.com/posts/1::",
|
GUID: "https://example.com/posts/1::",
|
||||||
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
|
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
|
||||||
URL: "https://example.com/posts/1",
|
URL: "https://example.com/posts/1",
|
||||||
Title: "one",
|
Title: "one",
|
||||||
Content: "",
|
Content: "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(want, have) {
|
if !reflect.DeepEqual(want, have) {
|
||||||
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,7 +2,6 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -120,7 +119,6 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,14 +132,11 @@ 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 len(feed.Items[i].MediaLinks) > 0 {
|
if item.ImageURL != "" && strings.Contains(item.Content, item.ImageURL) {
|
||||||
mediaLinks := make([]MediaLink, 0)
|
feed.Items[i].ImageURL = ""
|
||||||
for _, link := range item.MediaLinks {
|
}
|
||||||
if !strings.Contains(item.Content, link.URL) {
|
if item.AudioURL != "" && strings.Contains(item.Content, item.AudioURL) {
|
||||||
mediaLinks = append(mediaLinks, link)
|
feed.Items[i].AudioURL = ""
|
||||||
}
|
|
||||||
}
|
|
||||||
feed.Items[i].MediaLinks = mediaLinks
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,12 +168,3 @@ 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,32 +150,3 @@ 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,9 +1,5 @@
|
|||||||
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"`
|
||||||
@@ -12,17 +8,12 @@ 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 {
|
||||||
@@ -30,8 +21,8 @@ type mediaThumbnail struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mediaDescription struct {
|
type mediaDescription struct {
|
||||||
Type string `xml:"type,attr"`
|
Type string `xml:"type,attr"`
|
||||||
Text string `xml:",chardata"`
|
Description string `xml:",chardata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *media) firstMediaThumbnail() string {
|
func (m *media) firstMediaThumbnail() string {
|
||||||
@@ -53,59 +44,12 @@ 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.Text)
|
return plain2html(d.Description)
|
||||||
}
|
}
|
||||||
for _, g := range m.MediaGroups {
|
for _, g := range m.MediaGroups {
|
||||||
for _, d := range g.MediaDescriptions {
|
for _, d := range g.MediaDescriptions {
|
||||||
return plain2html(d.Text)
|
return plain2html(d.Description)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,12 +14,7 @@ type Item struct {
|
|||||||
URL string
|
URL string
|
||||||
Title string
|
Title string
|
||||||
|
|
||||||
Content string
|
Content string
|
||||||
MediaLinks []MediaLink
|
ImageURL string
|
||||||
}
|
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 {
|
||||||
mediaLinks := srcitem.mediaLinks()
|
podcastURL := ""
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,12 +92,13 @@ func ParseRSS(r io.Reader) (*Feed, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dstfeed.Items = append(dstfeed.Items, Item{
|
dstfeed.Items = append(dstfeed.Items, Item{
|
||||||
GUID: firstNonEmpty(srcitem.GUID.GUID, srcitem.Link),
|
GUID: firstNonEmpty(srcitem.GUID.GUID, srcitem.Link),
|
||||||
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, srcitem.firstMediaDescription()),
|
Content: firstNonEmpty(srcitem.ContentEncoded, srcitem.Description),
|
||||||
MediaLinks: mediaLinks,
|
AudioURL: podcastURL,
|
||||||
|
ImageURL: srcitem.firstMediaThumbnail(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return dstfeed, nil
|
return dstfeed, nil
|
||||||
|
|||||||
@@ -75,15 +75,9 @@ func TestRSSMediaContentThumbnail(t *testing.T) {
|
|||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
`))
|
`))
|
||||||
if len(feed.Items[0].MediaLinks) != 1 {
|
have := feed.Items[0].ImageURL
|
||||||
t.Fatalf("Expected 1 media link, got %#v", feed.Items[0].MediaLinks)
|
want := "https://i.vimeocdn.com/video/1092705247_960.jpg"
|
||||||
}
|
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()
|
||||||
@@ -133,15 +127,9 @@ func TestRSSPodcast(t *testing.T) {
|
|||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
`))
|
`))
|
||||||
if len(feed.Items[0].MediaLinks) != 1 {
|
have := feed.Items[0].AudioURL
|
||||||
t.Fatal("Invalid media links")
|
want := "http://example.com/audio.ext"
|
||||||
}
|
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()
|
||||||
@@ -159,15 +147,9 @@ func TestRSSOpusPodcast(t *testing.T) {
|
|||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
`))
|
`))
|
||||||
if len(feed.Items[0].MediaLinks) != 1 {
|
have := feed.Items[0].AudioURL
|
||||||
t.Fatal("Invalid media links")
|
want := "http://example.com/audio.ext"
|
||||||
}
|
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()
|
||||||
@@ -194,9 +176,8 @@ 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 != "" {
|
||||||
if len(feed.Items[0].MediaLinks) != 0 {
|
t.Fatal("item.audio_url must be unset if present in the content")
|
||||||
t.Fatal("item media must be excluded if present in the content")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,47 +223,8 @@ func TestRSSIsPermalink(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := 0; i < len(want); i++ {
|
for i := 0; i < len(want); i++ {
|
||||||
if !reflect.DeepEqual(want, have) {
|
if want[i] != have[i] {
|
||||||
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,7 +11,6 @@ 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()
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"github.com/nkanaev/yarr/src/assets"
|
"github.com/nkanaev/yarr/src/assets"
|
||||||
"github.com/nkanaev/yarr/src/server/router"
|
"github.com/nkanaev/yarr/src/server/router"
|
||||||
"github.com/nkanaev/yarr/src/storage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Middleware struct {
|
type Middleware struct {
|
||||||
@@ -14,7 +13,6 @@ type Middleware struct {
|
|||||||
Password string
|
Password string
|
||||||
BasePath string
|
BasePath string
|
||||||
Public []string
|
Public []string
|
||||||
DB *storage.Storage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsafeMethod(method string) bool {
|
func unsafeMethod(method string) bool {
|
||||||
@@ -48,15 +46,12 @@ func (m *Middleware) Handler(c *router.Context) {
|
|||||||
c.Redirect(rootUrl)
|
c.Redirect(rootUrl)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
|
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]string{
|
||||||
"username": username,
|
"username": username,
|
||||||
"error": "Invalid username/password",
|
"error": "Invalid username/password",
|
||||||
"settings": m.DB.GetSettings(),
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
|
c.HTML(http.StatusOK, assets.Template("login.html"), nil)
|
||||||
"settings": m.DB.GetSettings(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ func (s *Server) handler() http.Handler {
|
|||||||
Username: s.Username,
|
Username: s.Username,
|
||||||
Password: s.Password,
|
Password: s.Password,
|
||||||
Public: []string{"/static", "/fever"},
|
Public: []string{"/static", "/fever"},
|
||||||
DB: s.db,
|
|
||||||
}
|
}
|
||||||
r.Use(a.Handler)
|
r.Use(a.Handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
r.For("/", s.handleIndex)
|
r.For("/", s.handleIndex)
|
||||||
r.For("/manifest.json", s.handleManifest)
|
r.For("/manifest.json", s.handleManifest)
|
||||||
|
r.For("/sw.js", s.handleServiceWorker)
|
||||||
r.For("/static/*path", s.handleStatic)
|
r.For("/static/*path", s.handleStatic)
|
||||||
r.For("/api/status", s.handleStatus)
|
r.For("/api/status", s.handleStatus)
|
||||||
r.For("/api/folders", s.handleFolderList)
|
r.For("/api/folders", s.handleFolderList)
|
||||||
@@ -87,17 +87,31 @@ 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": "/" + strings.TrimPrefix(s.BasePath, "/"),
|
"start_url": s.BasePath,
|
||||||
"icons": []map[string]interface{}{
|
"icons": []map[string]interface{}{
|
||||||
{
|
{
|
||||||
"src": s.BasePath + "/static/graphicarts/favicon.png",
|
"src": s.BasePath + "/static/graphicarts/favicon.png",
|
||||||
"sizes": "64x64",
|
"sizes": "64x64",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"src": s.BasePath + "/static/graphicarts/favicon-144.png",
|
||||||
|
"sizes": "144x144",
|
||||||
|
"type": "image/png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": s.BasePath + "/static/graphicarts/favicon.svg",
|
||||||
|
"sizes": "any",
|
||||||
|
"type": "image/svg",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) handleServiceWorker(c *router.Context) {
|
||||||
|
http.ServeFile(c.Out, c.Req, "src/assets/javascripts/sw.js")
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) handleStatus(c *router.Context) {
|
func (s *Server) handleStatus(c *router.Context) {
|
||||||
c.JSON(http.StatusOK, map[string]interface{}{
|
c.JSON(http.StatusOK, map[string]interface{}{
|
||||||
"running": s.worker.FeedsPending(),
|
"running": s.worker.FeedsPending(),
|
||||||
@@ -294,11 +308,6 @@ func (s *Server) handleFeed(c *router.Context) {
|
|||||||
s.db.UpdateFeedFolder(id, &folderId)
|
s.db.UpdateFeedFolder(id, &folderId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if link, ok := body["feed_link"]; ok {
|
|
||||||
if reflect.TypeOf(link).Kind() == reflect.String {
|
|
||||||
s.db.UpdateFeedLink(id, link.(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.Out.WriteHeader(http.StatusOK)
|
c.Out.WriteHeader(http.StatusOK)
|
||||||
} else if c.Req.Method == "DELETE" {
|
} else if c.Req.Method == "DELETE" {
|
||||||
s.db.DeleteFeed(id)
|
s.db.DeleteFeed(id)
|
||||||
@@ -329,9 +338,6 @@ 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" {
|
||||||
@@ -374,19 +380,12 @@ 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, true)
|
items := s.db.ListItems(filter, perPage+1, newestFirst, false)
|
||||||
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,
|
||||||
|
|||||||
@@ -71,11 +71,6 @@ func (s *Storage) UpdateFeedFolder(feedId int64, newFolderId *int64) bool {
|
|||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Storage) UpdateFeedLink(feedId int64, newLink string) bool {
|
|
||||||
_, err := s.db.Exec(`update feeds set feed_link = ? where id = ?`, newLink, feedId)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Storage) UpdateFeedIcon(feedId int64, icon *[]byte) bool {
|
func (s *Storage) UpdateFeedIcon(feedId int64, icon *[]byte) bool {
|
||||||
_, err := s.db.Exec(`update feeds set icon = ? where id = ?`, icon, feedId)
|
_, err := s.db.Exec(`update feeds set icon = ? where id = ?`, icon, feedId)
|
||||||
return err == nil
|
return err == nil
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql/driver"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -45,35 +44,17 @@ 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"`
|
||||||
FeedId int64 `json:"feed_id"`
|
FeedId int64 `json:"feed_id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Link string `json:"link"`
|
Link string `json:"link"`
|
||||||
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"`
|
||||||
MediaLinks MediaLinks `json:"media_links"`
|
ImageURL *string `json:"image"`
|
||||||
|
AudioURL *string `json:"podcast_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemFilter struct {
|
type ItemFilter struct {
|
||||||
@@ -98,21 +79,22 @@ type MarkFilter struct {
|
|||||||
type ItemList []Item
|
type ItemList []Item
|
||||||
|
|
||||||
func (list ItemList) Len() int {
|
func (list ItemList) Len() int {
|
||||||
return len(list)
|
return len(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list ItemList) SortKey(i int) string {
|
func (list ItemList) SortKey(i int) string {
|
||||||
return list[i].Date.Format(time.RFC3339) + "::" + list[i].GUID
|
return list[i].Date.Format(time.RFC3339) + "::" + list[i].GUID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list ItemList) Less(i, j int) bool {
|
func (list ItemList) Less(i, j int) bool {
|
||||||
return list.SortKey(i) < list.SortKey(j)
|
return list.SortKey(i) < list.SortKey(j)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list ItemList) Swap(i, j int) {
|
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 {
|
||||||
@@ -122,24 +104,20 @@ func (s *Storage) CreateItems(items []Item) bool {
|
|||||||
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
|
|
||||||
itemsSorted := ItemList(items)
|
itemsSorted := ItemList(items)
|
||||||
sort.Sort(itemsSorted)
|
sort.Sort(itemsSorted)
|
||||||
|
|
||||||
for _, item := range itemsSorted {
|
for _, item := range itemsSorted {
|
||||||
_, 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, media_links,
|
content, image, podcast_url,
|
||||||
date_arrived, status
|
date_arrived, status
|
||||||
)
|
)
|
||||||
values (
|
values (?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%f', ?), ?, ?, ?, ?, ?)
|
||||||
?, ?, ?, ?, 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.MediaLinks,
|
item.Content, item.ImageURL, item.AudioURL,
|
||||||
now, UNREAD,
|
now, UNREAD,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -254,7 +232,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.media_links"
|
selectCols := "i.id, i.guid, i.feed_id, i.title, i.link, i.date, i.status, i.image, i.podcast_url"
|
||||||
if withContent {
|
if withContent {
|
||||||
selectCols += ", i.content"
|
selectCols += ", i.content"
|
||||||
} else {
|
} else {
|
||||||
@@ -277,7 +255,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.MediaLinks, &x.Content,
|
&x.Status, &x.ImageURL, &x.AudioURL, &x.Content,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
@@ -293,12 +271,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.media_links
|
i.date, i.status, i.image, i.podcast_url
|
||||||
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.MediaLinks,
|
&i.Date, &i.Status, &i.ImageURL, &i.AudioURL,
|
||||||
)
|
)
|
||||||
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.media_links
|
i.date, i.status, i.image, i.podcast_url
|
||||||
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.MediaLinks,
|
&i.Date, &i.Status, &i.ImageURL, &i.AudioURL,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|||||||
@@ -16,17 +16,13 @@ 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
|
||||||
if err := db.QueryRow("pragma user_version").Scan(&version); err != nil {
|
db.QueryRow("pragma user_version").Scan(&version)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if version >= maxVersion {
|
if version >= maxVersion {
|
||||||
return nil
|
return nil
|
||||||
@@ -298,37 +294,3 @@ 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,9 +2,6 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,17 +10,14 @@ 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,4 +1,3 @@
|
|||||||
//go:build darwin || windows
|
|
||||||
// +build darwin windows
|
// +build darwin windows
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//go:build never
|
|
||||||
// +build never
|
// +build never
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//go:build darwin
|
|
||||||
// +build darwin
|
// +build darwin
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package systray
|
package systray
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ 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,19 +143,24 @@ 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
|
||||||
mediaLinks := make(storage.MediaLinks, 0)
|
var audioURL *string = nil
|
||||||
for _, link := range item.MediaLinks {
|
if item.AudioURL != "" {
|
||||||
mediaLinks = append(mediaLinks, storage.MediaLink(link))
|
audioURL = &item.AudioURL
|
||||||
|
}
|
||||||
|
var imageURL *string = nil
|
||||||
|
if item.ImageURL != "" {
|
||||||
|
imageURL = &item.ImageURL
|
||||||
}
|
}
|
||||||
result[i] = storage.Item{
|
result[i] = storage.Item{
|
||||||
GUID: item.GUID,
|
GUID: item.GUID,
|
||||||
FeedId: feed.Id,
|
FeedId: feed.Id,
|
||||||
Title: item.Title,
|
Title: item.Title,
|
||||||
Link: item.URL,
|
Link: item.URL,
|
||||||
Content: item.Content,
|
Content: item.Content,
|
||||||
Date: item.Date,
|
Date: item.Date,
|
||||||
Status: storage.UNREAD,
|
Status: storage.UNREAD,
|
||||||
MediaLinks: mediaLinks,
|
ImageURL: imageURL,
|
||||||
|
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 2009 The Go Authors.
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
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 LLC nor the names of its
|
* Neither the name of Google Inc. 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,11 +78,16 @@ example, to process each anchor node in depth-first order:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
for n := range doc.Descendants() {
|
var f func(*html.Node)
|
||||||
|
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
|
||||||
@@ -99,7 +104,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 document's DOM tree.
|
specification, dynamically modifying or extending the docuemnt'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.EqualFold(lastAttr.Val, "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") {
|
strings.ToLower(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,7 +40,8 @@ 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" {
|
||||||
if strings.EqualFold(a.Val, "text/html") || strings.EqualFold(a.Val, "application/xhtml+xml") {
|
val := strings.ToLower(a.Val)
|
||||||
|
if val == "text/html" || val == "application/xhtml+xml" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
vendor/golang.org/x/net/html/iter.go
generated
vendored
56
vendor/golang.org/x/net/html/iter.go
generated
vendored
@@ -1,56 +0,0 @@
|
|||||||
// 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,10 +38,6 @@ 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,10 +840,6 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1035,7 +1031,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.EqualFold(t.Val, "hidden") {
|
if strings.ToLower(t.Val) == "hidden" {
|
||||||
// Skip setting framesetOK = false
|
// Skip setting framesetOK = false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -1463,7 +1459,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.EqualFold(t.Val, "hidden") {
|
if t.Key == "type" && strings.ToLower(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,6 +910,9 @@ 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
|
||||||
@@ -917,9 +920,7 @@ func (z *Tokenizer) readTagAttrKey() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case ' ', '\n', '\r', '\t', '\f', '/', '>':
|
case '>':
|
||||||
// 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
|
||||||
@@ -938,11 +939,6 @@ 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 2009 The Go Authors.
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
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 LLC nor the names of its
|
* Neither the name of Google Inc. 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,7 +2,8 @@
|
|||||||
// 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
|
//go:build windows && go1.9
|
||||||
|
// +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 fails.
|
// MustLoadDLL is like LoadDLL but panics if load operation failes.
|
||||||
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
Normal file
9
vendor/golang.org/x/sys/windows/empty.s
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// 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,17 +37,14 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer DestroyEnvironmentBlock(block)
|
defer DestroyEnvironmentBlock(block)
|
||||||
size := unsafe.Sizeof(*block)
|
blockp := unsafe.Pointer(block)
|
||||||
for *block != 0 {
|
for {
|
||||||
// find NUL terminator
|
entry := UTF16PtrToString((*uint16)(blockp))
|
||||||
end := unsafe.Pointer(block)
|
if len(entry) == 0 {
|
||||||
for *(*uint16)(end) != 0 {
|
break
|
||||||
end = unsafe.Add(end, size)
|
|
||||||
}
|
}
|
||||||
|
env = append(env, entry)
|
||||||
entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size)
|
blockp = unsafe.Add(blockp, 2*(len(entry)+1))
|
||||||
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,6 +3,7 @@
|
|||||||
// 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,6 +3,7 @@
|
|||||||
// 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,6 +3,7 @@
|
|||||||
// 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,6 +3,7 @@
|
|||||||
// 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,7 +68,6 @@ 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
|
||||||
@@ -894,7 +893,7 @@ type ACL struct {
|
|||||||
aclRevision byte
|
aclRevision byte
|
||||||
sbz1 byte
|
sbz1 byte
|
||||||
aclSize uint16
|
aclSize uint16
|
||||||
AceCount uint16
|
aceCount uint16
|
||||||
sbz2 uint16
|
sbz2 uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,27 +1086,6 @@ 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
|
||||||
|
|
||||||
@@ -1179,7 +1157,6 @@ 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,6 +3,7 @@
|
|||||||
// 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,6 +3,7 @@
|
|||||||
// 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,6 +3,7 @@
|
|||||||
// 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,10 +17,8 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type Handle uintptr
|
||||||
Handle uintptr
|
type HWND uintptr
|
||||||
HWND uintptr
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
InvalidHandle = ^Handle(0)
|
InvalidHandle = ^Handle(0)
|
||||||
@@ -127,7 +125,8 @@ 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 }
|
||||||
@@ -156,8 +155,6 @@ 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
|
||||||
@@ -167,9 +164,6 @@ 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
|
||||||
@@ -198,7 +192,6 @@ 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]
|
||||||
@@ -215,10 +208,6 @@ 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
|
||||||
@@ -244,7 +233,6 @@ 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
|
||||||
@@ -315,10 +303,6 @@ 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
|
||||||
@@ -361,19 +345,8 @@ 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
|
||||||
@@ -727,12 +700,20 @@ func DurationSinceBoot() time.Duration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Ftruncate(fd Handle, length int64) (err error) {
|
func Ftruncate(fd Handle, length int64) (err error) {
|
||||||
type _FILE_END_OF_FILE_INFO struct {
|
curoffset, e := Seek(fd, 0, 1)
|
||||||
EndOfFile int64
|
if e != nil {
|
||||||
|
return e
|
||||||
}
|
}
|
||||||
var info _FILE_END_OF_FILE_INFO
|
defer Seek(fd, curoffset, 0)
|
||||||
info.EndOfFile = length
|
_, e = Seek(fd, length, 0)
|
||||||
return SetFileInformationByHandle(fd, FileEndOfFileInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info)))
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e = SetEndOfFile(fd)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Gettimeofday(tv *Timeval) (err error) {
|
func Gettimeofday(tv *Timeval) (err error) {
|
||||||
@@ -888,11 +869,6 @@ 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.
|
||||||
@@ -993,8 +969,7 @@ 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] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
|
if sa.raw.Path[0] == '@' {
|
||||||
// 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--
|
||||||
@@ -1377,11 +1352,9 @@ 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
|
||||||
}
|
}
|
||||||
@@ -1684,16 +1657,13 @@ 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) {
|
||||||
s16, err := UTF16FromString(s)
|
var u NTUnicodeString
|
||||||
|
s16, err := UTF16PtrFromString(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
n := uint16(len(s16) * 2)
|
RtlInitUnicodeString(&u, s16)
|
||||||
return &NTUnicodeString{
|
return &u, nil
|
||||||
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.
|
||||||
@@ -1860,73 +1830,3 @@ 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
|
|
||||||
)
|
|
||||||
|
|||||||
251
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
251
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
@@ -176,7 +176,6 @@ 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
|
||||||
@@ -1061,7 +1060,6 @@ 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
|
||||||
|
|
||||||
@@ -1096,33 +1094,7 @@ 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
|
||||||
@@ -2005,21 +1977,7 @@ const (
|
|||||||
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
|
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
|
||||||
)
|
)
|
||||||
|
|
||||||
// Flags for GetAdaptersAddresses, see
|
const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
|
||||||
// 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
|
||||||
@@ -2033,50 +1991,6 @@ 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
|
||||||
@@ -2204,132 +2118,6 @@ 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.
|
||||||
|
|
||||||
@@ -3566,38 +3354,3 @@ 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,7 +91,6 @@ 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")
|
||||||
@@ -181,21 +180,13 @@ 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")
|
||||||
@@ -220,9 +211,7 @@ 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")
|
||||||
@@ -246,15 +235,11 @@ 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")
|
||||||
@@ -268,7 +253,6 @@ 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")
|
||||||
@@ -280,10 +264,8 @@ 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")
|
||||||
@@ -338,7 +320,6 @@ 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")
|
||||||
@@ -348,18 +329,12 @@ 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")
|
||||||
@@ -372,7 +347,6 @@ 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")
|
||||||
@@ -383,7 +357,6 @@ 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")
|
||||||
@@ -402,7 +375,6 @@ 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")
|
||||||
@@ -413,7 +385,6 @@ 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")
|
||||||
@@ -489,16 +460,12 @@ 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")
|
||||||
@@ -804,14 +771,6 @@ 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)
|
||||||
@@ -1613,14 +1572,6 @@ 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 {
|
||||||
@@ -1653,55 +1604,6 @@ 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 {
|
||||||
@@ -1726,22 +1628,6 @@ 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 {
|
||||||
@@ -1946,14 +1832,6 @@ 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 {
|
||||||
@@ -1966,14 +1844,6 @@ 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
|
||||||
@@ -2175,22 +2045,6 @@ 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 {
|
||||||
@@ -2221,15 +2075,6 @@ 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 {
|
||||||
@@ -2238,15 +2083,6 @@ 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 {
|
||||||
@@ -2349,14 +2185,6 @@ 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)
|
||||||
@@ -2448,14 +2276,6 @@ 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 {
|
||||||
@@ -2472,14 +2292,6 @@ 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 {
|
||||||
@@ -2977,14 +2789,6 @@ 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)
|
||||||
@@ -3066,14 +2870,6 @@ 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 {
|
||||||
@@ -3099,30 +2895,6 @@ 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 {
|
||||||
@@ -3131,14 +2903,6 @@ 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 {
|
||||||
@@ -3155,14 +2919,6 @@ 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 {
|
||||||
@@ -3267,14 +3023,6 @@ 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 {
|
||||||
@@ -3360,14 +3108,6 @@ 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)
|
||||||
@@ -3514,14 +3254,6 @@ 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 {
|
||||||
@@ -3609,14 +3341,6 @@ 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 {
|
||||||
@@ -4195,12 +3919,6 @@ 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)
|
||||||
@@ -4234,15 +3952,6 @@ 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)
|
||||||
@@ -4252,20 +3961,6 @@ 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 2009 The Go Authors.
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
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 LLC nor the names of its
|
* Neither the name of Google Inc. 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.33.0
|
# golang.org/x/net v0.17.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.17
|
||||||
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.28.0
|
# golang.org/x/sys v0.13.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.17
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/text v0.21.0
|
# golang.org/x/text v0.13.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.17
|
||||||
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