├── .dockerignore
├── .github
└── workflows
│ ├── build-test-lint.yml
│ ├── docker-images.yml
│ └── release.yml
├── .gitignore
├── API.md
├── CHANGELOG.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── config.example.json
├── go.mod
├── go.sum
├── http_root
├── css
│ ├── bootstrap.min.css
│ ├── screen.css
│ └── squashed.css
├── favicon
│ ├── browserconfig.xml
│ ├── favicon-114.png
│ ├── favicon-120.png
│ ├── favicon-144.png
│ ├── favicon-150.png
│ ├── favicon-152.png
│ ├── favicon-16.png
│ ├── favicon-160.png
│ ├── favicon-180.png
│ ├── favicon-192.png
│ ├── favicon-310.png
│ ├── favicon-32.png
│ ├── favicon-57.png
│ ├── favicon-60.png
│ ├── favicon-64.png
│ ├── favicon-70.png
│ ├── favicon-72.png
│ ├── favicon-76.png
│ ├── favicon-96.png
│ └── favicon.ico
├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ └── glyphicons-halflings-regular.woff2
├── images
│ ├── unknownAlbum.png
│ └── unknownArtist.png
├── js
│ ├── Jplayer.swf
│ ├── URI.min.js
│ ├── add-on
│ │ ├── jplayer.playlist.min.js
│ │ └── jquery.jplayer.inspector.js
│ ├── app.js
│ ├── bootstrap.min.js
│ ├── debug
│ │ ├── bootstrap.js
│ │ ├── jplayer.playlist.js
│ │ ├── jquery.jplayer.js
│ │ └── jquery.js
│ ├── ie8
│ │ ├── html5shiv.js
│ │ └── respond.min.js
│ ├── jquery.jplayer.min.js
│ ├── jquery.min.js
│ └── squashed.js
├── login
│ └── index.html
├── skin
│ └── blue.monday
│ │ ├── jplayer.blue.monday.css
│ │ ├── jplayer.blue.monday.jpg
│ │ ├── jplayer.blue.monday.seeking.gif
│ │ └── jplayer.blue.monday.video.play.png
└── squash
├── images
├── barded-spice-install-step1.png
├── barded-spice-install-step2.png
├── barded-spice-install-step3.png
├── euterpe-preview.webp
└── heavy-metal-128.png
├── main.go
├── sqls
├── library_schema.sql
└── migrations
│ ├── 001_album_artworks.sql
│ ├── 002_uniqueness.sql
│ ├── 003_track_duration.sql
│ ├── 004_artists_images.sql
│ ├── 005_small_images.sql
│ ├── 006_stats.sql
│ ├── 007_album_artist_stats.sql
│ ├── 008_more_track_columns.sql
│ ├── 009_internet_radio.sql
│ ├── 010_playlists.sql
│ └── 011_playlists_uniqe_index.sql
├── src
├── art
│ ├── album.go
│ ├── album_test.go
│ ├── art.go
│ ├── artfakes
│ │ ├── fake_caaclient.go
│ │ └── fake_finder.go
│ ├── artist.go
│ ├── artist_test.go
│ ├── caa_client.go
│ ├── client_test_helpers.go
│ ├── client_unexported_test.go
│ ├── doc.go
│ └── generate.go
├── assert
│ ├── assertfakes
│ │ └── fake_testing_fatalf.go
│ ├── common.go
│ ├── equal.go
│ ├── equal_test.go
│ ├── nils.go
│ └── nils_test.go
├── config
│ ├── config.go
│ └── config_test.go
├── daemon
│ ├── daemon_nix.go
│ ├── daemon_test.go
│ ├── daemon_win.go
│ └── doc.go
├── helpers
│ ├── helpers.go
│ ├── helpers_nix.go
│ ├── helpers_test.go
│ └── helpers_win.go
├── library
│ ├── artist_images.go
│ ├── artist_images_test.go
│ ├── artwork.go
│ ├── artwork_common.go
│ ├── artwork_test.go
│ ├── browser.go
│ ├── bytes_read_closer.go
│ ├── database.go
│ ├── format.go
│ ├── generate.go
│ ├── library.go
│ ├── library_test.go
│ ├── library_watch_test.go
│ ├── libraryfakes
│ │ ├── fake_artist_image_manager.go
│ │ ├── fake_artwork_manager.go
│ │ ├── fake_browser.go
│ │ └── fake_library.go
│ ├── local_browse.go
│ ├── local_browse_test.go
│ ├── local_database_utils.go
│ ├── local_favourites.go
│ ├── local_favourites_test.go
│ ├── local_library.go
│ ├── local_library_cleanup.go
│ ├── local_library_cleanup_test.go
│ ├── local_library_migrate.go
│ ├── local_library_scan.go
│ ├── local_library_watch.go
│ ├── local_ratings.go
│ ├── local_ratings_test.go
│ ├── media_file.go
│ ├── media_file_test.go
│ ├── mock_media_test.go
│ ├── os_fs.go
│ └── os_fs_test.go
├── main.go
├── playlists
│ ├── generate.go
│ ├── manager.go
│ ├── playlists.go
│ ├── playlists_test.go
│ └── playlistsfakes
│ │ └── fake_playlister.go
├── radio
│ ├── generate.go
│ ├── manager.go
│ ├── radio.go
│ ├── radio_test.go
│ └── radiofakes
│ │ └── fake_stations.go
├── scaler
│ ├── doc.go
│ ├── generate.go
│ ├── scaler.go
│ ├── scaler_test.go
│ └── scalerfakes
│ │ └── fake_scaler.go
├── tools
│ └── tools.go
├── version
│ ├── version.go
│ └── version_test.go
└── webserver
│ ├── apiv1_endpoints.go
│ ├── functions.go
│ ├── functions_test.go
│ ├── handler_about.go
│ ├── handler_about_test.go
│ ├── handler_access.go
│ ├── handler_access_test.go
│ ├── handler_album.go
│ ├── handler_album_artwork.go
│ ├── handler_album_artwork_test.go
│ ├── handler_artist_images.go
│ ├── handler_artist_images_test.go
│ ├── handler_auth.go
│ ├── handler_auth_test.go
│ ├── handler_browse.go
│ ├── handler_browse_test.go
│ ├── handler_create_qr_token.go
│ ├── handler_create_qr_token_test.go
│ ├── handler_file.go
│ ├── handler_file_test.go
│ ├── handler_gzip.go
│ ├── handler_login.go
│ ├── handler_login_test.go
│ ├── handler_login_token.go
│ ├── handler_login_token_test.go
│ ├── handler_logout.go
│ ├── handler_logout_test.go
│ ├── handler_playlist.go
│ ├── handler_playlist_test.go
│ ├── handler_playlists.go
│ ├── handler_playlists_test.go
│ ├── handler_register_token.go
│ ├── handler_register_token_test.go
│ ├── handler_search.go
│ ├── handler_template.go
│ ├── handler_terry.go
│ ├── subsonic
│ ├── auth.go
│ ├── auth_test.go
│ ├── base_responses.go
│ ├── cover_art_interfaces.go
│ ├── create_internet_radio_station.go
│ ├── create_playlist.go
│ ├── deleteInternetRadioStation.go
│ ├── delete_playlist.go
│ ├── errors.go
│ ├── generate.go
│ ├── get_album.go
│ ├── get_album_info.go
│ ├── get_album_info_2.go
│ ├── get_album_list.go
│ ├── get_album_list_2.go
│ ├── get_artist.go
│ ├── get_artist_info.go
│ ├── get_artist_info_2.go
│ ├── get_artist_info_2_test.go
│ ├── get_artist_info_test.go
│ ├── get_artists.go
│ ├── get_cover_art.go
│ ├── get_genres.go
│ ├── get_indexes.go
│ ├── get_internet_radion_stagions.go
│ ├── get_license.go
│ ├── get_music_directory.go
│ ├── get_music_folders.go
│ ├── get_open_subsonic_extensions.go
│ ├── get_playlist.go
│ ├── get_playlists.go
│ ├── get_random_songs.go
│ ├── get_song.go
│ ├── get_starred.go
│ ├── get_starred_2.go
│ ├── get_top_songs.go
│ ├── get_user.go
│ ├── get_video_info.go
│ ├── get_videos.go
│ ├── http.go
│ ├── id_conversion.go
│ ├── index.go
│ ├── open_subsonic_extensions_test.go
│ ├── ping.go
│ ├── progress.md
│ ├── scrobble.go
│ ├── search.go
│ ├── search2.go
│ ├── search3.go
│ ├── set_rating.go
│ ├── set_rating_test.go
│ ├── star.go
│ ├── stream.go
│ ├── subsonic-rest-api-1.16.1.xsd
│ ├── subsonicfakes
│ │ └── fake_cover_art_handler.go
│ ├── unstar.go
│ ├── update_internet_radio_station.go
│ ├── update_playlist.go
│ ├── xml_xsd_vaidate_test.go
│ └── xsd_types.go
│ ├── templates.go
│ ├── webserver.go
│ ├── webserver_test.go
│ └── webutils
│ ├── doc.go
│ ├── error.go
│ └── error_test.go
├── templates
├── add_device.html
├── layout.html
├── player.html
└── unauthorized.html
├── test_files
├── http_root
│ ├── second
│ │ └── static
│ └── static
├── library
│ ├── folder_one
│ │ ├── not_an_mp3
│ │ └── third_file.mp3
│ ├── test_file_one.mp3
│ └── test_file_two.mp3
├── more_mp3s
│ └── test_file_added.mp3
├── ogg_files
│ └── vorbis-tags.ogg
└── ssl
│ ├── cert.pem
│ └── key.pem
├── tools
├── bearded-spice.js
├── build
├── cross-compile
├── euterpe.service
├── install
├── nginx.conf
└── uninstall
├── vendor
├── github.com
│ ├── dhowden
│ │ └── tag
│ │ │ ├── .editorconfig
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── dsf.go
│ │ │ ├── flac.go
│ │ │ ├── id.go
│ │ │ ├── id3v1.go
│ │ │ ├── id3v2.go
│ │ │ ├── id3v2frames.go
│ │ │ ├── id3v2metadata.go
│ │ │ ├── mp4.go
│ │ │ ├── ogg.go
│ │ │ ├── sum.go
│ │ │ ├── tag.go
│ │ │ ├── util.go
│ │ │ └── vorbis.go
│ ├── gbrlsnchs
│ │ └── jwt
│ │ │ └── v3
│ │ │ ├── .editorconfig
│ │ │ ├── .gitignore
│ │ │ ├── CHANGELOG.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── algorithm.go
│ │ │ ├── audience.go
│ │ │ ├── doc.go
│ │ │ ├── ecdsa_sha.go
│ │ │ ├── ed25519.go
│ │ │ ├── ed25519_go1_12.go
│ │ │ ├── hash_pool.go
│ │ │ ├── header.go
│ │ │ ├── hmac_sha.go
│ │ │ ├── internal
│ │ │ ├── decode.go
│ │ │ ├── ed25519.go
│ │ │ ├── ed25519_go1_12.go
│ │ │ ├── epoch.go
│ │ │ ├── errors.go
│ │ │ └── errors_go1_12.go
│ │ │ ├── json.go
│ │ │ ├── magefile.go
│ │ │ ├── none.go
│ │ │ ├── payload.go
│ │ │ ├── raw_token.go
│ │ │ ├── resolver.go
│ │ │ ├── rsa_sha.go
│ │ │ ├── sign.go
│ │ │ ├── time.go
│ │ │ ├── validators.go
│ │ │ └── verify.go
│ ├── gorilla
│ │ ├── context
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── context.go
│ │ │ └── doc.go
│ │ └── mux
│ │ │ ├── .travis.yml
│ │ │ ├── ISSUE_TEMPLATE.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── context_gorilla.go
│ │ │ ├── context_native.go
│ │ │ ├── doc.go
│ │ │ ├── middleware.go
│ │ │ ├── mux.go
│ │ │ ├── regexp.go
│ │ │ ├── route.go
│ │ │ └── test_helpers.go
│ ├── howeyc
│ │ └── fsnotify
│ │ │ ├── .gitignore
│ │ │ ├── AUTHORS
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── fsnotify.go
│ │ │ ├── fsnotify_bsd.go
│ │ │ ├── fsnotify_linux.go
│ │ │ ├── fsnotify_open_bsd.go
│ │ │ ├── fsnotify_open_darwin.go
│ │ │ └── fsnotify_windows.go
│ ├── ironsmile
│ │ ├── sql-migrate
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── doc.go
│ │ │ ├── migrate.go
│ │ │ └── sqlparse
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ └── sqlparse.go
│ │ └── wrapfs
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── doc.go
│ │ │ └── modtimefs.go
│ ├── liyue201
│ │ └── goqr
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── decoding.go
│ │ │ ├── define.go
│ │ │ ├── errors.go
│ │ │ ├── qr_const.go
│ │ │ ├── qrcode.go
│ │ │ ├── recognition.go
│ │ │ ├── recognizer.go
│ │ │ ├── utils.go
│ │ │ └── version_db.go
│ ├── magefile
│ │ └── mage
│ │ │ ├── LICENSE
│ │ │ ├── mg
│ │ │ ├── color.go
│ │ │ ├── color_string.go
│ │ │ ├── deps.go
│ │ │ ├── errors.go
│ │ │ ├── fn.go
│ │ │ └── runtime.go
│ │ │ └── sh
│ │ │ ├── cmd.go
│ │ │ └── helpers.go
│ ├── mattn
│ │ └── go-sqlite3
│ │ │ ├── .codecov.yml
│ │ │ ├── .gitignore
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── backup.go
│ │ │ ├── callback.go
│ │ │ ├── convert.go
│ │ │ ├── doc.go
│ │ │ ├── error.go
│ │ │ ├── sqlite3-binding.c
│ │ │ ├── sqlite3-binding.h
│ │ │ ├── sqlite3.go
│ │ │ ├── sqlite3_context.go
│ │ │ ├── sqlite3_func_crypt.go
│ │ │ ├── sqlite3_go18.go
│ │ │ ├── sqlite3_libsqlite3.go
│ │ │ ├── sqlite3_load_extension.go
│ │ │ ├── sqlite3_load_extension_omit.go
│ │ │ ├── sqlite3_opt_allow_uri_authority.go
│ │ │ ├── sqlite3_opt_app_armor.go
│ │ │ ├── sqlite3_opt_column_metadata.go
│ │ │ ├── sqlite3_opt_foreign_keys.go
│ │ │ ├── sqlite3_opt_fts5.go
│ │ │ ├── sqlite3_opt_icu.go
│ │ │ ├── sqlite3_opt_introspect.go
│ │ │ ├── sqlite3_opt_math_functions.go
│ │ │ ├── sqlite3_opt_os_trace.go
│ │ │ ├── sqlite3_opt_preupdate.go
│ │ │ ├── sqlite3_opt_preupdate_hook.go
│ │ │ ├── sqlite3_opt_preupdate_omit.go
│ │ │ ├── sqlite3_opt_secure_delete.go
│ │ │ ├── sqlite3_opt_secure_delete_fast.go
│ │ │ ├── sqlite3_opt_serialize.go
│ │ │ ├── sqlite3_opt_serialize_omit.go
│ │ │ ├── sqlite3_opt_stat4.go
│ │ │ ├── sqlite3_opt_unlock_notify.c
│ │ │ ├── sqlite3_opt_unlock_notify.go
│ │ │ ├── sqlite3_opt_userauth.go
│ │ │ ├── sqlite3_opt_userauth_omit.go
│ │ │ ├── sqlite3_opt_vacuum_full.go
│ │ │ ├── sqlite3_opt_vacuum_incr.go
│ │ │ ├── sqlite3_opt_vtable.go
│ │ │ ├── sqlite3_other.go
│ │ │ ├── sqlite3_solaris.go
│ │ │ ├── sqlite3_trace.go
│ │ │ ├── sqlite3_type.go
│ │ │ ├── sqlite3_usleep_windows.go
│ │ │ ├── sqlite3_windows.go
│ │ │ ├── sqlite3ext.h
│ │ │ └── static_mock.go
│ ├── maxbrunsfeld
│ │ └── counterfeiter
│ │ │ └── v6
│ │ │ ├── .gitignore
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── appveyor.yml
│ │ │ ├── arguments
│ │ │ ├── files.go
│ │ │ ├── parser.go
│ │ │ └── usage.go
│ │ │ ├── command
│ │ │ └── runner.go
│ │ │ ├── generator
│ │ │ ├── cache.go
│ │ │ ├── ctx.go
│ │ │ ├── ctx_old.go
│ │ │ ├── fake.go
│ │ │ ├── file_reader.go
│ │ │ ├── function_loader.go
│ │ │ ├── function_template.go
│ │ │ ├── import.go
│ │ │ ├── interface_loader.go
│ │ │ ├── interface_template.go
│ │ │ ├── loader.go
│ │ │ ├── package_loader.go
│ │ │ ├── package_template.go
│ │ │ ├── param.go
│ │ │ └── return.go
│ │ │ └── main.go
│ ├── pborman
│ │ └── uuid
│ │ │ ├── .travis.yml
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── CONTRIBUTORS
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── dce.go
│ │ │ ├── doc.go
│ │ │ ├── hash.go
│ │ │ ├── marshal.go
│ │ │ ├── node.go
│ │ │ ├── sql.go
│ │ │ ├── time.go
│ │ │ ├── util.go
│ │ │ ├── uuid.go
│ │ │ ├── version1.go
│ │ │ └── version4.go
│ ├── skip2
│ │ └── go-qrcode
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── bitset
│ │ │ └── bitset.go
│ │ │ ├── encoder.go
│ │ │ ├── qrcode.go
│ │ │ ├── reedsolomon
│ │ │ ├── gf2_8.go
│ │ │ ├── gf_poly.go
│ │ │ └── reed_solomon.go
│ │ │ ├── regular_symbol.go
│ │ │ ├── symbol.go
│ │ │ └── version.go
│ ├── spf13
│ │ └── afero
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE.txt
│ │ │ ├── README.md
│ │ │ ├── afero.go
│ │ │ ├── appveyor.yml
│ │ │ ├── basepath.go
│ │ │ ├── cacheOnReadFs.go
│ │ │ ├── const_bsds.go
│ │ │ ├── const_win_unix.go
│ │ │ ├── copyOnWriteFs.go
│ │ │ ├── httpFs.go
│ │ │ ├── iofs.go
│ │ │ ├── ioutil.go
│ │ │ ├── lstater.go
│ │ │ ├── match.go
│ │ │ ├── mem
│ │ │ ├── dir.go
│ │ │ ├── dirmap.go
│ │ │ └── file.go
│ │ │ ├── memmap.go
│ │ │ ├── os.go
│ │ │ ├── path.go
│ │ │ ├── readonlyfs.go
│ │ │ ├── regexpfs.go
│ │ │ ├── symlink.go
│ │ │ ├── unionFile.go
│ │ │ └── util.go
│ ├── terminalstatic
│ │ └── go-xsd-validate
│ │ │ ├── .gitignore
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── errors.go
│ │ │ ├── libxml2.go
│ │ │ ├── validate_xsd.go
│ │ │ └── workspace.code-workspace
│ └── wtolson
│ │ └── go-taglib
│ │ ├── .gitignore
│ │ ├── .travis.yml
│ │ ├── README.md
│ │ ├── taglib.go
│ │ └── test.mp3
├── golang.org
│ └── x
│ │ ├── crypto
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ └── ed25519
│ │ │ └── ed25519.go
│ │ ├── image
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ ├── bmp
│ │ │ ├── reader.go
│ │ │ └── writer.go
│ │ ├── ccitt
│ │ │ ├── reader.go
│ │ │ ├── table.go
│ │ │ └── writer.go
│ │ ├── draw
│ │ │ ├── draw.go
│ │ │ ├── impl.go
│ │ │ └── scale.go
│ │ ├── math
│ │ │ └── f64
│ │ │ │ └── f64.go
│ │ ├── riff
│ │ │ └── riff.go
│ │ ├── tiff
│ │ │ ├── buffer.go
│ │ │ ├── compress.go
│ │ │ ├── consts.go
│ │ │ ├── fuzz.go
│ │ │ ├── lzw
│ │ │ │ └── reader.go
│ │ │ ├── reader.go
│ │ │ └── writer.go
│ │ ├── vp8
│ │ │ ├── decode.go
│ │ │ ├── filter.go
│ │ │ ├── idct.go
│ │ │ ├── partition.go
│ │ │ ├── pred.go
│ │ │ ├── predfunc.go
│ │ │ ├── quant.go
│ │ │ ├── reconstruct.go
│ │ │ └── token.go
│ │ ├── vp8l
│ │ │ ├── decode.go
│ │ │ ├── huffman.go
│ │ │ └── transform.go
│ │ └── webp
│ │ │ ├── decode.go
│ │ │ └── doc.go
│ │ ├── mod
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ ├── internal
│ │ │ └── lazyregexp
│ │ │ │ └── lazyre.go
│ │ ├── module
│ │ │ ├── module.go
│ │ │ └── pseudo.go
│ │ └── semver
│ │ │ └── semver.go
│ │ ├── sync
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ └── errgroup
│ │ │ └── errgroup.go
│ │ ├── text
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ ├── transform
│ │ │ └── transform.go
│ │ └── unicode
│ │ │ └── norm
│ │ │ ├── composition.go
│ │ │ ├── forminfo.go
│ │ │ ├── input.go
│ │ │ ├── iter.go
│ │ │ ├── normalize.go
│ │ │ ├── readwriter.go
│ │ │ ├── tables10.0.0.go
│ │ │ ├── tables11.0.0.go
│ │ │ ├── tables12.0.0.go
│ │ │ ├── tables13.0.0.go
│ │ │ ├── tables15.0.0.go
│ │ │ ├── tables9.0.0.go
│ │ │ ├── transform.go
│ │ │ └── trie.go
│ │ ├── tools
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ ├── go
│ │ │ ├── ast
│ │ │ │ └── astutil
│ │ │ │ │ ├── enclosing.go
│ │ │ │ │ ├── imports.go
│ │ │ │ │ ├── rewrite.go
│ │ │ │ │ └── util.go
│ │ │ ├── gcexportdata
│ │ │ │ ├── gcexportdata.go
│ │ │ │ └── importer.go
│ │ │ ├── internal
│ │ │ │ └── packagesdriver
│ │ │ │ │ └── sizes.go
│ │ │ ├── packages
│ │ │ │ ├── doc.go
│ │ │ │ ├── external.go
│ │ │ │ ├── golist.go
│ │ │ │ ├── golist_overlay.go
│ │ │ │ ├── loadmode_string.go
│ │ │ │ ├── packages.go
│ │ │ │ └── visit.go
│ │ │ └── types
│ │ │ │ ├── objectpath
│ │ │ │ └── objectpath.go
│ │ │ │ └── typeutil
│ │ │ │ ├── callee.go
│ │ │ │ ├── imports.go
│ │ │ │ ├── map.go
│ │ │ │ ├── methodsetcache.go
│ │ │ │ └── ui.go
│ │ ├── imports
│ │ │ └── forward.go
│ │ └── internal
│ │ │ ├── aliases
│ │ │ ├── aliases.go
│ │ │ ├── aliases_go121.go
│ │ │ └── aliases_go122.go
│ │ │ ├── event
│ │ │ ├── core
│ │ │ │ ├── event.go
│ │ │ │ ├── export.go
│ │ │ │ └── fast.go
│ │ │ ├── doc.go
│ │ │ ├── event.go
│ │ │ ├── keys
│ │ │ │ ├── keys.go
│ │ │ │ ├── standard.go
│ │ │ │ └── util.go
│ │ │ └── label
│ │ │ │ └── label.go
│ │ │ ├── gcimporter
│ │ │ ├── bimport.go
│ │ │ ├── exportdata.go
│ │ │ ├── gcimporter.go
│ │ │ ├── iexport.go
│ │ │ ├── iimport.go
│ │ │ ├── newInterface10.go
│ │ │ ├── newInterface11.go
│ │ │ ├── support_go118.go
│ │ │ ├── unified_no.go
│ │ │ ├── unified_yes.go
│ │ │ └── ureader_yes.go
│ │ │ ├── gocommand
│ │ │ ├── invoke.go
│ │ │ ├── vendor.go
│ │ │ └── version.go
│ │ │ ├── gopathwalk
│ │ │ └── walk.go
│ │ │ ├── imports
│ │ │ ├── fix.go
│ │ │ ├── imports.go
│ │ │ ├── mod.go
│ │ │ ├── mod_cache.go
│ │ │ └── sortimports.go
│ │ │ ├── packagesinternal
│ │ │ └── packages.go
│ │ │ ├── pkgbits
│ │ │ ├── codes.go
│ │ │ ├── decoder.go
│ │ │ ├── doc.go
│ │ │ ├── encoder.go
│ │ │ ├── flags.go
│ │ │ ├── frames_go1.go
│ │ │ ├── frames_go17.go
│ │ │ ├── reloc.go
│ │ │ ├── support.go
│ │ │ ├── sync.go
│ │ │ └── syncmarker_string.go
│ │ │ ├── stdlib
│ │ │ ├── manifest.go
│ │ │ └── stdlib.go
│ │ │ ├── tokeninternal
│ │ │ └── tokeninternal.go
│ │ │ ├── typeparams
│ │ │ ├── common.go
│ │ │ ├── coretype.go
│ │ │ ├── free.go
│ │ │ ├── normalize.go
│ │ │ ├── termlist.go
│ │ │ └── typeterm.go
│ │ │ ├── typesinternal
│ │ │ ├── errorcode.go
│ │ │ ├── errorcode_string.go
│ │ │ ├── recv.go
│ │ │ ├── toonew.go
│ │ │ └── types.go
│ │ │ └── versions
│ │ │ ├── features.go
│ │ │ ├── gover.go
│ │ │ ├── toolchain.go
│ │ │ ├── toolchain_go119.go
│ │ │ ├── toolchain_go120.go
│ │ │ ├── toolchain_go121.go
│ │ │ ├── types.go
│ │ │ ├── types_go121.go
│ │ │ ├── types_go122.go
│ │ │ └── versions.go
│ │ └── xerrors
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ ├── README
│ │ ├── adaptor.go
│ │ ├── codereview.cfg
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── fmt.go
│ │ ├── format.go
│ │ ├── frame.go
│ │ ├── internal
│ │ └── internal.go
│ │ └── wrap.go
├── gopkg.in
│ ├── gorp.v1
│ │ ├── .gitignore
│ │ ├── .travis.yml
│ │ ├── LICENSE
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── dialect.go
│ │ ├── errors.go
│ │ ├── gorp.go
│ │ └── test_all.sh
│ └── mineo
│ │ └── gocaa.v1
│ │ ├── .travis.yml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── client.go
│ │ ├── errors.go
│ │ ├── imagesizes.go
│ │ ├── reexports.go
│ │ └── types.go
└── modules.txt
└── watch.sh
/.dockerignore:
--------------------------------------------------------------------------------
1 | /dist
2 |
--------------------------------------------------------------------------------
/.github/workflows/docker-images.yml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub.
2 | # They are provided by a third-party and are governed by
3 | # separate terms of service, privacy policy, and support
4 | # documentation.
5 |
6 | name: Publish Docker image
7 |
8 | on:
9 | release:
10 | types: [published]
11 |
12 | jobs:
13 | push_to_registry:
14 | name: Push Docker image to Docker Hub
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Check out the repo
18 | uses: actions/checkout@v2
19 |
20 | - name: Log in to Docker Hub
21 | uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
22 | with:
23 | username: ${{ secrets.DOCKER_USERNAME }}
24 | password: ${{ secrets.DOCKER_PASSWORD }}
25 |
26 | - name: Extract metadata (tags, labels) for Docker
27 | id: meta
28 | uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
29 | with:
30 | images: ironsmile/euterpe
31 |
32 | - name: Build and push Docker image
33 | uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
34 | with:
35 | context: .
36 | push: true
37 | tags: ${{ steps.meta.outputs.tags }}
38 | labels: ${{ steps.meta.outputs.labels }}
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 |
24 | # Sublime project stuff
25 | *.sublime-project
26 | *.sublime-workspace
27 |
28 | # Application logfiles
29 | logfile
30 |
31 | # CTags
32 | .tags
33 | .tags_sorted_by_file
34 |
35 | # Build dir
36 | dist/*
37 |
38 | # The built binary
39 | /httpms
40 | /euterpe
41 |
42 | # OSX bullshits
43 | **/.DS_Store
44 |
45 | # Artifacts from test coverage
46 | /covprofile
47 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.24-alpine3.21 as builder
2 |
3 | RUN apk add --update taglib-dev libc-dev icu-dev icu-data-full upx bmake gcc git zlib-dev
4 |
5 | COPY . /src/euterpe
6 | WORKDIR /src/euterpe
7 |
8 | RUN bmake release
9 | RUN mv euterpe /tmp/euterpe
10 | RUN /tmp/euterpe -config-gen && sed -i 's/localhost:9996/0.0.0.0:9996/' /root/.euterpe/config.json
11 |
12 | FROM alpine:3.21
13 |
14 | RUN apk add --update taglib icu icu-data-full
15 |
16 | COPY --from=builder /tmp/euterpe /usr/local/bin/euterpe
17 | COPY --from=builder /root/.euterpe/config.json /root/.euterpe/config.json
18 |
19 | ENV HOME /root
20 | WORKDIR /root
21 | EXPOSE 9996
22 | CMD ["euterpe"]
23 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Build a normal binary for development.
2 | all:
3 | go build \
4 | --tags "sqlite_icu" \
5 | -ldflags "-X github.com/ironsmile/euterpe/src/version.Version=`git describe --tags --always`"
6 |
7 | # Build a release binary which could be used in the distribution archive.
8 | release:
9 | go build \
10 | --tags "sqlite_icu" \
11 | -ldflags "-X github.com/ironsmile/euterpe/src/version.Version=`git describe --tags --always`" \
12 | -o euterpe
13 |
14 | # Compress it somewhat. It seems that the Euterpe binary gets more than 3 times smaller
15 | # using upx.
16 | upx euterpe
17 |
18 | # Install in $GOPATH/bin.
19 | install:
20 | go install \
21 | --tags "sqlite_icu" \
22 | -ldflags "-X github.com/ironsmile/euterpe/src/version.Version=`git describe --tags --always`"
23 |
24 | # Build distribution archive.
25 | dist-archive:
26 | ./tools/build
27 |
28 | # Start euterpe after building it from source.
29 | run:
30 | go run --tags "sqlite_icu" main.go -D -local-fs
31 |
--------------------------------------------------------------------------------
/config.example.json:
--------------------------------------------------------------------------------
1 | {
2 | "listen": ":443",
3 |
4 | "ssl": true,
5 |
6 | "ssl_certificate": {
7 | "crt": "/full/path/to/certificate/file.crt",
8 | "key": "/full/path/to/key/file.key"
9 | },
10 |
11 | "basic_authenticate": true,
12 |
13 | "authentication": {
14 | "user": "example",
15 | "password": "example"
16 | },
17 |
18 | "libraries": [
19 | "/path/to/my/files",
20 | "/some/more/files/can/be/found/here"
21 | ],
22 |
23 | "library_scan": {
24 | "files_per_operation": 1500,
25 | "sleep_after_operation": "15ms",
26 | "initial_wait_duration": "1s"
27 | },
28 |
29 | "download_artwork": true,
30 | "discogs_auth_token": "personal-discogs-token-value"
31 | }
32 |
--------------------------------------------------------------------------------
/http_root/favicon/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | #FFFFFF
9 |
10 |
11 |
--------------------------------------------------------------------------------
/http_root/favicon/favicon-114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-114.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-120.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-144.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-150.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-152.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-16.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-160.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-160.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-180.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-192.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-310.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-32.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-57.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-60.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-64.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-70.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-72.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-76.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon-96.png
--------------------------------------------------------------------------------
/http_root/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/favicon/favicon.ico
--------------------------------------------------------------------------------
/http_root/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/http_root/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/http_root/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/http_root/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/http_root/images/unknownAlbum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/images/unknownAlbum.png
--------------------------------------------------------------------------------
/http_root/images/unknownArtist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/images/unknownArtist.png
--------------------------------------------------------------------------------
/http_root/js/Jplayer.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/js/Jplayer.swf
--------------------------------------------------------------------------------
/http_root/skin/blue.monday/jplayer.blue.monday.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/skin/blue.monday/jplayer.blue.monday.jpg
--------------------------------------------------------------------------------
/http_root/skin/blue.monday/jplayer.blue.monday.seeking.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/skin/blue.monday/jplayer.blue.monday.seeking.gif
--------------------------------------------------------------------------------
/http_root/skin/blue.monday/jplayer.blue.monday.video.play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/http_root/skin/blue.monday/jplayer.blue.monday.video.play.png
--------------------------------------------------------------------------------
/http_root/squash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd $(dirname `readlink -f $0`)
4 |
5 | cat js/jquery.min.js js/jquery.jplayer.min.js js/add-on/jplayer.playlist.min.js \
6 | js/bootstrap.min.js js/app.js js/URI.min.js > js/squashed.js
7 |
8 | cat css/bootstrap.min.css css/screen.css > css/squashed.css
9 |
--------------------------------------------------------------------------------
/images/barded-spice-install-step1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/images/barded-spice-install-step1.png
--------------------------------------------------------------------------------
/images/barded-spice-install-step2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/images/barded-spice-install-step2.png
--------------------------------------------------------------------------------
/images/barded-spice-install-step3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/images/barded-spice-install-step3.png
--------------------------------------------------------------------------------
/images/euterpe-preview.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/images/euterpe-preview.webp
--------------------------------------------------------------------------------
/images/heavy-metal-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/images/heavy-metal-128.png
--------------------------------------------------------------------------------
/sqls/library_schema.sql:
--------------------------------------------------------------------------------
1 | create table `albums` (
2 | `id` integer not null primary key,
3 | `name` text,
4 | `fs_path` text
5 | );
6 |
7 | create table `artists` (
8 | `id` integer not null primary key,
9 | `name` text
10 | );
11 |
12 | create table `tracks` (
13 | `id` integer not null primary key,
14 | `album_id` integer,
15 | `artist_id` integer,
16 | `name` text,
17 | `number` integer,
18 | `fs_path` text
19 | );
20 |
21 | create index tracks_ids on `tracks` (`id`);
22 | create index tracks_paths on `tracks` (`fs_path`);
23 | create index albums_ids on `albums` (`id`);
24 | create index artists_ids on `artists` (`id`);
25 |
--------------------------------------------------------------------------------
/sqls/migrations/001_album_artworks.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 |
3 | create table `albums_artworks` (
4 | `id` integer not null primary key,
5 | `album_id` integer unique,
6 | `artwork_cover` blob default null,
7 | `updated_at` integer
8 | );
9 |
10 | create index albums_artwork_album_ids on `albums_artworks` (`album_id`);
11 |
12 | -- +migrate Down
13 |
14 | drop table `albums_artworks`;
15 |
--------------------------------------------------------------------------------
/sqls/migrations/002_uniqueness.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 |
3 | -- First deal with the `artists` table. An artist is expected to be present
4 | -- only once in the database. So this should be represented in the schema.
5 | create unique index if not exists unique_artist on `artists` ('name');
6 |
7 | -- Now make sure albums are unique. This means an album in a particular directory
8 | -- since one might have the same album multiple times. Different formats, possibly.
9 | create unique index if not exists unique_albums on `albums` (`name`, `fs_path`);
10 |
11 | -- Next is line is the tracks. A track is uniquely identified by its file location.
12 | -- So make sure it is unique then!
13 | drop index if exists tracks_paths;
14 | create unique index if not exists unique_tracks on `tracks` ('fs_path');
15 |
16 | -- +migrate Down
17 |
18 | drop index if exists unique_artist;
19 | drop index if exists unique_albums;
20 | drop index if exists unique_tracks;
21 | create index tracks_paths on `tracks` (`fs_path`);
22 |
--------------------------------------------------------------------------------
/sqls/migrations/003_track_duration.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | alter table tracks add column duration integer;
3 |
4 | -- +migrate Down
5 | alter table tracks drop column duration;
6 |
--------------------------------------------------------------------------------
/sqls/migrations/004_artists_images.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 |
3 | create table `artists_images` (
4 | `id` integer not null primary key,
5 | `artist_id` integer unique,
6 | `image` blob default null,
7 | `updated_at` integer
8 | );
9 |
10 | create index artists_images_artist_ids on `artists_images` (`artist_id`);
11 |
12 | -- +migrate Down
13 |
14 | drop table `artists_images`;
15 |
--------------------------------------------------------------------------------
/sqls/migrations/005_small_images.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | alter table `artists_images` add column `image_small` blob default null;
3 | alter table `albums_artworks` add column `artwork_cover_small` blob default null;
4 |
5 | -- +migrate Down
6 | alter table `artists_images` drop column `image_small`;
7 | alter table `albums_artworks` drop column `artwork_cover_small`;
8 |
--------------------------------------------------------------------------------
/sqls/migrations/006_stats.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | create table if not exists `user_stats` (
3 | `track_id` integer,
4 | `favourite` integer null, -- Unix timestamp at which it was starred
5 | `user_rating` integer null,
6 | `last_played` integer null, -- Unix timestamp in seconds.
7 | `play_count` integer not null default 0,
8 | FOREIGN KEY(track_id) REFERENCES tracks(id) ON UPDATE CASCADE ON DELETE CASCADE
9 | );
10 |
11 | create unique index if not exists `unique_user_stats` on `user_stats` (`track_id`);
12 |
13 | -- +migrate Down
14 | drop index if exists `unique_user_stats`;
15 | drop table if exists `user_stats`;
16 |
--------------------------------------------------------------------------------
/sqls/migrations/007_album_artist_stats.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | create table if not exists `albums_stats` (
3 | `album_id` integer,
4 | `favourite` integer null, -- Unix timestamp at which it was starred
5 | `user_rating` integer null, -- Value in the 1-5 range
6 | FOREIGN KEY(album_id) REFERENCES albums(id) ON UPDATE CASCADE ON DELETE CASCADE
7 | );
8 |
9 | create unique index if not exists `unique_album_stats` on `albums_stats` (`album_id`);
10 |
11 | create table if not exists `artists_stats` (
12 | `artist_id` integer,
13 | `favourite` integer null, -- Unix timestamp at which it was starred
14 | `user_rating` integer null, -- Value in the 1-5 range
15 | FOREIGN KEY(artist_id) REFERENCES artists(id) ON UPDATE CASCADE ON DELETE CASCADE
16 | );
17 |
18 | create unique index if not exists `unique_artists_stats` on `artists_stats` (`artist_id`);
19 |
20 | -- +migrate Down
21 | drop index if exists `unique_album_stats`;
22 | drop table if exists `albums_stats`;
23 |
24 | drop index if exists `unique_artists_stats`;
25 | drop table if exists `artists_stats`;
26 |
--------------------------------------------------------------------------------
/sqls/migrations/008_more_track_columns.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | alter table tracks add column year integer null; -- four digit number
3 | alter table tracks add column bitrate integer null; -- bits per second
4 | alter table tracks add column size integer null; -- file size in bytes
5 | alter table tracks add column created_at integer null; -- unix timestamp
6 |
7 | -- +migrate Down
8 | alter table tracks drop column created_at;
9 | alter table tracks drop column size;
10 | alter table tracks drop column bitrate;
11 | alter table tracks drop column year;
12 |
--------------------------------------------------------------------------------
/sqls/migrations/009_internet_radio.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | CREATE TABLE IF NOT EXISTS `radio_stations` (
3 | `id` integer not null primary key,
4 | `name` text not null,
5 | `stream_url` text not null,
6 | `home_page` text null
7 | );
8 |
9 | -- +migrate Down
10 | drop table if exists `radio_stations`;
11 |
--------------------------------------------------------------------------------
/sqls/migrations/010_playlists.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | CREATE TABLE IF NOT EXISTS `playlists` (
3 | `id` integer not null primary key,
4 | `name` text not null,
5 | `description` text null,
6 | `public` integer default 1,
7 | `created_at` integer not null,
8 | `updated_at` integer not null
9 | );
10 |
11 | CREATE TABLE IF NOT EXISTS `playlists_tracks` (
12 | `playlist_id` integer not null,
13 | `track_id` integer not null,
14 | `index` integer not null default 0,
15 | FOREIGN KEY(playlist_id) REFERENCES playlists(id) ON UPDATE CASCADE ON DELETE CASCADE,
16 | FOREIGN KEY(track_id) REFERENCES tracks(id) ON UPDATE CASCADE ON DELETE CASCADE
17 | );
18 |
19 | CREATE TABLE IF NOT EXISTS `playlists_images` (
20 | `playlist_id` integer unique not null,
21 | `image` blob not null,
22 | `updated_at` integer not null,
23 | FOREIGN KEY(playlist_id) REFERENCES playlists(id) ON UPDATE CASCADE ON DELETE CASCADE
24 | );
25 |
26 | create unique index if not exists playlist_pairs on `playlists_tracks` ('playlist_id', `track_id`);
27 |
28 | -- +migrate Down
29 | drop table if exists `playlists`;
30 | drop table if exists `playlists_tracks`;
31 | drop table if exists `playlists_images`;
32 |
--------------------------------------------------------------------------------
/sqls/migrations/011_playlists_uniqe_index.sql:
--------------------------------------------------------------------------------
1 | -- +migrate Up
2 | drop index if exists playlist_pairs;
3 | create unique index if not exists playlist_pairs_with_index on `playlists_tracks` ('playlist_id', `index`);
4 |
5 | -- +migrate Down
6 | drop index if exists playlist_pairs_with_index;
7 | create unique index if not exists playlist_pairs on `playlists_tracks` ('playlist_id', `track_id`);
8 |
--------------------------------------------------------------------------------
/src/art/caa_client.go:
--------------------------------------------------------------------------------
1 | package art
2 |
3 | import (
4 | "github.com/pborman/uuid"
5 | cca "gopkg.in/mineo/gocaa.v1"
6 | )
7 |
8 | //counterfeiter:generate . CAAClient
9 |
10 | // CAAClient represents a Cover Art Archive client for getting a release front
11 | // image.
12 | type CAAClient interface {
13 | GetReleaseFront(mbid uuid.UUID, size int) (image cca.CoverArtImage, err error)
14 | }
15 |
--------------------------------------------------------------------------------
/src/art/client_test_helpers.go:
--------------------------------------------------------------------------------
1 | package art
2 |
3 | // SetCAAClient sets the underlying CAAClient which will be used by the Client. Only
4 | // useful for tests.
5 | func (c *Client) SetCAAClient(caac CAAClient) {
6 | c.caaClient = caac
7 | }
8 |
9 | // SetMusicBrainzAPIURL sets the MusicBrainz API URL. Only useful for tests.
10 | func (c *Client) SetMusicBrainzAPIURL(apiURL string) {
11 | c.musicBrainzAPIHost = apiURL
12 | }
13 |
14 | // SetDiscogsAPIURL sets the Discogs API URL. Only useful for tests.
15 | func (c *Client) SetDiscogsAPIURL(apiURL string) {
16 | c.discogsAPIHost = apiURL
17 | }
18 |
--------------------------------------------------------------------------------
/src/art/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package art is responsible for getting cover art for albums or artist images over the
3 | internet.
4 |
5 | It finds album artwork by first querying the MusicBrainz web service for a releaseID using
6 | the artist name and album name. Then using this ID it queries the Cover Art Archive
7 | for the corresponding album front art.
8 |
9 | Artist images are found using the MusicBrainz database and Discogs.
10 |
11 | The following APIs are used to achieve this packages' objective:
12 |
13 | * MusicBrainz API: https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2
14 | * Cover Art Archive: https://musicbrainz.org/doc/Cover_Art_Archive/
15 | * Discogs API: https://www.discogs.com/developers/
16 | */
17 | package art
18 |
--------------------------------------------------------------------------------
/src/art/generate.go:
--------------------------------------------------------------------------------
1 | package art
2 |
3 | // This file is here just to hold generate directives and to prevent them
4 | // being copied on more than one place throughout the package files.
5 |
6 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
7 |
--------------------------------------------------------------------------------
/src/assert/common.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import "fmt"
4 |
5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
6 |
7 | //counterfeiter:generate . TestingFatalf
8 |
9 | // TestingFatalf is an which supports reporting fatal errors in testing types such as
10 | // testing.T, testing.TB and similar.
11 | type TestingFatalf interface {
12 | Fatalf(format string, args ...any)
13 | Helper()
14 | }
15 |
16 | func fromMsgAndArgs(msgAndArgs ...any) string {
17 | if len(msgAndArgs) == 0 {
18 | return ""
19 | }
20 |
21 | fmtStr, ok := msgAndArgs[0].(string)
22 | if !ok {
23 | panic("The first argument in msgAndArgs must be a string format value.")
24 | }
25 |
26 | return fmt.Sprintf(" ("+fmtStr+")", msgAndArgs[1:]...)
27 | }
28 |
--------------------------------------------------------------------------------
/src/assert/equal.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | // Equal checks whether expected and actual are actually equal and fails the test
4 | // if they are not.
5 | func Equal[V comparable](t TestingFatalf, expected, actual V, msgAndArgs ...any) {
6 | t.Helper()
7 |
8 | if expected == actual {
9 | return
10 | }
11 |
12 | t.Fatalf("not equal: expected `%#v` but got `%#v`%s",
13 | expected, actual, fromMsgAndArgs(msgAndArgs...),
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/src/assert/nils.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | // NilErr checks that `val` is nil. Causes a fatal error otherwise.
4 | func NilErr(t TestingFatalf, val error, msgAndArgs ...any) {
5 | t.Helper()
6 |
7 | if val == nil {
8 | return
9 | }
10 |
11 | t.Fatalf("expected nil but got `%s`%s", val, fromMsgAndArgs(msgAndArgs...))
12 | }
13 |
14 | // NotNilErr checks that `val` is not nil. Causes a fatal error otherwise.
15 | func NotNilErr(t TestingFatalf, val error, msgAndArgs ...any) {
16 | t.Helper()
17 |
18 | if val != nil {
19 | return
20 | }
21 |
22 | t.Fatalf("unexpected nil%s", fromMsgAndArgs(msgAndArgs...))
23 | }
24 |
--------------------------------------------------------------------------------
/src/assert/nils_test.go:
--------------------------------------------------------------------------------
1 | package assert_test
2 |
3 | import (
4 | "io"
5 | "testing"
6 |
7 | "github.com/ironsmile/euterpe/src/assert"
8 | "github.com/ironsmile/euterpe/src/assert/assertfakes"
9 | )
10 |
11 | // TestNilErr makes sure that ErrNil works as expected.
12 | func TestNilErr(t *testing.T) {
13 | var nilErr error
14 |
15 | fakeTf := &assertfakes.FakeTestingFatalf{}
16 | assert.NilErr(fakeTf, nilErr)
17 | if fakeTf.FatalfCallCount() != 0 {
18 | t.Fatalf("unexpected Fatalf() call for nil error")
19 | }
20 | if fakeTf.HelperCallCount() != 1 {
21 | t.Fatalf("testing.T.Helper() not called")
22 | }
23 |
24 | assert.NilErr(fakeTf, io.EOF)
25 | if fakeTf.FatalfCallCount() != 1 {
26 | t.Fatalf("expected Fatalf() to be called but it was not")
27 | }
28 | }
29 |
30 | // TestNotNilErr makes sure that ErrNotNil works as expected.
31 | func TestNotNilErr(t *testing.T) {
32 |
33 | fakeTf := &assertfakes.FakeTestingFatalf{}
34 | assert.NotNilErr(fakeTf, io.EOF)
35 | if fakeTf.FatalfCallCount() != 0 {
36 | t.Fatalf("unexpected Fatalf() call for nil error")
37 | }
38 | if fakeTf.HelperCallCount() != 1 {
39 | t.Fatalf("testing.T.Helper() not called")
40 | }
41 |
42 | var nilErr error
43 | assert.NotNilErr(fakeTf, nilErr)
44 | if fakeTf.FatalfCallCount() != 1 {
45 | t.Fatalf("expected Fatalf() to be called but it was not")
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/daemon/daemon_nix.go:
--------------------------------------------------------------------------------
1 | // +build !windows
2 |
3 | package daemon
4 |
5 | import "syscall"
6 |
7 | // StopSignals contains all the signals which will make our daemon remove its pidfile
8 | var StopSignals = []syscall.Signal{
9 | syscall.SIGINT,
10 | syscall.SIGKILL,
11 | syscall.SIGTERM,
12 | }
13 |
--------------------------------------------------------------------------------
/src/daemon/daemon_test.go:
--------------------------------------------------------------------------------
1 | package daemon
2 |
3 | import "testing"
4 |
5 | func TestDaemonizing(t *testing.T) {
6 | //!TODO: figure out how to do that in the first place! :D
7 | }
8 |
--------------------------------------------------------------------------------
/src/daemon/daemon_win.go:
--------------------------------------------------------------------------------
1 | // +build windows
2 |
3 | package daemon
4 |
5 | import "os"
6 |
7 | var StopSignals []os.Signal = []os.Signal{
8 | os.Interrupt,
9 | os.Kill,
10 | }
11 |
--------------------------------------------------------------------------------
/src/daemon/doc.go:
--------------------------------------------------------------------------------
1 | // Package daemon contains utilities aimed to helping with the long-term
2 | // running of the application.
3 | package daemon
4 |
--------------------------------------------------------------------------------
/src/helpers/helpers_nix.go:
--------------------------------------------------------------------------------
1 | // +build !windows
2 |
3 | /*
4 | Helpers for all non-windows machines
5 | */
6 |
7 | package helpers
8 |
9 | const (
10 | // euterpeDir is the name of the Euterpe directory in the user's home directory.
11 | euterpeDir = ".euterpe"
12 |
13 | // httpmsDir was a directory where the Euterpe files were stored before its
14 | // rename from HTTPMS. Now it is kept for backward compatibility. If this
15 | // directory is present then it will be used instead of the one in euterpeDir.
16 | // With the presumption that migration to the new directory hasn't happened yet.
17 | httpmsDir = ".httpms"
18 | )
19 |
--------------------------------------------------------------------------------
/src/helpers/helpers_win.go:
--------------------------------------------------------------------------------
1 | // +build windows
2 |
3 | /*
4 | Helpers for windows machines
5 | */
6 |
7 | package helpers
8 |
9 | const (
10 | httpmsDir = "httpms"
11 |
12 | euterpeDir = "euterpe"
13 | )
14 |
--------------------------------------------------------------------------------
/src/library/bytes_read_closer.go:
--------------------------------------------------------------------------------
1 | package library
2 |
3 | import "bytes"
4 |
5 | // bytesReadCloser is a helper type which helps bytes.Reader implement io.ReadCloser.
6 | type bytesReadCloser struct {
7 | bytes.Buffer
8 | }
9 |
10 | // Close is a no-op which is here only to implement io.Closer and io.ReadCloser.
11 | func (b *bytesReadCloser) Close() error {
12 | return nil
13 | }
14 |
15 | func newBytesReadCloser(buff []byte) *bytesReadCloser {
16 | return &bytesReadCloser{
17 | Buffer: *bytes.NewBuffer(buff),
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/library/format.go:
--------------------------------------------------------------------------------
1 | package library
2 |
3 | import (
4 | "path/filepath"
5 | "strings"
6 | )
7 |
8 | func mediaFormatFromFileName(path string) string {
9 | format := strings.TrimLeft(filepath.Ext(path), ".")
10 | if format == "" {
11 | format = "mp3"
12 | }
13 | return strings.ToLower(format)
14 | }
15 |
--------------------------------------------------------------------------------
/src/library/generate.go:
--------------------------------------------------------------------------------
1 | package library
2 |
3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
4 |
5 | // This file is here just to hold the generate directives so that they are not duplicated
6 | // in many places.
7 |
--------------------------------------------------------------------------------
/src/library/local_library_migrate.go:
--------------------------------------------------------------------------------
1 | package library
2 |
3 | import (
4 | "fmt"
5 | "io/fs"
6 | "log"
7 | "net/http"
8 |
9 | migrate "github.com/ironsmile/sql-migrate"
10 | )
11 |
12 | // sqlMigrateDirectory is the directory whithin the `sqlFilesFS` which contains
13 | // the .sql files for sql-migrate.
14 | const sqlMigrateDirectory = "migrations"
15 |
16 | // applyMigrations reads the database migrations dir and applies them to the currently
17 | // open database if it is necessary.
18 | func (lib *LocalLibrary) applyMigrations() error {
19 | migrationFiles, err := fs.Sub(lib.sqlFilesFS, sqlMigrateDirectory)
20 | if err != nil {
21 | return fmt.Errorf("locating migrate dir within sqlFiles fs.FS failed: %w", err)
22 | }
23 |
24 | migrations := &migrate.HttpFileSystemMigrationSource{
25 | FileSystem: http.FS(migrationFiles),
26 | }
27 |
28 | _, err = migrate.ExecMax(lib.db, "sqlite3", migrations, migrate.Up, 0)
29 | if err == nil {
30 | return nil
31 | }
32 |
33 | if _, ok := err.(*migrate.PlanError); ok {
34 | log.Printf("Error applying database migrations: %s\n", err)
35 | return nil
36 | }
37 |
38 | return fmt.Errorf("executing db migration failed: %w", err)
39 | }
40 |
--------------------------------------------------------------------------------
/src/library/mock_media_test.go:
--------------------------------------------------------------------------------
1 | package library
2 |
3 | import "time"
4 |
5 | // MockMedia is a type used for testing the media insertion methods
6 | type MockMedia struct {
7 | artist string
8 | album string
9 | title string
10 | track int
11 | length time.Duration
12 | year int
13 | bitrate int
14 | }
15 |
16 | // Artist satisfies the MediaFile interface and just returns the object attribute.
17 | func (m *MockMedia) Artist() string {
18 | return m.artist
19 | }
20 |
21 | // Album satisfies the MediaFile interface and just returns the object attribute.
22 | func (m *MockMedia) Album() string {
23 | return m.album
24 | }
25 |
26 | // Title satisfies the MediaFile interface and just returns the object attribute.
27 | func (m *MockMedia) Title() string {
28 | return m.title
29 | }
30 |
31 | // Track satisfies the MediaFile interface and just returns the object attribute.
32 | func (m *MockMedia) Track() int {
33 | return m.track
34 | }
35 |
36 | // Length satisfies the MediaFile interface and just returns the object attribute.
37 | func (m *MockMedia) Length() time.Duration {
38 | return m.length
39 | }
40 |
41 | // Year satisfies the MediaFile interface. Returns the object attribute or a default
42 | // value if one is not set.
43 | func (m *MockMedia) Year() int {
44 | return m.year
45 | }
46 |
47 | // Bitrate satisfies the MediaFile interface. Returns the object attribute or a default
48 | // value if one is not set.
49 | func (m *MockMedia) Bitrate() int {
50 | if m.bitrate == 0 {
51 | return 256
52 | }
53 | return m.bitrate
54 | }
55 |
--------------------------------------------------------------------------------
/src/library/os_fs.go:
--------------------------------------------------------------------------------
1 | package library
2 |
3 | import (
4 | "io/fs"
5 | "os"
6 | )
7 |
8 | // osFS is a fs.FS implementation which uses the os package as the underlying file
9 | // opener.
10 | type osFS struct{}
11 |
12 | var _ fs.StatFS = (*osFS)(nil)
13 |
14 | func (osfs *osFS) Open(name string) (fs.File, error) {
15 | return os.Open(name)
16 | }
17 |
18 | func (osfs *osFS) Stat(name string) (fs.FileInfo, error) {
19 | return os.Stat(name)
20 | }
21 |
--------------------------------------------------------------------------------
/src/library/os_fs_test.go:
--------------------------------------------------------------------------------
1 | package library
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "io"
7 | "os"
8 | "path/filepath"
9 | "testing"
10 | )
11 |
12 | // TestOsFSOpen makes sure that the osFS Open function actually uses the OS file system
13 | // to do its work.
14 | func TestOsFSOpen(t *testing.T) {
15 | const tmpFileContents = "some-file-contents"
16 |
17 | osfs := &osFS{}
18 |
19 | _, err := osfs.Open(filepath.FromSlash("does/not/exists/here.png"))
20 | if !os.IsNotExist(err) {
21 | t.Errorf("unexpected error for file which does not exist: `%+v`", err)
22 | }
23 |
24 | tmpFile, err := os.CreateTemp(os.TempDir(), "pattern")
25 | if err != nil {
26 | t.Fatalf("failed to create a temporary file: %s", err)
27 | }
28 | tmpFileName := tmpFile.Name()
29 | defer os.Remove(tmpFileName)
30 | fmt.Fprint(tmpFile, tmpFileContents)
31 | tmpFile.Close()
32 |
33 | fh, err := osfs.Open(tmpFileName)
34 | if err != nil {
35 | t.Fatalf("error opening temporary file with osFS: %s", err)
36 | }
37 | defer fh.Close()
38 |
39 | foundContents, err := io.ReadAll(fh)
40 | if err != nil {
41 | t.Fatalf("error reading temporary file: %s", err)
42 | }
43 |
44 | if !bytes.Equal([]byte(tmpFileContents), foundContents) {
45 | t.Errorf("expected file `%s` but got `%s`", tmpFileContents, foundContents)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/playlists/generate.go:
--------------------------------------------------------------------------------
1 | package playlists
2 |
3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
4 |
5 | // This file is here just to hold the generate directives so that they are not duplicated
6 | // in many places.
7 |
--------------------------------------------------------------------------------
/src/radio/generate.go:
--------------------------------------------------------------------------------
1 | package radio
2 |
3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
4 |
5 | // This file is here just to hold the generate directives so that they are not duplicated
6 | // in many places.
7 |
--------------------------------------------------------------------------------
/src/scaler/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package scaler provides utilities for scaling images.
3 | */
4 | package scaler
5 |
--------------------------------------------------------------------------------
/src/scaler/generate.go:
--------------------------------------------------------------------------------
1 | package scaler
2 |
3 | // This file is here just to hold generate directives and to prevent them
4 | // being copied on more than one place throughout the package files.
5 |
6 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
7 |
--------------------------------------------------------------------------------
/src/tools/tools.go:
--------------------------------------------------------------------------------
1 | // +build tools
2 |
3 | package tools
4 |
5 | import (
6 | // Packages are imported anonymously so that they could be considered "used"
7 | // by `go mod`.
8 | _ "github.com/maxbrunsfeld/counterfeiter/v6"
9 | )
10 |
11 | // This file imports packages that are used when running go generate, or used
12 | // during the development process but not otherwise depended on by built code.
13 |
--------------------------------------------------------------------------------
/src/version/version.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package version provides version information and utilities.
3 | */
4 | package version
5 |
6 | import (
7 | "fmt"
8 | "io"
9 | "runtime"
10 | )
11 |
12 | // Version stores the current version of Euterpe. It is set during building.
13 | var Version = "dev-unreleased"
14 |
15 | // Print writes a plain text version information in out.
16 | func Print(out io.Writer) {
17 | fmt.Fprintf(out, "Euterpe Media Server %s\n", Version)
18 | fmt.Fprintf(out, "Build with %s\n", runtime.Version())
19 | }
20 |
--------------------------------------------------------------------------------
/src/version/version_test.go:
--------------------------------------------------------------------------------
1 | package version_test
2 |
3 | import (
4 | "bytes"
5 | "runtime"
6 | "strings"
7 | "testing"
8 |
9 | "github.com/ironsmile/euterpe/src/version"
10 | )
11 |
12 | // TestVersionPrinting makes sure some things are always part of the printed version
13 | // string.
14 | func TestVersionPrinting(t *testing.T) {
15 | if version.Version == "" {
16 | t.Fatalf("version.Version cannot be completely empty")
17 | }
18 |
19 | var buff bytes.Buffer
20 | version.Print(&buff)
21 |
22 | if !strings.Contains(buff.String(), version.Version) {
23 | t.Errorf("printed version does not contain the actual version string")
24 | }
25 |
26 | if !strings.Contains(buff.String(), runtime.Version()) {
27 | t.Errorf("printed version does not contain Golang version")
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/webserver/functions_test.go:
--------------------------------------------------------------------------------
1 | package webserver_test
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "net/http/httptest"
7 | "strings"
8 | "testing"
9 |
10 | "github.com/ironsmile/euterpe/src/webserver"
11 | )
12 |
13 | // TestWithInternalError makes sure that Internal Server Error status code is
14 | // set when the underlying handler returns an error and hasn't written anything
15 | // at the output.
16 | func TestWithInternalError(t *testing.T) {
17 | var someError = fmt.Errorf("test-error")
18 |
19 | h := webserver.WithInternalError(func(_ http.ResponseWriter, _ *http.Request) error {
20 | return someError
21 | })
22 |
23 | req := httptest.NewRequest(http.MethodGet, "/", nil)
24 | resp := httptest.NewRecorder()
25 |
26 | h.ServeHTTP(resp, req)
27 |
28 | statusCode := resp.Result().StatusCode
29 | if statusCode != http.StatusInternalServerError {
30 | t.Errorf("expected status code %d but got %d",
31 | http.StatusInternalServerError, statusCode)
32 | }
33 |
34 | if !strings.Contains(resp.Body.String(), someError.Error()) {
35 | // Make sure the error string is part of the response body. This makes
36 | // debugging any problems much easier.
37 | t.Errorf("response body did not include the error string")
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/webserver/handler_about.go:
--------------------------------------------------------------------------------
1 | package webserver
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "net/http"
7 |
8 | "github.com/ironsmile/euterpe/src/version"
9 | "github.com/ironsmile/euterpe/src/webserver/webutils"
10 | )
11 |
12 | type aboutHandler struct {
13 | resp aboutResponse
14 | }
15 |
16 | // NewAboutHandler returns the HTTP handler which shows a JSON with information
17 | // about the server.
18 | func NewAboutHandler() http.Handler {
19 | return &aboutHandler{
20 | resp: aboutResponse{
21 | ServerVersion: version.Version,
22 | },
23 | }
24 | }
25 |
26 | func (h *aboutHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
27 | w.Header().Add("Content-Type", "application/json; charset=utf-8")
28 | enc := json.NewEncoder(w)
29 | if err := enc.Encode(h.resp); err != nil {
30 | msg := fmt.Sprintf("Failed to encode JSON response: %s", err)
31 | webutils.JSONError(w, msg, http.StatusInternalServerError)
32 | return
33 | }
34 | }
35 |
36 | type aboutResponse struct {
37 | ServerVersion string `json:"server_version"`
38 | }
39 |
--------------------------------------------------------------------------------
/src/webserver/handler_about_test.go:
--------------------------------------------------------------------------------
1 | package webserver_test
2 |
3 | import (
4 | "encoding/json"
5 | "net/http"
6 | "net/http/httptest"
7 | "strings"
8 | "testing"
9 |
10 | "github.com/ironsmile/euterpe/src/assert"
11 | "github.com/ironsmile/euterpe/src/version"
12 | "github.com/ironsmile/euterpe/src/webserver"
13 | )
14 |
15 | // TestAboutHandler makes sure that the /v1/about HTTP handler returns the information
16 | // promised in the API contract.
17 | func TestAboutHandler(t *testing.T) {
18 | aboutHandler := webserver.NewAboutHandler()
19 |
20 | req := httptest.NewRequest(http.MethodGet, "/v1/about", nil)
21 | resp := httptest.NewRecorder()
22 |
23 | aboutHandler.ServeHTTP(resp, req)
24 | defer resp.Result().Body.Close()
25 |
26 | assert.Equal(t, http.StatusOK, resp.Result().StatusCode)
27 | if !strings.Contains(resp.Result().Header.Get("Content-Type"), "application/json") {
28 | t.Errorf("expected application/json content type")
29 | }
30 |
31 | kvStore := map[string]any{}
32 | dec := json.NewDecoder(resp.Result().Body)
33 | err := dec.Decode(&kvStore)
34 | assert.NilErr(t, err, "decoding JSON response failed")
35 |
36 | val, found := kvStore["server_version"]
37 | if !found {
38 | t.Fatalf("did not find `server_version` in JSON object")
39 | }
40 |
41 | valStr, ok := val.(string)
42 | if !ok {
43 | t.Fatalf("`server_version` was not a string")
44 | }
45 |
46 | assert.Equal(t, version.Version, valStr, "version string mismatch")
47 | }
48 |
--------------------------------------------------------------------------------
/src/webserver/handler_logout.go:
--------------------------------------------------------------------------------
1 | package webserver
2 |
3 | import "net/http"
4 |
5 | // NewLogoutHandler returns a handler which will logout the user form his HTTP
6 | // session by unsetting his session cookie.
7 | func NewLogoutHandler() http.Handler {
8 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
9 | cookie := &http.Cookie{
10 | Name: sessionCookieName,
11 | Value: "",
12 | Path: "/",
13 | HttpOnly: true,
14 | MaxAge: -1,
15 | }
16 | http.SetCookie(w, cookie)
17 |
18 | w.Header().Set("Location", "/login/")
19 | w.WriteHeader(http.StatusFound)
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/src/webserver/handler_register_token.go:
--------------------------------------------------------------------------------
1 | package webserver
2 |
3 | import "net/http"
4 |
5 | // NewRigisterTokenHandler returns a handler resposible for checking and eventually
6 | // registering registering in the database token generated to a device.
7 | // !TODO: actually store the device token in the database once it has a unique ID
8 | func NewRigisterTokenHandler() http.Handler {
9 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
10 | w.Header().Set("Content-Type", "application/json")
11 | w.WriteHeader(http.StatusNoContent)
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/src/webserver/handler_register_token_test.go:
--------------------------------------------------------------------------------
1 | package webserver_test
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "testing"
7 |
8 | "github.com/gorilla/mux"
9 | "github.com/ironsmile/euterpe/src/webserver"
10 | )
11 |
12 | // TestRegisterTokenHandler makes sure that the handler returns well formatted JSON
13 | // and responds with HTTP 204.
14 | func TestRegisterTokenHandler(t *testing.T) {
15 | h := routeRegisterTokenHandler(webserver.NewRigisterTokenHandler())
16 |
17 | req := httptest.NewRequest(http.MethodPost, "/v1/register/token/", nil)
18 | resp := httptest.NewRecorder()
19 |
20 | h.ServeHTTP(resp, req)
21 |
22 | responseCode := resp.Result().StatusCode
23 | if responseCode != http.StatusNoContent {
24 | t.Errorf(
25 | "expected HTTP response code `%d` but got `%d`",
26 | http.StatusNoContent,
27 | responseCode,
28 | )
29 | }
30 | }
31 |
32 | // routeRegisterTokenHandler wraps a handler the same way the web server will do when
33 | // constructing the main application router. This is needed for tests so that the
34 | // Gorilla mux variables will be parsed.
35 | func routeRegisterTokenHandler(h http.Handler) http.Handler {
36 | router := mux.NewRouter()
37 | router.StrictSlash(true)
38 | router.UseEncodedPath()
39 | router.Handle(webserver.APIv1EndpointRegisterToken, h).Methods(
40 | webserver.APIv1Methods[webserver.APIv1EndpointRegisterToken]...,
41 | )
42 |
43 | return router
44 | }
45 |
--------------------------------------------------------------------------------
/src/webserver/handler_template.go:
--------------------------------------------------------------------------------
1 | package webserver
2 |
3 | import (
4 | "fmt"
5 | "html/template"
6 | "log"
7 | "net/http"
8 |
9 | "github.com/ironsmile/euterpe/src/version"
10 | )
11 |
12 | // NewTemplateHandler returns a handler which will execute the page template inside
13 | // the layout template.
14 | func NewTemplateHandler(tpl *template.Template, title string) http.Handler {
15 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
16 | data := struct {
17 | Title string
18 | Version string
19 | Req *http.Request
20 | Menu []menu
21 | }{
22 | Title: title,
23 | Version: version.Version,
24 | Req: r,
25 | Menu: []menu{
26 | {
27 | Name: "Player",
28 | URI: "/",
29 | Active: r.URL.Path == "/",
30 | },
31 | {
32 | Name: "Add Device",
33 | URI: "/add_device/",
34 | Active: r.URL.Path == "/add_device/",
35 | },
36 | },
37 | }
38 | if err := tpl.Execute(w, data); err != nil {
39 | errorMessage := fmt.Sprintf("Error executing template: %s.\n", err)
40 | log.Print(errorMessage)
41 | http.Error(w, errorMessage, http.StatusInternalServerError)
42 | }
43 | })
44 | }
45 |
46 | type menu struct {
47 | URI string
48 | Name string
49 | Active bool
50 | }
51 |
--------------------------------------------------------------------------------
/src/webserver/handler_terry.go:
--------------------------------------------------------------------------------
1 | /*
2 | This HTTP handler echoes Terry's name.
3 |
4 | "A man is not dead while his name is still spoken."
5 |
6 | As proposed in in http://www.gnuterrypratchett.com/
7 | */
8 |
9 | package webserver
10 |
11 | import (
12 | "net/http"
13 | )
14 |
15 | // TerryHandler adds the X-Clacks-Overhead header. It wraps around the actual handler.
16 | type TerryHandler struct {
17 | wrapped http.Handler
18 | }
19 |
20 | // ServeHTTP satisfies the http.Handler interface.
21 | func (th TerryHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
22 | writer.Header().Set("X-Clacks-Overhead", "GNU Terry Pratchett")
23 | th.wrapped.ServeHTTP(writer, req)
24 | }
25 |
26 | // NewTerryHandler returns a new TerryHandler, ready for use.
27 | func NewTerryHandler(handler http.Handler) http.Handler {
28 | return &TerryHandler{wrapped: handler}
29 | }
30 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/cover_art_interfaces.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import "net/http"
4 |
5 | //counterfeiter:generate . CoverArtHandler
6 |
7 | // CoverArtHandler is an interface which exposes a http.Handler like function for
8 | // serving art images. It uses the database IDs for the albums and artists.
9 | type CoverArtHandler interface {
10 | Find(w http.ResponseWriter, req *http.Request, id int64) error
11 | }
12 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/deleteInternetRadioStation.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "net/http"
7 | "strconv"
8 |
9 | "github.com/ironsmile/euterpe/src/radio"
10 | )
11 |
12 | func (s *subsonic) deleteInternetRadioStation(w http.ResponseWriter, req *http.Request) {
13 | id := req.Form.Get("id")
14 | if id == "" {
15 | resp := responseError(
16 | errCodeMissingParameter,
17 | "the parameter `id` is required",
18 | )
19 | encodeResponse(w, req, resp)
20 | return
21 | }
22 |
23 | idInt, err := strconv.ParseInt(id, 10, 64)
24 | if err != nil {
25 | resp := responseError(
26 | errCodeNotFound,
27 | fmt.Sprintf("could not parse radio station ID: %s", err),
28 | )
29 | encodeResponse(w, req, resp)
30 | return
31 | }
32 |
33 | if err := s.radio.Delete(req.Context(), idInt); errors.Is(err, radio.ErrNotFound) {
34 | resp := responseError(
35 | errCodeNotFound,
36 | "radio station not found",
37 | )
38 | encodeResponse(w, req, resp)
39 | return
40 | } else if err != nil {
41 | resp := responseError(
42 | errCodeGeneric,
43 | fmt.Sprintf("could not delete radio station: %s", err),
44 | )
45 | encodeResponse(w, req, resp)
46 | return
47 | }
48 |
49 | encodeResponse(w, req, responseOk())
50 | }
51 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/delete_playlist.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "errors"
5 | "net/http"
6 | "strconv"
7 |
8 | "github.com/ironsmile/euterpe/src/playlists"
9 | )
10 |
11 | func (s *subsonic) deletePlaylist(w http.ResponseWriter, req *http.Request) {
12 | id, err := strconv.ParseInt(req.Form.Get("id"), 10, 64)
13 | if err != nil && req.Form.Get("id") == "" {
14 | resp := responseError(errCodeMissingParameter, "playlist ID is missing in query")
15 | encodeResponse(w, req, resp)
16 | return
17 | } else if err != nil {
18 | resp := responseError(errCodeNotFound, "playlist not found")
19 | encodeResponse(w, req, resp)
20 | return
21 | }
22 |
23 | err = s.playlists.Delete(req.Context(), id)
24 | if err != nil && errors.Is(err, playlists.ErrNotFound) {
25 | resp := responseError(errCodeNotFound, "playlist not found")
26 | encodeResponse(w, req, resp)
27 | return
28 | } else if err != nil {
29 | resp := responseError(errCodeGeneric, err.Error())
30 | encodeResponse(w, req, resp)
31 | return
32 | }
33 |
34 | encodeResponse(w, req, responseOk())
35 | }
36 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/errors.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | type apiErrorCode int
4 |
5 | // Error codes defined in the Subsonic API documentation.
6 | const (
7 | errCodeGeneric apiErrorCode = 0
8 | errCodeMissingParameter apiErrorCode = 10
9 | errCodeVersionClient apiErrorCode = 20
10 | errCodeVersionServer apiErrorCode = 30
11 | errCodeWrongUserOrPass apiErrorCode = 40
12 | errCodeTokenAuthLDAP apiErrorCode = 41
13 | errCodeNotAuthorized apiErrorCode = 50
14 | errCodeNotFound apiErrorCode = 70
15 | )
16 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/generate.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | // This file is here just to hold generate directives and to prevent them
4 | // being copied on more than one place throughout the package files.
5 |
6 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
7 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_album.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | "strconv"
6 | )
7 |
8 | func (s *subsonic) getAlbum(w http.ResponseWriter, req *http.Request) {
9 | idString := req.Form.Get("id")
10 | subsonicID, err := strconv.ParseInt(idString, 10, 64)
11 | if idString == "" || err != nil || !isAlbumID(subsonicID) {
12 | resp := responseError(errCodeNotFound, "album not found")
13 | encodeResponse(w, req, resp)
14 | return
15 | }
16 |
17 | albumID := toAlbumDBID(subsonicID)
18 |
19 | album, err := s.lib.GetAlbum(req.Context(), albumID)
20 | if err != nil {
21 | resp := responseError(errCodeGeneric, err.Error())
22 | encodeResponse(w, req, resp)
23 | return
24 | }
25 |
26 | alEntry := xsdAlbumWithSongsID3{
27 | xsdAlbumID3: dbAlbumToAlbumID3Entry(album),
28 | }
29 |
30 | tracks := s.lib.GetAlbumFiles(req.Context(), albumID)
31 | for _, track := range tracks {
32 | alEntry.Children = append(alEntry.Children, trackToChild(
33 | track,
34 | s.getLastModified(),
35 | ))
36 | }
37 |
38 | resp := albumResponse{
39 | baseResponse: responseOk(),
40 | Album: alEntry,
41 | }
42 |
43 | encodeResponse(w, req, resp)
44 | }
45 |
46 | type albumResponse struct {
47 | baseResponse
48 |
49 | Album xsdAlbumWithSongsID3 `xml:"album" json:"album"`
50 | }
51 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_album_info.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import "net/http"
4 |
5 | func (s *subsonic) getAlbumInfo(w http.ResponseWriter, req *http.Request) {
6 | s.getAlbumInfo2(w, req)
7 | }
8 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_artist.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | "strconv"
6 | )
7 |
8 | func (s *subsonic) getArtist(w http.ResponseWriter, req *http.Request) {
9 | idString := req.Form.Get("id")
10 | subsonicID, err := strconv.ParseInt(idString, 10, 64)
11 | if idString == "" || err != nil || !isArtistID(subsonicID) {
12 | resp := responseError(errCodeNotFound, "artist not found")
13 | encodeResponse(w, req, resp)
14 | return
15 | }
16 |
17 | artistID := toArtistDBID(subsonicID)
18 |
19 | entry, err := s.getArtistDirectory(req, artistID)
20 | if err != nil {
21 | resp := responseError(errCodeGeneric, err.Error())
22 | encodeResponse(w, req, resp)
23 | return
24 | }
25 |
26 | artEtr := xsdArtistWithAlbumsID3{
27 | xsdArtistID3: directoryToArtistID3(entry),
28 | }
29 |
30 | for _, child := range entry.Children {
31 | artEtr.Children = append(artEtr.Children, toAlbumID3Entry(child))
32 | }
33 |
34 | resp := artistResponse{
35 | baseResponse: responseOk(),
36 | Artist: artEtr,
37 | }
38 |
39 | encodeResponse(w, req, resp)
40 | }
41 |
42 | type artistResponse struct {
43 | baseResponse
44 |
45 | Artist xsdArtistWithAlbumsID3 `xml:"artist" json:"artist"`
46 | }
47 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_artist_info.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "errors"
5 | "net/http"
6 | "strconv"
7 |
8 | "github.com/ironsmile/euterpe/src/library"
9 | )
10 |
11 | func (s *subsonic) getArtistInfo(w http.ResponseWriter, req *http.Request) {
12 | idString := req.Form.Get("id")
13 | subsonicID, err := strconv.ParseInt(idString, 10, 64)
14 | if idString == "" || err != nil || !isArtistID(subsonicID) {
15 | resp := responseError(errCodeNotFound, "artist not found")
16 | encodeResponse(w, req, resp)
17 | return
18 | }
19 |
20 | artistID := toArtistDBID(subsonicID)
21 |
22 | artist, err := s.lib.GetArtist(req.Context(), artistID)
23 | if errors.Is(err, library.ErrArtistNotFound) {
24 | resp := responseError(errCodeNotFound, "artist not found")
25 | encodeResponse(w, req, resp)
26 | return
27 | } else if err != nil {
28 | resp := responseError(errCodeGeneric, err.Error())
29 | encodeResponse(w, req, resp)
30 | return
31 | }
32 |
33 | baseArtistInfo := s.getArtistInfoBase(req, artist)
34 | resp := artistInfoResponse{
35 | baseResponse: baseArtistInfo.baseResponse,
36 | ArtistInfo: baseArtistInfo.ArtistInfo2,
37 | }
38 |
39 | encodeResponse(w, req, resp)
40 | }
41 |
42 | type artistInfoResponse struct {
43 | baseResponse
44 |
45 | // ArtistInfo reuses the aristInfo2Element element since for the moment
46 | // it is exactly the same as what would've been the artistInfoElement.
47 | ArtistInfo xsdArtistInfoBase `xml:"artistInfo"`
48 | }
49 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_genres.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | )
6 |
7 | func (s *subsonic) getGenres(w http.ResponseWriter, req *http.Request) {
8 | resp := genresResponse{
9 | baseResponse: responseOk(),
10 | }
11 |
12 | encodeResponse(w, req, resp)
13 | }
14 |
15 | type genresResponse struct {
16 | baseResponse
17 |
18 | Genres struct{} `xml:"genres" json:"genres"`
19 | }
20 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_internet_radion_stagions.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import "net/http"
4 |
5 | func (s *subsonic) getInternetRadionStations(w http.ResponseWriter, req *http.Request) {
6 | stations, err := s.radio.GetAll(req.Context())
7 | if err != nil {
8 | resp := responseError(errCodeGeneric, err.Error())
9 | encodeResponse(w, req, resp)
10 | return
11 | }
12 |
13 | resp := getStationsResponse{
14 | baseResponse: responseOk(),
15 | }
16 |
17 | for _, station := range stations {
18 | resp.Result.Stations = append(resp.Result.Stations, fromRadioStation(station))
19 | }
20 | encodeResponse(w, req, resp)
21 | }
22 |
23 | type getStationsResponse struct {
24 | baseResponse
25 |
26 | Result xsdInternetRadioStations `xml:"internetRadioStations" json:"internetRadioStations"`
27 | }
28 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_license.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | "time"
6 | )
7 |
8 | func (s *subsonic) getLicense(w http.ResponseWriter, req *http.Request) {
9 | resp := licenseResponse{
10 | baseResponse: responseOk(),
11 | }
12 |
13 | // Always valid for 10 years into the future.
14 | t := time.Now().Add(365 * 10 * 24 * time.Hour)
15 |
16 | resp.License.Valid = "true"
17 | resp.License.Email = "always-valid@listen-to-euterpe.eu"
18 | resp.License.LicenseExpires = t.Format(time.RFC3339)
19 |
20 | encodeResponse(w, req, resp)
21 | }
22 |
23 | type licenseResponse struct {
24 | baseResponse
25 |
26 | License struct {
27 | Valid string `xml:"valid,attr" json:"valid"`
28 | Email string `xml:"email,attr" json:"email"`
29 | LicenseExpires string `xml:"licenseExpires,attr" json:"licenseExpires"`
30 | } `xml:"license" json:"license"`
31 | }
32 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_music_folders.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | )
6 |
7 | func (s *subsonic) getMusicFolders(w http.ResponseWriter, req *http.Request) {
8 | resp := musicFoldersResponse{
9 | baseResponse: responseOk(),
10 | MusicFolders: musicFolders{
11 | Children: []musicFolder{
12 | {
13 | ID: combinedMusicFolderID,
14 | Name: "Combined Music Library",
15 | },
16 | },
17 | },
18 | }
19 |
20 | encodeResponse(w, req, resp)
21 | }
22 |
23 | type musicFoldersResponse struct {
24 | baseResponse
25 |
26 | MusicFolders musicFolders `xml:"musicFolders" json:"musicFolders"`
27 | }
28 |
29 | type musicFolders struct {
30 | Children []musicFolder `xml:"musicFolder" json:"musicFolder"`
31 | }
32 |
33 | type musicFolder struct {
34 | ID int64 `xml:"id,attr" json:"id,string"`
35 | Name string `xml:"name,attr" json:"name"`
36 | }
37 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_open_subsonic_extensions.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import "net/http"
4 |
5 | func (s *subsonic) getOpenSubsonicExtensions(w http.ResponseWriter, req *http.Request) {
6 | resp := osExtensionsResponse{
7 | baseResponse: responseOk(),
8 | Extensions: []osExtension{
9 | {
10 | Name: "formPost",
11 | Versions: []int{1},
12 | },
13 | },
14 | }
15 |
16 | encodeResponse(w, req, resp)
17 | }
18 |
19 | type osExtensionsResponse struct {
20 | baseResponse
21 |
22 | Extensions []osExtension `xml:"openSubsonicExtensions" json:"openSubsonicExtensions"`
23 | }
24 |
25 | type osExtension struct {
26 | Name string `xml:"name,attr" json:"name"`
27 | Versions []int `xml:"versions" json:"versions"`
28 | }
29 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_playlist.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "net/http"
7 | "strconv"
8 |
9 | "github.com/ironsmile/euterpe/src/playlists"
10 | )
11 |
12 | func (s *subsonic) getPlaylist(w http.ResponseWriter, req *http.Request) {
13 | idString := req.Form.Get("id")
14 | if idString == "" {
15 | resp := responseError(errCodeMissingParameter, "playlist ID is required")
16 | encodeResponse(w, req, resp)
17 | return
18 | }
19 |
20 | playlistID, err := strconv.ParseInt(idString, 10, 64)
21 | if err != nil {
22 | resp := responseError(errCodeNotFound, "playlist not found")
23 | encodeResponse(w, req, resp)
24 | return
25 | }
26 |
27 | playlist, err := s.playlists.Get(req.Context(), playlistID)
28 | if err != nil && errors.Is(err, playlists.ErrNotFound) {
29 | resp := responseError(errCodeNotFound, "playlist not found")
30 | encodeResponse(w, req, resp)
31 | return
32 | } else if err != nil {
33 | resp := responseError(
34 | errCodeGeneric,
35 | fmt.Sprintf("failed to get created playlist: %s", err),
36 | )
37 | encodeResponse(w, req, resp)
38 | return
39 | }
40 |
41 | resp := playlistWithSongsResponse{
42 | baseResponse: responseOk(),
43 | Playlist: toXsdPlaylistWithSongs(playlist, s.auth.User, s.lastModified),
44 | }
45 |
46 | encodeResponse(w, req, resp)
47 | }
48 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_playlists.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/ironsmile/euterpe/src/playlists"
7 | )
8 |
9 | func (s *subsonic) getPlaylists(w http.ResponseWriter, req *http.Request) {
10 | username := req.Form.Get("username")
11 | if username != "" && username != s.auth.User {
12 | resp := responseError(errCodeNotFound, "username not found")
13 | encodeResponse(w, req, resp)
14 | return
15 | }
16 |
17 | playlists, err := s.playlists.List(req.Context(), playlists.ListArgs{
18 | Offset: 0,
19 | Count: 0, // 0 means "all"
20 | })
21 | if err != nil {
22 | resp := responseError(errCodeGeneric, err.Error())
23 | encodeResponse(w, req, resp)
24 | return
25 | }
26 |
27 | resp := playlistsResponse{
28 | baseResponse: responseOk(),
29 | }
30 |
31 | for _, playlist := range playlists {
32 | resp.Playlists.Children = append(
33 | resp.Playlists.Children,
34 | toXsdPlaylist(playlist, s.auth.User),
35 | )
36 | }
37 |
38 | encodeResponse(w, req, resp)
39 | }
40 |
41 | type playlistsResponse struct {
42 | baseResponse
43 |
44 | Playlists xsdPlaylists `xml:"playlists" json:"playlists"`
45 | }
46 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_song.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "errors"
5 | "net/http"
6 | "strconv"
7 |
8 | "github.com/ironsmile/euterpe/src/library"
9 | )
10 |
11 | func (s *subsonic) getSong(w http.ResponseWriter, req *http.Request) {
12 | idString := req.Form.Get("id")
13 | subsonicID, err := strconv.ParseInt(idString, 10, 64)
14 | if idString == "" || err != nil || !isTrackID(subsonicID) {
15 | resp := responseError(errCodeNotFound, "song not found")
16 | encodeResponse(w, req, resp)
17 | return
18 | }
19 |
20 | trackID := toTrackDBID(subsonicID)
21 |
22 | track, err := s.lib.GetTrack(req.Context(), trackID)
23 | if errors.Is(err, library.ErrNotFound) {
24 | resp := responseError(errCodeNotFound, "song not found")
25 | encodeResponse(w, req, resp)
26 | return
27 | }
28 |
29 | resp := songResponse{
30 | baseResponse: responseOk(),
31 | Song: trackToChild(track, s.lastModified),
32 | }
33 |
34 | encodeResponse(w, req, resp)
35 | }
36 |
37 | type songResponse struct {
38 | baseResponse
39 |
40 | Song xsdChild `xml:"song" json:"song"`
41 | }
42 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_user.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import "net/http"
4 |
5 | func (s *subsonic) getUser(w http.ResponseWriter, req *http.Request) {
6 | username := req.Form.Get("username")
7 | if username == "" {
8 | resp := responseError(errCodeMissingParameter, "missing username parameter")
9 | encodeResponse(w, req, resp)
10 | return
11 | }
12 |
13 | if username != s.auth.User {
14 | resp := responseError(errCodeNotFound, "user not found")
15 | encodeResponse(w, req, resp)
16 | return
17 | }
18 |
19 | resp := getUserResponse{
20 | baseResponse: responseOk(),
21 |
22 | User: xsdUser{
23 | Username: s.auth.User,
24 | Scrobbling: true,
25 | AdminRole: true,
26 | SettingsRole: true,
27 | DownloadRole: true,
28 | UploadRole: true,
29 | PlaylistRole: true,
30 | CoverArtRole: true,
31 | CommentRole: true,
32 | PodcastRole: true,
33 | StreamRole: true,
34 | JukeboxRole: true,
35 | ShareRole: true,
36 | Folders: []int64{
37 | combinedMusicFolderID,
38 | },
39 | },
40 | }
41 |
42 | encodeResponse(w, req, resp)
43 | }
44 |
45 | type getUserResponse struct {
46 | baseResponse
47 |
48 | User xsdUser `xml:"user" json:"user"`
49 | }
50 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_video_info.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | )
6 |
7 | func (s *subsonic) getVideoInfo(w http.ResponseWriter, req *http.Request) {
8 | resp := responseError(errCodeNotFound, "video not found")
9 | encodeResponse(w, req, resp)
10 | }
11 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/get_videos.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | )
6 |
7 | func (s *subsonic) getVideos(w http.ResponseWriter, req *http.Request) {
8 | resp := videosResponse{
9 | baseResponse: responseOk(),
10 | }
11 |
12 | encodeResponse(w, req, resp)
13 | }
14 |
15 | type videosResponse struct {
16 | baseResponse
17 |
18 | Videos struct{} `xml:"videos" json:"videos"`
19 | }
20 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/ping.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | )
6 |
7 | func (s *subsonic) apiPing(w http.ResponseWriter, req *http.Request) {
8 | encodeResponse(w, req, pingResponse{
9 | baseResponse: responseOk(),
10 | })
11 | }
12 |
13 | type pingResponse struct {
14 | baseResponse
15 | }
16 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/stream.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "os"
7 | "path/filepath"
8 | "strconv"
9 | "time"
10 | )
11 |
12 | func (s *subsonic) stream(w http.ResponseWriter, req *http.Request) {
13 | idString := req.Form.Get("id")
14 | trackID, err := strconv.ParseInt(idString, 10, 64)
15 | if idString == "" || err != nil || !isTrackID(trackID) {
16 | resp := responseError(errCodeNotFound, "track not found")
17 | encodeResponse(w, req, resp)
18 | return
19 | }
20 |
21 | //!TODO: support maximum bitrate and and transcoding. Once done, a separate
22 | // endpoint must be created for the "/download" endpoint.
23 |
24 | filePath := s.lib.GetFilePath(req.Context(), toTrackDBID(trackID))
25 |
26 | fh, err := os.Open(filePath)
27 | if err != nil {
28 | http.NotFoundHandler().ServeHTTP(w, req)
29 | return
30 | }
31 | defer fh.Close()
32 |
33 | modTime := time.Time{}
34 | st, err := fh.Stat()
35 | if err == nil {
36 | modTime = st.ModTime()
37 | }
38 |
39 | baseName := filepath.Base(filePath)
40 |
41 | w.Header().Add("Content-Disposition",
42 | fmt.Sprintf("filename=\"%s\"", baseName))
43 |
44 | http.ServeContent(w, req, baseName, modTime, fh)
45 | }
46 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/unstar.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "net/http"
5 | )
6 |
7 | func (s *subsonic) unstar(w http.ResponseWriter, req *http.Request) {
8 | favs, ok := s.parseStarArguments(w, req)
9 | if !ok {
10 | return
11 | }
12 |
13 | if err := s.lib.RemoveFavourite(req.Context(), favs); err != nil {
14 | resp := responseError(errCodeGeneric, err.Error())
15 | encodeResponse(w, req, resp)
16 | return
17 | }
18 |
19 | encodeResponse(w, req, responseOk())
20 | }
21 |
--------------------------------------------------------------------------------
/src/webserver/subsonic/update_internet_radio_station.go:
--------------------------------------------------------------------------------
1 | package subsonic
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "net/http"
7 | "strconv"
8 |
9 | "github.com/ironsmile/euterpe/src/radio"
10 | )
11 |
12 | func (s *subsonic) updateInternetRadioStation(w http.ResponseWriter, req *http.Request) {
13 | station, ok := s.radioStationFromParams(w, req)
14 | if !ok {
15 | // Response has already been written by radioStationFromParams.
16 | return
17 | }
18 |
19 | id := req.Form.Get("id")
20 | if id == "" {
21 | resp := responseError(
22 | errCodeMissingParameter,
23 | "the parameter `id` is required",
24 | )
25 | encodeResponse(w, req, resp)
26 | return
27 | }
28 |
29 | idInt, err := strconv.ParseInt(id, 10, 64)
30 | if err != nil {
31 | resp := responseError(
32 | errCodeNotFound,
33 | fmt.Sprintf("could not parse radio station ID: %s", err),
34 | )
35 | encodeResponse(w, req, resp)
36 | return
37 | }
38 |
39 | station.ID = idInt
40 | if err := s.radio.Replace(req.Context(), station); errors.Is(err, radio.ErrNotFound) {
41 | resp := responseError(
42 | errCodeNotFound,
43 | "radio station not found",
44 | )
45 | encodeResponse(w, req, resp)
46 | return
47 | } else if err != nil {
48 | resp := responseError(
49 | errCodeGeneric,
50 | fmt.Sprintf("could not update radio station: %s", err),
51 | )
52 | encodeResponse(w, req, resp)
53 | return
54 | }
55 |
56 | encodeResponse(w, req, responseOk())
57 | }
58 |
--------------------------------------------------------------------------------
/src/webserver/webutils/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package webutils contains functions and types commonly used by the HTTP handlers.
3 | */
4 | package webutils
5 |
--------------------------------------------------------------------------------
/src/webserver/webutils/error.go:
--------------------------------------------------------------------------------
1 | package webutils
2 |
3 | import (
4 | "encoding/json"
5 | "log"
6 | "net/http"
7 | )
8 |
9 | // JSONError writes a JSON object with an error message and sets the HTTP status code.
10 | func JSONError(w http.ResponseWriter, message string, statusCode int) {
11 | w.WriteHeader(statusCode)
12 | resp := jsonErrorMessage{
13 | Error: message,
14 | }
15 | enc := json.NewEncoder(w)
16 | if err := enc.Encode(&resp); err != nil {
17 | log.Printf("error writing body in browse handler: %s", err)
18 | }
19 | }
20 |
21 | type jsonErrorMessage struct {
22 | Error string `json:"error"`
23 | }
24 |
--------------------------------------------------------------------------------
/src/webserver/webutils/error_test.go:
--------------------------------------------------------------------------------
1 | package webutils_test
2 |
3 | import (
4 | "encoding/json"
5 | "net/http"
6 | "net/http/httptest"
7 | "testing"
8 |
9 | "github.com/ironsmile/euterpe/src/webserver/webutils"
10 | )
11 |
12 | // TestJSONError makes sure that the JSONError function really encodes the response
13 | // as a valid JSON.
14 | func TestJSONError(t *testing.T) {
15 | rec := httptest.NewRecorder()
16 | errMsg := "some error message for testing"
17 |
18 | webutils.JSONError(rec, errMsg, http.StatusBadGateway)
19 |
20 | res := rec.Result()
21 | defer func() {
22 | res.Body.Close()
23 | }()
24 |
25 | if res.StatusCode != http.StatusBadGateway {
26 | t.Errorf("Expected Bad Gateway status but got %d", res.StatusCode)
27 | }
28 |
29 | var respJSON json.RawMessage
30 | dec := json.NewDecoder(res.Body)
31 | if err := dec.Decode(&respJSON); err != nil {
32 | t.Errorf("Failed decoding the JSON response: %s", err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/templates/add_device.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | In your mobile app select "Use Barcode" when logging in and then
6 | scan this barcode.
7 |
8 |
9 |
10 |
11 | Generating...
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/templates/unauthorized.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 401 Unauthorized
6 |
7 |
8 | Authentication required
9 |
10 |
11 |
--------------------------------------------------------------------------------
/test_files/http_root/second/static:
--------------------------------------------------------------------------------
1 | Second static file
--------------------------------------------------------------------------------
/test_files/http_root/static:
--------------------------------------------------------------------------------
1 | This is a static file
--------------------------------------------------------------------------------
/test_files/library/folder_one/not_an_mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/test_files/library/folder_one/not_an_mp3
--------------------------------------------------------------------------------
/test_files/library/folder_one/third_file.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/test_files/library/folder_one/third_file.mp3
--------------------------------------------------------------------------------
/test_files/library/test_file_one.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/test_files/library/test_file_one.mp3
--------------------------------------------------------------------------------
/test_files/library/test_file_two.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/test_files/library/test_file_two.mp3
--------------------------------------------------------------------------------
/test_files/more_mp3s/test_file_added.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/test_files/more_mp3s/test_file_added.mp3
--------------------------------------------------------------------------------
/test_files/ogg_files/vorbis-tags.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/test_files/ogg_files/vorbis-tags.ogg
--------------------------------------------------------------------------------
/test_files/ssl/cert.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDczCCAlugAwIBAgIJALew3NcLQAVoMA0GCSqGSIb3DQEBBQUAMFAxCzAJBgNV
3 | BAYTAkJHMQ4wDAYDVQQIDAVTb2ZpYTEOMAwGA1UEBwwFU29maWExITAfBgNVBAoM
4 | GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDAxMDUyMTQzNDJaFw0yMjA1
5 | MTcyMTQzNDJaMFAxCzAJBgNVBAYTAkJHMQ4wDAYDVQQIDAVTb2ZpYTEOMAwGA1UE
6 | BwwFU29maWExITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIw
7 | DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPHlNxroVMUwl7L9jM9zgTXOWuj
8 | M/LgUcHWpbhvjDy6CQTaBBwZpye55UOj2zncZ8SqfmO2XoEn5+bj/ZMQgLooumy/
9 | ufttms9tJmZ7DiCKks5kVfyUBCDLcQx2i+pN5RozALriHymhZfWKbfCPWxhFoIlZ
10 | HAPfTVxYctOHJ9dWso/RXOw8x5RmaLmzDAeOkXq/zJVasKTGJYh/uolBlHff0Wtc
11 | 9Rk+xjE7PTxDqvuRilcHteB8DvUun4aO9D7Q6tnEKsrm3WPsneYA87DFU5mmjSSI
12 | ip0HZJ9nC+Jiqt8XbLplyehWuHm/hWjAAByJ5GWBLByIQCT16xkPdJIRBBMCAwEA
13 | AaNQME4wHQYDVR0OBBYEFFp9LymoSZtmz/uNuUeoKCKTjz2BMB8GA1UdIwQYMBaA
14 | FFp9LymoSZtmz/uNuUeoKCKTjz2BMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
15 | BQADggEBAN3YIysy4vvHdUzZVsIbtkVidA/ntYfVHORlcWKSfC0eDk1MfwWg0yhD
16 | Klmhmwc4Gns/U7YTtq9bCBwaEQ7bZdP3Jg4vNkeo8OnIxZxz3IT203B9Hv8H5k6I
17 | 85vEV/pwHSJLN6oSRIJvo5N1bSFRA5G7oOfIHl53/6dwNe/USJR62niZExLvAuzW
18 | Vv/vpld8hiz7ytkQZIETCokv9UdYU6uTf//AawlfoDFMdK8VJ3AfJqoFdpsekAoY
19 | 88edBHZfPHGET/DS8J7PVRWg6yxhBjdKbM2CjAiJs6GjKW2UOBfxhPJh75ksp2nb
20 | 2U6fUgBDU2N0z73rbllwGFnaOU2+jl4=
21 | -----END CERTIFICATE-----
22 |
--------------------------------------------------------------------------------
/tools/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
5 | cd ..
6 |
7 | os='unknown'
8 | unamestr=`uname`
9 | if [[ "$unamestr" == 'Linux' ]]; then
10 | os='linux'
11 | elif [[ "$unamestr" == 'FreeBSD' ]]; then
12 | os='freebsd'
13 | elif [[ "$unamestr" == 'Darwin' ]]; then
14 | os='darwin'
15 | fi
16 |
17 | arch="amd64"
18 | version=`git describe --tags --always`
19 |
20 | if [[ $# -gt 0 ]]; then
21 | export GOOS="$1"
22 | os="$GOOS"
23 | fi
24 |
25 | if [ -d dist/euterpe ]
26 | then
27 | echo "Removing old dist/euterpe directory..."
28 | rm -rf dist/euterpe
29 | fi
30 |
31 | echo "Making dist directory..."
32 | mkdir -p dist/euterpe
33 |
34 | echo "Building binaries..."
35 | make release
36 | mv euterpe dist/euterpe/euterpe
37 |
38 | for file in README.md
39 | do
40 | echo "Copying $file..."
41 | cp "$file" dist/euterpe
42 | done
43 |
44 | echo "Copying install/uninstall scripts..."
45 | cp tools/install dist/euterpe
46 | cp tools/uninstall dist/euterpe
47 |
48 | archive="euterpe_${version}_${os}_${arch}.tar.gz"
49 |
50 | echo "Creating archive..."
51 | cd dist
52 | tar cfzv "$archive" euterpe
53 |
54 | echo "dist/$archive created"
55 |
56 | echo "Cleaning up..."
57 | cd -
58 | rm -rf dist/euterpe || exit
59 |
60 | echo "Done"
61 |
--------------------------------------------------------------------------------
/tools/cross-compile:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Still work in progress.
4 |
5 | CGO_ENABLED=1 \
6 | CC=x86_64-w64-mingw32-gcc-win32 \
7 | PKG_CONFIG=x86_64-w64-mingw32-pkg-config \
8 | PKG_CONFIG_PATH=/home/iron4o/taglib/lib/pkgconfig/ \
9 | ./build windows
10 |
11 | # removing --tags "sqlite_icu" makes the sqlite compile!
12 |
--------------------------------------------------------------------------------
/tools/euterpe.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Euterpe Streaming Media Server
3 | ConditionFileIsExecutable=/usr/bin/euterpe
4 | Documentation=https://listen-to-euterpe.eu/docs/
5 | After=network.target
6 |
7 | [Service]
8 | Type=simple
9 | ExecStart=/usr/bin/euterpe
10 | Restart=on-failure
11 | User=$USER
12 | Group=$GROUP
13 | WorkingDirectory=/home/$USER/.euterpe
14 | StandardOutput=journal
15 | StandardError=journal
16 |
17 | [Install]
18 | WantedBy=multi-user.target
19 | Alias=httpms
20 |
--------------------------------------------------------------------------------
/tools/install:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | INSTALL_DIR=$(dirname `readlink -f $0`)
3 | cd "$INSTALL_DIR"
4 | cd ..
5 |
6 | if [ -d /etc/euterpe ]; then
7 | echo "Euterpe is already installed. Aborting."
8 | exit 0
9 | fi
10 |
11 | for binary in euterpe
12 | do
13 | if [ -f "/usr/bin/${binary}" ]; then
14 | echo "Euterpe is already installed. Aborting."
15 | exit 0
16 | fi
17 | done
18 |
19 | echo "Installing euterpe dir to /etc/..."
20 | cp -a "$INSTALL_DIR" /etc/euterpe || exit 1
21 |
22 | echo "Setting directory permissions..."
23 | find /etc/euterpe -type d -exec chmod 755 "{}" \; || exit 1
24 |
25 | echo "Moving binaries to /usr/bin/..."
26 | mv /etc/euterpe/euterpe /usr/bin/euterpe || exit 1
27 |
28 | echo "Done"
29 |
--------------------------------------------------------------------------------
/tools/nginx.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 443 ssl http2;
3 | server_name music.example.com;
4 |
5 | ssl_certificate /etc/certs/music.example.com/fullchain.pem;
6 | ssl_certificate_key /etc/certs/music.example.com/privkey.pem;
7 | include /etc/nginx/ssl-params.conf;
8 |
9 | location / {
10 | proxy_pass http://127.0.0.1:9996;
11 |
12 | proxy_set_header X-Real-IP $remote_addr;
13 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
14 | proxy_set_header X-Forwarded-Proto https;
15 | proxy_set_header X-Forwarded-Port 443;
16 | proxy_set_header Host $host;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tools/uninstall:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ ! -d /etc/euterpe ]; then
4 | echo "Euterpe is not installed. Aborting."
5 | exit 0
6 | fi
7 |
8 | rm -rf /etc/euterpe
9 | rm /usr/bin/euterpe
10 |
--------------------------------------------------------------------------------
/vendor/github.com/dhowden/tag/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*.go]
8 | indent_style = tab
9 | indent_size = 3
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
14 | [*]
15 | # We recommend you to keep these unchanged
16 | end_of_line = lf
17 | charset = utf-8
18 | trim_trailing_whitespace = true
19 | insert_final_newline = true
20 |
--------------------------------------------------------------------------------
/vendor/github.com/dhowden/tag/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - 1.7
5 | - tip
--------------------------------------------------------------------------------
/vendor/github.com/dhowden/tag/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2015, David Howden
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | Redistributions in binary form must reproduce the above copyright notice, this
11 | list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = false
6 | indent_size = 2
7 | indent_style = space
8 |
9 | [{README.md,*.go,Makefile}]
10 | indent_style = tab
11 |
12 | [{README.md,*.go,COMMIT_EDITMSG}]
13 | tab_width = 8
14 |
15 | [Makefile]
16 | indent_size = 4
17 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/.gitignore:
--------------------------------------------------------------------------------
1 | tags
2 | *.out
3 | .bin/
4 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Gabriel Sanches
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/algorithm.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | import (
4 | // Load all hashing functions needed.
5 | _ "crypto/sha256"
6 | _ "crypto/sha512"
7 | )
8 |
9 | // Algorithm is an algorithm for both signing and verifying a JWT.
10 | type Algorithm interface {
11 | Name() string
12 | Sign(headerPayload []byte) ([]byte, error)
13 | Size() int
14 | Verify(headerPayload, sig []byte) error
15 | }
16 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/audience.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | import "encoding/json"
4 |
5 | // Audience is a special claim that may either be
6 | // a single string or an array of strings, as per the RFC 7519.
7 | type Audience []string
8 |
9 | // MarshalJSON implements a marshaling function for "aud" claim.
10 | func (a Audience) MarshalJSON() ([]byte, error) {
11 | switch len(a) {
12 | case 0:
13 | return json.Marshal("") // nil or empty slice returns an empty string
14 | case 1:
15 | return json.Marshal(a[0])
16 | default:
17 | return json.Marshal([]string(a))
18 | }
19 | }
20 |
21 | // UnmarshalJSON implements an unmarshaling function for "aud" claim.
22 | func (a *Audience) UnmarshalJSON(b []byte) error {
23 | var (
24 | v interface{}
25 | err error
26 | )
27 | if err = json.Unmarshal(b, &v); err != nil {
28 | return err
29 | }
30 | switch vv := v.(type) {
31 | case string:
32 | aud := make(Audience, 1)
33 | aud[0] = vv
34 | *a = aud
35 | case []interface{}:
36 | aud := make(Audience, len(vv))
37 | for i := range vv {
38 | aud[i] = vv[i].(string)
39 | }
40 | *a = aud
41 | }
42 | return nil
43 | }
44 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/doc.go:
--------------------------------------------------------------------------------
1 | // Package jwt is a JSON Web Token signer, verifier and validator.
2 | package jwt
3 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/hash_pool.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | import (
4 | "hash"
5 | "sync"
6 | )
7 |
8 | type hashPool struct {
9 | *sync.Pool
10 | }
11 |
12 | func newHashPool(hfunc func() hash.Hash) *hashPool {
13 | return &hashPool{&sync.Pool{New: func() interface{} { return hfunc() }}}
14 | }
15 |
16 | func (hp *hashPool) sign(headerPayload []byte) ([]byte, error) {
17 | hh := hp.Pool.Get().(hash.Hash)
18 | defer func() {
19 | hh.Reset()
20 | hp.Pool.Put(hh)
21 | }()
22 |
23 | if _, err := hh.Write(headerPayload); err != nil {
24 | return nil, err
25 | }
26 | return hh.Sum(nil), nil
27 | }
28 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/header.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | // Header is a JOSE header narrowed down to the JWT specification from RFC 7519.
4 | //
5 | // Parameters are ordered according to the RFC 7515.
6 | type Header struct {
7 | Algorithm string `json:"alg,omitempty"`
8 | ContentType string `json:"cty,omitempty"`
9 | KeyID string `json:"kid,omitempty"`
10 | Type string `json:"typ,omitempty"`
11 | }
12 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/internal/decode.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | import (
4 | "encoding/base64"
5 | "encoding/json"
6 | )
7 |
8 | // Decode decodes a Base64 encoded JSON object using the proper encoding for JWTs.
9 | func Decode(enc []byte, v interface{}) error {
10 | dec, err := DecodeToBytes(enc)
11 | if err != nil {
12 | return err
13 | }
14 | return json.Unmarshal(dec, v)
15 | }
16 |
17 | // DecodeToBytes decodes a Base64 string using the proper encoding for JWTs.
18 | func DecodeToBytes(enc []byte) ([]byte, error) {
19 | encoding := base64.RawURLEncoding
20 | dec := make([]byte, encoding.DecodedLen(len(enc)))
21 | if _, err := encoding.Decode(dec, enc); err != nil {
22 | return nil, err
23 | }
24 | return dec, nil
25 | }
26 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/internal/ed25519.go:
--------------------------------------------------------------------------------
1 | // +build go1.13
2 |
3 | package internal
4 |
5 | import (
6 | "crypto/ed25519"
7 | "crypto/rand"
8 | )
9 |
10 | // GenerateEd25519Keys generates a pair of keys for testing purposes.
11 | func GenerateEd25519Keys() (ed25519.PrivateKey, ed25519.PublicKey) {
12 | pub, priv, err := ed25519.GenerateKey(rand.Reader)
13 | if err != nil {
14 | panic(err)
15 | }
16 | return priv, pub
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/internal/ed25519_go1_12.go:
--------------------------------------------------------------------------------
1 | // +build !go1.13
2 |
3 | package internal
4 |
5 | import (
6 | "crypto/rand"
7 |
8 | "golang.org/x/crypto/ed25519"
9 | )
10 |
11 | // GenerateEd25519Keys generates a pair of keys for testing purposes.
12 | func GenerateEd25519Keys() (ed25519.PrivateKey, ed25519.PublicKey) {
13 | pub, priv, err := ed25519.GenerateKey(rand.Reader)
14 | if err != nil {
15 | panic(err)
16 | }
17 | return priv, pub
18 | }
19 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/internal/epoch.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | import "time"
4 |
5 | // Epoch is 01/01/1970.
6 | var Epoch = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
7 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/internal/errors.go:
--------------------------------------------------------------------------------
1 | // +build go1.13
2 |
3 | package internal
4 |
5 | import (
6 | "errors"
7 | "fmt"
8 | )
9 |
10 | // Errorf wraps fmt.Errorf.
11 | func Errorf(format string, a ...interface{}) error { return fmt.Errorf(format, a...) }
12 |
13 | // ErrorAs wraps errors.As.
14 | func ErrorAs(err error, target interface{}) bool { return errors.As(err, target) }
15 |
16 | // ErrorIs wraps errors.Is.
17 | func ErrorIs(err, target error) bool { return errors.Is(err, target) }
18 |
19 | // NewError wraps errors.New.
20 | func NewError(text string) error { return errors.New(text) }
21 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/internal/errors_go1_12.go:
--------------------------------------------------------------------------------
1 | // +build !go1.13
2 |
3 | package internal
4 |
5 | import "golang.org/x/xerrors"
6 |
7 | // Errorf wraps xerrors.Errorf.
8 | func Errorf(format string, a ...interface{}) error { return xerrors.Errorf(format, a...) }
9 |
10 | // ErrorAs wraps xerrors.As.
11 | func ErrorAs(err error, target interface{}) bool { return xerrors.As(err, target) }
12 |
13 | // ErrorIs wraps xerrors.Is.
14 | func ErrorIs(err, target error) bool { return xerrors.Is(err, target) }
15 |
16 | // NewError wraps xerrors.New.
17 | func NewError(text string) error { return xerrors.New(text) }
18 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/json.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | )
7 |
8 | // ErrNotJSONObject is the error for when a JWT payload is not a JSON object.
9 | var ErrNotJSONObject = errors.New("jwt: payload is not a valid JSON object")
10 |
11 | func isJSONObject(payload []byte) bool {
12 | payload = bytes.TrimSpace(payload)
13 | return payload[0] == '{' && payload[len(payload)-1] == '}'
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/none.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | var _ Algorithm = none{}
4 |
5 | type none struct{}
6 |
7 | // None returns a dull, unsecured algorithm.
8 | func None() Algorithm { return none{} }
9 |
10 | // Name always returns "none".
11 | func (none) Name() string { return "none" }
12 |
13 | // Sign always returns a nil byte slice and a nil error.
14 | func (none) Sign(_ []byte) ([]byte, error) { return nil, nil }
15 |
16 | // Size always returns 0 and a nil error.
17 | func (none) Size() int { return 0 }
18 |
19 | // Verify always returns a nil error.
20 | func (none) Verify(_, _ []byte) error { return nil }
21 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/payload.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | // Payload is a JWT payload according to the RFC 7519.
4 | type Payload struct {
5 | Issuer string `json:"iss,omitempty"`
6 | Subject string `json:"sub,omitempty"`
7 | Audience Audience `json:"aud,omitempty"`
8 | ExpirationTime *Time `json:"exp,omitempty"`
9 | NotBefore *Time `json:"nbf,omitempty"`
10 | IssuedAt *Time `json:"iat,omitempty"`
11 | JWTID string `json:"jti,omitempty"`
12 | }
13 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/resolver.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | // Resolver is an Algorithm that needs to set some variables
4 | // based on a Header before performing signing and verification.
5 | type Resolver interface {
6 | Resolve(Header) error
7 | }
8 |
--------------------------------------------------------------------------------
/vendor/github.com/gbrlsnchs/jwt/v3/time.go:
--------------------------------------------------------------------------------
1 | package jwt
2 |
3 | import (
4 | "encoding/json"
5 | "time"
6 |
7 | "github.com/gbrlsnchs/jwt/v3/internal"
8 | )
9 |
10 | // Time is the allowed format for time, as per the RFC 7519.
11 | type Time struct {
12 | time.Time
13 | }
14 |
15 | // NumericDate is a resolved Unix time.
16 | func NumericDate(tt time.Time) *Time {
17 | if tt.Before(internal.Epoch) {
18 | tt = internal.Epoch
19 | }
20 | return &Time{time.Unix(tt.Unix(), 0)} // set time using Unix time
21 | }
22 |
23 | // MarshalJSON implements a marshaling function for time-related claims.
24 | func (t Time) MarshalJSON() ([]byte, error) {
25 | if t.Before(internal.Epoch) {
26 | return json.Marshal(0)
27 | }
28 | return json.Marshal(t.Unix())
29 | }
30 |
31 | // UnmarshalJSON implements an unmarshaling function for time-related claims.
32 | func (t *Time) UnmarshalJSON(b []byte) error {
33 | var unix *int64
34 | if err := json.Unmarshal(b, &unix); err != nil {
35 | return err
36 | }
37 | if unix == nil {
38 | return nil
39 | }
40 | tt := time.Unix(*unix, 0)
41 | if tt.Before(internal.Epoch) {
42 | tt = internal.Epoch
43 | }
44 | t.Time = tt
45 | return nil
46 | }
47 |
--------------------------------------------------------------------------------
/vendor/github.com/gorilla/context/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | sudo: false
3 |
4 | matrix:
5 | include:
6 | - go: 1.3
7 | - go: 1.4
8 | - go: 1.5
9 | - go: 1.6
10 | - go: 1.7
11 | - go: tip
12 | allow_failures:
13 | - go: tip
14 |
15 | script:
16 | - go get -t -v ./...
17 | - diff -u <(echo -n) <(gofmt -d .)
18 | - go vet $(go list ./... | grep -v /vendor/)
19 | - go test -v -race ./...
20 |
--------------------------------------------------------------------------------
/vendor/github.com/gorilla/context/README.md:
--------------------------------------------------------------------------------
1 | context
2 | =======
3 | [](https://travis-ci.org/gorilla/context)
4 |
5 | gorilla/context is a general purpose registry for global request variables.
6 |
7 | > Note: gorilla/context, having been born well before `context.Context` existed, does not play well
8 | > with the shallow copying of the request that [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) (added to net/http Go 1.7 onwards) performs. You should either use *just* gorilla/context, or moving forward, the new `http.Request.Context()`.
9 |
10 | Read the full documentation here: http://www.gorillatoolkit.org/pkg/context
11 |
--------------------------------------------------------------------------------
/vendor/github.com/gorilla/mux/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | sudo: false
3 |
4 | matrix:
5 | include:
6 | - go: 1.5.x
7 | - go: 1.6.x
8 | - go: 1.7.x
9 | - go: 1.8.x
10 | - go: 1.9.x
11 | - go: 1.10.x
12 | - go: tip
13 | allow_failures:
14 | - go: tip
15 |
16 | install:
17 | - # Skip
18 |
19 | script:
20 | - go get -t -v ./...
21 | - diff -u <(echo -n) <(gofmt -d .)
22 | - go tool vet .
23 | - go test -v -race ./...
24 |
--------------------------------------------------------------------------------
/vendor/github.com/gorilla/mux/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **What version of Go are you running?** (Paste the output of `go version`)
2 |
3 |
4 | **What version of gorilla/mux are you at?** (Paste the output of `git rev-parse HEAD` inside `$GOPATH/src/github.com/gorilla/mux`)
5 |
6 |
7 | **Describe your problem** (and what you have tried so far)
8 |
9 |
10 | **Paste a minimal, runnable, reproduction of your issue below** (use backticks to format it)
11 |
12 |
--------------------------------------------------------------------------------
/vendor/github.com/gorilla/mux/context_gorilla.go:
--------------------------------------------------------------------------------
1 | // +build !go1.7
2 |
3 | package mux
4 |
5 | import (
6 | "net/http"
7 |
8 | "github.com/gorilla/context"
9 | )
10 |
11 | func contextGet(r *http.Request, key interface{}) interface{} {
12 | return context.Get(r, key)
13 | }
14 |
15 | func contextSet(r *http.Request, key, val interface{}) *http.Request {
16 | if val == nil {
17 | return r
18 | }
19 |
20 | context.Set(r, key, val)
21 | return r
22 | }
23 |
24 | func contextClear(r *http.Request) {
25 | context.Clear(r)
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/github.com/gorilla/mux/context_native.go:
--------------------------------------------------------------------------------
1 | // +build go1.7
2 |
3 | package mux
4 |
5 | import (
6 | "context"
7 | "net/http"
8 | )
9 |
10 | func contextGet(r *http.Request, key interface{}) interface{} {
11 | return r.Context().Value(key)
12 | }
13 |
14 | func contextSet(r *http.Request, key, val interface{}) *http.Request {
15 | if val == nil {
16 | return r
17 | }
18 |
19 | return r.WithContext(context.WithValue(r.Context(), key, val))
20 | }
21 |
22 | func contextClear(r *http.Request) {
23 | return
24 | }
25 |
--------------------------------------------------------------------------------
/vendor/github.com/gorilla/mux/test_helpers.go:
--------------------------------------------------------------------------------
1 | // Copyright 2012 The Gorilla Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package mux
6 |
7 | import "net/http"
8 |
9 | // SetURLVars sets the URL variables for the given request, to be accessed via
10 | // mux.Vars for testing route behaviour. Arguments are not modified, a shallow
11 | // copy is returned.
12 | //
13 | // This API should only be used for testing purposes; it provides a way to
14 | // inject variables into the request context. Alternatively, URL variables
15 | // can be set by making a route that captures the required variables,
16 | // starting a server and sending the request to that server.
17 | func SetURLVars(r *http.Request, val map[string]string) *http.Request {
18 | return setVars(r, val)
19 | }
20 |
--------------------------------------------------------------------------------
/vendor/github.com/howeyc/fsnotify/.gitignore:
--------------------------------------------------------------------------------
1 | # Setup a Global .gitignore for OS and editor generated files:
2 | # https://help.github.com/articles/ignoring-files
3 | # git config --global core.excludesfile ~/.gitignore_global
4 |
5 | .vagrant
6 |
--------------------------------------------------------------------------------
/vendor/github.com/howeyc/fsnotify/AUTHORS:
--------------------------------------------------------------------------------
1 | # Names should be added to this file as
2 | # Name or Organization
3 | # The email address is not required for organizations.
4 |
5 | # You can update this list using the following command:
6 | #
7 | # $ git shortlog -se | awk '{print $2 " " $3 " " $4}'
8 |
9 | # Please keep the list sorted.
10 |
11 | Adrien Bustany
12 | Caleb Spare
13 | Case Nelson
14 | Chris Howey
15 | Christoffer Buchholz
16 | Dave Cheney
17 | Francisco Souza
18 | John C Barstow
19 | Kelvin Fo
20 | Nathan Youngman
21 | Paul Hammond
22 | Pursuit92
23 | Rob Figueiredo
24 | Travis Cline
25 | Tudor Golubenco
26 | bronze1man
27 | debrando
28 | henrikedwards
29 |
--------------------------------------------------------------------------------
/vendor/github.com/howeyc/fsnotify/fsnotify_open_bsd.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build freebsd openbsd netbsd
6 |
7 | package fsnotify
8 |
9 | import "syscall"
10 |
11 | const open_FLAGS = syscall.O_NONBLOCK | syscall.O_RDONLY
12 |
--------------------------------------------------------------------------------
/vendor/github.com/howeyc/fsnotify/fsnotify_open_darwin.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build darwin
6 |
7 | package fsnotify
8 |
9 | import "syscall"
10 |
11 | const open_FLAGS = syscall.O_EVTONLY
12 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/sql-migrate/.gitignore:
--------------------------------------------------------------------------------
1 | .*.swp
2 | *.test
3 |
4 | /sql-migrate/test.db
5 | /test.db
6 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/sql-migrate/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | sudo: false
4 |
5 | go:
6 | - "1.8"
7 | - "1.9"
8 | - "1.10"
9 |
10 | services:
11 | - mysql
12 | - postgresql
13 |
14 | before_install:
15 | - mysql -e "CREATE DATABASE IF NOT EXISTS test;" -uroot
16 | - mysql -e "CREATE DATABASE IF NOT EXISTS test_env;" -uroot
17 | - psql -c "CREATE DATABASE test;" -U postgres
18 |
19 | install:
20 | - go get -t ./...
21 | - go install ./...
22 |
23 | script:
24 | - go test -v ./...
25 | - bash test-integration/postgres.sh
26 | - bash test-integration/mysql.sh
27 | - bash test-integration/mysql-flag.sh
28 | - bash test-integration/mysql-env.sh
29 | - bash test-integration/sqlite.sh
30 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/sql-migrate/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (C) 2014-2017 by Ruben Vermeersch
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/sql-migrate/sqlparse/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (C) 2014-2017 by Ruben Vermeersch
4 | Copyright (C) 2012-2014 by Liam Staskawicz
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/sql-migrate/sqlparse/README.md:
--------------------------------------------------------------------------------
1 | # SQL migration parser
2 |
3 | Based on the [goose](https://bitbucket.org/liamstask/goose) migration parser.
4 |
5 | ## License
6 |
7 | This library is distributed under the [MIT](LICENSE) license.
8 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/wrapfs/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Doychin Atanasov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/wrapfs/README.md:
--------------------------------------------------------------------------------
1 | # WrapFS
2 |
3 | `wrapfs` is a Go module which provides wrappers around `fs.FS`.
4 |
5 | ## ModTimeFS
6 |
7 | This wrapper makes sure calls to [fs.FileInfo.Stat](https://pkg.go.dev/io/fs#FileInfo.Stat)
8 | and [fs.DirEntry.Info](https://pkg.go.dev/io/fs#DirEntry.Info) always return non-zero
9 | [ModTime()](https://pkg.go.dev/io/fs#FileInfo.ModTime). In case the wrapped file or entry
10 | return non-zero modification time it stays unchanged. In case they return a zero
11 | modification time then a static mod time will be used instead.
12 |
13 | Usage:
14 |
15 | ```go
16 | var someFs fs.FS = getFS()
17 | modTimeFS := wrapfs.WithModTime(someFS, time.Now())
18 | http.FileServer(http.FS(modTimeFS))
19 | ```
20 |
21 | This is especially helpful for `embed.FS` file systems when used in conjecture with
22 | `http.FileServer`. When `wrapfs.WithModTime` is used in this case the HTTP server will
23 | be able to handle caches which utilize the "Last-Modified" HTTP headers.
24 |
25 | ## Known Limitations
26 |
27 | If new interfaces are added in `fs` they will not be exposed as implemented by the
28 | wrappers until the library has been patched.
29 |
--------------------------------------------------------------------------------
/vendor/github.com/ironsmile/wrapfs/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package wrapfs provides wrappers of the [fs.FS] with additional functionality.
3 | */
4 | package wrapfs
5 |
--------------------------------------------------------------------------------
/vendor/github.com/liyue201/goqr/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | notifications:
4 | email:
5 | recipients:
6 | - liyue201@126.com
7 | on_success: change
8 | on_failure: always
9 |
10 | go:
11 | - 1.12
12 |
13 | install:
14 | - go get github.com/mattn/goveralls
15 |
16 | script:
17 | - go test ./... -v -covermode=count -coverprofile=coverage.out
18 | - $GOPATH/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN
19 |
20 | env:
21 | global:
22 | - GO111MODULE=on
23 | - secure: "aOzEdb/ST82OpO4LqLpwrdRs6GnkmdLJbm3o9+2HmJCyiHkhqPY1bGY1TiYxQLl3GkjFkuVP+3RB+E0p2R/1f4xYkg4cIpPoLm+4xJ7c1NsEGTaWVS8rCNTicqdym7C9kJart6KcAeWWoElFxob3+lTdS6sz4kFaURrVQ/lpbzBESH0B5Rwa35u1WasmHkPxsHJ/2a7Xnknv+SerjgMUDiXUYM5IjUWt2fV2Zq/9blTSReng6+6Lj9EdziZcQfWNJxBK/NDBtpNIpOdY+bZEUDQi7InB3IioKpQeVjMGKSAzqhedqnGbZsaO734Z8VjRjcFRJPuuYMMkMw4hGoplDqqrTa2aFgln54NiNk2R6WIcpPKAFdLEL7rCPx6qRLMRq1EEn6h+lAy5mJ6NIpmJmY/IbDEVH9D4z4YVLJbHhU+yAN4Tk5mwW9N2bLceSNxIRSJcCcDlRiBNba5XLdNb/tHq7PEM2lX1oXp4WzdYgGh08a69OAweY/CRQjiTZrbhmbsZ5qo3UMLA34HTfEVWt8UWeAFry5fhtzeLqQa5h0BPwtFsy9bsdukEL3nAWcWF4HaQ2jh2CNO6OvpzRb8i45qj1QpIvGqy/lJbuO5WswFQaZcKK2nmPa2M4f7+EBGFe3VvmOJcJvAt2ZRYVZalbdTLDKMmMgcdYIL4jzzcSs4="
--------------------------------------------------------------------------------
/vendor/github.com/liyue201/goqr/errors.go:
--------------------------------------------------------------------------------
1 | package goqr
2 |
3 | import "errors"
4 |
5 | // Error definition
6 | var (
7 | ErrNoQRCode = errors.New("no QR code in image")
8 | ErrInvalidGridSize = errors.New("invalid grid size")
9 | ErrInvalidVersion = errors.New("invalid version")
10 | ErrFormatEcc = errors.New("ecc format error")
11 | ErrDataEcc = errors.New("ecc data error")
12 | ErrUnknownDataType = errors.New("unknown data type")
13 | ErrDataOverflow = errors.New("data overflow")
14 | ErrDataUnderflow = errors.New("data underflow")
15 | )
16 |
--------------------------------------------------------------------------------
/vendor/github.com/liyue201/goqr/qr_const.go:
--------------------------------------------------------------------------------
1 | package goqr
2 |
3 | // Limits on the maximum size of QR-codes and their content
4 | const (
5 | qrMaxBimap = 3917
6 | qrMaxPayload = 8896
7 |
8 | // QR-code ECC types
9 | qrEccLevelM = 0
10 | qrEccLevelL = 1
11 | qrEccLevelH = 2
12 | qrEccLevelQ = 3
13 |
14 | // QR-code data types
15 | qrDataTypeNumeric = 1
16 | qrDataTypeAlpha = 2
17 | qrDataTypeByte = 4
18 | qrDataTypeKanji = 8
19 |
20 | // Common character encodings
21 | qrEciIos8859_1 = 1
22 | qrEciIbm437 = 2
23 | qrEciIos8859_2 = 4
24 | qrEciIso8859_3 = 5
25 | qrEciIso8859_4 = 6
26 | qrEciIso8859_5 = 7
27 | qrEciIso8859_6 = 8
28 | qrEciIso8859_7 = 9
29 | qrEciIso8859_8 = 10
30 | qrEciIso8859_9 = 11
31 | qrEciWindows874 = 13
32 | qrEciIso8859_13 = 15
33 | qrEciIso8859_15 = 17
34 | qrEciShiftJis = 20
35 | qrEciUtf8 = 26
36 | )
37 |
--------------------------------------------------------------------------------
/vendor/github.com/liyue201/goqr/utils.go:
--------------------------------------------------------------------------------
1 | package goqr
2 |
3 | func lineIntersect(p0, p1, q0, q1, r *point) bool {
4 | // (a, b) is perpendicular to line p
5 | a := -(p1.y - p0.y)
6 | b := p1.x - p0.x
7 |
8 | // (c, d) is perpendicular to line q
9 | c := -(q1.y - q0.y)
10 | d := q1.x - q0.x
11 |
12 | // e and f are dot products of the respective vectors with p and q
13 | e := a*p1.x + b*p1.y
14 | f := c*q1.x + d*q1.y
15 |
16 | // Now we need to solve:
17 | // [a b] [rx] [e]
18 | // [c d] [ry] = [f]
19 | //
20 | // We do this by inverting the matrix and applying it to (e, f):
21 | // [ d -b] [e] [rx]
22 | // 1/det [-c a] [f] = [ry]
23 | //
24 | det := (a * d) - (b * c)
25 | if det == 0 {
26 | return false
27 | }
28 | r.x = (d*e - b*f) / det
29 | r.y = (-c*e + a*f) / det
30 | return true
31 | }
32 |
--------------------------------------------------------------------------------
/vendor/github.com/magefile/mage/mg/color_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type=Color"; DO NOT EDIT.
2 |
3 | package mg
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[Black-0]
12 | _ = x[Red-1]
13 | _ = x[Green-2]
14 | _ = x[Yellow-3]
15 | _ = x[Blue-4]
16 | _ = x[Magenta-5]
17 | _ = x[Cyan-6]
18 | _ = x[White-7]
19 | _ = x[BrightBlack-8]
20 | _ = x[BrightRed-9]
21 | _ = x[BrightGreen-10]
22 | _ = x[BrightYellow-11]
23 | _ = x[BrightBlue-12]
24 | _ = x[BrightMagenta-13]
25 | _ = x[BrightCyan-14]
26 | _ = x[BrightWhite-15]
27 | }
28 |
29 | const _Color_name = "BlackRedGreenYellowBlueMagentaCyanWhiteBrightBlackBrightRedBrightGreenBrightYellowBrightBlueBrightMagentaBrightCyanBrightWhite"
30 |
31 | var _Color_index = [...]uint8{0, 5, 8, 13, 19, 23, 30, 34, 39, 50, 59, 70, 82, 92, 105, 115, 126}
32 |
33 | func (i Color) String() string {
34 | if i < 0 || i >= Color(len(_Color_index)-1) {
35 | return "Color(" + strconv.FormatInt(int64(i), 10) + ")"
36 | }
37 | return _Color_name[_Color_index[i]:_Color_index[i+1]]
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/github.com/magefile/mage/mg/errors.go:
--------------------------------------------------------------------------------
1 | package mg
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | )
7 |
8 | type fatalErr struct {
9 | code int
10 | error
11 | }
12 |
13 | func (f fatalErr) ExitStatus() int {
14 | return f.code
15 | }
16 |
17 | type exitStatus interface {
18 | ExitStatus() int
19 | }
20 |
21 | // Fatal returns an error that will cause mage to print out the
22 | // given args and exit with the given exit code.
23 | func Fatal(code int, args ...interface{}) error {
24 | return fatalErr{
25 | code: code,
26 | error: errors.New(fmt.Sprint(args...)),
27 | }
28 | }
29 |
30 | // Fatalf returns an error that will cause mage to print out the
31 | // given message and exit with the given exit code.
32 | func Fatalf(code int, format string, args ...interface{}) error {
33 | return fatalErr{
34 | code: code,
35 | error: fmt.Errorf(format, args...),
36 | }
37 | }
38 |
39 | // ExitStatus queries the error for an exit status. If the error is nil, it
40 | // returns 0. If the error does not implement ExitStatus() int, it returns 1.
41 | // Otherwise it retiurns the value from ExitStatus().
42 | func ExitStatus(err error) int {
43 | if err == nil {
44 | return 0
45 | }
46 | exit, ok := err.(exitStatus)
47 | if !ok {
48 | return 1
49 | }
50 | return exit.ExitStatus()
51 | }
52 |
--------------------------------------------------------------------------------
/vendor/github.com/magefile/mage/sh/helpers.go:
--------------------------------------------------------------------------------
1 | package sh
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "os"
7 | )
8 |
9 | // Rm removes the given file or directory even if non-empty. It will not return
10 | // an error if the target doesn't exist, only if the target cannot be removed.
11 | func Rm(path string) error {
12 | err := os.RemoveAll(path)
13 | if err == nil || os.IsNotExist(err) {
14 | return nil
15 | }
16 | return fmt.Errorf(`failed to remove %s: %v`, path, err)
17 | }
18 |
19 | // Copy robustly copies the source file to the destination, overwriting the destination if necessary.
20 | func Copy(dst string, src string) error {
21 | from, err := os.Open(src)
22 | if err != nil {
23 | return fmt.Errorf(`can't copy %s: %v`, src, err)
24 | }
25 | defer from.Close()
26 | finfo, err := from.Stat()
27 | if err != nil {
28 | return fmt.Errorf(`can't stat %s: %v`, src, err)
29 | }
30 | to, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, finfo.Mode())
31 | if err != nil {
32 | return fmt.Errorf(`can't copy to %s: %v`, dst, err)
33 | }
34 | defer to.Close()
35 | _, err = io.Copy(to, from)
36 | if err != nil {
37 | return fmt.Errorf(`error copying %s to %s: %v`, src, dst, err)
38 | }
39 | return nil
40 | }
41 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/.codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | status:
3 | project: off
4 | patch: off
5 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/.gitignore:
--------------------------------------------------------------------------------
1 | *.db
2 | *.exe
3 | *.dll
4 | *.o
5 |
6 | # VSCode
7 | .vscode
8 |
9 | # Exclude from upgrade
10 | upgrade/*.c
11 | upgrade/*.h
12 |
13 | # Exclude upgrade binary
14 | upgrade/upgrade
15 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Yasuhiro Matsumoto
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build libsqlite3
7 | // +build libsqlite3
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -DUSE_LIBSQLITE3
13 | #cgo linux LDFLAGS: -lsqlite3
14 | #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3
15 | #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/sqlite/include
16 | #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/sqlite/lib -lsqlite3
17 | #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/sqlite/include
18 | #cgo openbsd LDFLAGS: -lsqlite3
19 | #cgo solaris LDFLAGS: -lsqlite3
20 | #cgo windows LDFLAGS: -lsqlite3
21 | #cgo zos LDFLAGS: -lsqlite3
22 | */
23 | import "C"
24 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension_omit.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build sqlite_omit_load_extension
7 | // +build sqlite_omit_load_extension
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -DSQLITE_OMIT_LOAD_EXTENSION
13 | */
14 | import "C"
15 | import (
16 | "errors"
17 | )
18 |
19 | func (c *SQLiteConn) loadExtensions(extensions []string) error {
20 | return errors.New("Extensions have been disabled for static builds")
21 | }
22 |
23 | func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
24 | return errors.New("Extensions have been disabled for static builds")
25 | }
26 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_allow_uri_authority.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_allow_uri_authority
8 | // +build sqlite_allow_uri_authority
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_ALLOW_URI_AUTHORITY
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_app_armor.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build !windows && sqlite_app_armor
8 | // +build !windows,sqlite_app_armor
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_ENABLE_API_ARMOR
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_column_metadata.go:
--------------------------------------------------------------------------------
1 | //go:build sqlite_column_metadata
2 | // +build sqlite_column_metadata
3 |
4 | package sqlite3
5 |
6 | /*
7 | #ifndef USE_LIBSQLITE3
8 | #cgo CFLAGS: -DSQLITE_ENABLE_COLUMN_METADATA
9 | #include
10 | #else
11 | #include
12 | #endif
13 | */
14 | import "C"
15 |
16 | // ColumnTableName returns the table that is the origin of a particular result
17 | // column in a SELECT statement.
18 | //
19 | // See https://www.sqlite.org/c3ref/column_database_name.html
20 | func (s *SQLiteStmt) ColumnTableName(n int) string {
21 | return C.GoString(C.sqlite3_column_table_name(s.s, C.int(n)))
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_foreign_keys.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_foreign_keys
8 | // +build sqlite_foreign_keys
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_DEFAULT_FOREIGN_KEYS=1
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_fts5.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build sqlite_fts5 || fts5
7 | // +build sqlite_fts5 fts5
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -DSQLITE_ENABLE_FTS5
13 | #cgo LDFLAGS: -lm
14 | */
15 | import "C"
16 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_icu.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build sqlite_icu || icu
7 | // +build sqlite_icu icu
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo LDFLAGS: -licuuc -licui18n
13 | #cgo CFLAGS: -DSQLITE_ENABLE_ICU
14 | #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/icu4c/include
15 | #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/icu4c/lib
16 | #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/icu4c/include
17 | #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/icu4c/lib
18 | #cgo openbsd LDFLAGS: -lsqlite3
19 | */
20 | import "C"
21 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_introspect.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 |
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_introspect
8 | // +build sqlite_introspect
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_INTROSPECTION_PRAGMAS
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_math_functions.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2022 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build sqlite_math_functions
7 | // +build sqlite_math_functions
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -DSQLITE_ENABLE_MATH_FUNCTIONS
13 | #cgo LDFLAGS: -lm
14 | */
15 | import "C"
16 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_os_trace.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2022 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build sqlite_os_trace
7 | // +build sqlite_os_trace
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -DSQLITE_FORCE_OS_TRACE=1
13 | #cgo CFLAGS: -DSQLITE_DEBUG_OS_TRACE=1
14 | */
15 | import "C"
16 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 G.J.R. Timmer .
2 | // Copyright (C) 2018 segment.com
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build cgo
8 | // +build cgo
9 |
10 | package sqlite3
11 |
12 | // SQLitePreUpdateData represents all of the data available during a
13 | // pre-update hook call.
14 | type SQLitePreUpdateData struct {
15 | Conn *SQLiteConn
16 | Op int
17 | DatabaseName string
18 | TableName string
19 | OldRowID int64
20 | NewRowID int64
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 G.J.R. Timmer .
2 | // Copyright (C) 2018 segment.com
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build !sqlite_preupdate_hook && cgo
8 | // +build !sqlite_preupdate_hook,cgo
9 |
10 | package sqlite3
11 |
12 | // RegisterPreUpdateHook sets the pre-update hook for a connection.
13 | //
14 | // The callback is passed a SQLitePreUpdateData struct with the data for
15 | // the update, as well as methods for fetching copies of impacted data.
16 | //
17 | // If there is an existing preupdate hook for this connection, it will be
18 | // removed. If callback is nil the existing hook (if any) will be removed
19 | // without creating a new one.
20 | func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) {
21 | // NOOP
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_secure_delete
8 | // +build sqlite_secure_delete
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_SECURE_DELETE=1
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete_fast.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_secure_delete_fast
8 | // +build sqlite_secure_delete_fast
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_SECURE_DELETE=FAST
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_serialize_omit.go:
--------------------------------------------------------------------------------
1 | //go:build libsqlite3 && !sqlite_serialize
2 | // +build libsqlite3,!sqlite_serialize
3 |
4 | package sqlite3
5 |
6 | import (
7 | "errors"
8 | )
9 |
10 | /*
11 | #cgo CFLAGS: -DSQLITE_OMIT_DESERIALIZE
12 | */
13 | import "C"
14 |
15 | func (c *SQLiteConn) Serialize(schema string) ([]byte, error) {
16 | return nil, errors.New("sqlite3: Serialize requires the sqlite_serialize build tag when using the libsqlite3 build tag")
17 | }
18 |
19 | func (c *SQLiteConn) Deserialize(b []byte, schema string) error {
20 | return errors.New("sqlite3: Deserialize requires the sqlite_serialize build tag when using the libsqlite3 build tag")
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_stat4.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_stat4
8 | // +build sqlite_stat4
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_ENABLE_STAT4
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_full.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_vacuum_full
8 | // +build sqlite_vacuum_full
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_DEFAULT_AUTOVACUUM=1
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_incr.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | // Copyright (C) 2018 G.J.R. Timmer .
3 | //
4 | // Use of this source code is governed by an MIT-style
5 | // license that can be found in the LICENSE file.
6 |
7 | //go:build sqlite_vacuum_incr
8 | // +build sqlite_vacuum_incr
9 |
10 | package sqlite3
11 |
12 | /*
13 | #cgo CFLAGS: -DSQLITE_DEFAULT_AUTOVACUUM=2
14 | #cgo LDFLAGS: -lm
15 | */
16 | import "C"
17 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_other.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build !windows
7 | // +build !windows
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -I.
13 | #cgo linux LDFLAGS: -ldl
14 | #cgo linux,ppc LDFLAGS: -lpthread
15 | #cgo linux,ppc64 LDFLAGS: -lpthread
16 | #cgo linux,ppc64le LDFLAGS: -lpthread
17 | */
18 | import "C"
19 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_solaris.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build solaris
7 | // +build solaris
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -D__EXTENSIONS__=1
13 | #cgo LDFLAGS: -lc
14 | */
15 | import "C"
16 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2018 G.J.R. Timmer .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build cgo
7 | // +build cgo
8 |
9 | package sqlite3
10 |
11 | // usleep is a function available on *nix based systems.
12 | // This function is not present in Windows.
13 | // Windows has a sleep function but this works with seconds
14 | // and not with microseconds as usleep.
15 | //
16 | // This code should improve performance on windows because
17 | // without the presence of usleep SQLite waits 1 second.
18 | //
19 | // Source: https://github.com/php/php-src/blob/PHP-5.0/win32/time.c
20 | // License: https://github.com/php/php-src/blob/PHP-5.0/LICENSE
21 | // Details: https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
22 |
23 | /*
24 | #include
25 |
26 | void usleep(__int64 usec)
27 | {
28 | HANDLE timer;
29 | LARGE_INTEGER ft;
30 |
31 | // Convert to 100 nanosecond interval, negative value indicates relative time
32 | ft.QuadPart = -(10*usec);
33 |
34 | timer = CreateWaitableTimer(NULL, TRUE, NULL);
35 | SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
36 | WaitForSingleObject(timer, INFINITE);
37 | CloseHandle(timer);
38 | }
39 | */
40 | import "C"
41 |
42 | // EOF
43 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build windows
7 | // +build windows
8 |
9 | package sqlite3
10 |
11 | /*
12 | #cgo CFLAGS: -I.
13 | #cgo CFLAGS: -fno-stack-check
14 | #cgo CFLAGS: -fno-stack-protector
15 | #cgo CFLAGS: -mno-stack-arg-probe
16 | #cgo windows,386 CFLAGS: -D_USE_32BIT_TIME_T
17 | */
18 | import "C"
19 |
--------------------------------------------------------------------------------
/vendor/github.com/mattn/go-sqlite3/static_mock.go:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Yasuhiro Matsumoto .
2 | //
3 | // Use of this source code is governed by an MIT-style
4 | // license that can be found in the LICENSE file.
5 |
6 | //go:build !cgo
7 | // +build !cgo
8 |
9 | package sqlite3
10 |
11 | import (
12 | "database/sql"
13 | "database/sql/driver"
14 | "errors"
15 | )
16 |
17 | var errorMsg = errors.New("Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub")
18 |
19 | func init() {
20 | sql.Register("sqlite3", &SQLiteDriver{})
21 | }
22 |
23 | type (
24 | SQLiteDriver struct {
25 | Extensions []string
26 | ConnectHook func(*SQLiteConn) error
27 | }
28 | SQLiteConn struct{}
29 | )
30 |
31 | func (SQLiteDriver) Open(s string) (driver.Conn, error) { return nil, errorMsg }
32 | func (c *SQLiteConn) RegisterAggregator(string, any, bool) error { return errorMsg }
33 | func (c *SQLiteConn) RegisterAuthorizer(func(int, string, string, string) int) {}
34 | func (c *SQLiteConn) RegisterCollation(string, func(string, string) int) error { return errorMsg }
35 | func (c *SQLiteConn) RegisterCommitHook(func() int) {}
36 | func (c *SQLiteConn) RegisterFunc(string, any, bool) error { return errorMsg }
37 | func (c *SQLiteConn) RegisterRollbackHook(func()) {}
38 | func (c *SQLiteConn) RegisterUpdateHook(func(int, string, string, int64)) {}
39 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 | *.test
24 | *.iml
25 | .idea
26 | .envrc
27 |
28 | /counterfeiter
29 | integration/testdata/output
30 | *.profile
31 | *.bench
32 | /.vscode
33 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 maxbrunsfeld
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/appveyor.yml:
--------------------------------------------------------------------------------
1 | platform: x64
2 | shallow_clone: true
3 | clone_depth: 10
4 | clone_folder: c:\projects\counterfeiter
5 | image: Visual Studio 2019
6 | stack: go 1.16
7 |
8 | environment:
9 | GOPATH: c:\gopath
10 | COUNTERFEITER_NO_GENERATE_WARNING: true
11 |
12 | before_test:
13 | - go vet ./...
14 |
15 | test_script:
16 | - go install .
17 | - copy scripts\counterfeiter.bat c:\gopath\bin
18 | - set PATH=c:\gopath\bin;c:\go\bin;C:\msys64\mingw64\bin;C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
19 | - go version
20 | - go generate ./...
21 | - go build ./...
22 | - go test -race ./...
23 |
24 | build: off
25 | deploy: off
26 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/arguments/files.go:
--------------------------------------------------------------------------------
1 | package arguments
2 |
3 | import "os"
4 |
5 | type Evaler func(string) (string, error)
6 | type Stater func(string) (os.FileInfo, error)
7 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/generator/cache.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import "golang.org/x/tools/go/packages"
4 |
5 | type Cache struct {
6 | packageMap map[string]interface{}
7 | }
8 |
9 | type FakeCache struct{}
10 |
11 | func (c *FakeCache) Load(packagePath string) ([]*packages.Package, bool) { return nil, false }
12 | func (c *FakeCache) Store(packagePath string, packages []*packages.Package) {}
13 |
14 | type Cacher interface {
15 | Load(packagePath string) ([]*packages.Package, bool)
16 | Store(packagePath string, packages []*packages.Package)
17 | }
18 |
19 | func (c *Cache) Load(packagePath string) ([]*packages.Package, bool) {
20 | p, ok := c.packageMap[packagePath]
21 | if !ok {
22 | return nil, false
23 | }
24 | packages, ok := p.([]*packages.Package)
25 | return packages, ok
26 | }
27 |
28 | func (c *Cache) Store(packagePath string, packages []*packages.Package) {
29 | if c.packageMap == nil {
30 | c.packageMap = map[string]interface{}{}
31 | }
32 | c.packageMap[packagePath] = packages
33 | }
34 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/generator/ctx.go:
--------------------------------------------------------------------------------
1 | // +build go1.14
2 |
3 | package generator
4 |
5 | import "go/build"
6 |
7 | func getBuildContext(workingDir string) build.Context {
8 | ctx := build.Default
9 | ctx.Dir = workingDir
10 | return ctx
11 | }
12 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/generator/ctx_old.go:
--------------------------------------------------------------------------------
1 | // +build !go1.14
2 |
3 | package generator
4 |
5 | import "go/build"
6 |
7 | func getBuildContext(workingDir string) build.Context {
8 | ctx := build.Default
9 | return ctx
10 | }
11 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/generator/function_loader.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "errors"
5 | "go/types"
6 | )
7 |
8 | func (f *Fake) loadMethodForFunction() error {
9 | t, ok := f.Target.Type().(*types.Named)
10 | if !ok {
11 | return errors.New("target is not a named type")
12 | }
13 | sig, ok := t.Underlying().(*types.Signature)
14 | if !ok {
15 | return errors.New("target does not have an underlying function signature")
16 | }
17 | f.addTypesForMethod(sig)
18 | f.Function = methodForSignature(sig, f.TargetName, f.Imports)
19 | return nil
20 | }
21 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/generator/package_loader.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "go/types"
5 |
6 | "golang.org/x/tools/go/packages"
7 | )
8 |
9 | type rawMethod struct {
10 | Func *types.Func
11 | Signature *types.Signature
12 | }
13 |
14 | // packageMethodSet identifies the functions that are exported from a given
15 | // package.
16 | func packageMethodSet(p *packages.Package) []*rawMethod {
17 | if p == nil || p.Types == nil || p.Types.Scope() == nil {
18 | return nil
19 | }
20 | var result []*rawMethod
21 | scope := p.Types.Scope()
22 | for _, name := range scope.Names() {
23 | obj := scope.Lookup(name)
24 | if !obj.Exported() {
25 | continue // skip unexported names
26 | }
27 | fun, ok := obj.(*types.Func)
28 | if !ok {
29 | continue
30 | }
31 | sig, ok := obj.Type().(*types.Signature)
32 | if !ok {
33 | continue
34 | }
35 | result = append(result, &rawMethod{
36 | Func: fun,
37 | Signature: sig,
38 | })
39 | }
40 |
41 | return result
42 | }
43 |
--------------------------------------------------------------------------------
/vendor/github.com/maxbrunsfeld/counterfeiter/v6/generator/package_template.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "strings"
5 | "text/template"
6 | )
7 |
8 | var packageFuncs = template.FuncMap{
9 | "ToLower": strings.ToLower,
10 | "UnExport": unexport,
11 | "Replace": strings.Replace,
12 | "Generate": func(suffix string) string { return suffix + ":generate" }, // yes, this seems insane but ensures that we can use `go generate ./...` from the main package
13 | }
14 |
15 | const packageTemplate string = `{{.Header}}// Code generated by counterfeiter. DO NOT EDIT.
16 | package {{.DestinationPackage}}
17 |
18 | import (
19 | {{- range $index, $import := .Imports.ByAlias}}
20 | {{$import}}
21 | {{- end}}
22 | )
23 |
24 | //{{Generate "go"}} go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
25 | //{{Generate "counterfeiter"}} . {{.Name}}
26 |
27 | // {{.Name}} is a generated interface representing the exported functions
28 | // in the {{.TargetPackage}} package.
29 | type {{.Name}} interface {
30 | {{- range .Methods}}
31 | {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.AsReturnSignature}}
32 | {{- end}}
33 | }
34 |
35 | type {{.Name}}Shim struct {}
36 |
37 | {{- range .Methods}}
38 | func (p *{{$.Name}}Shim) {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.AsReturnSignature}} {
39 | {{if .Returns.HasLength}}return {{end}}{{$.TargetAlias}}.{{.Name}}({{.Params.AsNamedArgsForInvocation}})
40 | }
41 | {{end}}
42 | var _ {{.Name}} = new({{.Name}}Shim)
43 | `
44 |
--------------------------------------------------------------------------------
/vendor/github.com/pborman/uuid/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - 1.4.3
5 | - 1.5.3
6 | - tip
7 |
8 | script:
9 | - go test -v ./...
10 |
--------------------------------------------------------------------------------
/vendor/github.com/pborman/uuid/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | We definitely welcome patches and contribution to this project!
4 |
5 | ### Legal requirements
6 |
7 | In order to protect both you and ourselves, you will need to sign the
8 | [Contributor License Agreement](https://cla.developers.google.com/clas).
9 |
10 | You may have already signed it for other Google projects.
11 |
--------------------------------------------------------------------------------
/vendor/github.com/pborman/uuid/CONTRIBUTORS:
--------------------------------------------------------------------------------
1 | Paul Borman
2 |
--------------------------------------------------------------------------------
/vendor/github.com/pborman/uuid/README.md:
--------------------------------------------------------------------------------
1 | This project was automatically exported from code.google.com/p/go-uuid
2 |
3 | # uuid 
4 | The uuid package generates and inspects UUIDs based on [RFC 4122](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services.
5 |
6 | ###### Install
7 | `go get github.com/pborman/uuid`
8 |
9 | ###### Documentation
10 | [](http://godoc.org/github.com/pborman/uuid)
11 |
12 | Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here:
13 | http://godoc.org/github.com/pborman/uuid
14 |
--------------------------------------------------------------------------------
/vendor/github.com/pborman/uuid/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // The uuid package generates and inspects UUIDs.
6 | //
7 | // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services.
8 | package uuid
9 |
--------------------------------------------------------------------------------
/vendor/github.com/pborman/uuid/version1.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package uuid
6 |
7 | import (
8 | "encoding/binary"
9 | )
10 |
11 | // NewUUID returns a Version 1 UUID based on the current NodeID and clock
12 | // sequence, and the current time. If the NodeID has not been set by SetNodeID
13 | // or SetNodeInterface then it will be set automatically. If the NodeID cannot
14 | // be set NewUUID returns nil. If clock sequence has not been set by
15 | // SetClockSequence then it will be set automatically. If GetTime fails to
16 | // return the current NewUUID returns nil.
17 | func NewUUID() UUID {
18 | if nodeID == nil {
19 | SetNodeInterface("")
20 | }
21 |
22 | now, seq, err := GetTime()
23 | if err != nil {
24 | return nil
25 | }
26 |
27 | uuid := make([]byte, 16)
28 |
29 | time_low := uint32(now & 0xffffffff)
30 | time_mid := uint16((now >> 32) & 0xffff)
31 | time_hi := uint16((now >> 48) & 0x0fff)
32 | time_hi |= 0x1000 // Version 1
33 |
34 | binary.BigEndian.PutUint32(uuid[0:], time_low)
35 | binary.BigEndian.PutUint16(uuid[4:], time_mid)
36 | binary.BigEndian.PutUint16(uuid[6:], time_hi)
37 | binary.BigEndian.PutUint16(uuid[8:], seq)
38 | copy(uuid[10:], nodeID)
39 |
40 | return uuid
41 | }
42 |
--------------------------------------------------------------------------------
/vendor/github.com/pborman/uuid/version4.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package uuid
6 |
7 | // Random returns a Random (Version 4) UUID or panics.
8 | //
9 | // The strength of the UUIDs is based on the strength of the crypto/rand
10 | // package.
11 | //
12 | // A note about uniqueness derived from from the UUID Wikipedia entry:
13 | //
14 | // Randomly generated UUIDs have 122 random bits. One's annual risk of being
15 | // hit by a meteorite is estimated to be one chance in 17 billion, that
16 | // means the probability is about 0.00000000006 (6 × 10−11),
17 | // equivalent to the odds of creating a few tens of trillions of UUIDs in a
18 | // year and having one duplicate.
19 | func NewRandom() UUID {
20 | uuid := make([]byte, 16)
21 | randomBits([]byte(uuid))
22 | uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
23 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
24 | return uuid
25 | }
26 |
--------------------------------------------------------------------------------
/vendor/github.com/skip2/go-qrcode/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw*
2 | *.png
3 | *.directory
4 | qrcode/qrcode
5 |
--------------------------------------------------------------------------------
/vendor/github.com/skip2/go-qrcode/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - 1.7
5 |
6 | script:
7 | - go test -v ./...
8 |
9 |
--------------------------------------------------------------------------------
/vendor/github.com/skip2/go-qrcode/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Tom Harwood
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/afero/.gitignore:
--------------------------------------------------------------------------------
1 | sftpfs/file1
2 | sftpfs/test/
3 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/afero/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: go
3 | arch:
4 | - amd64
5 | - ppc64e
6 |
7 | go:
8 | - "1.14"
9 | - "1.15"
10 | - "1.16"
11 | - tip
12 |
13 | os:
14 | - linux
15 | - osx
16 |
17 | matrix:
18 | allow_failures:
19 | - go: tip
20 | fast_finish: true
21 |
22 | script:
23 | - go build -v ./...
24 | - go test -count=1 -cover -race -v ./...
25 | - go vet ./...
26 | - FILES=$(gofmt -s -l . zipfs sftpfs mem tarfs); if [[ -n "${FILES}" ]]; then echo "You have go format errors; gofmt your changes"; exit 1; fi
27 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/afero/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: '{build}'
2 | clone_folder: C:\gopath\src\github.com\spf13\afero
3 | environment:
4 | GOPATH: C:\gopath
5 | build_script:
6 | - cmd: >-
7 | go version
8 |
9 | go env
10 |
11 | go get -v github.com/spf13/afero/...
12 |
13 | go build -v github.com/spf13/afero/...
14 | test_script:
15 | - cmd: go test -count=1 -cover -race -v github.com/spf13/afero/...
16 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/afero/const_bsds.go:
--------------------------------------------------------------------------------
1 | // Copyright © 2016 Steve Francia .
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 |
14 | // +build aix darwin openbsd freebsd netbsd dragonfly
15 |
16 | package afero
17 |
18 | import (
19 | "syscall"
20 | )
21 |
22 | const BADFD = syscall.EBADF
23 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/afero/const_win_unix.go:
--------------------------------------------------------------------------------
1 | // Copyright © 2016 Steve Francia .
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 | // +build !darwin
14 | // +build !openbsd
15 | // +build !freebsd
16 | // +build !dragonfly
17 | // +build !netbsd
18 | // +build !aix
19 |
20 | package afero
21 |
22 | import (
23 | "syscall"
24 | )
25 |
26 | const BADFD = syscall.EBADFD
27 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/afero/lstater.go:
--------------------------------------------------------------------------------
1 | // Copyright © 2018 Steve Francia .
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 |
14 | package afero
15 |
16 | import (
17 | "os"
18 | )
19 |
20 | // Lstater is an optional interface in Afero. It is only implemented by the
21 | // filesystems saying so.
22 | // It will call Lstat if the filesystem iself is, or it delegates to, the os filesystem.
23 | // Else it will call Stat.
24 | // In addtion to the FileInfo, it will return a boolean telling whether Lstat was called or not.
25 | type Lstater interface {
26 | LstatIfPossible(name string) (os.FileInfo, bool, error)
27 | }
28 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/afero/mem/dir.go:
--------------------------------------------------------------------------------
1 | // Copyright © 2014 Steve Francia .
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 |
14 | package mem
15 |
16 | type Dir interface {
17 | Len() int
18 | Names() []string
19 | Files() []*FileData
20 | Add(*FileData)
21 | Remove(*FileData)
22 | }
23 |
24 | func RemoveFromMemDir(dir *FileData, f *FileData) {
25 | dir.memDir.Remove(f)
26 | }
27 |
28 | func AddToMemDir(dir *FileData, f *FileData) {
29 | dir.memDir.Add(f)
30 | }
31 |
32 | func InitializeDir(d *FileData) {
33 | if d.memDir == nil {
34 | d.dir = true
35 | d.memDir = &DirMap{}
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/github.com/terminalstatic/go-xsd-validate/.gitignore:
--------------------------------------------------------------------------------
1 | *.go_
2 |
--------------------------------------------------------------------------------
/vendor/github.com/terminalstatic/go-xsd-validate/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Wolfgang Grimm
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/github.com/terminalstatic/go-xsd-validate/workspace.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": "../../../embedTest"
5 | },
6 | {
7 | "path": "."
8 | },
9 | {
10 | "path": "../../../goPost"
11 | }
12 | ],
13 | "settings": {}
14 | }
--------------------------------------------------------------------------------
/vendor/github.com/wtolson/go-taglib/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 |
--------------------------------------------------------------------------------
/vendor/github.com/wtolson/go-taglib/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | before_install:
3 | - sudo apt-get update -qq
4 | - sudo apt-get install -qq libtagc0-dev
5 |
--------------------------------------------------------------------------------
/vendor/github.com/wtolson/go-taglib/README.md:
--------------------------------------------------------------------------------
1 | go-taglib
2 | =========
3 |
4 | Go wrapper for [taglib](http://taglib.github.com/)
5 | [](https://travis-ci.org/wtolson/go-taglib)
6 |
7 | Dependencies
8 | ------------
9 |
10 | You must have the static [taglib](http://taglib.github.com/) libraries installed
11 | in order to compile go-taglib.
12 |
13 | ### OSX:
14 |
15 | brew install taglib
16 |
17 | ### Ubuntu:
18 |
19 | sudo apt-get install libtagc0-dev
20 |
21 | Install
22 | -------
23 |
24 | go get github.com/wtolson/go-taglib
25 |
26 | Documentation
27 | -------------
28 |
29 | Checkout the documentation at http://godoc.org/github.com/wtolson/go-taglib
30 |
--------------------------------------------------------------------------------
/vendor/github.com/wtolson/go-taglib/test.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironsmile/euterpe/d69752807dfdd9f1b855a9345d67435af64c34c1/vendor/github.com/wtolson/go-taglib/test.mp3
--------------------------------------------------------------------------------
/vendor/golang.org/x/crypto/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/image/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/image/math/f64/f64.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package f64 implements float64 vector and matrix types.
6 | package f64 // import "golang.org/x/image/math/f64"
7 |
8 | // Vec2 is a 2-element vector.
9 | type Vec2 [2]float64
10 |
11 | // Vec3 is a 3-element vector.
12 | type Vec3 [3]float64
13 |
14 | // Vec4 is a 4-element vector.
15 | type Vec4 [4]float64
16 |
17 | // Mat3 is a 3x3 matrix in row major order.
18 | //
19 | // m[3*r + c] is the element in the r'th row and c'th column.
20 | type Mat3 [9]float64
21 |
22 | // Mat4 is a 4x4 matrix in row major order.
23 | //
24 | // m[4*r + c] is the element in the r'th row and c'th column.
25 | type Mat4 [16]float64
26 |
27 | // Aff3 is a 3x3 affine transformation matrix in row major order, where the
28 | // bottom row is implicitly [0 0 1].
29 | //
30 | // m[3*r + c] is the element in the r'th row and c'th column.
31 | type Aff3 [6]float64
32 |
33 | // Aff4 is a 4x4 affine transformation matrix in row major order, where the
34 | // bottom row is implicitly [0 0 0 1].
35 | //
36 | // m[4*r + c] is the element in the r'th row and c'th column.
37 | type Aff4 [12]float64
38 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/image/tiff/compress.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package tiff
6 |
7 | import (
8 | "bufio"
9 | "io"
10 | )
11 |
12 | type byteReader interface {
13 | io.Reader
14 | io.ByteReader
15 | }
16 |
17 | // unpackBits decodes the PackBits-compressed data in src and returns the
18 | // uncompressed data.
19 | //
20 | // The PackBits compression format is described in section 9 (p. 42)
21 | // of the TIFF spec.
22 | func unpackBits(r io.Reader) ([]byte, error) {
23 | buf := make([]byte, 128)
24 | dst := make([]byte, 0, 1024)
25 | br, ok := r.(byteReader)
26 | if !ok {
27 | br = bufio.NewReader(r)
28 | }
29 |
30 | for {
31 | b, err := br.ReadByte()
32 | if err != nil {
33 | if err == io.EOF {
34 | return dst, nil
35 | }
36 | return nil, err
37 | }
38 | code := int(int8(b))
39 | switch {
40 | case code >= 0:
41 | n, err := io.ReadFull(br, buf[:code+1])
42 | if err != nil {
43 | return nil, err
44 | }
45 | dst = append(dst, buf[:n]...)
46 | case code == -128:
47 | // No-op.
48 | default:
49 | if b, err = br.ReadByte(); err != nil {
50 | return nil, err
51 | }
52 | for j := 0; j < 1-code; j++ {
53 | buf[j] = b
54 | }
55 | dst = append(dst, buf[:1-code]...)
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/image/tiff/fuzz.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build gofuzz
6 |
7 | package tiff
8 |
9 | import "bytes"
10 |
11 | func Fuzz(data []byte) int {
12 | cfg, err := DecodeConfig(bytes.NewReader(data))
13 | if err != nil {
14 | return 0
15 | }
16 | if cfg.Width*cfg.Height > 1e6 {
17 | return 0
18 | }
19 | img, err := Decode(bytes.NewReader(data))
20 | if err != nil {
21 | return 0
22 | }
23 | var w bytes.Buffer
24 | err = Encode(&w, img, nil)
25 | if err != nil {
26 | panic(err)
27 | }
28 | return 1
29 | }
30 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/image/webp/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package webp implements a decoder for WEBP images.
6 | //
7 | // WEBP is defined at:
8 | // https://developers.google.com/speed/webp/docs/riff_container
9 | package webp // import "golang.org/x/image/webp"
10 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/mod/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/sync/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/trie.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package norm
6 |
7 | type valueRange struct {
8 | value uint16 // header: value:stride
9 | lo, hi byte // header: lo:n
10 | }
11 |
12 | type sparseBlocks struct {
13 | values []valueRange
14 | offset []uint16
15 | }
16 |
17 | var nfcSparse = sparseBlocks{
18 | values: nfcSparseValues[:],
19 | offset: nfcSparseOffset[:],
20 | }
21 |
22 | var nfkcSparse = sparseBlocks{
23 | values: nfkcSparseValues[:],
24 | offset: nfkcSparseOffset[:],
25 | }
26 |
27 | var (
28 | nfcData = newNfcTrie(0)
29 | nfkcData = newNfkcTrie(0)
30 | )
31 |
32 | // lookup determines the type of block n and looks up the value for b.
33 | // For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
34 | // is a list of ranges with an accompanying value. Given a matching range r,
35 | // the value for b is by r.value + (b - r.lo) * stride.
36 | func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
37 | offset := t.offset[n]
38 | header := t.values[offset]
39 | lo := offset + 1
40 | hi := lo + uint16(header.lo)
41 | for lo < hi {
42 | m := lo + (hi-lo)/2
43 | r := t.values[m]
44 | if r.lo <= b && b <= r.hi {
45 | return r.value + uint16(b-r.lo)*header.value
46 | }
47 | if b < r.lo {
48 | hi = m
49 | } else {
50 | lo = m + 1
51 | }
52 | }
53 | return 0
54 | }
55 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/go/ast/astutil/util.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package astutil
6 |
7 | import "go/ast"
8 |
9 | // Unparen returns e with any enclosing parentheses stripped.
10 | func Unparen(e ast.Expr) ast.Expr {
11 | for {
12 | p, ok := e.(*ast.ParenExpr)
13 | if !ok {
14 | return e
15 | }
16 | e = p.X
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/go/packages/loadmode_string.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package packages
6 |
7 | import (
8 | "fmt"
9 | "strings"
10 | )
11 |
12 | var allModes = []LoadMode{
13 | NeedName,
14 | NeedFiles,
15 | NeedCompiledGoFiles,
16 | NeedImports,
17 | NeedDeps,
18 | NeedExportFile,
19 | NeedTypes,
20 | NeedSyntax,
21 | NeedTypesInfo,
22 | NeedTypesSizes,
23 | }
24 |
25 | var modeStrings = []string{
26 | "NeedName",
27 | "NeedFiles",
28 | "NeedCompiledGoFiles",
29 | "NeedImports",
30 | "NeedDeps",
31 | "NeedExportFile",
32 | "NeedTypes",
33 | "NeedSyntax",
34 | "NeedTypesInfo",
35 | "NeedTypesSizes",
36 | }
37 |
38 | func (mod LoadMode) String() string {
39 | m := mod
40 | if m == 0 {
41 | return "LoadMode(0)"
42 | }
43 | var out []string
44 | for i, x := range allModes {
45 | if x > m {
46 | break
47 | }
48 | if (m & x) != 0 {
49 | out = append(out, modeStrings[i])
50 | m = m ^ x
51 | }
52 | }
53 | if m != 0 {
54 | out = append(out, "Unknown")
55 | }
56 | return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|"))
57 | }
58 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/go/types/typeutil/imports.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package typeutil
6 |
7 | import "go/types"
8 |
9 | // Dependencies returns all dependencies of the specified packages.
10 | //
11 | // Dependent packages appear in topological order: if package P imports
12 | // package Q, Q appears earlier than P in the result.
13 | // The algorithm follows import statements in the order they
14 | // appear in the source code, so the result is a total order.
15 | func Dependencies(pkgs ...*types.Package) []*types.Package {
16 | var result []*types.Package
17 | seen := make(map[*types.Package]bool)
18 | var visit func(pkgs []*types.Package)
19 | visit = func(pkgs []*types.Package) {
20 | for _, p := range pkgs {
21 | if !seen[p] {
22 | seen[p] = true
23 | visit(p.Imports())
24 | result = append(result, p)
25 | }
26 | }
27 | }
28 | visit(pkgs)
29 | return result
30 | }
31 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/aliases/aliases.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package aliases
6 |
7 | import (
8 | "go/token"
9 | "go/types"
10 | )
11 |
12 | // Package aliases defines backward compatible shims
13 | // for the types.Alias type representation added in 1.22.
14 | // This defines placeholders for x/tools until 1.26.
15 |
16 | // NewAlias creates a new TypeName in Package pkg that
17 | // is an alias for the type rhs.
18 | //
19 | // The enabled parameter determines whether the resulting [TypeName]'s
20 | // type is an [types.Alias]. Its value must be the result of a call to
21 | // [Enabled], which computes the effective value of
22 | // GODEBUG=gotypesalias=... by invoking the type checker. The Enabled
23 | // function is expensive and should be called once per task (e.g.
24 | // package import), not once per call to NewAlias.
25 | func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type) *types.TypeName {
26 | if enabled {
27 | tname := types.NewTypeName(pos, pkg, name, nil)
28 | newAlias(tname, rhs)
29 | return tname
30 | }
31 | return types.NewTypeName(pos, pkg, name, rhs)
32 | }
33 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build !go1.22
6 | // +build !go1.22
7 |
8 | package aliases
9 |
10 | import (
11 | "go/types"
12 | )
13 |
14 | // Alias is a placeholder for a go/types.Alias for <=1.21.
15 | // It will never be created by go/types.
16 | type Alias struct{}
17 |
18 | func (*Alias) String() string { panic("unreachable") }
19 | func (*Alias) Underlying() types.Type { panic("unreachable") }
20 | func (*Alias) Obj() *types.TypeName { panic("unreachable") }
21 | func Rhs(alias *Alias) types.Type { panic("unreachable") }
22 |
23 | // Unalias returns the type t for go <=1.21.
24 | func Unalias(t types.Type) types.Type { return t }
25 |
26 | func newAlias(name *types.TypeName, rhs types.Type) *Alias { panic("unreachable") }
27 |
28 | // Enabled reports whether [NewAlias] should create [types.Alias] types.
29 | //
30 | // Before go1.22, this function always returns false.
31 | func Enabled() bool { return false }
32 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/event/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package event provides a set of packages that cover the main
6 | // concepts of telemetry in an implementation agnostic way.
7 | package event
8 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/event/keys/standard.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package keys
6 |
7 | var (
8 | // Msg is a key used to add message strings to label lists.
9 | Msg = NewString("message", "a readable message")
10 | // Label is a key used to indicate an event adds labels to the context.
11 | Label = NewTag("label", "a label context marker")
12 | // Start is used for things like traces that have a name.
13 | Start = NewString("start", "span start")
14 | // Metric is a key used to indicate an event records metrics.
15 | End = NewTag("end", "a span end marker")
16 | // Metric is a key used to indicate an event records metrics.
17 | Detach = NewTag("detach", "a span detach marker")
18 | // Err is a key used to add error values to label lists.
19 | Err = NewError("error", "an error that occurred")
20 | // Metric is a key used to indicate an event records metrics.
21 | Metric = NewTag("metric", "a metric event marker")
22 | )
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/event/keys/util.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package keys
6 |
7 | import (
8 | "sort"
9 | "strings"
10 | )
11 |
12 | // Join returns a canonical join of the keys in S:
13 | // a sorted comma-separated string list.
14 | func Join[S ~[]T, T ~string](s S) string {
15 | strs := make([]string, 0, len(s))
16 | for _, v := range s {
17 | strs = append(strs, string(v))
18 | }
19 | sort.Strings(strs)
20 | return strings.Join(strs, ",")
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build !go1.11
6 | // +build !go1.11
7 |
8 | package gcimporter
9 |
10 | import "go/types"
11 |
12 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
13 | named := make([]*types.Named, len(embeddeds))
14 | for i, e := range embeddeds {
15 | var ok bool
16 | named[i], ok = e.(*types.Named)
17 | if !ok {
18 | panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
19 | }
20 | }
21 | return types.NewInterface(methods, named)
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build go1.11
6 | // +build go1.11
7 |
8 | package gcimporter
9 |
10 | import "go/types"
11 |
12 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
13 | return types.NewInterfaceType(methods, embeddeds)
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package gcimporter
6 |
7 | import "go/types"
8 |
9 | const iexportVersion = iexportVersionGenerics
10 |
11 | // additionalPredeclared returns additional predeclared types in go.1.18.
12 | func additionalPredeclared() []types.Type {
13 | return []types.Type{
14 | // comparable
15 | types.Universe.Lookup("comparable").Type(),
16 |
17 | // any
18 | types.Universe.Lookup("any").Type(),
19 | }
20 | }
21 |
22 | // See cmd/compile/internal/types.SplitVargenSuffix.
23 | func splitVargenSuffix(name string) (base, suffix string) {
24 | i := len(name)
25 | for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
26 | i--
27 | }
28 | const dot = "·"
29 | if i >= len(dot) && name[i-len(dot):i] == dot {
30 | i -= len(dot)
31 | return name[:i], name[i:]
32 | }
33 | return name, ""
34 | }
35 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build !goexperiment.unified
6 | // +build !goexperiment.unified
7 |
8 | package gcimporter
9 |
10 | const unifiedIR = false
11 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build goexperiment.unified
6 | // +build goexperiment.unified
7 |
8 | package gcimporter
9 |
10 | const unifiedIR = true
11 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/packagesinternal/packages.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package packagesinternal exposes internal-only fields from go/packages.
6 | package packagesinternal
7 |
8 | var GetForTest = func(p interface{}) string { return "" }
9 | var GetDepsErrors = func(p interface{}) []*PackageError { return nil }
10 |
11 | type PackageError struct {
12 | ImportStack []string // shortest path from package named on command line to this one
13 | Pos string // position of error (if present, file:line:col)
14 | Err string // the error itself
15 | }
16 |
17 | var TypecheckCgo int
18 | var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
19 | var ForTest int // must be set as a LoadMode to call GetForTest
20 |
21 | var SetModFlag = func(config interface{}, value string) {}
22 | var SetModFile = func(config interface{}, value string) {}
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/pkgbits/flags.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package pkgbits
6 |
7 | const (
8 | flagSyncMarkers = 1 << iota // file format contains sync markers
9 | )
10 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build !go1.7
6 | // +build !go1.7
7 |
8 | // TODO(mdempsky): Remove after #44505 is resolved
9 |
10 | package pkgbits
11 |
12 | import "runtime"
13 |
14 | func walkFrames(pcs []uintptr, visit frameVisitor) {
15 | for _, pc := range pcs {
16 | fn := runtime.FuncForPC(pc)
17 | file, line := fn.FileLine(pc)
18 |
19 | visit(file, line, fn.Name(), pc-fn.Entry())
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build go1.7
6 | // +build go1.7
7 |
8 | package pkgbits
9 |
10 | import "runtime"
11 |
12 | // walkFrames calls visit for each call frame represented by pcs.
13 | //
14 | // pcs should be a slice of PCs, as returned by runtime.Callers.
15 | func walkFrames(pcs []uintptr, visit frameVisitor) {
16 | if len(pcs) == 0 {
17 | return
18 | }
19 |
20 | frames := runtime.CallersFrames(pcs)
21 | for {
22 | frame, more := frames.Next()
23 | visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry)
24 | if !more {
25 | return
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/pkgbits/reloc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package pkgbits
6 |
7 | // A RelocKind indicates a particular section within a unified IR export.
8 | type RelocKind int32
9 |
10 | // An Index represents a bitstream element index within a particular
11 | // section.
12 | type Index int32
13 |
14 | // A relocEnt (relocation entry) is an entry in an element's local
15 | // reference table.
16 | //
17 | // TODO(mdempsky): Rename this too.
18 | type RelocEnt struct {
19 | Kind RelocKind
20 | Idx Index
21 | }
22 |
23 | // Reserved indices within the meta relocation section.
24 | const (
25 | PublicRootIdx Index = 0
26 | PrivateRootIdx Index = 1
27 | )
28 |
29 | const (
30 | RelocString RelocKind = iota
31 | RelocMeta
32 | RelocPosBase
33 | RelocPkg
34 | RelocName
35 | RelocType
36 | RelocObj
37 | RelocObjExt
38 | RelocObjDict
39 | RelocBody
40 |
41 | numRelocs = iota
42 | )
43 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/pkgbits/support.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package pkgbits
6 |
7 | import "fmt"
8 |
9 | func assert(b bool) {
10 | if !b {
11 | panic("assertion failed")
12 | }
13 | }
14 |
15 | func errorf(format string, args ...interface{}) {
16 | panic(fmt.Errorf(format, args...))
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/typesinternal/recv.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package typesinternal
6 |
7 | import (
8 | "go/types"
9 |
10 | "golang.org/x/tools/internal/aliases"
11 | )
12 |
13 | // ReceiverNamed returns the named type (if any) associated with the
14 | // type of recv, which may be of the form N or *N, or aliases thereof.
15 | // It also reports whether a Pointer was present.
16 | func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) {
17 | t := recv.Type()
18 | if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
19 | isPtr = true
20 | t = ptr.Elem()
21 | }
22 | named, _ = aliases.Unalias(t).(*types.Named)
23 | return
24 | }
25 |
26 | // Unpointer returns T given *T or an alias thereof.
27 | // For all other types it is the identity function.
28 | // It does not look at underlying types.
29 | // The result may be an alias.
30 | //
31 | // Use this function to strip off the optional pointer on a receiver
32 | // in a field or method selection, without losing the named type
33 | // (which is needed to compute the method set).
34 | //
35 | // See also [typeparams.MustDeref], which removes one level of
36 | // indirection from the type, regardless of named types (analogous to
37 | // a LOAD instruction).
38 | func Unpointer(t types.Type) types.Type {
39 | if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
40 | return ptr.Elem()
41 | }
42 | return t
43 | }
44 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/versions/features.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package versions
6 |
7 | // This file contains predicates for working with file versions to
8 | // decide when a tool should consider a language feature enabled.
9 |
10 | // GoVersions that features in x/tools can be gated to.
11 | const (
12 | Go1_18 = "go1.18"
13 | Go1_19 = "go1.19"
14 | Go1_20 = "go1.20"
15 | Go1_21 = "go1.21"
16 | Go1_22 = "go1.22"
17 | )
18 |
19 | // Future is an invalid unknown Go version sometime in the future.
20 | // Do not use directly with Compare.
21 | const Future = ""
22 |
23 | // AtLeast reports whether the file version v comes after a Go release.
24 | //
25 | // Use this predicate to enable a behavior once a certain Go release
26 | // has happened (and stays enabled in the future).
27 | func AtLeast(v, release string) bool {
28 | if v == Future {
29 | return true // an unknown future version is always after y.
30 | }
31 | return Compare(Lang(v), Lang(release)) >= 0
32 | }
33 |
34 | // Before reports whether the file version v is strictly before a Go release.
35 | //
36 | // Use this predicate to disable a behavior once a certain Go release
37 | // has happened (and stays enabled in the future).
38 | func Before(v, release string) bool {
39 | if v == Future {
40 | return false // an unknown future version happens after y.
41 | }
42 | return Compare(Lang(v), Lang(release)) < 0
43 | }
44 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/versions/toolchain.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package versions
6 |
7 | // toolchain is maximum version (<1.22) that the go toolchain used
8 | // to build the current tool is known to support.
9 | //
10 | // When a tool is built with >=1.22, the value of toolchain is unused.
11 | //
12 | // x/tools does not support building with go <1.18. So we take this
13 | // as the minimum possible maximum.
14 | var toolchain string = Go1_18
15 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build go1.19
6 | // +build go1.19
7 |
8 | package versions
9 |
10 | func init() {
11 | if Compare(toolchain, Go1_19) < 0 {
12 | toolchain = Go1_19
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build go1.20
6 | // +build go1.20
7 |
8 | package versions
9 |
10 | func init() {
11 | if Compare(toolchain, Go1_20) < 0 {
12 | toolchain = Go1_20
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build go1.21
6 | // +build go1.21
7 |
8 | package versions
9 |
10 | func init() {
11 | if Compare(toolchain, Go1_21) < 0 {
12 | toolchain = Go1_21
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/versions/types.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package versions
6 |
7 | import (
8 | "go/types"
9 | )
10 |
11 | // GoVersion returns the Go version of the type package.
12 | // It returns zero if no version can be determined.
13 | func GoVersion(pkg *types.Package) string {
14 | // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25.
15 | if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok {
16 | return pkg.GoVersion()
17 | }
18 | return ""
19 | }
20 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/tools/internal/versions/types_go121.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build !go1.22
6 | // +build !go1.22
7 |
8 | package versions
9 |
10 | import (
11 | "go/ast"
12 | "go/types"
13 | )
14 |
15 | // FileVersion returns a language version (<=1.21) derived from runtime.Version()
16 | // or an unknown future version.
17 | func FileVersion(info *types.Info, file *ast.File) string {
18 | // In x/tools built with Go <= 1.21, we do not have Info.FileVersions
19 | // available. We use a go version derived from the toolchain used to
20 | // compile the tool by default.
21 | // This will be <= go1.21. We take this as the maximum version that
22 | // this tool can support.
23 | //
24 | // There are no features currently in x/tools that need to tell fine grained
25 | // differences for versions <1.22.
26 | return toolchain
27 | }
28 |
29 | // InitFileVersions is a noop when compiled with this Go version.
30 | func InitFileVersions(*types.Info) {}
31 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/xerrors/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/xerrors/README:
--------------------------------------------------------------------------------
1 | This repository holds the transition packages for the new Go 1.13 error values.
2 | See golang.org/design/29934-error-values.
3 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/xerrors/codereview.cfg:
--------------------------------------------------------------------------------
1 | issuerepo: golang/go
2 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/xerrors/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package xerrors implements functions to manipulate errors.
6 | //
7 | // This package is based on the Go 2 proposal for error values:
8 | // https://golang.org/design/29934-error-values
9 | //
10 | // These functions were incorporated into the standard library's errors package
11 | // in Go 1.13:
12 | // - Is
13 | // - As
14 | // - Unwrap
15 | //
16 | // Also, Errorf's %w verb was incorporated into fmt.Errorf.
17 | //
18 | // Use this package to get equivalent behavior in all supported Go versions.
19 | //
20 | // No other features of this package were included in Go 1.13, and at present
21 | // there are no plans to include any of them.
22 | package xerrors // import "golang.org/x/xerrors"
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/xerrors/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package xerrors
6 |
7 | import "fmt"
8 |
9 | // errorString is a trivial implementation of error.
10 | type errorString struct {
11 | s string
12 | frame Frame
13 | }
14 |
15 | // New returns an error that formats as the given text.
16 | //
17 | // The returned error contains a Frame set to the caller's location and
18 | // implements Formatter to show this information when printed with details.
19 | func New(text string) error {
20 | return &errorString{text, Caller(1)}
21 | }
22 |
23 | func (e *errorString) Error() string {
24 | return e.s
25 | }
26 |
27 | func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) }
28 |
29 | func (e *errorString) FormatError(p Printer) (next error) {
30 | p.Print(e.s)
31 | e.frame.Format(p)
32 | return nil
33 | }
34 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/xerrors/format.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package xerrors
6 |
7 | // A Formatter formats error messages.
8 | type Formatter interface {
9 | error
10 |
11 | // FormatError prints the receiver's first error and returns the next error in
12 | // the error chain, if any.
13 | FormatError(p Printer) (next error)
14 | }
15 |
16 | // A Printer formats error messages.
17 | //
18 | // The most common implementation of Printer is the one provided by package fmt
19 | // during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message
20 | // typically provide their own implementations.
21 | type Printer interface {
22 | // Print appends args to the message output.
23 | Print(args ...interface{})
24 |
25 | // Printf writes a formatted string.
26 | Printf(format string, args ...interface{})
27 |
28 | // Detail reports whether error detail is requested.
29 | // After the first call to Detail, all text written to the Printer
30 | // is formatted as additional detail, or ignored when
31 | // detail has not been requested.
32 | // If Detail returns false, the caller can avoid printing the detail at all.
33 | Detail() bool
34 | }
35 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/xerrors/internal/internal.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal
6 |
7 | // EnableTrace indicates whether stack information should be recorded in errors.
8 | var EnableTrace = true
9 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/gorp.v1/.gitignore:
--------------------------------------------------------------------------------
1 | _test
2 | _testmain.go
3 | _obj
4 | *~
5 | *.6
6 | 6.out
7 | gorptest.bin
8 | tmp
9 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/gorp.v1/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | go:
3 | - 1.1
4 | - tip
5 |
6 | services:
7 | - mysql
8 | - postgres
9 | - sqlite3
10 |
11 | before_script:
12 | - mysql -e "CREATE DATABASE gorptest;"
13 | - mysql -u root -e "GRANT ALL ON gorptest.* TO gorptest@localhost IDENTIFIED BY 'gorptest'"
14 | - psql -c "CREATE DATABASE gorptest;" -U postgres
15 | - psql -c "CREATE USER "gorptest" WITH SUPERUSER PASSWORD 'gorptest';" -U postgres
16 | - go get github.com/lib/pq
17 | - go get github.com/mattn/go-sqlite3
18 | - go get github.com/ziutek/mymysql/godrv
19 | - go get github.com/go-sql-driver/mysql
20 |
21 | script: ./test_all.sh
22 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/gorp.v1/LICENSE:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright (c) 2012 James Cooper
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | 'Software'), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/gorp.v1/Makefile:
--------------------------------------------------------------------------------
1 | include $(GOROOT)/src/Make.inc
2 |
3 | TARG = github.com/coopernurse/gorp
4 | GOFILES = gorp.go dialect.go
5 |
6 | include $(GOROOT)/src/Make.pkg
--------------------------------------------------------------------------------
/vendor/gopkg.in/gorp.v1/errors.go:
--------------------------------------------------------------------------------
1 | package gorp
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // A non-fatal error, when a select query returns columns that do not exist
8 | // as fields in the struct it is being mapped to
9 | type NoFieldInTypeError struct {
10 | TypeName string
11 | MissingColNames []string
12 | }
13 |
14 | func (err *NoFieldInTypeError) Error() string {
15 | return fmt.Sprintf("gorp: No fields %+v in type %s", err.MissingColNames, err.TypeName)
16 | }
17 |
18 | // returns true if the error is non-fatal (ie, we shouldn't immediately return)
19 | func NonFatalError(err error) bool {
20 | switch err.(type) {
21 | case *NoFieldInTypeError:
22 | return true
23 | default:
24 | return false
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/gorp.v1/test_all.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # on macs, you may need to:
4 | # export GOBUILDFLAG=-ldflags -linkmode=external
5 |
6 | set -e
7 |
8 | export GORP_TEST_DSN=gorptest/gorptest/gorptest
9 | export GORP_TEST_DIALECT=mysql
10 | go test $GOBUILDFLAG .
11 |
12 | export GORP_TEST_DSN=gorptest:gorptest@/gorptest
13 | export GORP_TEST_DIALECT=gomysql
14 | go test $GOBUILDFLAG .
15 |
16 | export GORP_TEST_DSN="user=gorptest password=gorptest dbname=gorptest sslmode=disable"
17 | export GORP_TEST_DIALECT=postgres
18 | go test $GOBUILDFLAG .
19 |
20 | export GORP_TEST_DSN=/tmp/gorptest.bin
21 | export GORP_TEST_DIALECT=sqlite
22 | go test $GOBUILDFLAG .
23 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/mineo/gocaa.v1/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - "tip"
5 | - "1.10"
6 | - "1.9"
7 | - "1.8"
8 | - "1.7"
9 | - "1.6"
10 | - "1.5"
11 | - "1.4"
12 | - "1.3"
13 | - "1.2"
14 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/mineo/gocaa.v1/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Wieland Hoffmann
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so,
8 | subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/mineo/gocaa.v1/README.md:
--------------------------------------------------------------------------------
1 | # gocaa
2 |
3 | [](https://travis-ci.org/mineo/gocaa)
4 | [](https://godoc.org/gopkg.in/mineo/gocaa.v1)
5 |
6 | This package contains a library to access the
7 | [Cover Art Archive](https://coverartarchive.org) from Go.
8 |
9 | ## Installation
10 | To get the latest stable version, user
11 |
12 | go get gopkg.in/mineo/gocaa.v1
13 |
14 | and import it with
15 |
16 | import "gopkg.in/mineo/gocaa.v1"
17 |
18 | To get the latest version, use
19 |
20 | go get github.com/mineo/gocaa
21 |
22 | and import it with
23 |
24 | import "github.com/mineo/gocaa"
25 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/mineo/gocaa.v1/errors.go:
--------------------------------------------------------------------------------
1 | package caa
2 |
3 | import (
4 | "fmt"
5 | "net/url"
6 | )
7 |
8 | // HTTPError is an error that occured while accessing URL.
9 | // Instead of a status code of 200, StatusCode was returned by the server.
10 | type HTTPError struct {
11 | StatusCode int
12 | URL *url.URL
13 | }
14 |
15 | func (e HTTPError) Error() string {
16 | return fmt.Sprintf("%d on %s", e.StatusCode, e.URL.String())
17 | }
18 |
19 | // InvalidImageSizeError indicates that Size is not valid for EntityType
20 | type InvalidImageSizeError struct {
21 | EntityType string
22 | Size int
23 | }
24 |
25 | func (e InvalidImageSizeError) Error() string {
26 | return fmt.Sprintf("%s doesn't support image size %d", e.EntityType, e.Size)
27 | }
28 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/mineo/gocaa.v1/imagesizes.go:
--------------------------------------------------------------------------------
1 | package caa
2 |
3 | // These constants can be used to indicate the required image size to the various image retrieval methods
4 | const (
5 | // 250px
6 | ImageSizeSmall = iota
7 | // 500px
8 | ImageSizeLarge
9 | ImageSizeOriginal
10 | // 250px
11 | ImageSize250 = ImageSizeSmall
12 | // 500px
13 | ImageSize500 = ImageSizeLarge
14 | // 1200px
15 | ImageSize1200
16 | )
17 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/mineo/gocaa.v1/reexports.go:
--------------------------------------------------------------------------------
1 | package caa
2 |
3 | import (
4 | u "github.com/pborman/uuid"
5 | )
6 |
7 | // StringToUUID is a reexported helper function of the UUID module to parse a
8 | // string into a UUID.
9 | func StringToUUID(str string) (uuid u.UUID) {
10 | return u.Parse(str)
11 | }
12 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/mineo/gocaa.v1/types.go:
--------------------------------------------------------------------------------
1 | package caa
2 |
3 | // CoverArtInfo is the unmarshaled representation of a JSON file in the Cover Art Archive.
4 | // See https://musicbrainz.org/doc/Cover_Art_Archive/API#Cover_Art_Archive_Metadata for an example.
5 | type CoverArtInfo struct {
6 | Images []CoverArtImageInfo
7 | Release string
8 | }
9 |
10 | // CoverArtImageInfo is the unmarshaled representation of a single images metadata in a CAA JSON file.
11 | // See https://musicbrainz.org/doc/Cover_Art_Archive/API#Cover_Art_Archive_Metadata for an example.
12 | type CoverArtImageInfo struct {
13 | Approved bool
14 | Back bool
15 | Comment string
16 | Edit int
17 | Front bool
18 | ID string
19 | Image string
20 | Thumbnails ThumbnailMap
21 | Types []string
22 | }
23 |
24 | // CoverArtImage is a wrapper around an image from the CAA, containing its binary data and mimetype information.
25 | type CoverArtImage struct {
26 | Data []byte
27 | Mimetype string
28 | }
29 |
30 | // ThumbnailMap maps thumbnail names to their URLs. The only valid keys are
31 | // "large" and "small", "250", "500" and "1200".
32 | type ThumbnailMap map[string]string
33 |
--------------------------------------------------------------------------------
/watch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script will watch for changes in the .css or .js files of the project
4 | # and rebuild the "squashed" versions which are to be released.
5 |
6 | find . -type f -name '*.css' -or -name '*.js' | grep -v '.min.' | entr ./http_root/squash
7 |
--------------------------------------------------------------------------------